PHP V5.3 中的新特性,第 1 部分: 对象接口的变化

简介: PHP V5 和面向对象编程 与 PHP V4 提供的特性相比,2004 年发布的 PHP V5 在面向对象编程(OOP)和设计方面向前迈出了很大的一步。它提供了一些必要的改进,例如类可见性、合适的构造函数和解构函数、输入提示和类反射(class-reflection)API。

PHP V5 和面向对象编程

与 PHP V4 提供的特性相比,2004 年发布的 PHP V5 在面向对象编程(OOP)和设计方面向前迈出了很大的一步。它提供了一些必要的改进,例如类可见性、合适的构造函数和解构函数、输入提示和类反射(class-reflection)API。它为在 PHP 中进行高级的面向对象编程敞开了大门,并允许实现更加简单的设计模式,以及更好的设计类和 API。

PHP V5.3 在 OOP 方面提供了大量渐进式补充。这些改进一直集中在语法补充和性能改进方面。首先,我们将查看静态方法和成员方面的新特性。

 

回页首

改进静态方法和成员处理

PHP V5 中的一个有用补充就是能够将一个方法或类成员指定为静态的(PHP V4 确实支持对方法和类成员的静态访问,但是不能够将方法或成员指定为专门用于静态访问)。静态访问特别适合实现单一设计模式,在这种模式中只存在一个类实例。

PHP V5.3 提供一些特性来增强对类的静态成员和方法的支持。我们将查看最近添加的一种魔术方法:__callStatic()

_callStatic() 魔术方法

PHP V5 提供了一些可用于类内部的特别定义的方法,称为魔术方法。当在类内部定义时,这些方法可以提供特殊的功能,并支持重载(允许一种方法接受不同类型的参数)和多态(允许不同数据类型使用相同的接口)。它们还允许通过 PHP 轻松地使用不同类型的 OOP 编程方法和设计模式。

在 PHP V5.3 中,添加了一种新的魔术方法:__callStatic()。它的工作方式类似于 __call() 魔术方法,后者的设计意图是处理那些没有在类中定义或对类不可见的方法的调用。然而,__callStatic() 是为了处理静态方法调用,这使我们能够更好地设计方法重载。下面给出了一个使用该方法的示例。


清单 1. 使用 __callStatic() 和 __call() 的示例

				 
class Foo 
{ 
    public static function __callStatic( 
        $name, 
        $args 
        ) 
    { 
        echo "Called method $name statically"; 
    } 

    public function __call( 
        $name, 
        $args 
        ) 
    { 
        echo "Called method $name"; 
    } 
} 

Foo::dog();       // outputs "Called method dog statically" 
$foo = new Foo; 
$foo->dog();      // outputs "Called method dog" 

 

需要注意,PHP 确实加强了对 __callStatic() 方法的定义;它必须是公共的,并且必须被声明为静态的。同样,__call() 魔术方法必须被定义为公共的,所有其他魔术方法都必须如此。

 

回页首

动态的静态调用

PHP 的一个优秀特性是可变变量。这表示可以使用某个变量的字符串值指定另一个变量的名称。换句话说,可以执行与下面类似的操作。


清单 2. 可变变量

				
x = 'y'; 
$$x = 'z'; 
echo $x;  // outputs 'y' 
echo $$x; // 
outputs 'z' 

 

这也适用于函数,甚至是类方法,如下所示。


清单 3. 可变函数和类方法名

				 
class Dog 
{ 
    public function bark() 
    { 
        echo "Woof!"; 
    } 
} 

$class = 'Dog' 
$action = 'bark'; 
$x = new $class(); // instantiates the class 'Dog' 
$x->$action();     // outputs "Woof!" 

 

PHP V5.3 的一个新特性就是在进行静态调用时,能够使指定的类名成为一个变量。这提供了一些新的机会,如下所示。


清单 4. 可变的类命名

				 
class Dog 
{ 
    public static function bark() 
    { 
         echo "Woof!"; 
    } 
} 

$class = 'Dog'; 
$action = 'bark'; 
$class::$action();  //outputs "Woof!" 

 

这一补充完善了 PHP 的可变变量特性,允许将它们应用到涉及 PHP 的所有情形。

让我们查看一个有关静态方法和成员应用的更有用的增强:延迟静态绑定(late static binding)。

 

回页首

延迟静态绑定

在 V5.3 以前,PHP 存在的麻烦问题是如何处理静态方法和成员。到目前为止,使用自身或 __CLASS__ 进行的静态引用都是在定义函数的类作用域中解析的。问题在于,如果类进行了扩展并且调用来自新的子类,那么解析将是错误的。PHP V5.3 添加了延迟静态绑定来解决这个问题。为了更好地进行解释,我们在下面将创建一个具有静态方法的类。


清单 5. 使用静态方法 test() 的 Foo 类

				 
class Foo 
{ 
    protected static $name = 'Foo'; 

    public static function test() 
    { 
        return self::$name; 
    } 
} 

 

让我们对这个类进行扩展。我们将在子类中重新定义成员 $name


清单 6. 子类 Bar 扩展了父类 Foo

				 
class Bar 
{ 
    protected static $name = 'Bar'; 
} 

 

我们在清单 7 中进行了静态调用。


清单 7. 静态方法调用 test()

				 
echo Bar::test(); 

 

该调用的输出是字符串 Foo。这是因为在 test() 方法中进行的引用 self::$name 是在 Foo 类中完成的。这样绑定的原因是:函数是在Foo 类中定义的。

PHP V5.3 添加了关键字 static 以允许针对当前类进行引用。因此将修改上面的 Foo 类以在清单 8 中使用该关键字,我们将看到输出的内容变成了 Bar


清单 8. 使用 static 关键字

				 
class Foo 
{ 
    protected static $name = 'Foo'; 

    public static function test() 
    { 
        return static::$name; 
    } 
} 

class Bar 
{ 
    protected static $name = 'Bar'; 
} 

echo Bar::test(); // outputs 'Bar'

 

有关 static 关键字需要注意一点,它的工作方式与在非静态上下文中的工作方式不同。这意味着普通的继承规则没有应用到静态调用中。静态关键字将仅仅尝试在当前类中解析调用,而不是在定义函数的类中执行。这一点值得注意。

现在您已经了解了有关静态方法和成员的增强,现在让我们看一看 PHP V5 中新添的类,它们构成了非常有用的部分:标准 PHP 库。

 

回页首

标准 PHP 库

标准 PHP 库(Standard PHP Library,SPL)是 PHP V5 中新增的接口和类的集合,旨在解决标准问题。这些问题包括实现可迭代的对象,使对象具有数组的行为或实现一个链接的列表。这些类和方法的优点是它们是原生的 PHP,这意味用 PHP 本身实现它们会获得更快的速度。在很多情况下,这些类和方法还允许内部 PHP 函数直接使用这些对象,就像 Iterator 接口允许您使用 foreach 结构迭代对象一样。

PHP V5.3 向 SPL 添加了更多的类。我们前面提到一个类就是在 SPL 类 SplDoublyLinkedList 中实现的双重链接列表。它供其他两个新 SPL 类使用:SplStack(实现一个栈)和 SplQueue(实现一个队列)。

让我们看一看如何使用 SplStack 类实现一个栈。


清单 9. 使用 SplStack

				
$stack = new SplStack(); 

// push a few new items on the stack 
$stack->push('a'); 
$stack->push('b'); 
$stack->push('c'); 

// see how many items are on the stack 
echo count($stack); // returns 3 

// iterate over the items in the stack 
foreach ( $stack as $item ) 
    echo "[$item],";   
// the above outputs: [c],[b],[a]

// pop an item off the stack 
echo $stack->pop(); // returns 'c' 

// now see how many items are on the stack 
echo count($stack); // returns 2

 

SqlQueue 也采取类似的方式,但是它像队列那样工作(先进先出;而不是像栈一样最后一个项进栈,第一个项出栈)。此外,还存在堆实现(SplHeap),以及针对某些情况的特定队列和堆实现(SplMinHeapSplMaxHeap 和 SplPriorityQueue)。

另一个有用的补充是 SplFixedArray 类,顾名思义,这是一个固定大小的数组实现。然而,它的性能非常快 — 实际上它在基准测试中要比 PHP 内置数组实现快 10% 至 30%。造成这种速度优势的原因是数组是固定大小的,而默认的 PHP 数组是可变大小的,并且不允许非数值型索引。清单 10 显示了它的使用方法。


清单 10. SplFixedArray

				
$array = new SplFixedArray(3); 
$array[0] = 'dog'; 
$array[1] = 'cat'; 
$array[2] = 'bird'; 
$a->setSize(4); // increase the size on the fly 
$array[3] = 'mouse'; 
foreach ( $array as $value ) 
    echo "[$value],";

Output: 
[dog],[cat],[bird],[mouse] 

 

此外,添加了一些新的迭代器类:FilesystemIterator 和 GlobIterator。它们与 PHP 中的其他迭代器类使用相同的工作方式,但是它们分别针对不同的情况。

SPL 的另一个改变是现在的 PHP V5.3 通常启用 SPL。在以前的 PHP V5 版本中,可以在编译时禁用 SPL,但是 PHP V5.3 不能禁用 SPL。

SPL 中的新补充?? PHP 添加了一些有用的并且易于使用的功能,以及数据结构的实现,例如双重链接列表、栈、堆和队列。这些类可用于替换用户空间实现,这将改进速度并更好地集成各种 PHP 函数和构造。

现在我们已经了解了 SPL 中的一些新内容,让我们看一看 PHP V5.3 中的 OOP 如何通过循环垃圾收集获得显著的性能和内存使用改善。

 

回页首

循环垃圾收集

垃圾收集是 PHP 开发人员在性能方面遇到的一个问题。PHP 有一个非常简单的垃圾收集器,它实际上将对不再位于内存范围(scope)中的对象进行垃圾收集。垃圾收集的内部方式是使用一个引用计数器,因此当计数器达到 0 时(意味着对该对象的引用都不可用),对象将被当作垃圾收集并从内存中删除。

这种方式工作得很好,但是如果一个对象使用父子关系引用另一个对象,那就会引发问题。在这种情况下,这些对象的引用计数器没有被收集,因此这些对象使用的内存仍然属于未引用的内存,并且直到完成请求后才能够进行分配。下面看一下关于这种问题的例子。


清单 11. PHP V5.2 及之前版本不能恰当地对父子类关系进行垃圾收集

				
class Parent 
{ 
    public function __construct() 
    { 
        $this->child = new Child($this); 
    } 
} 

class Child 
{ 
    public function __construct( 
        Parent $parent 
        ) 
    { 
        $this->parent = $parent; 
    } 
} 

 

在这种情况下,每当创建 Parent 类的实例并且该实例随后超出内存范围时,内存不会被释放,因此脚本在内存使用中不断增加。有一些用户空间解决方案可以解决这个问题。例如为父类创建一个解构函数将直接释放子对象。这种解构器必须在解除父类引用之前进行调用。但是执行这些工作会使您的代码也变得非常复杂。

在 PHP V5.3 中,垃圾收集器将检测这些循环引用,并且能够释放它们所占用的内存,因此在执行脚本时 PHP 内存使用情况将保持平稳。当 Parent 类的每个引用被删除后,Parent 类中的 Child 类引用也将会被当作垃圾收集。

 

回页首

结束语

PHP 在支持面向对象编程方面经历了长期的发展。PHP V4 时期的支持是比较弱的,但在 PHP V5 中得到显著的改善,并且后续版本还会调整。现在,PHP V5.3 提供了一些令人兴奋的改进,包括语法增强,例如新 __callStatic() 魔术方法、动态的静态调用、延迟静态绑定、静态方法和成员支持。它为 SPL 添加了新的内容,包括双重链接表、栈、堆和队列的实现,使您获得了一些常见的数据结构并且可以轻松使用它们。最后,期待已久的循环垃圾收集器是一个经过改进的垃圾收集器,它恰当地为这些循环实例释放内存,解决了自引用类的内存和性能问题。所有这些特性使 PHP V5.3 成为一种更加强大的面向对象编程语言。

目录
相关文章
|
5月前
|
PHP 开发者 UED
深入理解PHP 7的新特性及其性能优化
【7月更文挑战第26天】本文将深入探讨PHP 7版本引入的诸多新特性,并着重分析这些变化如何影响应用程序的性能。我们将通过具体示例和实际应用场景来展示PHP 7在提升开发效率和运行速度方面的优势,同时提供一些实用的性能优化技巧。
47 3
|
5月前
|
缓存 编译器 测试技术
PHP 8新特性解析与应用
在软件开发的广阔天地中,PHP始终是一颗耀眼的星辰。随着PHP 8的发布,一系列激动人心的新特性为开发者带来了前所未有的编程体验。本文将深入探讨PHP 8中的JIT编译器、联合类型、命名参数、匹配表达式等关键特性,并通过实例分析它们如何优化代码结构、提升执行效率。我们将一起见证PHP 8如何开启现代化PHP开发的新篇章,并为读者提供实用的技术参考。
39 2
|
5月前
|
安全 IDE 编译器
深入理解PHP 7的新特性及其对现代Web开发的影响
【7月更文挑战第30天】本文将深入探索PHP 7版本中引入的关键新特性,并分析这些改进如何优化现代Web开发实践。通过对比PHP 5和PHP 7的性能差异,我们将揭示PHP 7如何提升应用响应速度和资源利用效率。此外,本文还将讨论PHP 7对开发者工作流程的影响,包括新的语言特性、错误处理机制以及内置函数的增强,旨在为读者提供全面了解PHP 7所带来的变革性影响。
|
5月前
|
存储 SQL 编译器
PHP 8新特性深度解析与实战应用
本文将深入探讨PHP 8的新增特性,并结合实际案例演示如何有效利用这些特性优化现有项目。通过本文,您将了解到PHP 8带来的性能提升、安全性增强以及代码简化等方面的改进,以及如何将这些新特性融入日常开发工作之中。 【7月更文挑战第29天】
53 8
|
5月前
|
缓存 安全 测试技术
深入PHP 7:新特性与性能提升解析
在PHP 7的发布中,我们见证了一系列令人兴奋的性能改进和新特性的加入。本文将深入探讨这些变化如何影响开发者的日常编程实践,并展示通过实际例子如何最大化利用PHP 7的优势。准备好迎接代码效率和开发体验的全新升级!
|
5月前
|
安全 API PHP
深入理解PHP 7的新特性及其对现代Web开发的影响
【7月更文挑战第29天】本文将探索PHP 7版本引入的一系列新特性,并分析它们如何革新了现代Web开发。我们将从性能提升、语言特性增强、以及面向对象编程的改进等方面进行详细讨论,旨在为开发者提供一份全面的PHP 7新特性指南,帮助他们更好地利用这些新工具优化和加速Web应用的开发。
|
5月前
|
编译器 测试技术 PHP
深入理解PHP 7的新特性及其性能优化
随着Web开发的不断进步,PHP作为一门广泛使用的服务器端脚本语言,其新版本的发布总是备受瞩目。PHP 7的问世带来了一系列令人振奋的性能改进和新特性,这些变化不仅提升了语言本身的处理能力,也为开发者提供了更多的优化手段。本文将深入探讨PHP 7中的新特性,并通过实际案例分析其对性能的具体影响,旨在为读者提供一套实用的PHP性能优化策略。
|
5月前
|
大数据 编译器 API
PHP 7新特性深度解析与应用实践
【7月更文挑战第28天】本文深入探讨PHP 7带来的革新特性,从性能优化到语法改进,逐一剖析其背后的技术原理和实际影响。通过实例展示如何有效利用这些新特性来提升开发效率和代码质量,为PHP开发者提供切实可行的升级和优化策略。
|
5月前
|
存储 设计模式 安全
PHP 7新特性及其对现代Web开发的影响
随着PHP 7的发布,这一广泛使用的服务器端脚本语言带来了显著的性能提升和新的编程特性。本文将深入探讨PHP 7中的关键更新,包括性能优化、类型声明、异常处理改进以及匿名类等,并分析这些变化如何影响现代Web开发的实践和模式。通过具体案例,我们将了解开发者如何利用这些新特性来编写更快、更安全、更易维护的代码。 【7月更文挑战第28天】
38 3
|
5月前
|
安全 编译器 API
深入理解PHP 8的新特性及其对现代Web开发的影响
【7月更文挑战第29天】随着PHP 8的发布,这个广受欢迎的服务器端脚本语言迎来了重大更新。本文将深入探讨PHP 8引入的关键新特性,包括JIT编译器、联合类型、命名参数、匹配表达式以及错误处理改进等,并分析这些变化如何影响现代Web开发实践。我们将通过具体示例和代码片段,展示这些新特性如何提升性能、增强类型安全和支持更简洁的代码编写,同时讨论它们对现有PHP项目的迁移和维护的潜在影响。
42 2