首頁/ 娛樂/ 正文

PHP8 - 註解的使用

PHP8 - 註解的使用

概述

php8 中新增了註解特性,官方文件地址如下:

https://www。php。net/manual/zh/language。attributes。php

本文將使用這個新特性實現一個路由註解

實現過程

一、宣告一個註解類

<?

php

namespace

App

\

Route

\

Attributes

use

Attribute

// 宣告該Route註解可以重複使用,只能繫結在類方法上

#[Attribute

Attribute

::

IS_REPEATABLE

|

Attribute

::

TARGET_METHOD

class

Route

{

public

static

$all

=

[];

public

string

$path

=

“”

// 路由地址

public

string

$method

=

“GET”

// 路由請求方法

public

string

$controller

=

“”

// 路由指向的控制器

public

string

$function

=

“”

// 路由指向的控制器的方法

public

function

__construct

{

}

/**

*

@description

: 設定路由地址

*

@param

string $path

*

@return

self

*/

public

function

setPath

string

$path

self

{

$this

->

path

=

$path

return

$this

}

/**

*

@description

: 設定控制器

*

@param

string $controller

*

@return

self

*/

public

function

setController

string

$controller

self

{

$this

->

controller

=

$controller

return

$this

}

/**

*

@description

: 設定請求方法

*

@param

string $method

*

@return

self

*/

public

function

setMethod

string

$method

self

{

$this

->

method

=

$method

return

$this

}

/**

*

@description

: 設定繫結的function

*

@param

string $function

*

@return

self

*/

public

function

setFunction

string

$function

self

{

$this

->

function

=

$

function

return

$this

}

/**

*

@description

: 新增路由

*

@return

void

*/

public

function

addRoute

void

{

self

::

$all

[]

=

$this

}

}

二、使用註解類

<?

php

namespace

App

\

Controller

use

App

\

Route

\

Attributes

\

Route

class

TestController

{

#[Route

‘/test/route’

‘GET’

#[Route

‘/route/test’

‘POST’

public

function

testRoute

{

// do something here

}

}

三、使註解類生效

利用反射讀取註解的引數,並執行註解類裡面的方法

<?

php

function

getAttributeData

$reflection

{

$controller

=

$reflection

->

getName

();

// 如果註解是直接繫結在類上面,那麼直接從類的反射獲取註解

// $attributes = $reflection->getAttributes(App\Route\Attributes\Route::class);

$methods

=

$reflection

->

getMethods

();

// 因為註解是繫結在方法上的,因此迴圈方法,獲取方法的註解

foreach

$methods

as

$method

){

// 方法名

$function

=

$method

->

getName

();

// 指定獲取某個註解的資料

$attributes

=

$method

->

getAttributes

App

\Route\Attributes\Route

::

class

);

foreach

$attributes

as

$attribute

{

// 拿到一個新的 Route 例項

$route

=

$attribute

->

newInstance

();

// 拿到註解上的引數

$params

=

$attribute

->

getArguments

();

/**

* [

* [‘/test/route’,‘GET’],

* [‘/route/test’,‘POST’]

* ]

*/

// 執行路由新增

$route

->

setController

$controller

)->

setFunction

$function

->

setPath

$params

0

])->

setMethod

$params

1

])->

addRoute

();

}

}

}

// 對 TestController 使用反射,並執行註解生效的方法

getAttributeData

new

ReflectionClass

App

\Controller\TestController

::

class

));

var_dump

App

\Route\Attributes\Route

::

$all

);

// 執行結果 :

// array(2) {

// [0]=>

// object(App\Route\Attributes\Route)#5 (4) {

// [“path”]=>

// string(11) “/test/route”

// [“method”]=>

// string(3) “GET”

// [“controller”]=>

// string(29) “App\Controller\TestController”

// [“function”]=>

// string(9) “testRoute”

// }

// [1]=>

// object(App\Route\Attributes\Route)#6 (4) {

// [“path”]=>

// string(11) “/route/test”

// [“method”]=>

// string(4) “POST”

// [“controller”]=>

// string(29) “App\Controller\TestController”

// [“function”]=>

// string(9) “testRoute”

// }

// }

注意事項

註解的引數是用反射讀取的,可以直接反射類,而沒必要使用例項

註解可以在很多個位置,類、方法、屬性等,在哪裡使用註解就反射到哪裡再使用

getAttributes()

方法

註解使用

newInstance()

方法獲得註解類的例項

註解使用

getArguments()

方法獲得註解上的引數

註解語法參考官方文件,不外乎幾種形式,用於生成註解類的引數

零基礎學PHP

陳浩

計算機

免費閱讀

https://www。php。net/manual/zh/language。attributes。syntax。php

問題/總結

在 使註解類生效 一節中,在另一個檔案中寫了一個方法,用於讓註解生效,但是在實際使用過程中它應該放到什麼位置呢?

PHP 入門經典

李慧

計算機

免費閱讀

可以看到,在該方法中,對目標類進行了反射,也就是說,要使註解生效,我們至少要提前知曉我們要反射的類(或方法)是哪一個。

以本文中的路由註解為例,一般的PHP框架中都會有顯式路由的使用方式,例如:

<?

php

// laravel

Route

::

any

‘/test/route’

‘TestController::testRoute’

);

也就是說,一般情況下,路由表是提前生成的,或者在執行之前就能拿到的。

那麼至少可以使用兩種方式使路由註解生效:

直接使用command的遍歷所有控制器,生成這個路由檔案,再在執行程式碼中引入,並快取路由

在路由生效之前,遍歷所有的控制器,將路由表

收集

出來,動態地註冊路由

** 如果有在路由之後生效的註解,可以在路由執行到方法之前進行反射,得到引數並執行 **

篇幅有限,未對各種實現方式的執行效率進行測試,想來php8中有JIT生效的時候執行效率不會低

以上僅為一些簡單的實現和思考,如果有更好的實現方式歡迎交流

相關文章

頂部