【问题标题】:Extend PHP Class to allow new methods found via __callStatic扩展 PHP 类以允许通过 __callStatic 找到新方法
【发布时间】:2020-10-18 07:13:27
【问题描述】:

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

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

快速示例(伪代码):

-- 查看/page.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...

    }

}

我希望允许开发人员从他们自己包含的类中扩展可用的方法 - 这样他们就可以创建例如 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() 类的一个扩展。

【问题讨论】:

    标签: php class namespaces extend


    【解决方案1】:

    一种常见的方法(Twig 和 Smarty 使用的几个示例)是要求开发人员手动将其扩展注册为可调用对象。 render 类对它们进行记录,然后除了检查自己的内部方法之外,还检查来自_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

    【讨论】:

    • 感谢@iainn,我已经实现了这种方法,但我希望找到更简单、更一致的路线——我会更新我的问题以显示我现在正在使用的另一条路线。跨度>
    • 但是,这个想法是可靠的。我希望 render::method() 的实际格式是一致的,所以也许我会将注册提取到另一个函数调用并定义这些新方法的查找点..
    • 接受答案,因为它让我走上了正确的道路 - 一旦这一切充实起来,我将在 GH 上添加解决方案的链接。基本上我注册了任何扩展类并收集了所有方法,然后检查 extended_class::method -- 谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    • 2013-06-14
    • 1970-01-01
    • 2018-04-02
    相关资源
    最近更新 更多