本文主要说说PHP V5.3 的以下特性:
- 延迟静态绑定
- 名称空间
- 类方法重载
- 变量解析和 heredoc
延迟静态绑定
PHP V5.3 扩展了 static 关键词的使用。现在,无需实例化类便可访问静态类方法和属性。当类不存在对象,或者不需要对象时,这个特性就比较方便。下面就是展示了延迟静态绑定的一个例子。
<?php
class A {
public static function who() {
echo 'Calling who method from class '.__CLASS__;
}
public static function test() {
static::who();
}
}
class B extends A {
public static function who() {
echo 'Calling who method from class '.__CLASS__;
}
}
B::test();
?>
以上会产生这样的输出:
Calling who method from class B在 PHP V5.3.0 之前,类 A 中的方法可能被定义为 self::who()。不幸的是,这将导致调用类 A 中的函数,而不是子类 B 中的函数。PHP V5.3.0 用 static:: 关键词修复了这个问题,允许在运行时才引用之前调用的类方法。显然这就是这段代码的目的。
增强面向对象 任何能增强 PHP 面向对象方面的改变都是受鼓励的,因为这将导致更可靠的设计和更易于维护的代码。对于上面的代码我有些许微词,基类(A)和派生类(B)中的 who() 方法是重复的。如果类 B 中不必复制该代码就好了,但是似乎 PHP V5.3.0 中的 __CLASS__ 语法要求必须这么做。也就是说,__CLASS__ 不支持延迟绑定。代码中使用 CLASS 也许有点勉强,但确实可以说明 PHP V5.3.0 有一个小小的问题。显然,对于这个例子,这不是多大的问题,但是对于有数千行 PHP 代码的网站来说,就没那么简单了。重复代码通常意味着重复劳动。
名称空间(也有叫命名空间的)
PHP V5.3 提供名称空间功能,以增强该语言的封装能力。名称空间在现代语言中非常常见,例如 C# 和 XML。名称空间的主要优点是,通过它可以为代码符号(类、函数和常量)定义独立的容器,这听起来有点复杂,其实不然。以下代码显示了使用 PHP 名称空间定义本地和全局字符串常量的一个例子。
<?php
namespace test;
define('ASTRING', 'Hello World!');
define('testASTRING', 'Hello World from my namespace!');
echo "<p>My string is: ";
echo ASTRING;
echo "</p>";
echo "<p>My string is ";
echo ASTRING;
echo "</p>";
?>
以上代码的输出:
My string is: Hello World from my namespace! My string is: Hello World!那么,代码中发生了什么?第一个 define 语句在名称空间 test 中创建一个字符串常量 ASTRING。然后,当引用 ASTRING 字符串时,引擎首先查看本地 test 名称空间。这就是为什么看到本地定义的字符串首先显示。然后,要看到全局定义的字符串,只需使用语法 ASTRING。有了这些简单的规则,便可以使用任意数量的名称空间,而不必担心名称冲突。
有了名称空间功能,和之前相比,代码之间的界限更加清晰。而这一点又有助于团队环境中的代码整合。换句话说,不同的团队可以分配他们自己的名称空间,当所有团队成员都遵循这个惯例时,名称冲突的情况应该会降为零。这也是 5.3.0 版对 PHP 语言在面向对象方面的一个增强。
类方法重载
在 PHP 中,术语重载(overloading) 与通常的面向对象上下文稍有不同。在 Java 语言或 C# 中,“重载” 方法是指为不同参数列表提供相同代码的方法。例如,如果有一个名为 draw(String str) 的方法,那么重载的方法可以有以下形式:draw(String str, int i)。这种方法符号名称被称作方法签名,为了便于重载,返回类型被省略。
在 PHP 中,“重载” 是指动态创建的方法和属性。这实际上是动态代码,任何这样的动态实体都是由所谓的魔术方法(magic methods) 来处理。可以在一个类中为各种不同的动作创建这些魔术方法。然后,当代码中遇到未声明或不可见的属性或方法时,便可以调用重载方法。这样风格的重载提供了很大程度上的灵活性。
听起来有些复杂,所以来看看一个具体的例子。以下代码展示如何使用 PHP 重载调用对象和类方法。
<?php
class OverloadedMethodTest {
public function __call($name, $arguments) {
// The value of $name is case sensitive.
echo "Calling object method '$name' "
. implode(', ', $arguments) . "n";
}
/** As of PHP 5.3.0 */
public static function __callStatic($name, $arguments) {
// The value of $name is case sensitive.
echo "Calling static method '$name' "
. implode(', ', $arguments) . "n";
}
}
$obj = new OverloadedMethodTest;
$obj->runOverloadedTest('in an object context');
OverloadedMethodTest::runOverloadedTest('in a static context'); // As of PHP 5.3.0
?>
代码产生以下输出:
Calling object method 'runOverloadedTest' in an object context Calling static method 'runOverloadedTest' in a static context注意重载的代码是如何根据调用代码来推断方法名和参数的:
$obj->runOverloadedTest('in an object context');
OverloadedMethodTest::runOverloadedTest('in a static context'); // As of PHP 5.3.0
要使用这种能力,程序员需要承担较大的责任。虽然重载为编写灵活的代码提供了便利,但同时也为错误提供了土壤。所以,使用重载时应该谨慎,并且要有严格的代码测试纪律。
变量解析和 heredoc
PHP 的优势之一在于字符串解析。PHP 对于字符串的长度没有限制,只要主机的可用内存够大就行。下面代码展示了使用 PHP 时拥有的灵活性。
<?php
$beverage = 'coffee';
// The following works; "'" is an invalid
character for variable names
echo "$beverage's taste is great";
// The following won't work; 's' is a valid
character for variable names but the
echo "He drank a number of $beverages";
variable is "$beverage"
echo "He drank some ${beverage}s"; // works
echo "He drank some {$beverage}s"; // works
?>
代码产生以下输出:
coffee's taste is great He drank a number of He drank some coffees He drank some coffees
这样的代码并不是直到 PHP V5.3.0 才有的。这里给出这段代码,只是为了提醒您字符串处理支持和一些解析规则。但是,PHP V5.3.0 增加了增强的 heredoc 语法支持。下面显示了一个简单的例子。
<?php
echo >>>"FOOBAR"
Hello World!
FOOBAR;
?>
代码产生以下令人惊叹的输出:
Hello World!那么,上面的代码有什么特别之处呢?PHP V5.3.0 中的 heredoc 支持使用双引号。其优点主要在于,双引号中的内容不会被解析,这样便有了更大的灵活性。基本上,这只是在已经强大的字符串支持的基础上增加了更多的灵活性。PHP V5.3.0 的在线参考包括更多关于这个主题和 PHP V5.3.0 其他相关主题的资料。