成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

php8的注解你了解多少?

注解語法

#[Route] #[Route()] #[Route("/path", ["get"])] #[Route(path: "/path", methods: ["get"])]

其實語法跟實例化類非常相似,只是少了個 new 關(guān)鍵詞而已。

要注意的是, 注解名不能是變量,只能是常量或常量表達式

//實例化類 $route = new Route(path: "/path", methods: ["get"]);

(path: "/path", methods: ["get"])php8 的新語法,在傳參的時候可以指定參數(shù)名,不按照形參的順序傳參。

注解類作用范圍

在定義注解類時,你可以使用內(nèi)置注解類 #[Attribute] 定義注解類的作用范圍,也可以省略,由 PHP 動態(tài)地根據(jù)使用場景自動定義范圍。

注解作用范圍列表:

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

在使用時, #[Attribute] 等同于 #[Attribute(Attribute::TARGET_ALL)],為了方便,一般使用前者。

1~7都很好理解,分別對應(yīng)類、函數(shù)、類方法、類屬性、類常量、參數(shù)、所有,前6項可以使用 | 或運算符隨意組合,比如Attribute::TARGET_CLASS | Attribute::TARGET_FUNCTION。(Attribute::TARGET_ALL包含前6項,但并不包含 Attribute::IS_REPEATABLE)。

Attribute::IS_REPEATABLE 設(shè)置該注解是否可以重復,比如:

class IndexController {     #[Route('/index')]     #[Route('/index_alias')]     public function index()     {         echo "hello!world" . PHP_EOL;     } }

如果沒有設(shè)置 Attribute::IS_REPEATABLERoute不允許使用兩次。

上述提到的,如果沒有指定作用范圍,會由 PHP 動態(tài)地確定范圍,如何理解?舉例:

<?php  class Deprecated {  }  class NewLogger {     public function newLogAction(): void     {         //do something     }      #[Deprecated('oldLogAction已廢棄,請使用newLogAction代替')]     public function oldLogAction(): void      {      } }  #[Deprecated('OldLogger已廢棄,請使用NewLogger代替')] class OldLogger {  }

上述的自定義注解類 Deprecated 并沒有使用內(nèi)置注解類 #[Attribute] 定義作用范圍,因此當它修飾類 OldLogger 時,它的作用范圍被動態(tài)地定義為 TARGET_CLASS。當它修飾方法 oldLogAction 時,它的作用范圍被動態(tài)地定義為 TARGET_METHOD一句話概括,就是修飾哪,它的作用范圍就在哪

需要注意的是, 在設(shè)置了作用范圍之后,在編譯階段,除了內(nèi)置注解類 #[Attribute],自定義的注解類是不會自動檢查作用范圍的。除非你使用反射類 ReflectionAttributenewInstance 方法。

舉例:

<?php  #[Attribute] function foo() {  }

這里會報錯 Fatal error: Attribute "Attribute" cannot target function (allowed targets: class),因為內(nèi)置注解類的作用范圍是 TARGET_CLASS,只能用于修飾類而不能是函數(shù),因為內(nèi)置注解類的作用范圍僅僅是 TARGET_CLASS,所以也不能重復修飾。

而自定義的注解類,在編譯時是不會檢查作用范圍的。

<?php   #[Attribute(Attribute::TARGET_CLASS)] class A1 {  }  #[A1]  function foo() {}

這樣是不會報錯的。那定義作用范圍有什么意義呢?看一個綜合實例。

<?php   #[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION | Attribute::IS_REPEATABLE)] class Route {     protected $handler;      public function __construct(         public string $path = '',         public array $methods = []     ) {}      public function setHandler($handler): self     {         $this->handler = $handler;         return $this;     }      public function run()     {         call_user_func([new $this->handler->class, $this->handler->name]);     } }  class IndexController {     #[Route(path: "/index_alias", methods: ["get"])]     #[Route(path: "/index", methods: ["get"])]     public function index(): void     {         echo "hello!world" . PHP_EOL;     }      #[Route("/test")]     public function test(): void      {         echo "test" . PHP_EOL;     } }  class CLIRouter {     protected static array $routes = [];      public static function setRoutes(array $routes): void     {         self::$routes = $routes;     }      public static function match($path)     {         foreach (self::$routes as $route) {             if ($route->path == $path) {                 return $route;             }         }          die('404' . PHP_EOL);     } }  $controller = new ReflectionClass(IndexController::class); $methods = $controller->getMethods(ReflectionMethod::IS_PUBLIC);  $routes = []; foreach ($methods as $method) {     $attributes = $method->getAttributes(Route::class);      foreach ($attributes as $attribute) {         $routes[] = $attribute->newInstance()->setHandler($method);     } }  CLIRouter::setRoutes($routes); CLIRouter::match($argv[1])->run();
php test.php /index php test.php /index_alias php test.php /test

在使用 newInstance 時,定義的作用范圍才會生效,檢測注解類定義的作用范圍和實際修飾的范圍是否一致,其它場景并不檢測。

注解命名空間

<?php  namespace {     function dump_attributes($attributes) {         $arr = [];         foreach ($attributes as $attribute) {             $arr[] = ['name' => $attribute->getName(), 'args' => $attribute->getArguments()];         }         var_dump($arr);     } }  namespace DoctrineORMMapping {     class Entity {     } }  namespace DoctrineORMAttributes {     class Table {     } }  namespace Foo {     use DoctrineORMMappingEntity;     use DoctrineORMMapping as ORM;     use DoctrineORMAttributes;      #[Entity("imported class")]     #[ORMEntity("imported namespace")]     #[DoctrineORMMappingEntity("absolute from namespace")]     #[Entity("import absolute from global")]     #[AttributesTable()]     function foo() {     } }  namespace {     class Entity {}      dump_attributes((new ReflectionFunction('Foofoo'))->getAttributes()); }  //輸出:  array(5) {   [0]=>   array(2) {     ["name"]=>     string(27) "DoctrineORMMappingEntity"     ["args"]=>     array(1) {       [0]=>       string(14) "imported class"     }   }   [1]=>   array(2) {     ["name"]=>     string(27) "DoctrineORMMappingEntity"     ["args"]=>     array(1) {       [0]=>       string(18) "imported namespace"     }   }   [2]=>   array(2) {     ["name"]=>     string(27) "DoctrineORMMappingEntity"     ["args"]=>     array(1) {       [0]=>       string(23) "absolute from namespace"     }   }   [3]=>   array(2) {     ["name"]=>     string(6) "Entity"     ["args"]=>     array(1) {       [0]=>       string(27) "import absolute from global"     }   }   [4]=>   array(2) {     ["name"]=>     string(29) "DoctrineORMAttributesTable"     ["args"]=>     array(0) {     }   } }

跟普通類的命名空間一致。

其它要注意的一些問題

  • 不能在注解類參數(shù)列表中使用 unpack 語法。
<?php  class IndexController {     #[Route(...["/index", ["get"]])]     public function index()     {      } }

雖然在詞法解析階段是通過的,但是在編譯階段會拋出錯誤。

  • 在使用注解時可以換行
<?php   class IndexController {     #[Route(         "/index",         ["get"]     )]     public function index()     {      } }
  • 注解可以成組使用
<?php  class IndexController {     #[Route(         "/index",         ["get"]     ), Other, Another]     public function index()     {      } }
  • 注解的繼承

注解是可以繼承的,也可以覆蓋。

<?php  class C1 {     #[A1]     public function foo() { } }  class C2 extends C1 {     public function foo() { } }  class C3 extends C1 {     #[A1]     public function bar() { } }  $ref = new ReflectionClass(C1::class); print_r(array_map(fn ($a) => $a->getName(), $ref->getMethod('foo')->getAttributes()));  $ref = new ReflectionClass(C2::class); print_r(array_map(fn ($a) => $a->getName(), $ref->getMethod('foo')->getAttributes()));  $ref = new ReflectionClass(C3::class); print_r(array_map(fn ($a) => $a->getName(), $ref->getMethod('foo')->getAttributes()));

C3 繼承了 C1foo 方法,也繼承了 foo 的注解。而 C2 覆蓋了 C1foo 方法,因此注解也就不存在了。

推薦學習:《PHP8教程》

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
国产亚洲成AⅤ人片在线观看麻豆| 国产精品久线在线观看| 丰满老师少妇久久久久久1| 国产AV一区二区三区日韩| 国产成人亚洲影院在线| 国产精品沙发系列| 精品人妻少妇AV一区二区三区| 久久久久无码专区亚洲AV| 妺妺窝人体色WWW在线直播| 欧美胖老太牲交XXⅩXXX| 日韩精品无码一区二区三区四区| 天海翼一区二区三区高清在线| 性生大片免费观看性| 亚洲熟妇少妇任你躁在线观看| 伊人久久精品AV无码一区| CHINA末成年VIDEO学生| 公侵犯玩弄熟睡人妻电影| 国产在线看片无码不卡| 久久亚洲精品无码| 日本按摩高潮S级中文片| 无码人妻AⅤ一区二区三区蜜桃 | 丰满的熟妇人妻中文字幕久久 | 久久精品亚洲乱码伦伦中文| 欧美精品人妻大乳一区二区 | 国产精品免费久久久久影院仙踪林| 国产在线码观看超清无码视频| 久久青草精品38国产| 奇米精品视频一区二区三区| 无码天堂亚洲国产AV| 夜夜爽8888免费视频| 成年无码AV片在线| 国模无码人体一区二区| 男女乱婬免费视频黑人| 翁止熄痒苏钥第9章的内容| 亚洲午夜精品一区二区 | 欧美婷婷六月丁香综合色| 污污污污污WWW网站免费| 亚洲中文字幕AV无码专区| 草草地址线路①屁屁影院成人| 国产最好的高清播放机品牌| 男女久久久国产一区二区三区| 四虎成人精品一区二区免费网站| 亚洲欧洲国无码成人片| 超碰色偷偷男人的天堂| 精品久久久久久久久午夜福利| 漂亮人妻洗澡被强人人躁| 亚洲AⅤ永久无码精品AA| 99精品国产福利在线观看| 国产美女极度色诱视频WWW| 免费A级毛片18禁网站APP| 无码AVAV无码中文字幕| 中文字幕无码日韩AV| 国产精品久久久久久久久久免费 | 日本一区二区三区免费播放| 亚洲精品无码伊人久久| 成年女人免费碰碰视频| 久久精品人妻中文系列葵司| 少妇无码人妻一区二区三区| 一边下奶一边吃面膜视频讲解图片| 夫妻互换呻吟抽插小说| 乱码专区一卡二卡国色天香| 无码综合天天久久综合网色吧影院| √天堂资源中文WWW| 国产午夜亚洲精品理论片八戒| 欧美成人精品高清在线播放 | 精品人妻伦一二三区久久| 色婷婷AV一区二区三区浪潮慧瑟| 一二三四免费观看高清在线| 国产精品日日摸夜夜添夜夜添| 女人自熨全过程直播| 亚洲国产精品久久久久婷婷老年 | 少妇性饥渴XXⅩXXHD| 中文字幕精品久久久久人妻| 含羞草传媒入口免费网站腾讯网 | 亚洲鲁丝片AV无码多人| 公交车大龟廷进我身体里| 男女体裸下00动态视频| 亚洲国产精品日韩AV专区| 囯产精品一品二区三区| 欧美人与牲禽ⅩXXX伦交| 亚洲人成绝费网站色WWW吃脚| 国产AV人人夜夜澡人人爽小说| 女性の乳頭を遮住する方法| 亚洲精品乱码久久久久久蜜桃| 国产成人精品亚洲日本专区61| 欧美成人精品欧美一级乱黄| 亚洲婷婷五月综合狠狠| 国产麻豆VIDEOXXXX实拍| 人妻无码人妻有码中文字幕在线| 永久免费看照片的聊骚软件 | 亚洲国产精品久久一线不卡| 国产成人一区二区三区在线| 人妻无码一区二区| 中字年轻漂亮的儿媳BD| 久久久WWW免费人成精品| 亚洲AV成人无码精品直播在线| 公翁大龟挺进秀婷全文免费阅读| 欧美性爱XXXX黑人XYX性爽| 张柏芝阿娇全套无删减1313| 狠狠噜天天噜日日噜色综合| 五十路丰满熟女av名单大全| 公交车伦流澡到高潮HNP| 日本大一大二大三在一起读吗| 52色擼99热99RE超碰| 狂野欧美激情性XXXX| 亚洲日韩亚洲另类激情文学一| 国内精品人妻无码久久久影院导航| 天天看AV片在线观看| 丁香花在线观看免费高清版| 人妻无码一区二区三区视频 | 人人妻人人爽人人澡AV| AV无码AV在线A∨天堂APP| 美国ZOOM人与ZOOM| 永久免费观看国产裸体美女| 久久婷婷五月综合色区| 亚洲日本VA午夜在线影院| 精品人妻少妇一区二区三区夜夜嗨| 亚洲AV成人无码网天堂| 国产女人乱人伦精品一区二区| 无码纯肉视频在线观看| 国产成人无码18禁午夜福利免费| 色偷偷人人澡人人爽人人模| 敌伦交换第11部分给了轨公领| 日韩AV无码AV免费AV不卡| 成人国产精品一区二区视频 | 免费的最近直播比较火的黄台| 又大又粗弄得我好爽GIF| 看国产一毛片在线看手机看| 在镜子面前看我是怎么爱你的| 老外免费CSGO交易网站有哪些| 伊人久久大香线蕉AV不变影院 | 国产亚洲AV寡妇| 亚洲AV无码国产精品久久不卡| 国产一区二区精品久久岳| 亚洲AV日韩AV高潮喷无码| 人妻无奈被迫屈辱1-9| 中文字幕人妻色偷偷久久 | 成人A级毛片免费视频| 三个女儿一锅烩大团圆全文阅读| 大胸年轻继拇HD无码| 天堂影院一区二区三区四区| 国产精品无码素人福利不卡| 亚洲6080YY久久无码产自国| 记忆女神的女儿们| 野花高清视频免费观看完整版中文| 久久午夜夜伦鲁鲁片无码免费| 中文一国产一无码一日韩| 欧美人妻少妇精品久久黑人| 成年网站未满十八禁在线观看| 水多的女人男人最上瘾| 国产欧美久久一区二区| 亚洲精品无码永久在线观看你懂的 | 精品久久久久久天美传媒| 一边下奶一边吃面膜视频| 女人夜夜春高潮爽A∨片| 宝贝对着镜子CAO好不好| 少妇高潮喷潮久久久影院| 国产免费一区二区三区不卡| 亚洲成A人片在线观看无码| 久久天天躁狠狠躁夜夜96流白浆| 18禁裸乳无遮挡啪啪无码免费| 人伦片无码中文字| 国产成人亚洲综合A∨婷婷图片| 亚洲A∨无码一区二区| 久久久一本精品99久久精品88| 97久久精品人人爽人人爽蜜臀| 日本乱偷人妻中文字幕久久| 国产精品视频YJIZZ| 亚洲日韩VA无码中文字幕| 免费观看人成影片| 大炕上的肉体交换| 亚洲AV纯肉无码精品动漫| 狂猛欧美激情性XXXX在线观看 | 国产精品自在拍一区二区不卡 | 无码AV无码一区二区| 精品亚洲AⅤ在线观看| 777爽死你免费看一二区无码| 日韩中文无码有码免费视频| 国内精品乱码卡一卡2卡三卡| 在线黄色网站观看汙| 日韩精品无码一区二区三区视频| 国产午夜无码视频在线观看| 月光影视WWW在线观看| 日本乱妇乱子视频网站-百度| 国产欧美精品一区二区三区四区 | 日本欧美午夜成人免费观看| 国产午夜成人免费看片APP| 中国OLDWOMAN老熟妇| 涩反差合集91综合一区二区清纯| 和朋友换娶妻野外夫妇3| 97超级碰碰碰久久久久| 无码AV无码免费一区二区| 久久久一本精品99久久精品66| 超碰CAOPROM 永久地址发| 亚洲国产成人久久一区久久| 欧美色成人综合天天影院| 国产性生大片免费观看性| 99热都是精品久久久久久| 亚洲AⅤ无码乱码在线观看性色| 男男H双腿涨灌PLAY慎入|