在PHP中实例化类的正确方法 [英] Right way to instantiate class in PHP

查看:151
本文介绍了在PHP中实例化类的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在类内部创建一个方法,该方法将实例化当前所在的类.但是,我还需要此方法中的方法才能在所有扩展类中正常工作.正如我从此线程中学到的那样,对于self这个任务.因此,显而易见的选择是使用static关键字.

I am trying to create a method inside class, that will instantiate class that is currently in. But I would also need that from this method to work correctly in all extended classes. As I have learned from this thread, it's not good to use self keyword for this task. So obvious choice would be using static keyword.

但是,我遇到了也可以使用的不同方法.

But, I've come across different method that also works.

示例:

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);

从本例中可以看到,

staticInstancethisInstance都产生正确"的结果.还是他们?

As I can see from this example, both staticInstance and thisInstance produce "correct" results. Or do they?

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

Can someone explain difference between these two methods and which one is "correct" one.

推荐答案

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

As of PHP 5.3.0, PHP implements a feature called late static bindings which can be used to reference the called class in a context of static inheritance.

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

More precisely, late static bindings work by storing the class named in the last "non-forwarding call". In case of static method calls, this is the class explicitly named (usually the one on the left of the :: operator); in case of non static method calls, it is the class of the object. A "forwarding call" is a static one that is introduced by self::, parent::, static::, or, if going up in the class hierarchy, forward_static_call(). The function get_called_class() can be used to retrieve a string with the name of the called class and static:: introduces its scope.

此功能被命名为后期静态绑定",同时考虑了内部视角. 后期绑定"来自以下事实:static ::不会使用定义方法的类来解析,而是使用运行时信息来计算.它也被称为静态绑定",因为它可用于(但不限于)静态方法调用.

This feature was named "late static bindings" with an internal perspective in mind. "Late binding" comes from the fact that static:: will not be resolved using the class where the method is defined but it will rather be computed using runtime information. It was also called a "static binding" as it can be used for (but is not limited to) static method calls.

自我限制:

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

Static references to the current class like self:: or CLASS are resolved using the class in which the function belongs, as in where it was defined:

<?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();
?>

上面的示例将输出:A

最新静态绑定的用法:

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

Late static bindings tries to solve that limitation by introducing a keyword that references the class that was initially called at runtime. Basically, a keyword that would allow you to reference B from test() in the previous example. It was decided not to introduce a new keyword but rather use static that was already reserved.

<?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();
?>

上面的示例将输出:B

$this关键字引用当前对象,您不能在静态方法中使用它.当您说return $this时,它意味着某些方法返回与其在其上被调用的对象相同的对象.

$this keyword refers to current object and you cannot use it in static methods. When you say return $this it means that some method returns the same object on which it was invoked.

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

So the correct way would be using static keyword because if you say return new static() it refers to the class the method is currently in.

这篇关于在PHP中实例化类的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆