cari
Rumahpembangunan bahagian belakangPHP8Sejauh manakah anda tahu tentang anotasi php8?

Sintaks anotasi

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

Malah, sintaks sangat serupa dengan kelas instantiated, kecuali kata kunci new tiada .

Perlu diambil perhatian bahawa nama anotasi tidak boleh menjadi pembolehubah, tetapi hanya boleh menjadi ungkapan malar atau malar

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

(path: "/path", methods: ["get"]) ialah sintaks baharu daripada php8 , anda boleh menentukan nama parameter apabila menghantar parameter, dan jangan lulus parameter dalam susunan parameter formal.

Skop kelas anotasi

Apabila mentakrifkan kelas anotasi, anda boleh menggunakan kelas anotasi terbina dalam #[Attribute] untuk menentukan skop kelas anotasi atau anda boleh meninggalkannya, ditentukan secara dinamik oleh PHP Gunakan senario untuk menentukan julat secara automatik .

Senarai skop anotasi:

  • Atribut::TARGET_CLASS
  • Atribut::TARGET_FUNCTION
  • Atribut::TARGET_METHOD>
  • Atribut::TARGET_CLASS_CONSTANT
  • Attribute::TARGET_PARAMETER
  • Atribut::TARGET_ALL
  • IS_REPETribut:
  • digunakan,
  • bersamaan dengan
  • Untuk kemudahan, yang pertama biasanya digunakan.
1~7 mudah difahami dan sepadan dengan kelas, fungsi, kaedah kelas, atribut kelas, pemalar kelas, parameter, dan semuanya masing-masing 6 item pertama boleh digabungkan sesuka hati menggunakan #[Attribute] atau operator , seperti #[Attribute(Attribute::TARGET_ALL)]. (

termasuk 6 item pertama, tetapi tidak termasuk |Attribute::TARGET_CLASS | Attribute::TARGET_FUNCTION). Attribute::TARGET_ALLAttribute::IS_REPEATABLE Tetapkan sama ada anotasi boleh diulang, contohnya:

Jika Attribute::IS_REPEATABLE tidak ditetapkan,

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

Seperti yang dinyatakan di atas, jika skop tidak dinyatakan, PHP akan menentukan skop secara dinamik. Bagaimana anda memahaminya? Contoh: Attribute::IS_REPEATABLERoute

Kelas anotasi tersuai yang disebutkan di atas

tidak menggunakan kelas anotasi terbina dalam

untuk mentakrifkan skop, jadi apabila ia mengubah suai kelas
<?php class Deprecated
{

}

class NewLogger
{
    public function newLogAction(): void
    {
        //do something
    }

    #[Deprecated(&#39;oldLogAction已废弃,请使用newLogAction代替&#39;)]
    public function oldLogAction(): void 
    {

    }
}

#[Deprecated(&#39;OldLogger已废弃,请使用NewLogger代替&#39;)]
class OldLogger
{

}
, skopnya secara dinamik Ditakrifkan sebagai

. Apabila ia mengubah suai kaedah Deprecated, skopnya ditakrifkan secara dinamik sebagai #[Attribute]. OldLoggerDalam satu ayat, di mana sahaja ia diubah suai, skopnya juga adaTARGET_CLASSoldLogActionTARGET_METHODPerlu diingatkan bahawa selepas menetapkan skop, semasa fasa penyusunan, sebagai tambahan kepada bina- dalam kelas anotasi , kelas anotasi tersuai tidak akan menyemak skop secara automatik. Melainkan anda menggunakan kaedah

kelas refleksi

. #[Attribute]ReflectionAttribute Contoh: newInstance

Ralat akan dilaporkan di sini

, kerana skop kelas anotasi terbina dalam ialah

dan hanya boleh digunakan untuk ubah suai kelas dan bukan fungsi
<?php #[Attribute]
function foo()
{

}
Oleh kerana skop kelas anotasi terbina dalam hanyalah

, jadi Fatal error: Attribute "Attribute" cannot target function (allowed targets: class) tidak boleh diubah suai berulang kali. TARGET_CLASSKelas anotasi tersuai tidak akan menyemak skop semasa penyusunan. TARGET_CLASS

Dengan cara ini tiada ralat akan dilaporkan. Jadi apa gunanya menentukan skop? Mari kita lihat contoh yang komprehensif.

<?php  

#[Attribute(Attribute::TARGET_CLASS)]
class A1
{

}

#[A1] 
function foo() {}

Apabila menggunakan

, skop yang ditentukan akan berkuat kuasa sama ada skop yang ditakrifkan oleh kelas anotasi adalah konsisten dengan skop yang diubah suai sebenar tidak akan diuji.
<?php  

#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION | Attribute::IS_REPEATABLE)]
class Route
{
    protected $handler;

    public function __construct(
        public string $path = &#39;&#39;,
        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
Ruang nama anotasi

newInstance

adalah sama dengan ruang nama kelas biasa.

Beberapa isu lain yang perlu diberi perhatian
<?php namespace {
    function dump_attributes($attributes) {
        $arr = [];
        foreach ($attributes as $attribute) {
            $arr[] = [&#39;name&#39; => $attribute->getName(), 'args' => $attribute->getArguments()];
        }
        var_dump($arr);
    }
}

namespace Doctrine\ORM\Mapping {
    class Entity {
    }
}

namespace Doctrine\ORM\Attributes {
    class Table {
    }
}

namespace Foo {
    use Doctrine\ORM\Mapping\Entity;
    use Doctrine\ORM\Mapping as ORM;
    use Doctrine\ORM\Attributes;

    #[Entity("imported class")]
    #[ORM\Entity("imported namespace")]
    #[\Doctrine\ORM\Mapping\Entity("absolute from namespace")]
    #[\Entity("import absolute from global")]
    #[Attributes\Table()]
    function foo() {
    }
}

namespace {
    class Entity {}

    dump_attributes((new ReflectionFunction('Foo\foo'))->getAttributes());
}

//输出:

array(5) {
  [0]=>
  array(2) {
    ["name"]=>
    string(27) "Doctrine\ORM\Mapping\Entity"
    ["args"]=>
    array(1) {
      [0]=>
      string(14) "imported class"
    }
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(27) "Doctrine\ORM\Mapping\Entity"
    ["args"]=>
    array(1) {
      [0]=>
      string(18) "imported namespace"
    }
  }
  [2]=>
  array(2) {
    ["name"]=>
    string(27) "Doctrine\ORM\Mapping\Entity"
    ["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) "Doctrine\ORM\Attributes\Table"
    ["args"]=>
    array(0) {
    }
  }
}

Anda tidak boleh

menggunakan sintaks
    dalam senarai parameter kelas anotasi.
  • unpackWalaupun ia lulus dalam peringkat penghuraian leksikal, ralat akan dilemparkan dalam peringkat penyusunan.
<?php class IndexController
{
    #[Route(...["/index", ["get"]])]
    public function index()
    {

    }
}
Anda boleh membalut baris apabila menggunakan anotasi

  • Anotasi boleh digunakan dalam kumpulan
<?php  

class IndexController
{
    #[Route(
        "/index",
        ["get"]
    )]
    public function index()
    {

    }
}
  • Warisan anotasi
<?php class IndexController
{
    #[Route(
        "/index",
        ["get"]
    ), Other, Another]
    public function index()
    {

    }
}
    Anotasi boleh diwarisi atau ditindih.

mewarisi kaedah

<?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()));
dan juga mewarisi anotasi

. Dan C3 merangkumi kaedah C1 foo, jadi anotasi tidak wujud. fooC2C1Pembelajaran yang disyorkan: "fooTutorial PHP8

"

Atas ialah kandungan terperinci Sejauh manakah anda tahu tentang anotasi php8?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Artikel ini dikembalikan pada:segmentfault. Jika ada pelanggaran, sila hubungi admin@php.cn Padam

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

mPDF

mPDF

mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

SublimeText3 Linux versi baharu

SublimeText3 Linux versi baharu

SublimeText3 Linux versi terkini

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Persekitaran pembangunan bersepadu PHP yang berkuasa