PHP code example of hehex / hehep-hcontainer

1. Go to this page and download the library: Download hehex/hehep-hcontainer library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

hehex / hehep-hcontainer example snippets


$beanDefinition = [
    'id'=>'user',// bean 别名
    'class'=>'\site\service\User\User', # 类路径
    '_single'=> true, // 是否单例,默认是单例,
    '_scope'=> 'request', // 对象作用域,request 请求作用域
    '_init'=> 'init', // 初始化方法, 对象创建后调用设置的方法(设置属性完成后调用),
    '_onProxy'=>false,// bean 是否启用代理类,一般用于切面aop
    '_proxyHandler'=>"",// 代理事件,每调用一次对象方法,自动触发代理事件
    '_args'=> [], // true 构造方法参数,支持索引,关联数组
    '_attrs'=> [  // 类其他属性,直接注入
        'attr1'=>'26',
        'attr2'=>'26',
    ],
    'attr3'=>'类其他属性3',
    'attr4'=>'类其他属性4',
    'attr5Bean'=>'<func::bean>',// 属性调用函数, 自动调用func函数(bean) 获取属性值,
    'attr6Bean'=>'<ref::address>',// 属性对应另一个bean(user),| 之后为bean 的参数
];

namespace app\services\UserBean;
use hehe\core\hcontainer\annotation\Bean;

/**
 * Class UserBean
 * @package hcontainer\tests\common
 * @Bean('user')
 */
class UserBean
{
    /**
     * 姓名
     * @var
     */
    public $name;

    public function __construct($name = '')
    {
        $this->name = $name;
    }
}

use hehe\core\hcontainer\ContainerManager;
$hcontainer = new ContainerManager();

// 注册bean
$hcontainer->register('user',UserinfoBean::class);

// 注册bean,增加其他配置
$hcontainer->register('user',UserinfoBean::class,['_single'=>true]);

// 批量注册
 $beans = [
    // 格式['bean别名'=>["class"=>"bean 类路径","其他参数1"=>'xxx']]
    'userinfo'=>['class'=>UserinfoBean::class]
];
$hcontainer->batchRegister($beans);


use hehe\core\hcontainer\ContainerManager;
$hcontainer = new ContainerManager();
$beans = [
    'user'=>['class'=>'app\services\UserBean'],
];

$hcontainer->batchRegister($beans);

// 获取bean对象
$user = $hcontainer->getBean('user');

// 创建新bean对象
$new_user = $hcontainer->make('user');

// 创建新bean对象,并提供构造参数,索引数组
$userinfo = $hcontainer->make('user',["hehe"]);

// 创建新bean对象,并提供构造参数,关联数组
$userinfo = $hcontainer->make('user',["name"=>"hehe"]);


use hehe\core\hcontainer\ContainerManager;
$hcontainer = new ContainerManager();
// 定义request 级别类(每次请求完成,此对象都会被回收)
class App
{
    public $container;
    
    public function __construct(ContainerManager $hcontainer)
	{
	    // 从容器管理器创建一个空容器
        $this->container = $hcontainer->makeContainer();
    }
}

$app = new App($hcontainer);

// 设置作用域容器事件
$hcontainer->setScopeHandler('request',function()use($app){
    return $app->container;
});

// 或者
$hcontainer->setScopeHandlers(['request'=>function()use($app){
    return $app->container;
}]);

// 业务代码
$beans = [
    'user'=>['class'=>'app\servers\User','_scope'=>'request'],
];

// user bean 从$app->container 容器中取出
$user = $hcontainer->getBean('user');

// 注销$app变量,其$container属性也会注销,随着request容器的回收,Bean $user 对象也会被注销
unset($app);



/**
 * 角色类
 */
class RoleBean
{
    
}

/**
 * 用户类
 */
class UserBean
{
    /**
     * 地址名称
     * @var string
     */
    public $name;

    /**
     * 角色对象
     * @var RoleBean
     */
    public $argRole;
    
     /**
     * 角色对象
     * @var RoleBean
     */
    public $argRefRole;
    
    /**
     * 角色对象
     * @var RoleBean
     */
    public $argLazyRole;
    
    // 如RoleBean 配置过bean,则系统会自动从容器中获取RoleBean对象传入
    public function __construct($name,RoleBean $argRole,$argRefRole = '<ref:role>',$argLazyRole = '<lazy:role>')
    {
        $this->name = $name;
        $this->argRole = $argRole;
        $this->argRefRole = $argRefRole;
        $this->argLazyRole = $argLazyRole;
    }
}

// bean 定义
$beans = [
    'user'=>[
       'class'=>'\user\UserBean',
       '_args'=>['公司地址']
    ],
    'role'=>['class'=>'\user\RoleBean']
];


/**
 * 角色类
 */
class RoleBean
{
    
}

/**
 * 用户类
 */
class UserBean
{
    /**
     * 地址名称
     * @var string
     */
    public $name;

    /**
     * 详细地址
     * @var string
     */
    public $address;
}
// 对应的bean 定义
$beans = [
    'user'=>[
       'class'=>'\user\UserBean',
       'name'=>'公司地址',
     ],
];

// 或者
$beans = [
    'user'=>[
       'class'=>'\user\UserBean',
       '_attrs'=>[
          'name'=>'公司地址',
       ]
     ],
];


namespace user\service;
use hehe\core\hcontainer\annotation\Ref;

/**
 * 用户类
 */
class User
{
    /**
     * 用户名
     * @var string
     */
    public $name;
   
    /**
     * 用户角色
     * @var Role
     */
    public $role1;
    
     /**
     * 用户角色
     * @Ref("role")
     * @var Role
     */
    public $role2;
}

/**
 * 角色类
 */
class Role
{
    public function ok()
    {
        return 'ok';
    }
}

// bean 定义
$beans = [
    'user'=>[
       'class'=>'user\service\user',
       'name'=>'公司地址',
       'role1'=>'<ref::role>'
     ],
     
    'role'=>[
       'class'=>'user\service\Role',
    ]
];


// Bean 定义
$benans =  [
    ['user'=>['class'=>'user\service\user','_onProxy'=>true]]
];


use hehe\core\hcontainer\annotation\Bean;
/**
 * @bean("user",_onProxy=true)
 */
class UserBean
{

}


use hehe\core\hcontainer\annotation\Bean;
use hehe\core\hcontainer\aop\annotation\After;

/**
 * @bean("user")
 * @After("hcontainer\tests\common\LogBehavior@log",pointcut=".+Action")
 */
class UserBean
{
    
    /**
     * @After("hcontainer\tests\common\LogBehavior")
     */
    public function doAfter(){}
}

use hehe\core\hcontainer\annotation\Bean;
use hehe\core\hcontainer\annotation\Ref;

/**
 * @bean("user")
 */
class UserBean
{
    
    /**
     * $annRole 为代理对象
     * @Ref("role","lazy"=>true)
     * @var RoleBean
     */
    public $annRole;
}


// Bean 定义
$beans = [
    'user'=>[
       'class'=>'user\service\user',
       'name'=>'公司地址',
       'role1'=>'<ref::role>'
     ],
     
    'role'=>[
       'class'=>'user\service\Role',
       'user'=>'<lazy::user>'
    ]
];

use hehe\core\hcontainer\annotation\Ref;
// 注解方式
class RoleBean
{
    /**
     * @Ref("user",lazy=true)
     * @var UserBean
     */
    public $user;
    
}


use hehe\core\hcontainer\ContainerManager;
$hcontainer = new ContainerManager();

// 扫描指定类命名空间下所有类
$hcontainer->addScanRule(ContainerManager::class,App::class);

// 扫描指定路径下的所有类文件,格式['扫描的命名空间','命名空间对应的路径']
$hcontainer->addScanRule(['hehe\core\hcontainer','d:/work/web/app'],['hehe\core\hcontainer1','d:/work/web/app1']);

// 添加优先扫描规则
$hcontainer->addFirstScanRule(ContainerManager::class,App::class);

// 开始扫描
$hcontainer->startScan();


use hehe\core\hcontainer\ann\base\AnnotationProcessor;
class BeanProcessor extends AnnotationProcessor
{
    // 实现以下方法即可
    
    // 统一处理类,方法,类类型注解 $target_type = class,method,property
    public function handleAnnotation($annotation,string $class,string $target,string $target_type):void{}
    
    // 注解类方式
    public function handleAnnotationClass($annotation,string $class):void{}
    
    // 注解类方法方式
    public function handleAnnotationMethod($annotation,string $class,string $method):void{}
    
    // 注解类属性方式
    public function handleAnnotationProperty($annotation,string $class,string $property):void{}
    
    // 处理器结束事件处理方法
    public function handleProcessorFinish()
    {
        // 注册bean信息到容器
    }
}


use hehe\core\hcontainer\ContainerManager;
$hcontainer = new ContainerManager();

// 注册优先处理器
$hcontainer->addFirstProcessor("hehe\core\hcontainer\annotation\BeanProcessor");

// 注册重置处理器[旧注解器类,新注解处理器类]
$hcontainer->addCustomProcessors(["hehe\core\hcontainer\annotation\BeanProcessor","hehe\core\hcontainer\annotation\NewBeanProcessor"]);


//可通过"hehe\core\hcontainer\annotation\Annotation"注解器将"注解器"与"注解处理器"绑定
//Annotation格式:@Annotation("注解处理器类路径")
use  hehe\core\hcontainer\ann\base\Annotation;
/**
 * @Annotation("hehe\core\hcontainer\annotation\BeanProcessor")
 */
class Bean
{
    public $id;
    public $_scope;
    public $_single;

    public function __construct($value,$_scope = null,$_single = null)
    {
        foreach ($attrs as $attr=>$value) {
            if ($attr == "value") {
                $this->id = $value;
            } else {
                $this->$attr = $value;
            }
        }
    }
}

namespace app\behaviors;
use hehe\core\hcontainer\aop\base\AopBehavior;
use hehe\core\hcontainer\aop\base\PointcutContext;
class LogBehavior extends AopBehavior
{
    // 默认调用方法
    public function handle(PointcutContext $pointcutCtx)
    {
        
        $pointcutCtx->advice;// 通知点位置
        $pointcutCtx->target;// 调用的对象
        $pointcutCtx->method;// 被调用的方法
        $pointcutCtx->parameters;// 被调用方法的参数
        $pointcutCtx->methodResult;// 执行被调用方法后返回的结果
        $pointcutCtx->exception;// 执行被调用方法后发生异常后,抛出的异常对象
    }
    
    // 方法1
    public function handle1(PointcutContext $pointcutCtx)
    {
        // 业务行为代码
    }
    
    // 静态方法1
    public static function handle2(PointcutContext $pointcutCtx)
    {
        // 业务行为代码
    }
}


namespace  app\beans;

use hehe\core\hcontainer\annotation\Bean;
use hehe\core\hcontainer\aop\annotation\Advice;
use hehe\core\hcontainer\aop\annotation\After;
use hehe\core\hcontainer\aop\annotation\Before;
use hehe\core\hcontainer\aop\annotation\Around;
use hehe\core\hcontainer\aop\annotation\AfterThrowing;

/**
 * @bean("user")
 * 
 * 匹配以"Action"结尾的方法名,并在调用目标方法之后切入"hcontainer\tests\common\LogBehavior@log"业务行为
 * @After("hcontainer\tests\common\LogBehavior@log",pointcut=".+Action")
 */
class UserBean
{
     /**
     * 在执行方法之后执行“LogBehavior” 类的handle方法
     * @After("hcontainer\tests\common\LogBehavior")
     */
    public function doAfter($user,$msg = '')
    {
        return $msg;
    }

    /**
     * 在执行方法之前执行“LogBehavior”类的handle方法
     * @Before("hcontainer\tests\common\LogBehavior")
     */
    public function doBefore($user,$msg = '')
    {
        return $msg;
    }

    /**
     * 在执行方法之前与之后执行“LogBehavior”类的handle方法
     * @Around("hcontainer\tests\common\LogBehavior")
     */
    public function doAround($user,$msg = '')
    {
        return $msg;
    }

    /**
     * 在执行方法时发生异常,则执行"LogBehavior"
     * @AfterThrowing("hcontainer\tests\common\LogBehavior")
     */
    public function doAfterThrowing($user,$msg = '')
    {
        throw new Exception($msg);
    }

    /**
     * 在执行方法之后以对象的方式调用“LogBehavior”的"log"方法
     * @After("hcontainer\tests\common\LogBehavior@handle1")
     */
    public function doNewMethod($user,$msg = '')
    {
        return $msg;
    }

    /**
     * 在执行方法之后以类的方式调用“LogBehavior”的静态"log"方法
     * @After("hcontainer\tests\common\LogBehavior@@handle2")
     */
    public function doNew2Method($user,$msg = '')
    {
        return $msg;
    }


    // 以下两方法被类切面拦截
    public function do1Action($user,$msg = '')
    {
        return $msg;
    }

    public function do2Action($user,$msg = '')
    {
        return $msg;
    }
}


class BeanProcessor extends AnnotationProcessor
{
    // 自定义注解处理方法
    protected $annotationHandlers = [
        'Ref'=>'handleRefAnnotation'
    ];
    
    // 实现以下方法即可
    
    // 统一处理类,方法,类类型注解 $target_type = class,method,property
    public function handleAnnotation($annotation,string $class,string $target,string $target_type):void{}
    
    // 注解类方式
    public function handleAnnotationClass($annotation,string $class):void{}
    
    // 注解类方法方式
    public function handleAnnotationMethod($annotation,string $class,string $method):void{}
    
    // 注解类属性方式
    public function handleAnnotationProperty($annotation,string $class,string $property):void{}
    
    public function handleRefAnnotation($annotation,string $class,string $target,string $target_type)
    {
        
    }
    
    // 处理器结束事件处理方法
    public function handleProcessorFinish()
    {
        // 注册bean信息到容器
    }
}

namespace hehe\core\hcontainer\annotation;
use  hehe\core\hcontainer\annotation\Annotation;

/**
 * @Annotation("hehe\core\hcontainer\annotation\BeanProcessor")
 */
class Ref
{
    public $ref;

    public function __construct($value = null,bool $lazy = null,string $ref = null)
    {
       // 无需处理构造参数,调用injectArgParams将构造参数直接赋值给注解器属性
       // 如需处理构造参数,通过$this->getArgParams(func_get_args(),'ref') 获取格式化后的构造参数
        $this->injectArgParams(func_get_args(),'ref');
    }
}


namespace admin\service;
use hehe\core\hcontainer\annotation\Bean;
use hehe\core\hcontainer\annotation\Ref;

/**
 * @Bean(id="user")
 */
class User
{
    public $name;

    /**
     * role 值为Role bean对象
     * @Ref("Role");
     */
    public $role;
}


namespace hehe\core\hcontainer\annotation;

use  hehe\core\hcontainer\annotation\Annotation;
use Attribute;

#[Annotation("hehe\core\hcontainer\annotation\BeanProcessor")]
#[Attribute]
class Ref
{
    public $ref;

    public function __construct($value = null,bool $lazy = null,string $ref = null)
    {
        // 自己处理构造参数
    }
}


namespace hehe\core\hcontainer\annotation;

use hehe\core\hcontainer\ann\base\Ann;
use hehe\core\hcontainer\annotation\Annotation;
use Attribute;

#[Annotation("hehe\core\hcontainer\annotation\BeanProcessor")]
#[Attribute]
class Ref extends Ann
{
    public $ref;

    public function __construct($value = null,bool $lazy = null,string $ref = null)
    {
        // 无需处理构造参数,调用injectArgParams将构造参数直接赋值给注解器属性
        $this->injectArgParams(func_get_args(),'ref');
    }
}


namespace hehe\core\hcontainer\annotation;

use hehe\core\hcontainer\ann\base\Ann;
use hehe\core\hcontainer\annotation\Annotation;
use Attribute;

#[Annotation("hehe\core\hcontainer\annotation\BeanProcessor")]
#[Attribute]
class Advice extends Ann
{
    // 通知点位置
    public $advice;

    // 业务行为集合
    public $behaviors = [];

    // 拦截点表达式
    public $pointcut = '';

    public function __construct($value = null,string $pointcut = null,string $advice = null,string $behaviors = null)
    {
        // 需处理构造参数,获取格式化的构造参数
        $values = $this->getArgParams(func_get_args(),'behaviors');
        foreach ($values as $name=>$val) {
            if ($name == 'behaviors') {
                if (is_string($val)) {
                    $this->behaviors = explode(',',$val);
                } else {
                    $this->behaviors = $val;
                }
            } else {
                $this->$name = $val;
            }
        }
    }
}


namespace admin\service;
use hehe\core\hcontainer\annotation\Bean;
use hehe\core\hcontainer\annotation\Ref;


#[Bean("user")]
class User
{
    public $name;

    /**
     * role 值为Role bean对象
     * 
     */
     #[Ref("role",lazy:true)]
    public $role;
    
    #[After("hcontainer\\tests\common\LogBehavior@@log2")]
    public function okaop1($log,$msg)
    {

        return $msg;
    }
    
    #[After(behaviors:"hcontainer\\tests\common\LogBehavior@@log2")]
    public function okaop2($log,$msg)
    {

        return $msg;
    }
}