PHP中的(双冒号)和 – >(箭头)有什么区别?
在PHP中访问方法有两种截然不同的方式,但有什么不同?
$response->setParameter('foo', 'bar');
和
sfConfig::set('foo', 'bar');
我假设->
(破折号大于符号或V形)用于variables的函数,而::
:(双冒号)用于类的函数。 正确?
赋值运算符是否仅用于在数组内分配数据? 这与用于实例化或修改variables的赋值运算符相反吗?
当左边部分是一个对象实例时,使用->
。 否则,你使用::
。
这意味着->
主要用于访问实例成员(尽pipe它也可以用来访问静态成员,这种用法是不鼓励的),而::
通常用于访问静态成员(尽pipe在一些特殊情况下,访问实例成员)。
一般来说, ::
用于范围parsing ,它可以有一个类名, parent
, self
,或者(在PHP 5.3中)左边是static
。 parent
指的是它使用的类的超类范围; self
指的是它所使用的类的范围; static
是指“调用范围”(请参阅后期的静态绑定 )。
规则是::
是一个实例调用当且仅当:
- 目标方法没有声明为静态的
- 在调用的时候有一个兼容的对象上下文,这意味着这些必须是正确的:
- 这个调用是从
$this
存在的上下文中进行的 -
$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(),而其他的则不行。
如果有人可以扩大为什么这样做,请做。