小白兔晒黑了

导航

 

https://www.bilibili.com/video/BV14E411t7T4?p=6

1 通过反射获取注释的简单使用案例

新建一个anntest文件夹

composer init

 

index.php

<?php
require_once __DIR__.'/vendor/autoload.php';

/**
 * Class mytest
 * 我的注释
 */
class mytest
{
    
}

$c = new ReflectionClass(mytest::class);
echo $c->getDocComment();

 

 会打印出类的注释

2 使用第三方组件

2.1 部署

composer require doctrine/annotations 1.6

 文档 https://blog.csdn.net/anhe0516/article/details/101188650

自动加载

\composer.json

    "autoload": {
        "psr-4": {
            "App\\" : "app/"

        }
    },
    "require": {
        "doctrine/annotations": "1.6"
    }

执行

composer dump-autoload

 2.2 代码

D:\seckill\anntest\app\annotations\Value.php

namespace App\annotations;

/**
 * @Annotation
 */
class Value
{
   public $name;
}

D:\seckill\anntest\app\test\MyRedis.php

class MyRedis
{ 
    /**
     * @Value(name="url")
     */
     public $conn_url;

     
}

D:\seckill\anntest\index.php

<?php
require_once __DIR__.'/vendor/autoload.php';

use \Doctrine\Common\Annotations\AnnotationReader;
use \Doctrine\Common\Annotations\AnnotationRegistry;
use \App\test\MyRedis;
use \App\annotations\Value;


//注册注释
AnnotationRegistry::registerLoader('class_exists'); //回调需返回true
//AnnotationRegistry::registerAutoloadNamespace("App\annotations");
//AnnotationRegistry::registerFile(__DIR__ . '/app/annotations/Value.php'); //注册文件



//获取反射对象 MyRedis
$rc = new ReflectionClass(MyRedis::class);
//获取反射对象的变量
$p = $rc->getProperty("conn_url");

$reader = new AnnotationReader();
//获取变量的注释中@Value的name
$anno = $reader->getPropertyAnnotation($p,Value::class);
echo $anno->name;

运行后成功获取注释信息

 3 利用注解动态读取配置文件

3.1 代码部署

3.1.1 配置文件 \.env

url = 127.0.0.1:8080

3.2.2 类的加载器 \app\core\ClassFactory.php

<?php
/**
 * 类的加载器
 */

namespace App\core;


use Doctrine\Common\Annotations\AnnotationReader;

class ClassFactory
{
     public static function loadClass($className)
     {
         $refClass = new \ReflectionClass($className);
         //return $refClass->newInstance();
         //获取所有的属性集合
         $properties = $refClass->getProperties();
         foreach ($properties as $property){
             $read = new AnnotationReader();
             $annos = $read->getPropertyAnnotations($property);
             foreach ($annos as $anno){
                 //var_dump($anno);
                 $getValue =  $anno->do();
                 //实例化
                 $obj  =  $refClass->newInstance();
                 //给属性赋值
                 $property->setValue($obj,$getValue);
                 return $obj;
             }
         }
         return false;
         
     }
}
View Code

3.2.3 业务类 \app\test\MyRedis.php

<?php


namespace App\test;
use App\annotations\Value;


class MyRedis
{ 
    /**
     * @Value(name="url")
     */
     public $conn_url;

     
}
View Code

3.2.4 注释类 \app\annotations\Value.php

<?php
namespace App\annotations;

/**
 * @Annotation
 */
class Value
{
   public $name;
   public function do()
   {
       //return $this->name;
       $env = parse_ini_file('./.env');
       if(isset($env[$this->name])){
           return $env[$this->name];
       }
       return  false;
   }
}
View Code

3.2 测试

成功动态加载的实例

 

4 注解类型

CLASS 类的注解

PROPERTY 属性

METHOD 方法

ALL 所有

ANNOTATION 注释的嵌套

5 Hyperf 使用注解的几种方式

什么是注解什么是注释? 注解 与 注释 的区别:

注释:给程序员看,帮助理解代码,对代码起到解释、说明的作用。

注解:给应用程序看,用于元数据的定义,单独使用时没有任何作用,需配合应用程序对其元数据进行利用才有作用。 PHP 语法本身并没有实支持 注解 ,实现注解只能从注释中解析。

@Target("CLASS")

<?php
namespace App\Annotation; 
use Hyperf\Di\Annotation\AbstractAnnotation;
 
/**
 * @Annotation
 * @Target("CLASS")
 */
class User extends AbstractAnnotation
{
 
}

类方法 @Target("METHOD")

<?php
 
namespace App\Annotation;
 
use Hyperf\Di\Annotation\AbstractAnnotation;
 
/**
 * @Annotation
 * @Target("METHOD")
 */
class User extends AbstractAnnotation
{
 
}

类属性@Target("PROPERTY")

<?php
 
namespace App\Annotation;
 
use Hyperf\Di\Annotation\AbstractAnnotation;
 
/**
 * @Annotation
 * @Target("PROPERTY")
 */
class User extends AbstractAnnotation
{
 
}

默认支持以上三种所有注解@Target("ALL")

<?php
 
namespace App\Annotation;
 
use Hyperf\Di\Annotation\AbstractAnnotation;
 
/**
 * @Annotation
 * @Target("ALL")
 */
class User extends AbstractAnnotation
{
 
}

数组方式@Target({"CLASS","METHOD"})

假如同时想要支持 METHOD 和 CLASS 两种注解,那么就可以采用 {"CLASS","METHOD"} 这种方式

<?php
 
namespace App\Annotation;
 
use Hyperf\Di\Annotation\AbstractAnnotation;
 
/**
 * @Annotation
 * @Target({"CLASS","METHOD"})
 */
class User extends AbstractAnnotation
{
 
}

 

其他 https://blog.csdn.net/a603423130/article/details/117260790

posted on 2021-11-13 01:23  小白兔晒黑了  阅读(281)  评论(0编辑  收藏  举报