[英]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.