【问题标题】:Adding a custom function to an already instantiated object in PHP?向 PHP 中已实例化的对象添加自定义函数?
【发布时间】:2023-03-10 01:15:01
【问题描述】:

在 PHP 中执行此类操作的最佳方法是什么?:

$a = new CustomClass();

$a->customFunction = function() {
    return 'Hello World';
}

echo $a->customFunction();

(以上代码无效。)

【问题讨论】:

  • 这个技巧你有什么实际用途吗?

标签: php oop function class


【解决方案1】:

与 Javascript 不同,您不能在事后将函数分配给 PHP 类(我假设您来自 Javascript,因为您正在使用它们的匿名函数)。

Javascript 有一个无类原型系统,而 PHP 有一个经典分类系统。在 PHP 中,您必须定义要使用的每个类,而在 Javascript 中,您可以根据需要创建和更改每个对象。

用 Douglas Crockford 的话来说:您可以像使用经典系统一样使用 Javascript 进行编程,但不能像使用 Javascript 那样使用经典系统进行编程。这意味着您可以在 Javascript 中完成的很多事情,如果不进行修改,您就无法在 PHP 中完成。

【讨论】:

    【解决方案2】:

    我闻到了Adapter Pattern,甚至可能是Decorator Pattern

    【讨论】:

      【解决方案3】:

      这是一个简单且有限的 PHP 类猴子补丁类。添加到类实例的方法必须将对象引用 ($this) 作为它们的第一个参数,python 样式。 此外,parentself 之类的构造也不起作用。

      OTOH,它允许您将任何callback type 修补到类中。

      class Monkey {
      
          private $_overload = "";
          private static $_static = "";
      
      
          public function addMethod($name, $callback) {
              $this->_overload[$name] = $callback;
          }
      
          public function __call($name, $arguments) {
              if(isset($this->_overload[$name])) {
                  array_unshift($arguments, $this);
                  return call_user_func_array($this->_overload[$name], $arguments);
                  /* alternatively, if you prefer an argument array instead of an argument list (in the function)
                  return call_user_func($this->_overload[$name], $this, $arguments);
                  */
              } else {
                  throw new Exception("No registered method called ".__CLASS__."::".$name);
              }
          }
      
          /* static method calling only works in PHP 5.3.0 and later */
          public static function addStaticMethod($name, $callback) {
              $this->_static[$name] = $callback;
          }
      
          public static function __callStatic($name, $arguments) {
              if(isset($this->_static[$name])) {
                  return call_user_func($this->_static[$name], $arguments);
                  /* alternatively, if you prefer an argument list instead of an argument array (in the function)
                  return call_user_func_array($this->_static[$name], $arguments);
                  */
              } else {
                  throw new Exception("No registered method called ".__CLASS__."::".$name);
              }
          }
      
      }
      
      /* note, defined outside the class */
      function patch($this, $arg1, $arg2) {
          echo "Arguments $arg1 and $arg2\n";
      }
      
      $m = new Monkey();
      $m->addMethod("patch", "patch");
      $m->patch("one", "two");
      
      /* any callback type works. This will apply `get_class_methods` to the $m object. Quite useless, but fun. */
      $m->addMethod("inspect", "get_class_methods");
      echo implode("\n", $m->inspect())."\n";
      

      【讨论】:

        猜你喜欢
        • 2022-12-06
        • 2020-02-20
        • 2013-03-14
        • 2012-09-16
        • 1970-01-01
        • 2020-06-06
        • 2011-11-01
        • 1970-01-01
        相关资源
        最近更新 更多