}
}
class DBConfiguration extends Configuration
{
protected function load() {
$this->_items[ 'imgpath' ] = 'images';
}
}
$c = new DBConfiguration();
echo( $c->get( 'imgpath' )."\n" );
?>
现在,所有要将 Configuration 类型的对象实例化的尝试都会出错,因为系统认为该类是抽象的并且不完整。
静态方法和成员
PHP V5 中的另一个重要的新功能是支持对类使用静态成员和方法。通过使用这种功能,您可以使用流行的单例模式。这种模式对于 Configuration 类是十分理想的,因为应用程序应当仅有一个配置对象。
清单 10 显示了 PHP V5 版的 Configuration 类作为一个单例。
清单 10. static.php5
<?php
class Configuration
{
private $_items = array();
static private $_instance = null;
static public function get() {
if ( self::$_instance == null )
self::$_instance = new Configuration();
return self::$_instance;
}
private function __construct() {
$this->_items[ 'imgpath' ] = 'images';
}
public function __get( $key ) {
return $this->_items[ $key ];
}
}
echo( Configuration::get()->{ 'imgpath' }."\n" );
?>
static 关键字有很多用法。当需要访问单个类型的所有对象的某些全局数据时,请考虑使用此关键字。
Magic Method
PHP V5 中的另一个很大的新功能是支持 magic method,使用这些方法使对象可以迅速更改对象的接口 —— 例如,为 Configuration 对象中的每个配置项添加成员变量。无须使用 get() 方法,只要寻找一个特殊项将它当作一个阵列,如下所示。
清单 11. magic.php5
<?php
class Configuration
{
private $_items = array();
function __construct() {
$this->_items[ 'imgpath' ] = 'images';
}
function __get( $key ) {
return $this->_items[ $key ];
}
}
$c = new Configuration();
echo( $c->{ 'imgpath' }."\n" );
?>
在本例中,我创建了新的 __get() 方法,只要使用者寻找对象上的成员变量时即调用此方法。然后,方法中的代码将使用项阵列来查找值并返回该值,就像有一个专门用于该关键字的成员变量在那儿一样。假定对象就是一个阵列,在脚本的末尾,您可以看到使用 Configuration 对象就像寻找 imgpath 的值一样简单。
从 PHP V4 迁移到 PHP V5 时,必须要注意这些在 PHP V4 中完全不可用的语言特性,还必须重新验证类来查看可以怎样使用这些类。
异常
最后介绍 PHP V5 中的新异常机制来结束本文。异常为考虑错误处理提供了一种全新的方法。所有程序都不可避免地会生成错误 —— 找不到文件、内存不足等等。如果不使用异常,则必须返回错误代码。请看下面的 PHP V4 代码。
清单 12. file.php4
<?php
function parseLine( $l )
{
// ...
return array( 'error' => 0,
data => array() // data here
);
}
function readConfig( $path )
{
if ( $path == null ) return -1;
$fh = fopen( $path, 'r' );
if ( $fh == null ) return -2;
while( !feof( $fh ) ) {
$l = fgets( $fh );
$ec = parseLine( $l );
if ( $ec['error'] != 0 ) return $ec['error'];
}
fclose( $fh );
return 0;
}
$e = readConfig( 'myconfig.txt' );
if ( $e != 0 )
echo( "There was an error (".$e.")\n" );
?>
这段标准的文件 I/O 代码将读取一个文件,检索一些数据,并在遇到任何错误时返回错误代码。对于这个脚本,我有两个问题。第一个是错误代码。这些错误代码的含义是什么?要找出这些错误代码的含义,则必须创建另一个系统将这些错误代码映射到有含义的字符串中。第二个问题是 parseLine 的返回结果十分复杂。我只需要它返回数据,但它实际上必须返回错误代码 和 数据。大多数工程师 (包括我本人在内) 经常偷懒,仅返回数据,而忽略掉错误,因为错误很难管理。
清单 13 显示了使用异常时代码的清晰程度。
清单 13. file.php5
<?php
function parseLine( $l )
{
// Parses and throws and exception when invalid
return array(); // data
}
function readConfig( $path )
{
if ( $path == null )
throw new Exception( 'bad argument' );
$fh = fopen( $path, 'r' );
if ( $fh == null )
throw new Exception( 'could not open file' );
while( !feof( $fh ) ) {
$l = fgets( $fh );
$ec = parseLine( $l );
}
fclose( $fh );
}
try {
readConfig( 'myconfig.txt' );
} catch( Exception $e ) {
echo( $e );
}
?>
我无需考虑错误代码问题,因为异常中包含了错误的说明性文字。我也无需考虑如何追踪从 parseLine 返回的错误代码,因为如果出现错误,该函数将只抛出一个错误。堆栈将延伸至最近的 try/catch 块,该块位于脚本的底部。
异常机制将彻底改变编写代码的方法。您不必管理让人头痛的错误代码和映射,可以将精力集中在要处理的错误上。这样的代码更易于阅读、维护,而且我要说,甚至要鼓励您添加错误处理机制,它通常都能带来好处。
结束语
新的面向对象特性和异常处理的增加为将代码从 PHP V4 迁移到 PHP V5 提供了强有力的理由。正如您所见,升级过程并不难。扩展到 PHP V5 的语法感觉就像 PHP 一样。是的,这些语法来自诸如 Ruby 之类的语言,但我认为它们配合得非常好。并且这些语言将 PHP 的范围从一种用于小型站点的脚本语言扩展为可用于完成企业级应用的语言。
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




