PHP中的(双冒号)和 – >(箭头)有什么区别?

在PHP中访问方法有两种截然不同的方式,但有什么不同?

$response->setParameter('foo', 'bar'); 

 sfConfig::set('foo', 'bar'); 

我假设-> (破折号大于符号或V形)用于variables的函数,而:: :(双冒号)用于类的函数。 正确?

赋值运算符是否仅用于在数组内分配数据? 这与用于实例化或修改variables的赋值运算符相反吗?

当左边部分是一个对象实例时,使用-> 。 否则,你使用::

这意味着->主要用于访问实例成员(尽pipe它也可以用来访问静态成员,这种用法是不鼓励的),而::通常用于访问静态成员(尽pipe在一些特殊情况下,访问实例成员)。

一般来说, ::用于范围parsing ,它可以有一个类名, parentself ,或者(在PHP 5.3中)左边是staticparent指的是它使用的类的超类范围; self指的是它所使用的类的范围; static是指“调用范围”(请参阅后期的静态绑定 )。

规则是::是一个实例调用当且仅当:

  • 目标方法没有声明为静态的
  • 在调用的时候有一个兼容的对象上下文,这意味着这些必须是正确的:
    1. 这个调用是从$this存在的上下文中进行的
    2. $this的类是要调用的方法的类或其子类。

例:

 class A { public function func_instance() { echo "in ", __METHOD__, "\n"; } public function callDynamic() { echo "in ", __METHOD__, "\n"; B::dyn(); } } class B extends A { public static $prop_static = 'B::$prop_static value'; public $prop_instance = 'B::$prop_instance value'; public function func_instance() { echo "in ", __METHOD__, "\n"; /* this is one exception where :: is required to access an * instance member. * The super implementation of func_instance is being * accessed here */ parent::func_instance(); A::func_instance(); //same as the statement above } public static function func_static() { echo "in ", __METHOD__, "\n"; } public function __call($name, $arguments) { echo "in dynamic $name (__call)", "\n"; } public static function __callStatic($name, $arguments) { echo "in dynamic $name (__callStatic)", "\n"; } } echo 'B::$prop_static: ', B::$prop_static, "\n"; echo 'B::func_static(): ', B::func_static(), "\n"; $a = new A; $b = new B; echo '$b->prop_instance: ', $b->prop_instance, "\n"; //not recommended (static method called as instance method): echo '$b->func_static(): ', $b->func_static(), "\n"; echo '$b->func_instance():', "\n", $b->func_instance(), "\n"; /* This is more tricky * in the first case, a static call is made because $this is an * instance of A, so B::dyn() is a method of an incompatible class */ echo '$a->dyn():', "\n", $a->callDynamic(), "\n"; /* in this case, an instance call is made because $this is an * instance of B (despite the fact we are in a method of A), so * B::dyn() is a method of a compatible class (namely, it's the * same class as the object's) */ echo '$b->dyn():', "\n", $b->callDynamic(), "\n"; 

输出:

 B :: $ prop_static:B :: $ prop_static值
 B :: func_static():在B :: func_static中

 $ b-> prop_instance:B :: $ prop_instance的值
 $ b-> func_static():在B :: func_static中

 $ B-> func_instance():
在B :: func_instance
在A :: func_instance
在A :: func_instance

 $ A->达因():
在A :: callDynamic
在dynamicdyn(__callStatic)

 $ B->达因():
在A :: callDynamic
在dynamicdyn(__call)

::静态上下文中使用,即。 当某些方法或属性声明为静态时:

 class Math { public static function sin($angle) { return ...; } } $result = Math::sin(123); 

另外,当您调用父类的方法/属性时, ::运算符(范围parsing运算符,又名Paamayim Nekudotayim )在dynamic上下文中使用:

 class Rectangle { protected $x, $y; public function __construct($x, $y) { $this->x = $x; $this->y = $y; } } class Square extends Rectangle { public function __construct($x) { parent::__construct($x, $x); } } 

->dynamic上下文中使用,即。 当你处理某个类的某个实例时:

 class Hello { public function say() { echo 'hello!'; } } $h = new Hello(); $h->say(); 

顺便说一句:我不认为使用Symfony是一个好主意,当你没有任何OOP的经验。

实际上,通过这个符号,我们可以调用一个静态的类方法,而不依赖于其他初始化…

 class Test { public $name; public function __construct() { $this->name = 'Mrinmoy Ghoshal'; } public static function doWrite($name) { print 'Hello '.$name; } public function write() { print $this->name; } } 

这里的doWrite()函数不依赖于任何其他的方法或variables,它是一个静态的方法。 这就是为什么我们可以通过这个操作符调用这个方法,而不需要初始化这个类的对象。

Test::doWrite('Mrinmoy'); // Output: Hello Mrinmoy.

但是如果你想以这种方式调用write方法,它将会产生一个错误,因为它依赖于初始化。

=>运算符用于在关联数组中分配键值对。 例如:

 $fruits = array( 'Apple' => 'Red', 'Banana' => 'Yellow' ); 

这在foreach语句中的含义是相似的:

 foreach ($fruits as $fruit => $color) echo "$fruit is $color in color."; 

静态和实例化的方法和属性之间的区别似乎是刚刚在PHP 5中使用OOP PHP开始的最大障碍之一。

当从静态上下文中调用对象或属性时,使用双冒号操作符(从希伯来语称为Paamayim Nekudotayim)。 这意味着该对象的一个​​实例还没有被创build。

相反,箭头运算符会调用对象实例引用的方法或属性。

因为您可以将返回值设置为插入的表id,然后使用构造函数通过行id实例化对象,所以静态方法在链接到数据库以创build和删除方法的对象模型中特别有用。

是的,我只是打我的第一个'PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM' 。 我的坏,我有一个$instance::method()应该是$instance->method() 。 我傻。

奇怪的是,这仍然适用于我的本地机器(运行PHP 5.3.8) – 没有,甚至没有error_reporting = E_ALL警告 – 但根本不在testing服务器上,它只是爆炸与语法错误并在浏览器中的白色屏幕。 由于在testing机器上closures了PHP日志logging,并且托pipe公司太忙而无法启用它,所以它不是太明显。

所以,警告的话:显然,一些PHP安装会让你使用$ instance :: method(),而其他的则不行。

如果有人可以扩大为什么这样做,请做。