【发布时间】:2011-02-23 14:49:44
【问题描述】:
当我们遇到这种情况时,我不知道它在做什么:
Foo::Bar
它看起来像一条路径。
【问题讨论】:
标签: php zend-framework
当我们遇到这种情况时,我不知道它在做什么:
Foo::Bar
它看起来像一条路径。
【问题讨论】:
标签: php zend-framework
补充关于 PHP 使用两个冒号作为其"scope resolution operator" 的答案:
另外,使用了双冒号:
将非限定、限定或别名类名解析为其完全限定形式,并且
使用以前未声明的任意方法名称调用类的“__callStatic”方法。
两个冒号后跟“class”关键字,放在类名之后,提供该类的完全限定名作为字符串。 即,“ClassName::class”解析为“ClassName”的完全限定名称。 见:(A)Manual: Classes and Objects: Basics,(B)Manual: Classes and Objects: Class Constants,和(C)Manual: Language Reference: Constants
该语法在 PHP 5.5 中采用。 见:(A)RFC 和(B)PHP 5.5 New Features
"::class" 语法在命名空间中很有用,可用于从类的unqualified or qualified form 或从其名称的alias 获取类的完全限定名称。
“::class”语法似乎可以解析接口名称和类名称,尽管上面链接的来源似乎没有记录这一点。
在一个类中,该语法也适用于“self::class”,如上面链接的“::class” RFC 所述。
几个例子:
<?php
namespace MyNamespace;
use MyNamespace\YourInterface as HerInterface;
use MyNamespace\YourClass as HerClass;
use MyNamespace\TheirClass as OurClass;
interface MyInterface { }
interface YourInterface { }
class MyClass { }
class YourClass { }
class TheirClass
{
public function fullName()
{
echo self::class;
}
}
$ourClassInstance = new OurClass;
echo MyClass::class, PHP_EOL;
// outputs: MyNamespace\MyClass
echo HerClass::class, PHP_EOL;
// outputs: MyNamespace\YourClass
echo MyInterface::class, PHP_EOL;
// outputs: MyNamespace\MyInterface
echo HerInterface::class, PHP_EOL;
// outputs: MyNamespace\YourInterface
echo $ourClassInstance->fullName(), PHP_EOL;
// outputs: MyNamespace\TheirClass
两个冒号可用于“调用”类未声明的静态方法名称。例如,“ClassName::arbitraryMethodName()”。这样做会调用该类的“__callStatic”方法,如果该类已声明一个。它还将未声明方法的名称和传递给未声明方法的任何参数传递给 __callStatic。然后 __callStatic 方法可以“动态地”选择如何处理调用。 PHP 将此称为 "overloading" 和 __callStatic "magic method"。
例子:
<?php
namespace OurCompany\Orders;
class Intake
{
public static function __callStatic($name, $arguments)
{
$item = substr($name, 5); // trims "order" prefix
$specialistClass = "\OurCompany\Specialists\\" . $item;
if (class_exists($specialistClass)) {
$specialist = new $specialistClass;
return $specialist->handleOrder($arguments);
}
return "I'm sorry, we can't help you with " .
lcfirst($item) . ".";
}
}
namespace OurCompany\Specialists;
class Car
{
public function handleOrder($arguments)
{
return "May I help you with a $arguments[0] car?";
}
}
class Truck
{
public function handleOrder($arguments)
{
return "May I help you with a $arguments[0] truck?";
}
}
use OurCompany\Orders\Intake;
echo Intake::orderCar("red"), PHP_EOL;
// outputs: May I help you with a red car?
echo Intake::orderTruck("pickup"), PHP_EOL;
// outputs: May I help you with a pickup truck?
echo Intake::orderShoes("suede"), PHP_EOL;
// outputs: I'm sorry, we can't help you with shoes.
【讨论】:
范围解析运算符的使用
类常量、类属性(静态)、类函数(静态) 都可以共享相同的名称并使用双冒号访问
class B{
public static $par = "par";
}
class A extends B{
const B = "constant";
public static $sel = "self";
public static $b = "static property";
public static function b(){
echo "static function";
}
public static function c(){
return parent::$par;
}
public static function d(){
return self::$sel;
}
public static function e(){
return self::$par;
}
}
echo A::B.PHP_EOL;
echo A::$b.PHP_EOL;
echo A::b().PHP_EOL;
echo A::c().PHP_EOL;
echo A::d().PHP_EOL;
【讨论】:
作用域解析运算符 (::) 双冒号是一个标记,它允许访问 static、constant 以及类的重写属性或方法。
<?php
class A {
public static $B = '1'; # Static class variable.
const B = '2'; # Class constant.
public static function B() { # Static class function.
return '3';
}
}
echo A::$B . A::B . A::B(); # Outputs: 123
?>
【讨论】:
这(通常)用于访问类中的静态方法或属性。它被称为范围解析操作符,或 Paamayim Nekudotayim(这会导致一些令人惊讶的令人困惑的错误消息!)。见http://www.php.net/manual/en/language.oop5.paamayim-nekudotayim.php。
【讨论】:
:: operator is the scope resolution operator。它用于从类外部访问类常量或静态属性和方法:
ClassName::CONSTANT_VALUE
ClassName::staticMethod()
或在类方法中使用self 和parent 引用相同或父类:
self::CONSTANT_VALUE
self::staticMethod()
parent::CONSTANT_VALUE
parent::staticMethod()
【讨论】:
static::CONSTANT_VALUE,static::staticMethod()