PHP 中的 ::(双冒号)和 ->(箭头)有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3173501/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the difference between :: (double colon) and -> (arrow) in PHP?
提问by Joe
There are two distinct ways to access methods in PHP, but what's the difference?
在 PHP 中有两种不同的方法来访问方法,但有什么区别呢?
$response->setParameter('foo', 'bar');
and
和
sfConfig::set('foo', 'bar');
I'm assuming ->(dash with greater than sign or chevron) is used for functions for variables, and ::(double colons) is used for functions for classes. Correct?
我假设->(带有大于号或 V 形的破折号)用于变量函数,而::(双冒号)用于类函数。正确的?
Is the =>assignment operator only used to assign data within an array? Is this in contrast to the =assignment operator which is used to instantiate or modify a variable?
是=>赋值运算符仅用于分配数据的数组中?这与=用于实例化或修改变量的赋值运算符形成对比吗?
回答by Artefacto
When the left part is an object instance, you use ->. Otherwise, you use ::.
当左侧部分是对象实例时,您使用->. 否则,您使用::.
This means that ->is mostly used to access instance members (though it can also be used to access static members, such usage is discouraged), while ::is usually used to access static members (though in a few special cases, it's used to access instance members).
这意味着->主要用于访问实例成员(虽然它也可以用于访问静态成员,但不鼓励这种用法),而::通常用于访问静态成员(尽管在少数特殊情况下,它用于访问实例成员)。
In general, ::is used for scope resolution, and it may have either a class name, parent, self, or (in PHP 5.3) staticto its left. parentrefers to the scope of the superclass of the class where it's used; selfrefers to the scope of the class where it's used; staticrefers to the "called scope" (see late static bindings).
通常,::用于作用域解析,它的左边可能有一个类名parent、self、 或(在 PHP 5.3 中)static。parent指使用它的类的超类的范围;self指的是使用它的类的范围;static指的是“被调用的范围”(参见后期静态绑定)。
The rule is that a call with ::is an instance call if and only if:
规则是::当且仅当以下情况调用with是实例调用:
- the target method is not declared as static and
- there is a compatible object context at the time of the call, meaning these must be true:
- the call is made from a context where
$thisexists and - the class of
$thisis either the class of the method being called or a subclass of it.
- the call is made from a context where
- 目标方法未声明为静态方法,并且
- 在调用时有一个兼容的对象上下文,这意味着这些必须是真的:
- 调用是从
$this存在的上下文中进行的,并且 - 的类
$this要么是被调用方法的类,要么是它的子类。
- 调用是从
Example:
例子:
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";
Output:
输出:
B::$prop_static: B::$prop_static value B::func_static(): in B::func_static $b->prop_instance: B::$prop_instance value $b->func_static(): in B::func_static $b->func_instance(): in B::func_instance in A::func_instance in A::func_instance $a->dyn(): in A::callDynamic in dynamic dyn (__callStatic) $b->dyn(): in A::callDynamic in dynamic dyn (__call)
回答by Crozin
::is used in staticcontext, ie. when some method or property is declared as static:
::用于静态上下文,即。当某些方法或属性被声明为静态时:
class Math {
public static function sin($angle) {
return ...;
}
}
$result = Math::sin(123);
Also, the ::operator (the Scope Resolution Operator, a.k.a Paamayim Nekudotayim) is used in dynamic context when you invoke a method/property of a parent class:
此外,当您调用父类的方法/属性时,将在动态上下文中使用::运算符(范围解析运算符,又名Paamayim Nekudotayim):
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);
}
}
->is used in dynamiccontext, ie. when you deal with some instance of some class:
->用于动态上下文,即。当您处理某个类的某个实例时:
class Hello {
public function say() {
echo 'hello!';
}
}
$h = new Hello();
$h->say();
By the way: I don't think that using Symfony is a good idea when you don't have any OOP experience.
顺便说一句:当您没有任何 OOP 经验时,我认为使用 Symfony 不是一个好主意。
回答by Mrinmoy Ghoshal
Actually by this symbol we can call a class method that is static and not be dependent on other initialization...
实际上通过这个符号我们可以调用一个静态的不依赖于其他初始化的类方法......
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;
}
}
Here the doWrite()function is not dependent on any other method or variable, and it is a static method. That's why we can call this method by this operator without initializing the object of this class.
这里的doWrite()函数不依赖于任何其他方法或变量,它是一个静态方法。这就是为什么我们可以通过这个操作符调用这个方法而不用初始化这个类的对象。
Test::doWrite('Mrinmoy');
// Output: Hello Mrinmoy.
Test::doWrite('Mrinmoy');
// Output: Hello Mrinmoy.
But if you want to call the writemethod in this way, it will generate an error because it is dependent on initialization.
但是如果要以write这种方式调用该方法,就会产生错误,因为它依赖于初始化。
回答by casablanca
The =>operator is used to assign key-value pairs in an associative array. For example:
该=>运算符用于在关联数组中分配键值对。例如:
$fruits = array(
'Apple' => 'Red',
'Banana' => 'Yellow'
);
It's meaning is similar in the foreachstatement:
它的意思在foreach声明中是相似的:
foreach ($fruits as $fruit => $color)
echo "$fruit is $color in color.";
回答by DeaconDesperado
The difference between static and instantiated methods and properties seem to be one of the biggest obstacles to those just starting out with OOP PHP in PHP 5.
静态和实例化的方法和属性之间的差异似乎是那些刚开始在 PHP 5 中使用 OOP PHP 的人的最大障碍之一。
The double colon operator (which is called the Paamayim Nekudotayim from Hebrew - trivia) is used when calling an object or property from a staticcontext. This means an instance of the object has not been created yet.
双冒号运算符(在希伯来语中称为 Paamayim Nekudotayim - 琐事)用于从静态上下文调用对象或属性。这意味着尚未创建对象的实例。
The arrow operator, conversely, calls methods or properties that from a reference of an instance of the object.
相反,箭头运算符调用来自对象实例的引用的方法或属性。
Static methods can be especially useful in object models that are linked to a database for create and delete methods, since you can set the return value to the inserted table id and then use the constructor to instantiate the object by the row id.
静态方法在为创建和删除方法链接到数据库的对象模型中特别有用,因为您可以将返回值设置为插入的表 id,然后使用构造函数通过行 id 实例化对象。
回答by PapaFreud
Yes, I just hit my first 'PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM'. My bad, I had a $instance::method()that should have been $instance->method(). Silly me.
是的,我刚打了我的第一个'PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM'。我的错,我有一个$instance::method()应该是$instance->method()。傻我。
The odd thing is that this still works just fine on my local machine (running PHP 5.3.8) - nothing, not even a warning with error_reporting = E_ALL - but not at all on the test server, there it just explodes with a syntax error and a white screen in the browser. Since PHP logging was turned off at the test machine, and the hosting company was too busy to turn it on, it was not too obvious.
奇怪的是,这在我的本地机器(运行 PHP 5.3.8)上仍然可以正常工作 - 没有,甚至没有错误报告 = E_ALL 的警告 - 但在测试服务器上根本没有,它只是因语法错误而爆炸和浏览器中的白屏。由于在测试机上关闭了PHP日志记录,而且托管公司太忙没有开启,所以不是太明显。
So, word of warning: apparently, some PHP installations will let you use a $instance::method(), while others don't.
因此,警告:显然,某些 PHP 安装将允许您使用 $instance::method(),而另一些则不允许。
If anybody can expand on why that is, please do.
如果有人可以扩展原因,请做。

