在PHP中实例化类的正确方法

AlF*_*Fra 5 php instantiation instance

我正在尝试在类中创建一个方法,它将实例化当前的类.但是我还需要使用此方法在所有扩展类中正常工作.正如我从这个线程中学到的,使用self关键字来完成这项任务并不好.所以明显的选择是使用static关键字.

但是,我遇到了不同的方法,也有效.

例:

class SimpleClass
{
    private $arg;

    public function __construct( $arg ){
        $this->arg = $arg;
    }

    public function getArg(){return $this->arg;}
    public function setArg($arg){$this->arg = $arg;}

    public function staticInstance()
    {
        return new static( $this->arg );
    }

    public function thisInstance()
    {
        return new $this( $this->arg );
    }

    public function selfInstance()
    {
        return new self( $this->arg );
    }
}

class ExtendedClass extends SimpleClass
{
}

$c1 = 'SimpleClass';
$c2 = 'ExtendedClass';

$inst1 = new $c1('simple');
$inst2 = new $c2('extended');

$static_instance_1 = $inst1->staticInstance();
$this_instance_1 = $inst1->thisInstance();
$self_instance_1 = $inst1->selfInstance();

$static_instance_2 = $inst2->staticInstance();
$this_instance_2 = $inst2->thisInstance();
$self_instance_2 = $inst2->selfInstance();

echo "SimpleClass Instances\n";
echo get_class($static_instance_1);
echo get_class($this_instance_1);
echo get_class($self_instance_1);

echo "ExtendedClass Instances\n";
echo get_class($static_instance_2);
echo get_class($this_instance_2);
echo get_class($self_instance_2);
Run Code Online (Sandbox Code Playgroud)

当我从这个例子可以看到,无论是staticInstance和thisInstance产生"正确"的结果.或者他们呢?

有人可以解释这两种方法之间的差异,哪一种是"正确"的.

And*_* J. 6

php.net说:

从 PHP 5.3.0 开始,PHP 实现了一项称为后期静态绑定的功能,该功能可用于在静态继承上下文中引用被调用的类。

更准确地说,后期静态绑定通过存储最后一个“非转发调用”中命名的类来工作。对于静态方法调用,这是显式命名的类(通常是 :: 运算符左侧的类);对于非静态方法调用,它是对象的类。“转发调用”是一种静态调用,由 self::、parent::、static:: 引入,或者,如果在类层次结构中向上,则由forward_static_call() 引入。函数 get_used_class() 可用于检索带有被调用类名称的字符串,并且 static:: 引入其范围。

从内部角度考虑,此功能被命名为“后期静态绑定”。“后期绑定”来自这样一个事实:static:: 不会使用定义该方法的类来解析,而是使用运行时信息来计算。它也被称为“静态绑定”,因为它可用于(但不限于)静态方法调用。

自我的局限性:

对当前类(如 self:: 或CLASS)的静态引用使用函数所属的类进行解析,如定义函数的位置:

<?php
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        self::who();
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test();
?>
Run Code Online (Sandbox Code Playgroud)

上面的例子将输出:A

后期静态绑定的用法:

后期静态绑定试图通过引入一个引用最初在运行时调用的类的关键字来解决该限制。基本上,这是一个允许您从上一个示例中的 test() 引用 B 的关键字。决定不引入新的关键字,而是使用已经保留的 static。

<?php
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who(); // Here comes Late Static Bindings
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test();
?>
Run Code Online (Sandbox Code Playgroud)

上面的例子将输出:B

$this关键字引用当前对象,不能在静态方法中使用它。当你说return $this这意味着某个方法返回调用它的同一对象时。

因此,正确的方法是使用static关键字,因为如果您说它return new static()引用该方法当前所在的类。