久久精品水蜜桃av综合天堂,久久精品丝袜高跟鞋,精品国产肉丝袜久久,国产一区二区三区色噜噜,黑人video粗暴亚裔

PHP注解

2024-01-04 168

PHP的注解功能提供了在代碼中添加結(jié)構(gòu)化、機器可讀的元數(shù)據(jù)的能力。它可以應用于類、方法、函數(shù)、參數(shù)、屬性和類常量等聲明部分。通過反射API,我們可以在運行時獲取注解所定義的元數(shù)據(jù)。因此,注解可以作為一種直接嵌入代碼的配置式語言。

一、PHP注解概述

通過注解的使用,在應用中實現(xiàn)功能、使用功能可以相互解耦。 某種程度上講,它可以和接口(interface)與其實現(xiàn)(implementation)相比較。 但接口與實現(xiàn)是代碼相關的,注解則與聲明額外信息和配置相關。 接口可以通過類來實現(xiàn),而注解也可以聲明到方法、函數(shù)、參數(shù)、屬性、類常量中。 因此它們比接口更靈活。

注解使用的一個簡單例子:將接口(interface)的可選方法改用注解實現(xiàn)。 我們假設接口 ActionHandler 代表了應用的一個操作: 部分 action handler 的實現(xiàn)需要 setup,部分不需要。 我們可以使用注解,而不用要求所有類必須實現(xiàn) ActionHandler 接口并實現(xiàn) setUp() 方法。 因此帶來一個好處——可以多次使用注解。

用注解實現(xiàn)接口的可選方法:

<?php
interface?ActionHandler
{
????public?function?execute();
}

#[Attribute]
class?SetUp?{}

class?CopyFile?implements?ActionHandler
{
????public?string?$fileName;
????public?string?$targetDirectory;

????#[SetUp]
????public?function?fileExists()
????{
????????if?(!file_exists($this->fileName))?{
????????????throw?new?RuntimeException("File?does?not?exist");
????????}
????}

????#[SetUp]
????public?function?targetDirectoryExists()
????{
????????if?(!file_exists($this->targetDirectory))?{
????????????mkdir($this->targetDirectory);
????????}?elseif?(!is_dir($this->targetDirectory))?{
????????????throw?new?RuntimeException("Target?directory?$this->targetDirectory?is?not?a?directory");
????????}
????}

????public?function?execute()
????{
????????copy($this->fileName,?$this->targetDirectory?.?'/'?.?basename($this->fileName));
????}
}

function?executeAction(ActionHandler?$actionHandler)
{
????$reflection?=?new?ReflectionObject($actionHandler);

????foreach?($reflection->getMethods()?as?$method)?{
????????$attributes?=?$method->getAttributes(SetUp::class);

????????if?(count($attributes)?>?0)?{
????????????$methodName?=?$method->getName();

????????????$actionHandler->$methodName();
????????}
????}

????$actionHandler->execute();
}

$copyAction?=?new?CopyFile();
$copyAction->fileName?=?"/tmp/foo.jpg";
$copyAction->targetDirectory?=?"/home/user";

executeAction($copyAction);

二、PHP注解語法

注解語法包含以下幾部分。 首先,注解聲明總是以 #[ 開頭,以 ] 結(jié)尾來包圍。 內(nèi)部則是一個或以逗號包含的多個注解。 注解的名稱可以是非限定、限定、完全限定的名稱。 注解的參數(shù)是可以選的,以常見的括號()包圍。 注解的參數(shù)只能是字面值或者常量表達式。 它同時接受位置參數(shù)和命名參數(shù)兩種語法。

通過反射 API 請求注解實例時,注解的名稱會被解析到一個類,注解的參數(shù)則傳入該類的構(gòu)造器中。 因此每個注解都需要引入一個類。

注解語法:

<?php
//?a.php
namespace?MyExample;

use?Attribute;

#[Attribute]
class?MyAttribute
{
????const?VALUE?=?'value';

????private?$value;

????public?function?__construct($value?=?null)
????{
????????$this->value?=?$value;
????}
}

//?b.php

namespace?Another;

use?MyExample\MyAttribute;

#[MyAttribute]
#[\MyExample\MyAttribute]
#[MyAttribute(1234)]
#[MyAttribute(value:?1234)]
#[MyAttribute(MyAttribute::VALUE)]
#[MyAttribute(array("key"?=>?"value"))]
#[MyAttribute(100?+?200)]
class?Thing
{
}

#[MyAttribute(1234),?MyAttribute(5678)]
class?AnotherThing
{
}

三、使用反射API讀取注解

反射 API 提供了 getAttributes() 方法, 類、方法、函數(shù)、參數(shù)、屬性、類常量的反射對象可通過它獲取相應的注解。 該方法返回了 ReflectionAttribute 實例的數(shù)組, 可用于查詢注解名稱、參數(shù)、也可以實例化一個注解。

實例和反射注解的分離使得程序員增加了在丟失反射類、類型錯誤、丟失參數(shù)等情況下的處理能力,也能處理錯誤。 只有調(diào)用 ReflectionAttribute::newInstance() 后,注解類的對象才會以驗證過匹配的參數(shù)來實例化。

通過反射 API 讀取注解:

<?php

#[Attribute]
class?MyAttribute
{
????public?$value;

????public?function?__construct($value)
????{
????????$this->value?=?$value;
????}
}

#[MyAttribute(value:?1234)]
class?Thing
{
}

function?dumpAttributeData($reflection)?{
????$attributes?=?$reflection->getAttributes();

????foreach?($attributes?as?$attribute)?{
???????var_dump($attribute->getName());
???????var_dump($attribute->getArguments());
???????var_dump($attribute->newInstance());
????}
}

dumpAttributeData(new?ReflectionClass(Thing::class));
/*
string(11)?"MyAttribute"
array(1)?{
??["value"]=>
??int(1234)
}
object(MyAttribute)#3?(1)?{
??["value"]=>
??int(1234)
}
*/

通過傳入?yún)?shù):待搜索的注解類名,可返回指定的注解類, 而不需要再到反射類中迭代循環(huán)獲取所有注解。

使用反射 API 讀取指定的注解:

<?php

function?dumpMyAttributeData($reflection)?{
????$attributes?=?$reflection->getAttributes(MyAttribute::class);

????foreach?($attributes?as?$attribute)?{
???????var_dump($attribute->getName());
???????var_dump($attribute->getArguments());
???????var_dump($attribute->newInstance());
????}
}

dumpMyAttributeData(new?ReflectionClass(Thing::class));

四、聲明注解類

雖然沒有嚴格要求,推薦為每個注解創(chuàng)建一個實際的類。 在這個最簡單的例子中,通過 use 語法從全局命名空間引入 #[Attribute] 注解所需要全空的類。

簡單的 Attribute 類:

<?php
namespace Example;
use Attribute;
#[Attribute]
class MyAttribute
{
}

要限制指定注解的聲明類型,可為 #[Attribute] 注解第一個參數(shù)傳入字節(jié)位掩碼設置。

目標限定使用的注解:

<?php
namespace Example;
use Attribute;
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION)]
class MyAttribute
{
}

在另一個類型中聲明 MyAttribute 會在調(diào)用 ReflectionAttribute::newInstance() 時拋出異常。

可以指定以下目標:

Attribute::TARGET_CLASS
Attribute::TARGET_FUNCTION
Attribute::TARGET_METHOD
Attribute::TARGET_PROPERTY
Attribute::TARGET_CLASS_CONSTANT
Attribute::TARGET_PARAMETER
Attribute::TARGET_ALL

注解在每個聲明中默認情況下只能使用一次。 如果需要重復,可以在 #[Attribute] 聲明中設置字節(jié)位掩碼。

使用 IS_REPEATABLE 允許注解在聲明中出現(xiàn)多次:

<?php
namespace Example;
use Attribute;
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION | Attribute::IS_REPEATABLE)]
class MyAttribute
{
}
  • 廣告合作

  • QQ群號:4114653

溫馨提示:
1、本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享網(wǎng)絡內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。郵箱:2942802716#qq.com(#改為@)。 2、本站原創(chuàng)內(nèi)容未經(jīng)允許不得轉(zhuǎn)裁,轉(zhuǎn)載請注明出處“站長百科”和原文地址。
PHP注解
上一篇: PHP生成器
PHP注解
下一篇: PHP引用