简体   繁体   English

PHP 等效于 jQuery $.extend()?

[英]PHP equivalent for jQuery $.extend()?

Is there anything equivalent in PHP for jQuery's $.extend()? jQuery 的 $.extend() 在 PHP 中是否有任何等价物?

I want to pragmatically merge/combine/extend classes with other classes and it's properties (including methods) without using late static binding.我想在不使用后期 static 绑定的情况下,务实地将类与其他类及其属性(包括方法)合并/组合/扩展。

class a {}
class b {}
class c {}

$merged = combine(new a(), new b(), new c());

This is not what I am looking for:不是我要找的:

class a {}
class b extends a {}

$merged = new b();

There isn't really anything equivalent in PHP, because their object systems are very different. PHP 中没有任何等效的东西,因为它们的 object 系统非常不同。

JavaScript doesn't have real classes like PHP does, its object system is based on prototypes. JavaScript 没有像 PHP 那样的真实类,它的 object 系统是基于原型的。 Methods can be direct properties of the instance, but if there isn't a direct property the prototype chain will be searched to find it.方法可以是实例的直接属性,但如果没有直接属性,将搜索原型链以找到它。 $.extend() automatically copies properties that are inherited from the prototype to the target object, so the result is kind of like an instance of a subclass of all the original classes. $.extend()自动将从原型继承的属性复制到目标 object,因此结果有点像所有原始类的子类的实例。

But PHP doesn't have any equivalent to attaching methods directly to objects, so there's no way that a combine() function could merge all the methods from classes of the arguments.但是 PHP 没有任何等同于将方法直接附加到对象的方法,因此combine() function 无法合并 ZDBC11CAA5BDA99F77E6FB4DABD882E7D 类中的所有方法。 An object is an instance of a particular class, and it gets its methods from the class object (and its superclasses) only. object 是特定 class 的一个实例,它的方法来自 class ZA8CFDE6331BD59EB2AC96F8911ZC4(仅及其超类)。

Like @Barmar said, this isn't really a thing in PHP.就像@Barmar 所说,这在 PHP 中并不是真正的事情。 Workarounds are ugly but I am going to describe ugly workarounds for whoever want a big laugh.变通办法很丑陋,但我将为想要大笑的人描述丑陋的变通办法。

Workaround #1 - Extend classes by the use of magic methods in a class.解决方法 #1 - 通过在 class 中使用魔术方法来扩展类。 Pros are that the properties and methods can be accessed from one merged object.优点是可以从一个合并的 object 访问属性和方法。 But under the surface they are not really merged.但在表面之下,它们并没有真正合并。 So setting properties is discouraged and cross accessing properties is a no go.因此不鼓励设置属性,并且交叉访问属性是没有 go。

class extend {
  private $_objects;
  private $_properties = [];

  public function __construct(...$objects) {
    $this->_objects =  array_reverse($objects);
  }

  public function &__isset($name) {
    return $this->__get($name);
  }

  public function __get($name) {

    foreach ($this->_objects as $object) {
      if (isset($object->$name)) {
        return $object->$name;
      }
    }

    if (isset($this->_properties[$name])) {
      return $this->_properties[$name];
    }

    return null;
  }

   public function __set($name, $value) {

    foreach ($this->_objects as $object) {
      if (isset($object->$name)) {
        $object->$name = $value;
        return true;
      }
    }

    $this->_properties[$name] = $value;

    return true;
  }

  public function __call($name, $params) {

    foreach ($this->_objects as $object) {
      if (method_exists($object, $name)) {
        call_user_func_array([$object, $name], $params);
      }
    }

    return null;
  }
}

Example Objects:示例对象:

class a {
  var $fruit= 'apple';
  function foo() { echo 'a'; }
}

class b {
  var $fruit = 'banana';
  function bar() { echo 'b'; }
}

Merge Example:合并示例:

$merged = new extend(new a(), new b());
$merged->foo();
$merged->bar();

$merged->this = 'that';
echo $merged->this;

Workaround #2 - Merging objects with anonymous functions instead of methods makes them portable and mergeable.解决方法 #2 - 将对象与匿名函数而不是方法合并,使它们具有可移植性和可合并性。 Cons are it may be considered unethic or a future security risk to rely on them.缺点是依赖它们可能被认为是不道德的或未来的安全风险。 Anonymous functions in properties can not be defined in the class, but must be set in __construct().属性中的匿名函数不能在 class 中定义,但必须在 __construct() 中设置。 And accessing anonymous functions as properties conflicts the syntax for regular methods so a workaround for the syntax calling them is also needed (PHP 7.0+).并且将匿名函数作为属性访问与常规方法的语法冲突,因此还需要一种解决方法来调用它们的语法(PHP 7.0+)。

Object Example: Object 示例:

class a {
  var $fruit = 'apple';

  function __construct(){
    $this->foo = function() { return 'a'; };
  }
}

class b {
  var $fruit = 'banana';

  function __construct() {
    $this->bar = function() { return 'b'; };
  }
}

Example Objects:示例对象:

$merged = (object)array_merge(
  get_object_vars(new a()),
  get_object_vars(new b())
);

echo ($merged->foo)(); // $class->var() doesn't work for anonymous functions
echo ($merged->bar)();

$merged->fruit = 'orange';
echo $merged->fruit;

Final conclusions: Surely unconventional, mostly ugly.最终结论:肯定是非常规的,大多是丑陋的。

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

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