首页 文章

什么时候使用自我超过$?

提问于
浏览
1830

在PHP 5中,使用 self$this 有什么区别?

什么时候适合?

22 回答

  • 17

    self:: 运算符一起使用时,它引用当前类,可以在静态和非静态上下文中完成 . $this 指的是对象本身 . 此外,使用 $this 来调用静态方法(但不是引用字段)是完全合法的 .

  • 232

    DO NOT USE self::, use static::

    自我的另一个方面::值得一提 . 恼人地 self:: refers to the scope at the point of definition not at the point of execution . 考虑这个简单的类有两种方法:

    class Person
    {
    
        public static function status()
        {
            self::getStatus();
        }
    
        protected static function getStatus()
        {
            echo "Person is alive";
        }
    
    }
    

    如果我们打电话 Person::status() ,我们会看到"Person is alive" . 现在考虑当我们创建一个继承自this的类时会发生什么:

    class Deceased extends Person
    {
    
        protected static function getStatus()
        {
            echo "Person is deceased";
        }
    
    }
    

    调用 Deceased::status() 我们希望看到"Person is deceased"但是我们看到的是"Person is alive",因为在定义了对 self::getStatus() 的调用时,作用域包含原始方法定义 .

    PHP 5.3有一个解决方案 . static:: 解析运算符实现"late static binding",这是一种奇特的方式,它说它绑定到被调用类的范围 . 将 status() 中的行更改为 static::getStatus() ,结果就是您所期望的 . 在旧版本的PHP中,你必须找到一个kludge来做到这一点 .

    PHP Documentation

    所以回答问题不是问...

    $this-> 指的是当前对象(类的实例),而 static:: 指的是类

  • 5

    在PHP中,您使用self关键字来访问静态属性和方法 .

    问题是你可以在任何地方用 self::method() 替换 $this->method() ,无论 method() 是否被声明为静态 . 那么你应该使用哪一个?

    考虑以下代码:

    class ParentClass {
        function test() {
            self::who();    // will output 'parent'
            $this->who();   // will output 'child'
        }
    
        function who() {
            echo 'parent';
        }
    }
    
    class ChildClass extends ParentClass {
        function who() {
            echo 'child';
        }
    }
    
    $obj = new ChildClass();
    $obj->test();
    

    在此示例中, self::who() 将始终输出'parent',而 $this->who() 将取决于对象具有的类 .

    现在我们可以看到self指的是调用它的类,而 $this 指的是 class of the current object .

    因此,仅当 $this 不可用时,或者当您不希望允许后代类覆盖当前方法时,才应使用self .

  • 717

    根据php.net,在此上下文中有三个特殊关键字: selfparentstatic . 它们用于从类定义中访问属性或方法 .

    另一方面, $this 用于调用任何类的实例和方法,只要该类可访问即可 .

  • 27

    以下是对非静态和静态成员变量正确使用$ this和self的示例:

    <?php
    class X {
        private $non_static_member = 1;
        private static $static_member = 2;
    
        function __construct() {
            echo $this->non_static_member . ' '
               . self::$static_member;
        }
    }
    
    new X();
    ?>
    
  • 19

    关键字self确实 NOT 仅指'current class',至少不会限制您使用静态成员 . 在非静态成员的上下文中, self 还提供了绕过当前对象的vtable(see wiki on vtable)的方法 . 正如您可以使用 parent::methodName() 来调用函数的父版本,因此您可以调用 self::methodName() 来调用当前类的方法实现 .

    class Person {
        private $name;
    
        public function __construct($name) {
            $this->name = $name;
        }
    
        public function getName() {
            return $this->name;
        }
    
        public function getTitle() {
            return $this->getName()." the person";
        }
    
        public function sayHello() {
            echo "Hello, I'm ".$this->getTitle()."
    "; } public function sayGoodbye() { echo "Goodbye from ".self::getTitle()."
    "; } } class Geek extends Person { public function __construct($name) { parent::__construct($name); } public function getTitle() { return $this->getName()." the geek"; } } $geekObj = new Geek("Ludwig"); $geekObj->sayHello(); $geekObj->sayGoodbye();

    这将输出:

    你好,我是来自路德维希的极客路德维希

    sayHello() 使用 $this 指针,因此调用vtable来调用 Geek::getTitle() . sayGoodbye() 使用 self::getTitle() ,因此不使用vtable,并调用 Person::getTitle() . 在这两种情况下,我们都在处理实例化对象的方法,并且可以访问被调用函数中的 $this 指针 .

  • 5

    $this-> 用于引用类的变量(成员变量)或方法的特定实例 .

    Example: 
    $derek = new Person();
    

    $ derek现在是Person的特定实例 . 每个Person都有first_name和last_name,但$ derek有一个特定的first_name和last_name(Derek Martin) . 在$ derek实例中,我们可以将它们称为$ this-> first_name和$ this-> last_name

    ClassName ::用于引用该类型的类及其静态变量,静态方法 . 如果有帮助,您可以在心理上将“静态”替换为“共享” . 因为它们是共享的,所以它们不能引用$ this,它引用特定的实例(不共享) . 静态变量(即静态$ db_connection)可以在一种对象的所有实例之间共享 . 例如,所有数据库对象共享一个连接(静态$连接) .

    Static Variables Example: 假设我们有一个包含单个成员变量的数据库类:static $ num_connections;现在,把它放在构造函数中:

    function __construct()
    {
        if(!isset $num_connections || $num_connections==null)
        {
            $num_connections=0;
        }
        else
        {
            $num_connections++;
        }
    }
    

    正如对象具有构造函数一样,它们也具有析构函数,这些析构函数在对象死亡或未设置时执行:

    function __destruct()
    {
        $num_connections--;
    }
    

    每次我们创建一个新实例时,它都会将我们的连接计数器增加一个 . 每次我们销毁或停止使用实例时,它都会将连接计数器减一 . 通过这种方式,我们可以监视我们使用的数据库对象的实例数:

    echo DB::num_connections;
    

    因为$ num_connections是静态的(共享),所以它将反映活动数据库对象的总数 . 您可能已经看到过这种技术用于在数据库类的所有实例之间共享数据库连接 . 这样做是因为创建数据库连接需要很长时间,所以最好只创建一个并共享它(这称为Singleton模式) .

    静态方法(即公共静态View :: format_phone_number($ digits))可以在没有首先实例化其中一个对象的情况下使用(即它们不在内部引用$ this) .

    Static Method Example:

    public static function prettyName($first_name, $last_name)
    {
        echo ucfirst($first_name).' '.ucfirst($last_name);
    }
    
    echo Person::prettyName($derek->first_name, $derek->last_name);
    

    如您所见,public static function prettyName对该对象一无所知 . 它只是处理你传入的参数,就像一个不属于对象的普通函数 . 那么,为什么我们可以把它作为对象的一部分呢?

    • 首先,将函数附加到对象可以帮助您保持组织有序,因此您知道在哪里找到它们 .

    • 其次,它可以防止命名冲突 . 在一个大项目中,你根本没问题 . 没有冲突 . 耶静的方法!

    SELF:: 如果您在具有要引用的静态方法的对象外编码,则必须使用对象的名称View :: format_phone_number($ phone_number)调用它;如果您在具有要引用的静态方法的对象内编码,您可以使用对象的名称View :: format_phone_number($ pn),或者您可以使用self :: format_phone_number($ pn)快捷方式

    静态变量也是如此: Example: View :: templates_path与self :: templates_path

    在DB类中,如果我们引用某个其他对象的静态方法,我们将使用该对象的名称: Example: Session :: getUsersOnline();

    但是如果DB类想要引用它自己的静态变量,它只会说自己: Example: self :: connection;

    希望有助于清理事情:)

  • 1560

    在类定义中,$ this引用当前对象,而self引用当前类 .

    有必要使用self引用类元素,并使用$ this引用对象元素 .

    self::STAT // refer to a constant value
    self::$stat // static variable
    $this->stat // refer to an object variable
    
  • 10

    $this 指的是当前的类对象, self 指的是当前类(Not object) . 该类是对象的蓝图 . 所以你定义了一个类,但是你构造了对象 .

    换句话说,使用 self for staticthis for none-static members or methods .

    同样在子/父场景中 self / parent 主要用于识别子类和父类成员和方法 .

  • 12

    根据http://www.php.net/manual/en/language.oop5.static.php,没有 $self . 只有 $this ,用于引用类(对象)的当前实例,以及self,可用于引用类的静态成员 . 对象实例和类之间的区别在这里发挥作用 .

  • 432

    我遇到了同样的问题,简单的答案是:

    • $this 需要该类的实例

    • self:: 没有

    无论何时使用 static methodsstatic attributes 并且想要在没有实例化类的对象的情况下调用它们,您需要使用 self:: 来调用它们,因为 $this 始终要求创建对象 .

  • 0

    我相信问题不是你是否可以通过调用 ClassName::staticMember 来调用类的静态成员 . 问题是使用 self::classmember$this->classmember 之间的区别 .

    例如,以下两个示例均可正常运行,无论您使用 self:: 还是 $this->

    class Person{
        private $name;
        private $address;
    
        public function __construct($new_name,$new_address){
            $this->name = $new_name;
            $this->address = $new_address;
        }
    }
    
    class Person{
        private $name;
        private $address;
        public function __construct($new_name,$new_address){
            self::$name = $new_name;
            self::$address = $new_address;
        }
    }
    
  • 93

    为了真正理解当我们谈论 self$this 时我们正在讨论的内容,我们需要真正深入了解's going on at a conceptual and a practical level. I don't真正感觉到任何答案都做到了这一点,所以这是我的尝试 .

    让我们先谈谈一个类和一个对象是什么 .

    类和对象,从概念上讲

    那么, is 一类?很多人将它定义为对象的蓝图或模板 . 事实上,你可以阅读更多About Classes In PHP Here . 在某种程度上,'s what it really is. Let'看一个类:

    class Person {
        public $name = 'my name';
        public function sayHello() {
            echo "Hello";
        }
    }
    

    正如您所知,该类上有一个名为 $name 的属性和一个名为 sayHello() 的方法(函数) .

    值得注意的是,该类是一个静态结构 . 这意味着,一旦定义,类 Person 在您看到的任何地方始终都是相同的 .

    另一方面,对象是所谓的类的实例 . 这意味着我们采用类的"blueprint",并使用它来制作动态副本 . 此副本现在特别与其存储的变量相关联 . 因此,对实例的任何更改都是该实例的本地更改 .

    $bob = new Person;
    $adam = new Person;
    $bob->name = 'Bob';
    echo $adam->name; // "my name"
    

    我们使用 new 运算符创建类的新实例 .

    因此,我们说Class是一个全局结构,Object是一个本地结构 . 不要担心那个有趣的 -> 语法,我们将稍微介绍一下 .

    我们应该谈谈,另一件事是,我们可以检查一个实例是 instanceof 特定类: $bob instanceof Person 如果 $bob 实例是使用 Person 类,或 Person 的孩子做返回boolean .

    定义国家

    那么让我们深入了解一个类实际包含的内容 . 一个类包含5种类型的“东西”:

    • 属性 - 将这些视为每个实例将包含的变量 .
    class Foo {
        public $bar = 1;
    }
    
    • 静态属性 - 将这些视为在类级别共享的变量 . 这意味着它们永远不会被每个实例复制 .
    class Foo {
        public static $bar = 1;
    }
    
    • 方法 - 这些是每个实例将包含的函数(并对实例进行操作) .
    class Foo {
        public function bar() {}
    }
    
    • 静态方法 - 这些是在整个类中共享的函数 . 它们对实例进行操作,而只对静态属性进行操作 .
    class Foo {
        public static function bar() {}
    }
    
    • 常量 - 类解析常量 . 这里没有更深入,但添加完整性:
    class Foo {
        const BAR = 1;
    }
    

    所以基本上,我们使用"hints"关于静态来存储关于类和对象容器的信息,这些静态标识信息是否是共享的(因而是静态的)(因此是动态的) .

    状态和方法

    在方法内部,对象的实例由 $this 变量表示 . 该对象的当前状态就在那里,并且改变(改变)任何属性将导致对该实例的改变(但不改变其他属性) .

    如果静态调用方法,则不定义 $this 变量 . 这是因为没有与静态调用相关联的实例 .

    这里有趣的是如何进行静态调用 . 那么让我们谈谈我们如何访问状态:

    进入国家

    所以现在我们已经存储了那个状态,我们需要访问它 . 这可能会有点棘手(或多一点),所以让我们把它分成两个视点:从实例/类的外部(比如来自普通函数调用,或来自全局范围),以及实例内部/ class(来自对象上的方法) .

    来自实例/类的外部

    从实例/类的外部,我们的规则非常简单且可预测 . 我们有两个运算符,每个运算符都会立即告诉我们是否正在处理实例或静态类:

    • -> - object-operator - 在我们访问实例时总是使用它 .
    $bob = new Person;
    echo $bob->name;
    

    重要的是要注意调用 Person->foo 没有意义(因为 Person 是一个类,而不是一个实例) . 因此,这是一个解析错误 .

    • :: - scope-resolution-operator - 始终用于访问Class静态属性或方法 .
    echo Foo::bar()
    

    另外,我们可以用相同的方式在对象上调用静态方法:

    echo $foo::bar()
    

    非常重要的是要注意,当我们这样做 from outside 时,对象的实例在 bar() 方法中是隐藏的 . 这意味着它与运行完全相同:

    $class = get_class($foo);
    $class::bar();
    

    因此,静态调用中未定义 $this .

    来自实例/类的内部

    事情在这里有所改变 . 使用相同的运算符,但它们的含义变得非常模糊 .

    对象运算符 -> 仍用于调用对象的实例状态 .

    class Foo {
        public $a = 1;
        public function bar() {
            return $this->a;
        }
    }
    

    使用object-operator: $foo->bar()$fooFoo 的实例)上调用 bar() 方法将导致实例的 $a 版本 .

    这就是我们的期望 .

    :: 运算符的含义虽然有所改变 . 它取决于对当前函数的调用的上下文:

    • 在静态上下文中

    在静态上下文中,使用 :: 进行的任何调用也将是静态的 . 我们来看一个例子:

    class Foo {
        public function bar() {
            return Foo::baz();
        }
        public function baz() {
            return isset($this);
        }
    }
    

    调用 Foo::bar() 将静态调用 baz() 方法,因此 $this 将填充 not . 值得注意的是,在PHP(5.3)的最新版本中,这将触发 E_STRICT 错误,因为我们静态地调用非静态方法 .

    • 在实例上下文中

    另一方面,在实例上下文中,使用 :: 进行的调用取决于调用的接收者(我们正在调用的方法) . 如果该方法定义为 static ,则它将使用静态调用 . 如果不是,它将转发实例信息 .

    因此,查看上面的代码,调用 $foo->bar() 将返回 true ,因为"static"调用发生在实例上下文中 .

    合理?不这么认为 . 这令人困惑 .

    快捷方式关键字

    因为使用类名将所有内容捆绑在一起相当脏,所以PHP提供了3个基本的“快捷方式”关键字,使范围解析更容易 .

    • self - 这是指当前的类名 . 所以 self::baz()Foo 类中的 Foo::baz() 相同(上面的任何方法) .

    • parent - 这是指当前类的父级 .

    • static - 这是指被调用的类 . 由于继承,子类可以覆盖方法和静态属性 . 因此,使用 static 而不是类名称调用它们可以让我们解决调用的来源,而不是当前级别 .

    例子

    理解这一点的最简单方法是开始查看一些示例 . 我们选一节课:

    class Person {
        public static $number = 0;
        public $id = 0;
        public function __construct() {
            self::$number++;
            $this->id = self::$number;
        }
        public $name = "";
        public function getName() {
            return $this->name;
        }
        public function getId() {
            return $this->id;
        }
    }
    
    class Child extends Person {
        public $age = 0;
        public function __construct($age) {
            $this->age = $age;
            parent::__construct();
        }
        public function getName() {
            return 'child: ' . parent::getName();
        }
    }
    

    现在,我们也在看这里的继承 . 暂时忽略这是一个糟糕的对象模型,但让我们来看看当我们玩这个时会发生什么:

    $bob = new Person;
    $bob->name = "Bob";
    $adam = new Person;
    $adam->name = "Adam";
    $billy = new Child;
    $billy->name = "Billy";
    var_dump($bob->getId()); // 1
    var_dump($adam->getId()); // 2
    var_dump($billy->getId()); // 3
    

    所以ID计数器在两个实例和子节点之间共享(因为我们正在使用它) self 访问它 . 如果我们使用 static ,我们可以在子类中覆盖它 .

    var_dump($bob->getName()); // Bob
    var_dump($adam->getName()); // Adam
    var_dump($billy->getName()); // child: Billy
    

    请注意,我们每次都在执行 Person::getName() 实例方法 . 但我们正在使用 parent::getName() 在其中一个案例(子案例)中这样做 . 这就是使这种方法变得强大的原因 .

    谨慎的话#1

    请注意,调用上下文决定了是否使用了实例 . 因此:

    class Foo {
        public function isFoo() {
            return $this instanceof Foo;
        }
    }
    

    不是 always 是真的 .

    class Bar {
        public function doSomething() {
            return Foo::isFoo();
        }
    }
    $b = new Bar;
    var_dump($b->doSomething()); // bool(false)
    

    现在这真的很奇怪 . 我们正在调用另一个类,但传递给 Foo::isFoo() 方法的 $this$bar 的实例 .

    这可能会导致各种错误和概念性的WTF-ery . 所以我强烈建议在实例方法中避免使用 :: 运算符,除了那三个虚拟"short-cut"关键字( staticselfparent ) .

    谨慎的话#2

    请注意,每个人都共享静态方法和属性 . 这使它们基本上成为全局变量 . 与全局变量相同的问题 . 因此,我会非常犹豫是否将信息存储在静态方法/属性中,除非您对其真正的全局性感到满意 .

    谨慎的话#3

    通常,您使用 static 而不是 self 称为Late-Static-Binding . 但请注意,它们不是一回事,所以说“总是使用 static 而不是 self 是非常短视的 . 相反,停下来想想你想做的电话,并想想你是否希望子课能够覆盖那个静态解决的电话 .

    TL / DR

    太糟糕了,回去看看吧 . 它可能太长了,但它很长,因为这是一个复杂的话题

    TL / DR#2

    好的 . 简而言之, self 用于引用类中的当前类名,其中 $this 引用当前对象实例 . 请注意 self 是复制/粘贴快捷方式 . 您可以安全地用您的 class 名称替换它,它会正常工作 . 但 $this 是一个动态变量,无法提前确定(甚至可能不是您的 class ) .

    TL / DR#3

    如果使用了对象操作符( -> ),那么您始终知道您正在处理实例 . 如果使用范围解析运算符( :: ),则需要有关上下文的更多信息(我们是否已经在对象上下文中?我们是否在对象之外?等等) .

  • 16

    self (不是$ self)指的是类的类型,其中 $this 指的是类的当前实例 . self 用于静态成员函数,以允许您访问静态成员变量 . $this 用于非静态成员函数,并且是对调用成员函数的类的实例的引用 .

    因为 this 是一个对象,所以你可以使用它: $this->member

    因为 self 不是一个对象,它基本上是一个自动引用当前类的类型,你可以使用它: self::member

  • 12

    self 指当前类(在其中调用它),

    $this 指当前对象 . 你可以使用static而不是self . 看例子:

    class ParentClass {
                function test() {
                        self::which();  // output 'parent'
                        $this->which(); // output 'child'
                }
    
                function which() {
                        echo 'parent';
                }
        }
    
        class ChildClass extends ParentClass {
                function which() {
                        echo 'child';
                }
        }
    
        $obj = new ChildClass();
        $obj->test();
    

    输出:父子

  • 11

    简答

    使用$ this来引用当前对象 . 使用self来引用当前类 . 换句话说,对非静态成员使用$ this-> member,对静态成员使用self :: $ member .

    完整答案

    以下是 correctself 用于非静态和静态成员变量的示例:

    <?php
    class X {
        private $non_static_member = 1;
        private static $static_member = 2;
    
        function __construct() {
            echo $this->non_static_member . ' '
               . self::$static_member;
        }
    }
    
    new X();
    ?>
    

    以下是 incorrectself 用于非静态和静态成员变量的示例:

    <?php
    class X {
        private $non_static_member = 1;
        private static $static_member = 2;
    
        function __construct() {
            echo self::$non_static_member . ' '
               . $this->static_member;
        }
    }
    
    new X();
    ?>
    

    以下是 polymorphism 与成员函数 $this 的示例:

    <?php
    class X {
        function foo() {
            echo 'X::foo()';
        }
    
        function bar() {
            $this->foo();
        }
    }
    
    class Y extends X {
        function foo() {
            echo 'Y::foo()';
        }
    }
    
    $x = new Y();
    $x->bar();
    ?>
    

    以下是使用 self 作为成员函数的 suppressing polymorphic behaviour 示例:

    <?php
    class X {
        function foo() {
            echo 'X::foo()';
        }
    
        function bar() {
            self::foo();
        }
    }
    
    class Y extends X {
        function foo() {
            echo 'Y::foo()';
        }
    }
    
    $x = new Y();
    $x->bar();
    ?>
    

    想法是$ this-> foo()调用foo()成员函数,无论当前对象的确切类型是什么 . 如果对象是X类型,则它调用X :: foo() . 如果对象是Y类型,则调用Y :: foo() . 但是使用self :: foo(),总是调用X :: foo() .

    来自http://www.phpbuilder.com/board/showthread.php?t=10354489

    http://board.phpbuilder.com/member.php?145249-laserlight

  • 4
    • 对象指针$ this引用当前对象 .

    • 类值"static"引用当前对象 .

    • 类值"self"指的是它所定义的确切类 .

    • 类值"parent"指的是其定义的确切类的父级 .

    请参阅以下显示重载的示例 .

    <?php
    
    class A {
    
        public static function newStaticClass()
        {
            return new static;
        }
    
        public static function newSelfClass()
        {
            return new self;
        }
    
        public function newThisClass()
        {
            return new $this;
        }
    }
    
    class B extends A
    {
        public function newParentClass()
        {
            return new parent;
        }
    }
    
    
    $b = new B;
    
    var_dump($b::newStaticClass()); // B
    var_dump($b::newSelfClass()); // A because self belongs to "A"
    var_dump($b->newThisClass()); // B
    var_dump($b->newParentClass()); // A
    
    
    class C extends B
    {
        public static function newSelfClass()
        {
            return new self;
        }
    }
    
    
    $c = new C;
    
    var_dump($c::newStaticClass()); // C
    var_dump($c::newSelfClass()); // C because self now points to "C" class
    var_dump($c->newThisClass()); // C
    var_dump($b->newParentClass()); // A because parent was defined *way back* in class "B"
    

    大多数时候你想引用当前的类,这就是你使用 static$this 的原因 . 但是,有时您需要 self 因为您想要原始类而不管扩展它的内容 . (很少,很少)

  • 1

    此外,由于 $this:: 尚未讨论过 .

    仅供参考,从PHP 5.3开始处理实例化对象以获取当前作用域值时,与使用 static:: 相反,可以选择使用 $this:: .

    http://ideone.com/7etRHy

    class Foo
    {
        const NAME = 'Foo';
    
        //Always Foo::NAME (Foo) due to self
        protected static $staticName = self::NAME;
    
        public function __construct()
        {
            echo $this::NAME;
        }
    
        public function getStaticName()
        {
           echo $this::$staticName;
        }
    }
    
    class Bar extends Foo
    {
        const NAME = 'FooBar';
    
        /**
         * override getStaticName to output Bar::NAME
         */
        public function getStaticName()
        {
            $this::$staticName = $this::NAME;
            parent::getStaticName();
        }
    }
    
    $foo = new Foo; //outputs Foo
    $bar = new Bar; //outputs FooBar
    $foo->getStaticName(); //outputs Foo
    $bar->getStaticName(); //outputs FooBar
    $foo->getStaticName(); //outputs FooBar
    

    使用上面的代码并不常见或推荐的做法,但只是为了说明它的用法,并且更像是“你知道吗?”参考原始海报的问题 .

    它还表示 $object::CONSTANT 的用法,例如 echo $foo::NAME; ,而不是 $this::NAME;

  • 23

    如果要在不创建该类的对象/实例的情况下调用类的方法,请使用 self ,从而保存RAM(有时为此目的使用self) . 换句话说,它实际上是静态调用方法 . 使用 this 作为对象透视图 .

  • 1

    来自this blog post

    self指的是当前类self可以用来调用静态函数和引用静态成员变量self可以在static函数里面使用self也可以通过绕过vtable来关闭多态行为$ this指的是当前对象$ this可以用调用静态函数$ this不应该用于调用静态成员变量 . 用自己代替 . $ this不能在静态函数中使用

  • 109

    情况1:使用 self 可用于类常量

    class classA { 
         const FIXED_NUMBER = 4; 
         self::POUNDS_TO_KILOGRAMS
    }
    

    如果要在类之外调用它,请使用 classA::POUNDS_TO_KILOGRAMS 来访问常量

    案例2:对于静态属性

    class classC {
         public function __construct() { 
         self::$_counter++; $this->num = self::$_counter;
       }
    }
    
  • 10

    由于这里没有人谈到表演,这里有一个小基准(5.6):

    Name     | Time    | Percent  
    ----------|---------|---------  
     $this->  | 0.99163 | 106.23%  
     self::   | 0.96912 | 103.82%  
     static:: | 0.93348 | 100%
    

    这些是2 000 000次运行的结果,这是我使用的代码:

    <?php
    
    require '../vendor/autoload.php';
    
    // My small class to do benchmarks
    // All it does is looping over every test x times and record the
    //   time it takes using `microtime(true)`
    // Then, the percentage is calculated, with 100% being the quickest
    // Times are being rouned for outputting only, not to calculate the percentages
    $b = new Tleb\Benchmark\Benchmark(2000000);
    
    class Foo
    {
        public function calling_this()
        {
            $this->called();
        }
    
        public function calling_self()
        {
            self::called();
        }
    
        public function calling_static()
        {
            static::called();
        }
    
        public static function called()
        {
        }
    }
    
    $b->add('$this->',  function () { $foo = new Foo; $foo->calling_this(); });
    $b->add('self::',   function () { $foo = new Foo; $foo->calling_self(); });
    $b->add('static::', function () { $foo = new Foo; $foo->calling_static(); });
    
    $b->run();
    

相关问题