繁体   English   中英

扩展 PHP Class 以允许通过 __callStatic 找到新方法

[英]Extend PHP Class to allow new methods found via __callStatic

寻找一种灵活的方式来允许其他开发人员为模板系统扩展渲染方法,基本上允许他们生成自己的 render::whatever([ 'params' ]) 方法。

从单个开发人员的角度来看,当前设置运行良好,我根据上下文(帖子、媒体、分类等)设置了许多类,使用__callStatic方法收集调用 function 来检查method_exists是否在class,如果是,则提取任何通过的 arguments 并呈现 output。

快速示例(伪代码):

--查看/页面.php

render::title('<div>{{ title }}</div>');

-- app/render.php

class render {

    public static function __callStatic( $function, $args ) {
         
        // check if method exists 
        if ( method_exists( __CLASS__, $function ){

            self::{ $function }( $args );

        }

    }

    public static function title( $args ) {
         
        // do something with the passed args...

    }

}

我想让开发人员从他们自己的 class 中扩展可用的方法 - 这样他们就可以创建例如render::date( $args ); 并将其传递给他们的逻辑以收集数据,然后将结果呈现给模板。

问题是,哪种方法最有效且性能最佳 - 错误是安全性目前不是一个大问题,可能会在以后出现。

编辑 -

我已经通过执行以下操作(再次伪代码..)来完成这项工作:

-- app/render.php

class render {

    public static function __callStatic( $function, $args ) {
         
        // check if method exists 
        if ( 
            method_exists( __CLASS__, $function
        ){

            self::{ $function }( $args );

        }

        // check if method exists in extended class
        if ( 
            method_exists( __CLASS__.'_extend', $function 
        ){

            __CLASS__.'_extend'::{ $function }( $args );

        }

    }

    public static function title( $args ) {
         
        // do something with the passed args...

    }

}

-- child_app/render_extend.php

class render_extend {

    public static function date( $args = null ) {

        // do some dating..

    }

}

这里的问题是这仅限于基本 render() class 的一个扩展。

一种常见的方法(例如,Twig 和 Smarty 使用)是要求开发人员手动将其扩展注册为可调用对象。 render器 class 会记录它们,然后除了检查自己的内部方法外,还会从_callStatic中检查此列表。

根据您已经拥有的,这可能如下所示:

class render
{
    /** @var array */
    private static $extensions;
    
    public static function __callStatic($function, $args)
    {
        // check if method exists in class methods...
        if ( method_exists( __CLASS__, $function )) {
            self::{$function}(self::$args);
        }
        // and also in registry
        elseif (isset(self::$extensions[$function])) {
            (self::$extensions[$function])($args);
        }
    }
    
    public static function title($args)
    {
        // do something with the passed args...
    }
    
    public static function register(string $name, callable $callback)
    {
        self::$extensions[$name] = $callback;
    }
}

开发人员会像这样使用它:

render::register('date', function($args) {
    // Do something to do with dates
});

完整演示: https://3v4l.org/oOiN6

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM