静态变量不能通过对象或$ this访问,但静态函数可以通过$ this或PHP中的对象访问

时间:2013-09-08 08:21:08

标签: php

<?php
class c1
{
  public static function f1()
  {
    return "hello";
  }

  public static $a=10;

  public function f2()
  {
    echo $this->f1(); //prints "hello"
    echo $this->a;//ERROR:Undefined property: c1::$a in C:\wamp\www\class_in_php\example5.php on line 14
  }
}

$obj1=new c1;
$obj1->f2();
?>

为什么我们不能使用$ this或该类的对象访问类的静态变量? 但我们可以使用$ this或该类的对象访问该类的静态函数

这种现象背后的原因是什么?

3 个答案:

答案 0 :(得分:6)

您应该使用self::代替$this->来访问静态成员。

原因是$this引用了类的当前实例,而静态成员是类本身的一部分,而不是实例的一部分。

答案 1 :(得分:2)

静态变量不属于“实例”,而属于类本身。当你在运行时拥有类的实际“实例”时,那时$this指针才有意义:它意味着“我现在发现自己的这个实例”...你怎么能使用$ this this指针引用实例外不存在的东西?

当我第一次学习C ++的时候(Metacomco,我认为)是一个实际上使用了大量C预处理器宏来模拟对象的系统,它非常有启发性,因此可以理解$this({事实上,在C ++中{1}}只是作为第一个参数传递给所有方法函数的额外参数:

this

实际上是这样执行的:

this->foo("Hello");
this->bar(42, "Finished");

并在foo()函数内部对方法变量的任何引用,例如:

foo(this_ptr, "Hello");
bar(this_ptr, 42, "Finished");

只不过是对指针解引用变量的引用:

this->status

因此,您可以看到尝试从this_ptr->status 指针访问静态变量将会受到打击,因为它不是该特定内存块的成员。这就是“过去工作”的方式,但我认为解释仍然很好。

希望有所帮助! :)

答案 2 :(得分:0)

  

为什么我们不能使用$ this或该类的对象访问类的静态变量?但是我们可以使用$ this或该类的对象访问该类的静态函数。

嗯,我们可以,但是你使用了错误的语法。

错:

echo $this->a;

右:

$this::$a;

由于c1::$a是一个静态类变量,您需要使用正确的语法,即使用双冒号::然后使用美元符号($)来表示变量:$this::$a

但是,不要被这种语法愚弄太容易,因为

的原因
$this->f1()

虽然c1::f1()是一个静态函数,但由于向后兼容性,因为PHP版本5之前没有静态类方法(因为那些显式定义了the static keyword)和第一个PHP 5版本->可用于调用静态类方法。

然而,通过$this访问静态类变量是一种PHP 5.3+语法特性,更新了。

示例代码(run against multiple PHP versions):

<?php
/**
 * @link http://stackoverflow.com/a/24059368/367456
 */
class c1
{
    public static function f1()
    {
        return "hello";
    }

    public static $a = 10;

    public function f2()
    {
        echo $this->f1(); // prints "hello"
        echo $this->a;    // Strict Standards: Accessing static property c1::$a as non static
        echo $this::$a;   // prints "10" (PHP <= 5.2.17: Parse error)
    }
}

$obj1 = new c1;
$obj1->f2();