PHP5新功能初探系列二
时间:2007-02-08 来源:shiyaowen
2.8
[color="#000000"]统一化的构造方法和析构方法(Constructor
& Destructor)
[color="#000000"]每当一个类被实例化[color="#000000"]([color="#000000"]即是被「[color="#000000"]new])[color="#000000"]时,构造方法(Constructor
method)[color="#000000"]便会被呼叫执行[color="#000000"]([color="#000000"]如果有定义构造方法的话。留意构造方法并不是用来创建该对象[color="#000000"])[color="#000000"],这最适合用来初始化一个新生的对象。在[color="#000000"]PHP4[color="#000000"]的时代,构造方法就是和类的名称一样的方法,但这样在日后若果改变class
hierarchy[color="#000000"]时会造一些不便。[color="#000000"]
[color="#000000"]故[color="#000000"]PHP5[color="#000000"]就统一了构造方法的语法,一律命名为[color="#000000"]__construct()[color="#000000"],留意开头是两个底线[color="#000000"](underscore[color="#000000"],[color="#000000"]_)[color="#000000"]。为了和[color="#000000"]PHP4[color="#000000"]作向后兼容,如果在类内找不到[color="#000000"]__construct()[color="#000000"],[color="#000000"]PHP[color="#000000"]就会尝试找找[color="#000000"]PHP4[color="#000000"]时代的构造方法。请参考以下的简单例子
(php5.chp1.2.8a.phps)[color="#000000"]及其运行结果
(php5.chp1.2.8a.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Human [color="#007700"]{
public
$nationality[color="#007700"]=[color="#dd0000"]"Unknown";
function
[color="#0000bb"]__construct()
{
echo("A
human is born!
");
}
}
class
[color="#0000bb"]Chinese extends
[color="#0000bb"]Human {
function
[color="#0000bb"]__construct()
{
[color="#0000bb"]parent[color="#007700"]::[color="#0000bb"]__construct[color="#007700"]();
[color="#0000bb"]$this[color="#007700"]->nationality
[color="#007700"]= [color="#dd0000"]"China"[color="#007700"];
echo("A
Chinese is born!
"[color="#007700"]);
}
}
$obj
[color="#007700"]= new [color="#0000bb"]Human[color="#007700"]();
echo("Nationality:
"[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]nationality[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
$obj
[color="#007700"]= new [color="#0000bb"]Chinese[color="#007700"]();
echo("Nationality:
"[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]nationality[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
[color="#0000bb"]?>
[color="#000000"]
[color="#000000"]同样,一个对象在执行完毕后便会先调用析构方法[color="#000000"](Destructor)([color="#000000"]留意析构方法并不会释放该对象[color="#000000"])[color="#000000"],才会把对象释放回内存。析构方法通常用来释放对象拥有的资源,例如一个[color="#000000"]Database[color="#000000"]的[color="#000000"]connection[color="#000000"]。[color="#000000"]
PHP4[color="#000000"]没有析构方法,而[color="#000000"]PHP5[color="#000000"]就支持在类内定义一个名为[color="#000000"]__destruct()[color="#000000"]的无参数方法来作析构方法。请留意,[color="#000000"]PHP[color="#000000"]的[color="#000000"]Engine[color="#000000"]是不会自动调用父类中的构造或析构方法的,如你想调用父类的构造或析构方法,就得使用[color="#000000"]parent::__construct()[color="#000000"]或[color="#000000"]parent::__destruct()[color="#000000"]。在以下[color="#000000"]([color="#000000"]或更多[color="#000000"])[color="#000000"]情况[color="#000000"]PHP[color="#000000"]会决定销毁你的对象:
*
[color="#000000"]将储存该对象[color="#000000"]([color="#000000"]的[color="#000000"]reference)[color="#000000"]的变量设为[color="#000000"]NULL[color="#000000"]或其它值[color="#000000"]([color="#000000"]例:[color="#000000"]$obj=NULL;)[color="#000000"]。
*
[color="#000000"]调用[color="#000000"]unset()([color="#000000"]例:[color="#000000"]unset($obj);)[color="#000000"]。[color="#000000"]
[color="#000000"] *
[color="#000000"]留意若已另设一变量储存了对象[color="#000000"]([color="#000000"]的[color="#000000"]reference)[color="#000000"],则此两项无效,直到那另设的变量也不再使用为止,如此类推。
*
PHP[color="#000000"]脚本全部执行完毕。[color="#000000"]([color="#000000"]如下例说明[color="#000000"])
[color="#000000"]以下为一个简单例子
(php5.chp1.2.8b.phps)[color="#000000"]及其运行结果
(php5.chp1.2.8b.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]WWWViewer [color="#007700"]{
private
$resource[color="#007700"];
private
$url;
function
[color="#0000bb"]__construct[color="#007700"]([color="#0000bb"]$url)
{
[color="#0000bb"]$this[color="#007700"]->url
[color="#007700"]= [color="#0000bb"]$url[color="#007700"];
[color="#0000bb"]$this[color="#007700"]->resource
=
[color="#0000bb"]fopen[color="#007700"]([color="#0000bb"]$url[color="#007700"],[color="#dd0000"]'r'[color="#007700"]);
}
public
[color="#007700"]function [color="#0000bb"]display()
{
echo("The
following will display the page:
"[color="#007700"].[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]url[color="#007700"].[color="#dd0000"]"");
while
(![color="#0000bb"]feof[color="#007700"]([color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]resource[color="#007700"])){
$contents
=
[color="#0000bb"]fgets[color="#007700"]([color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]resource[color="#007700"]);
echo([color="#0000bb"]$contents[color="#007700"]);
}
echo("End
display"[color="#007700"]);
}
public
function
[color="#0000bb"]showMessage[color="#007700"](){
echo("I
am alive!
");
}
function
[color="#0000bb"]__destruct()
{
echo("WWWViewer
object is destructing
now"[color="#007700"]);
[color="#0000bb"]fclose[color="#007700"]([color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]resource[color="#007700"]);
}
}
$obj
= new
[color="#0000bb"]WWWViewer[color="#007700"]([color="#dd0000"]'http://www.google.com/'[color="#007700"]);
[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]display[color="#007700"]();
[color="#0000bb"]?>
Normal
HTML goes here....
[color="#0000bb"]//
Still alive here...
[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]showMessage[color="#007700"]();
[color="#0000bb"]?>
2.9
[color="#000000"]对象复制(Objects
Cloning)
[color="#000000"]当牵涉到要复制一个对象时,情况就不如复制[color="#000000"]integer[color="#000000"]般简单。在[color="#000000"]PHP4[color="#000000"],对象被复制时是会被按位复制(bit-by-bit
copy)[color="#000000"],即是副本会和正本一模一样。但有时这并不是理想的情况,例如你有的对象内拥有个[color="#000000"]XXX[color="#000000"]类的对象[color="#000000"]([color="#000000"]的[color="#000000"]reference)[color="#000000"],而你想在复制的同时创建一个新的[color="#000000"]XXX[color="#000000"]类的对象,那么[color="#000000"]PHP4[color="#000000"]就未能简单解决你的问题了。[color="#000000"]
[color="#000000"]在[color="#000000"]PHP5[color="#000000"],你得使用[color="#000000"]clone[color="#000000"]这[color="#000000"]keyword[color="#000000"]去命令复制一个对象[color="#000000"]([color="#000000"]语法:$copied_obj
= clone
$org_obj;)[color="#000000"],这时候那个类的[color="#000000"]__clone()[color="#000000"]方法便会被调用[color="#000000"]([color="#000000"]不能直接调用[color="#000000"]__clone())[color="#000000"]。[color="#000000"]
[color="#000000"]当你执行[color="#000000"]clone[color="#000000"]命令时,[color="#000000"]PHP5[color="#000000"]会在你的类的定义内找找有没有[color="#000000"]__clone()[color="#000000"]:
*
[color="#000000"]如果没有,一个内建的默认[color="#000000"]__clone()[color="#000000"]便会被使用,那将是一个按位复制(bit-by-bit
copy)[color="#000000"]。
*
[color="#000000"]如果有,[color="#000000"]PHP5[color="#000000"]会先进行一次按位复制,再执行你定义的[color="#000000"]__clone()[color="#000000"]。[color="#000000"]
[color="#000000"]以下为一个简单例子
(php5.chp1.2.9.phps)[color="#000000"]及其运行结果
(php5.chp1.2.9.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo [color="#007700"]{
public
$id;
function
[color="#0000bb"]__construct()
{
[color="#0000bb"]$this[color="#007700"]->id
[color="#007700"]= [color="#0000bb"]1;
}
function
[color="#0000bb"]__clone()
{
[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]id[color="#007700"]++;
}
}
$foo1
[color="#007700"]= new [color="#0000bb"]Foo[color="#007700"]();
$foo2
[color="#007700"]= clone
$foo1[color="#007700"];
$foo3
[color="#007700"]= clone
$foo2[color="#007700"];
//
Change to $foo4 doesn't affect $foo1
$foo4
[color="#007700"]= clone
$foo1[color="#007700"];
[color="#0000bb"]$foo4[color="#007700"]->id
[color="#007700"]= [color="#0000bb"]999[color="#007700"];
echo("foo1's
id is: "[color="#007700"].[color="#0000bb"]$foo1[color="#007700"]->[color="#0000bb"]id[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
echo("foo2's
id is: "[color="#007700"].[color="#0000bb"]$foo2[color="#007700"]->[color="#0000bb"]id[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
echo("foo3's
id is: "[color="#007700"].[color="#0000bb"]$foo3[color="#007700"]->[color="#0000bb"]id[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
echo("foo4's
id is: "[color="#007700"].[color="#0000bb"]$foo4[color="#007700"]->[color="#0000bb"]id[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
[color="#0000bb"]?>
2.10
Dereference[color="#000000"]从函数返回的对象[color="#000000"]
PHP4[color="#000000"]并不能直接[color="#000000"]Dereference[color="#000000"]从函数返回的对象,以立刻作method
call[color="#000000"],在[color="#000000"]PHP5[color="#000000"]就可以了:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo {
function
[color="#0000bb"]showMsg()
{
echo("I
am Foo
");
}
}
class
[color="#0000bb"]Bar {
function
[color="#0000bb"]showMsg()
{
echo("I
am Bar
");
}
}
function
[color="#0000bb"]DecideFooBar[color="#007700"]([color="#0000bb"]$name)
{
switch ([color="#0000bb"]$name)
{
case
[color="#dd0000"]"Foo":
return
new [color="#0000bb"]Foo();
case
[color="#dd0000"]"Bar":
return
new
[color="#0000bb"]Bar[color="#007700"]();
}
}
[color="#0000bb"]DecideFooBar[color="#007700"]([color="#dd0000"]"Foo"[color="#007700"])->[color="#0000bb"]showMsg[color="#007700"]();
[color="#0000bb"]DecideFooBar[color="#007700"]([color="#dd0000"]"Bar"[color="#007700"])->[color="#0000bb"]showMsg[color="#007700"]();
[color="#0000bb"]?>
2.11
instanceof[color="#000000"]关键词及类型提示(Class
Type Hints)
PHP5[color="#000000"]新增了[color="#000000"]instanceof[color="#000000"]关键词,如果受检测的对象是属于某类[color="#000000"]/[color="#000000"]某类的子类[color="#000000"]/[color="#000000"]某界面的实现,就会return
true[color="#000000"]。以下例子将输出[color="#000000"]3[color="#000000"]个[color="#000000"]"1"[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]baseClass {}
class
[color="#0000bb"]subClass extends
[color="#0000bb"]baseClass[color="#007700"]{}
interface
aInterface {}
class
[color="#0000bb"]aClass implements aInterface [color="#007700"]{}
$a
[color="#007700"]= new [color="#0000bb"]baseClass();
echo(
($a instanceof
baseClass[color="#007700"]).[color="#dd0000"]"
"[color="#007700"]);
$b
[color="#007700"]= new [color="#0000bb"]subClass();
echo(
($b instanceof
baseClass[color="#007700"]).[color="#dd0000"]"
"[color="#007700"]);
$c
[color="#007700"]= new [color="#0000bb"]aClass();
echo(
($c instanceof
aInterface[color="#007700"]).[color="#dd0000"]"
"[color="#007700"]);
[color="#0000bb"]?>
[color="#000000"]
[color="#000000"]虽然[color="#000000"]PHP5[color="#000000"]是loosely
typed[color="#000000"]的程序语言,但[color="#000000"]PHP5[color="#000000"]仍新增了Class
Type Hints[color="#000000"]的功能,用来声明传入之对象参数所需要的类型。如果类型有所违反会发生fatal
error[color="#000000"]。以下为一个简单例子
(php5.chp1.2.11.phps)[color="#000000"]及其运行结果[color="#000000"](php5.chp1.2.11.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo {}
class
[color="#0000bb"]Bar {}
function
[color="#0000bb"]check[color="#007700"](Foo
$obj[color="#007700"]) {
echo("The
passed in object is Foo/its subclass/its implementation(if Foo is
interface).
"[color="#007700"]);
}
$a
[color="#007700"]= new [color="#0000bb"]Foo[color="#007700"]();
$b
= new
[color="#0000bb"]Bar[color="#007700"]();
[color="#0000bb"]check[color="#007700"]([color="#0000bb"]$a[color="#007700"]);
[color="#0000bb"]check[color="#007700"]([color="#0000bb"]$b[color="#007700"]);
[color="#0000bb"]?>
[color="#000000"]
[color="#000000"]其实使用Class
Type Hints[color="#000000"]就和以下程序代码的意义一样:[color="#000000"]
[color="#0000bb"]function
[color="#0000bb"]check[color="#007700"]([color="#0000bb"]$obj)
{
if (!($obj
instanceof aClassName))
{
die("Argument
1 must be an instance of aClassName"[color="#007700"]);
}
}
[color="#0000bb"]?>
2.12 [color="#000000"]可重载的成员方法调用和属性存取(Method
calls and Property accesses)
[color="#000000"]重载[color="#000000"](Overload)[color="#000000"]一字在[color="#000000"]PHP[color="#000000"]这种Dynamic
Typing[color="#000000"]语言中的意义和「方法重载(Method
Overloading)[color="#000000"]」有些不同。在[color="#000000"]PHP[color="#000000"]你只需使用
func_num_args()[color="#000000"]和像[color="#000000"]is_int()[color="#000000"]等函数就可做到像[color="#000000"]Java/C++[color="#000000"]那些Static
Typing[color="#000000"]语言方法重载的效果。[color="#000000"]PHP[color="#000000"]的重载是指可存取或调用未经定义的成员方法式属性。这种成员方法调用和属性存取在[color="#000000"]PHP5[color="#000000"]可使用[color="#000000"]__call()[color="#000000"]、__get()
[color="#000000"]和
__set()[color="#000000"]重载,当[color="#000000"]PHP5[color="#000000"]试图使用未定义的方法或属性的时候,就会调用这些重载的方法。[color="#000000"]
[color="#000000"]让我解释一下属性[color="#000000"](Property)[color="#000000"]的意思,属性是一个抽象概念,它和成员变量是不同的。属性泛指一个类内一些非常明显、可对外开放的数据,通常是可让用户直接存取的变量。例如在一个
window_form[color="#000000"]的对象中,它的[color="#000000"]title[color="#000000"]、[color="#000000"]width[color="#000000"]、[color="#000000"]height[color="#000000"]就是最明显和重要的数据。而属性的概念通常会透过定义一套[color="#000000"]public[color="#000000"]的
setXXX()[color="#000000"]和[color="#000000"]getXXX()[color="#000000"]的成员方法实践[color="#000000"](XXX[color="#000000"]是属性名称,通常会被定为[color="#000000"]private[color="#000000"]的成员[color="#000000"])[color="#000000"]。但在[color="#000000"]PHP[color="#000000"]里,属性通是用一个数组
(array)[color="#000000"]存放,再配合[color="#000000"]__get()[color="#000000"]和[color="#000000"]__set()[color="#000000"]来统一地存取。[color="#000000"]
[color="#000000"]当你试图读取一个不存在或不可见的属性时,[color="#000000"]PHP5[color="#000000"]就会执行__get()
([color="#000000"]如有定义[color="#000000"])[color="#000000"],[color="#000000"]__get()[color="#000000"]必须设有一个参数[color="#000000"](parameter)[color="#000000"],会用来存放试图读取的属性名称;而当试图写入一个不存在或不可见的属性时,
PHP5[color="#000000"]就会执行__set()
([color="#000000"]如有定义[color="#000000"])[color="#000000"],[color="#000000"]__set()[color="#000000"]必须设有两个参数,用来存放试图写入的属性名称和属性值。以下为一个简单例子
(php5.chp1.2.12a.phps)[color="#000000"]及其运行结果
(php5.chp1.2.12a.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]myWindow [color="#007700"]{
private
$myProperties[color="#007700"]=array([color="#dd0000"]"title"[color="#007700"]=>[color="#dd0000"]"itZone.info");
function
[color="#0000bb"]__get[color="#007700"]([color="#0000bb"]$property_name[color="#007700"]){
echo('Try
to read non-exist/invisible
member:'[color="#007700"].[color="#0000bb"]$property_name[color="#007700"].',
__get() is called.
');
if
( isset([color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]myProperties[color="#007700"][[color="#0000bb"]$property_name])
){
echo("Alter
to access:\$this->myProperties[$property_name] instead:
"[color="#007700"].[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]myProperties[color="#007700"][[color="#0000bb"]$property_name[color="#007700"]].[color="#dd0000"]"
");
return
[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]myProperties[color="#007700"][[color="#0000bb"]$property_name];
}
}
function
[color="#0000bb"]__set[color="#007700"]([color="#0000bb"]$property_name[color="#007700"],[color="#0000bb"]$value[color="#007700"]){
echo('Try
to write non-exist/invisible
member:'[color="#007700"].[color="#0000bb"]$property_name[color="#007700"].',
__set() is
called.
'[color="#007700"]);
[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]myProperties[color="#007700"][[color="#0000bb"]$property_name[color="#007700"]]=[color="#0000bb"]$value[color="#007700"];
}
}
$obj
[color="#007700"]= new [color="#0000bb"]myWindow[color="#007700"]();
echo('Try
to use $obj->title:'[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]title[color="#007700"].[color="#dd0000"]'
'[color="#007700"]);
echo('Try
to use $obj->width:'[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]width[color="#007700"].[color="#dd0000"]'
'[color="#007700"]);
[color="#0000bb"]$obj[color="#007700"]->width
[color="#007700"]= [color="#0000bb"]800[color="#007700"];
echo('Try
to use
$obj->width:'[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]width[color="#007700"].[color="#dd0000"]'
'[color="#007700"]);
[color="#0000bb"]?>
[color="#000000"]
[color="#000000"]同样地,当你试图调用一个不存在[color="#000000"]/[color="#000000"]不可见的方法时,[color="#000000"]PHP5[color="#000000"]就会执行__call()
([color="#000000"]如有定义[color="#000000"])[color="#000000"],[color="#000000"]__call()[color="#000000"]必须设有两个参数,用来存放试图调用的方法名称和其参数[color="#000000"]([color="#000000"]其参数会被放入一数组中[color="#000000"])[color="#000000"]。以下为一个简单例子
(php5.chp1.2.12b.phps)[color="#000000"]及其运行结果
(php5.chp1.2.12b.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo [color="#007700"]{
private
$nums [color="#007700"]= array([color="#0000bb"]1,
[color="#0000bb"]2[color="#007700"]);
private
$text [color="#007700"]= [color="#dd0000"]"itZone";
function
[color="#0000bb"]__call[color="#007700"]([color="#0000bb"]$method_name,
[color="#0000bb"]$parameters)
{
echo('Try
to call non-exist/invisible member method:
'[color="#007700"]);
echo([color="#dd0000"]''[color="#007700"].[color="#0000bb"]$method_name[color="#007700"].[color="#dd0000"]''[color="#007700"]);
echo('
, __call() is called.
'[color="#007700"]);
echo('The
following is the array of parameters passed in:
'[color="#007700"]);
[color="#0000bb"]var_dump[color="#007700"]([color="#0000bb"]$parameters[color="#007700"]);
echo('Now
attempt to execute
'[color="#007700"]);
echo([color="#dd0000"]''[color="#007700"].[color="#0000bb"]$method_name[color="#007700"].'
:
');
switch
([color="#0000bb"]$method_name)
{
case
[color="#dd0000"]'sum':
return
([color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]nums[color="#007700"][[color="#0000bb"]0[color="#007700"]]+[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]nums[color="#007700"][[color="#0000bb"]1]);
break;
case
[color="#dd0000"]'strlen':
return
[color="#0000bb"]strlen[color="#007700"]([color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]text[color="#007700"]);
break;
default:
echo("Requested
method not
supported!
"[color="#007700"]);
break;
}
}
}
$obj
[color="#007700"]= new [color="#0000bb"]Foo[color="#007700"]();
echo('Result
of calling $obj->sum() is:
'[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]sum[color="#007700"]().[color="#dd0000"]'
'[color="#007700"]);
echo('Result
of calling $obj->strlen() is:
'[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]strlen[color="#007700"]().[color="#dd0000"]'
'[color="#007700"]);
echo('Result
of calling $obj->someMethod(1,9.9,"Text...") is:
'[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]someMethod[color="#007700"]([color="#0000bb"]1[color="#007700"],[color="#0000bb"]9.9[color="#007700"],[color="#dd0000"]"Text..."[color="#007700"]).[color="#dd0000"]'
'[color="#007700"]);
[color="#0000bb"]?>
2.13
[color="#000000"]自动加载[color="#000000"]
PHP5[color="#000000"]新增支持一个名为[color="#000000"]__autoload()[color="#000000"]的函数,凡当试图实例化一个未定义类的时候就会被调用。而那个未定义类的名称就会传入[color="#000000"]__autoload()[color="#000000"]中作为唯一的参数。使用例子如下:[color="#000000"]
[color="#0000bb"]function
[color="#0000bb"]__autoload[color="#007700"]([color="#0000bb"]$className)
{
if
([color="#0000bb"]strcmp[color="#007700"]([color="#0000bb"]$className[color="#007700"],[color="#dd0000"]"Foo"[color="#007700"])==[color="#0000bb"]0)
{
include_once
[color="#0000bb"]$className .
[color="#dd0000"]".php"[color="#007700"];
}else{
echo("Attempted
to load an undefined class!"[color="#007700"]);
}
}
$obj
[color="#007700"]= new [color="#0000bb"]someClassName[color="#007700"];
[color="#0000bb"]?>
2.14
__METHOD__ [color="#000000"]伪常数及__toString()
[color="#000000"]方法
__METHOD__
[color="#000000"]这个新的伪常数会传回其所属类及方法的值,留意它是个[color="#000000"]compile-time[color="#000000"]的值:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo {
function
[color="#0000bb"]show()
{
echo(
[color="#0000bb"]__METHOD__);
}
}
class
[color="#0000bb"]Bar extends
[color="#0000bb"]Foo [color="#007700"]{
}
[color="#0000bb"]Foo[color="#007700"]::[color="#0000bb"]show[color="#007700"](); //
outputs Foo::show
[color="#0000bb"]Bar[color="#007700"]::[color="#0000bb"]show[color="#007700"](); //
outputs Foo::show either since __METHOD__ is
//
compile-time evaluated token
function
[color="#0000bb"]test()
{
echo(
[color="#0000bb"]__METHOD__[color="#007700"]);
}
[color="#0000bb"]test[color="#007700"](); //
outputs test
[color="#0000bb"]?>
[color="#000000"]
[color="#000000"]而定义__toString()
[color="#000000"]方法就可以重载对象转化字符串的方法:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo {
function
[color="#0000bb"]__toString()
{
return
"This is
Foo..."[color="#007700"];
}
}
$obj
[color="#007700"]= new [color="#0000bb"]Foo[color="#007700"];
echo([color="#0000bb"]$obj[color="#007700"]); //
call __toString()
[color="#0000bb"]?>
[color="#000000"]来到这里,[color="#000000"]PHP5[color="#000000"]的新对象模型已经大致介绍完毕了,如果你是[color="#000000"]Java[color="#000000"]的使用者的话,以上的语法绝不陌生。相信[color="#000000"]PHP5[color="#000000"]全面投入支持[color="#000000"]OOP[color="#000000"]后,对使用[color="#000000"]PHP[color="#000000"]开发大型应用程序将有重大的帮助。在下一章,我们会看看其它[color="#000000"]PHP5[color="#000000"]的新功能,包括支持异常处理(Exception
Handling)[color="#000000"]的语法。
[color="#000000"]统一化的构造方法和析构方法(Constructor
& Destructor)
[color="#000000"]每当一个类被实例化[color="#000000"]([color="#000000"]即是被「[color="#000000"]new])[color="#000000"]时,构造方法(Constructor
method)[color="#000000"]便会被呼叫执行[color="#000000"]([color="#000000"]如果有定义构造方法的话。留意构造方法并不是用来创建该对象[color="#000000"])[color="#000000"],这最适合用来初始化一个新生的对象。在[color="#000000"]PHP4[color="#000000"]的时代,构造方法就是和类的名称一样的方法,但这样在日后若果改变class
hierarchy[color="#000000"]时会造一些不便。[color="#000000"]
[color="#000000"]故[color="#000000"]PHP5[color="#000000"]就统一了构造方法的语法,一律命名为[color="#000000"]__construct()[color="#000000"],留意开头是两个底线[color="#000000"](underscore[color="#000000"],[color="#000000"]_)[color="#000000"]。为了和[color="#000000"]PHP4[color="#000000"]作向后兼容,如果在类内找不到[color="#000000"]__construct()[color="#000000"],[color="#000000"]PHP[color="#000000"]就会尝试找找[color="#000000"]PHP4[color="#000000"]时代的构造方法。请参考以下的简单例子
(php5.chp1.2.8a.phps)[color="#000000"]及其运行结果
(php5.chp1.2.8a.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Human [color="#007700"]{
public
$nationality[color="#007700"]=[color="#dd0000"]"Unknown";
function
[color="#0000bb"]__construct()
{
echo("A
human is born!
");
}
}
class
[color="#0000bb"]Chinese extends
[color="#0000bb"]Human {
function
[color="#0000bb"]__construct()
{
[color="#0000bb"]parent[color="#007700"]::[color="#0000bb"]__construct[color="#007700"]();
[color="#0000bb"]$this[color="#007700"]->nationality
[color="#007700"]= [color="#dd0000"]"China"[color="#007700"];
echo("A
Chinese is born!
"[color="#007700"]);
}
}
$obj
[color="#007700"]= new [color="#0000bb"]Human[color="#007700"]();
echo("Nationality:
"[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]nationality[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
$obj
[color="#007700"]= new [color="#0000bb"]Chinese[color="#007700"]();
echo("Nationality:
"[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]nationality[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
[color="#0000bb"]?>
[color="#000000"]
[color="#000000"]同样,一个对象在执行完毕后便会先调用析构方法[color="#000000"](Destructor)([color="#000000"]留意析构方法并不会释放该对象[color="#000000"])[color="#000000"],才会把对象释放回内存。析构方法通常用来释放对象拥有的资源,例如一个[color="#000000"]Database[color="#000000"]的[color="#000000"]connection[color="#000000"]。[color="#000000"]
PHP4[color="#000000"]没有析构方法,而[color="#000000"]PHP5[color="#000000"]就支持在类内定义一个名为[color="#000000"]__destruct()[color="#000000"]的无参数方法来作析构方法。请留意,[color="#000000"]PHP[color="#000000"]的[color="#000000"]Engine[color="#000000"]是不会自动调用父类中的构造或析构方法的,如你想调用父类的构造或析构方法,就得使用[color="#000000"]parent::__construct()[color="#000000"]或[color="#000000"]parent::__destruct()[color="#000000"]。在以下[color="#000000"]([color="#000000"]或更多[color="#000000"])[color="#000000"]情况[color="#000000"]PHP[color="#000000"]会决定销毁你的对象:
*
[color="#000000"]将储存该对象[color="#000000"]([color="#000000"]的[color="#000000"]reference)[color="#000000"]的变量设为[color="#000000"]NULL[color="#000000"]或其它值[color="#000000"]([color="#000000"]例:[color="#000000"]$obj=NULL;)[color="#000000"]。
*
[color="#000000"]调用[color="#000000"]unset()([color="#000000"]例:[color="#000000"]unset($obj);)[color="#000000"]。[color="#000000"]
[color="#000000"] *
[color="#000000"]留意若已另设一变量储存了对象[color="#000000"]([color="#000000"]的[color="#000000"]reference)[color="#000000"],则此两项无效,直到那另设的变量也不再使用为止,如此类推。
*
PHP[color="#000000"]脚本全部执行完毕。[color="#000000"]([color="#000000"]如下例说明[color="#000000"])
[color="#000000"]以下为一个简单例子
(php5.chp1.2.8b.phps)[color="#000000"]及其运行结果
(php5.chp1.2.8b.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]WWWViewer [color="#007700"]{
private
$resource[color="#007700"];
private
$url;
function
[color="#0000bb"]__construct[color="#007700"]([color="#0000bb"]$url)
{
[color="#0000bb"]$this[color="#007700"]->url
[color="#007700"]= [color="#0000bb"]$url[color="#007700"];
[color="#0000bb"]$this[color="#007700"]->resource
=
[color="#0000bb"]fopen[color="#007700"]([color="#0000bb"]$url[color="#007700"],[color="#dd0000"]'r'[color="#007700"]);
}
public
[color="#007700"]function [color="#0000bb"]display()
{
echo("The
following will display the page:
"[color="#007700"].[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]url[color="#007700"].[color="#dd0000"]"");
while
(![color="#0000bb"]feof[color="#007700"]([color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]resource[color="#007700"])){
$contents
=
[color="#0000bb"]fgets[color="#007700"]([color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]resource[color="#007700"]);
echo([color="#0000bb"]$contents[color="#007700"]);
}
echo("End
display"[color="#007700"]);
}
public
function
[color="#0000bb"]showMessage[color="#007700"](){
echo("I
am alive!
");
}
function
[color="#0000bb"]__destruct()
{
echo("WWWViewer
object is destructing
now"[color="#007700"]);
[color="#0000bb"]fclose[color="#007700"]([color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]resource[color="#007700"]);
}
}
$obj
= new
[color="#0000bb"]WWWViewer[color="#007700"]([color="#dd0000"]'http://www.google.com/'[color="#007700"]);
[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]display[color="#007700"]();
[color="#0000bb"]?>
Normal
HTML goes here....
[color="#0000bb"]//
Still alive here...
[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]showMessage[color="#007700"]();
[color="#0000bb"]?>
2.9
[color="#000000"]对象复制(Objects
Cloning)
[color="#000000"]当牵涉到要复制一个对象时,情况就不如复制[color="#000000"]integer[color="#000000"]般简单。在[color="#000000"]PHP4[color="#000000"],对象被复制时是会被按位复制(bit-by-bit
copy)[color="#000000"],即是副本会和正本一模一样。但有时这并不是理想的情况,例如你有的对象内拥有个[color="#000000"]XXX[color="#000000"]类的对象[color="#000000"]([color="#000000"]的[color="#000000"]reference)[color="#000000"],而你想在复制的同时创建一个新的[color="#000000"]XXX[color="#000000"]类的对象,那么[color="#000000"]PHP4[color="#000000"]就未能简单解决你的问题了。[color="#000000"]
[color="#000000"]在[color="#000000"]PHP5[color="#000000"],你得使用[color="#000000"]clone[color="#000000"]这[color="#000000"]keyword[color="#000000"]去命令复制一个对象[color="#000000"]([color="#000000"]语法:$copied_obj
= clone
$org_obj;)[color="#000000"],这时候那个类的[color="#000000"]__clone()[color="#000000"]方法便会被调用[color="#000000"]([color="#000000"]不能直接调用[color="#000000"]__clone())[color="#000000"]。[color="#000000"]
[color="#000000"]当你执行[color="#000000"]clone[color="#000000"]命令时,[color="#000000"]PHP5[color="#000000"]会在你的类的定义内找找有没有[color="#000000"]__clone()[color="#000000"]:
*
[color="#000000"]如果没有,一个内建的默认[color="#000000"]__clone()[color="#000000"]便会被使用,那将是一个按位复制(bit-by-bit
copy)[color="#000000"]。
*
[color="#000000"]如果有,[color="#000000"]PHP5[color="#000000"]会先进行一次按位复制,再执行你定义的[color="#000000"]__clone()[color="#000000"]。[color="#000000"]
[color="#000000"]以下为一个简单例子
(php5.chp1.2.9.phps)[color="#000000"]及其运行结果
(php5.chp1.2.9.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo [color="#007700"]{
public
$id;
function
[color="#0000bb"]__construct()
{
[color="#0000bb"]$this[color="#007700"]->id
[color="#007700"]= [color="#0000bb"]1;
}
function
[color="#0000bb"]__clone()
{
[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]id[color="#007700"]++;
}
}
$foo1
[color="#007700"]= new [color="#0000bb"]Foo[color="#007700"]();
$foo2
[color="#007700"]= clone
$foo1[color="#007700"];
$foo3
[color="#007700"]= clone
$foo2[color="#007700"];
//
Change to $foo4 doesn't affect $foo1
$foo4
[color="#007700"]= clone
$foo1[color="#007700"];
[color="#0000bb"]$foo4[color="#007700"]->id
[color="#007700"]= [color="#0000bb"]999[color="#007700"];
echo("foo1's
id is: "[color="#007700"].[color="#0000bb"]$foo1[color="#007700"]->[color="#0000bb"]id[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
echo("foo2's
id is: "[color="#007700"].[color="#0000bb"]$foo2[color="#007700"]->[color="#0000bb"]id[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
echo("foo3's
id is: "[color="#007700"].[color="#0000bb"]$foo3[color="#007700"]->[color="#0000bb"]id[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
echo("foo4's
id is: "[color="#007700"].[color="#0000bb"]$foo4[color="#007700"]->[color="#0000bb"]id[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
[color="#0000bb"]?>
2.10
Dereference[color="#000000"]从函数返回的对象[color="#000000"]
PHP4[color="#000000"]并不能直接[color="#000000"]Dereference[color="#000000"]从函数返回的对象,以立刻作method
call[color="#000000"],在[color="#000000"]PHP5[color="#000000"]就可以了:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo {
function
[color="#0000bb"]showMsg()
{
echo("I
am Foo
");
}
}
class
[color="#0000bb"]Bar {
function
[color="#0000bb"]showMsg()
{
echo("I
am Bar
");
}
}
function
[color="#0000bb"]DecideFooBar[color="#007700"]([color="#0000bb"]$name)
{
switch ([color="#0000bb"]$name)
{
case
[color="#dd0000"]"Foo":
return
new [color="#0000bb"]Foo();
case
[color="#dd0000"]"Bar":
return
new
[color="#0000bb"]Bar[color="#007700"]();
}
}
[color="#0000bb"]DecideFooBar[color="#007700"]([color="#dd0000"]"Foo"[color="#007700"])->[color="#0000bb"]showMsg[color="#007700"]();
[color="#0000bb"]DecideFooBar[color="#007700"]([color="#dd0000"]"Bar"[color="#007700"])->[color="#0000bb"]showMsg[color="#007700"]();
[color="#0000bb"]?>
2.11
instanceof[color="#000000"]关键词及类型提示(Class
Type Hints)
PHP5[color="#000000"]新增了[color="#000000"]instanceof[color="#000000"]关键词,如果受检测的对象是属于某类[color="#000000"]/[color="#000000"]某类的子类[color="#000000"]/[color="#000000"]某界面的实现,就会return
true[color="#000000"]。以下例子将输出[color="#000000"]3[color="#000000"]个[color="#000000"]"1"[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]baseClass {}
class
[color="#0000bb"]subClass extends
[color="#0000bb"]baseClass[color="#007700"]{}
interface
aInterface {}
class
[color="#0000bb"]aClass implements aInterface [color="#007700"]{}
$a
[color="#007700"]= new [color="#0000bb"]baseClass();
echo(
($a instanceof
baseClass[color="#007700"]).[color="#dd0000"]"
"[color="#007700"]);
$b
[color="#007700"]= new [color="#0000bb"]subClass();
echo(
($b instanceof
baseClass[color="#007700"]).[color="#dd0000"]"
"[color="#007700"]);
$c
[color="#007700"]= new [color="#0000bb"]aClass();
echo(
($c instanceof
aInterface[color="#007700"]).[color="#dd0000"]"
"[color="#007700"]);
[color="#0000bb"]?>
[color="#000000"]
[color="#000000"]虽然[color="#000000"]PHP5[color="#000000"]是loosely
typed[color="#000000"]的程序语言,但[color="#000000"]PHP5[color="#000000"]仍新增了Class
Type Hints[color="#000000"]的功能,用来声明传入之对象参数所需要的类型。如果类型有所违反会发生fatal
error[color="#000000"]。以下为一个简单例子
(php5.chp1.2.11.phps)[color="#000000"]及其运行结果[color="#000000"](php5.chp1.2.11.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo {}
class
[color="#0000bb"]Bar {}
function
[color="#0000bb"]check[color="#007700"](Foo
$obj[color="#007700"]) {
echo("The
passed in object is Foo/its subclass/its implementation(if Foo is
interface).
"[color="#007700"]);
}
$a
[color="#007700"]= new [color="#0000bb"]Foo[color="#007700"]();
$b
= new
[color="#0000bb"]Bar[color="#007700"]();
[color="#0000bb"]check[color="#007700"]([color="#0000bb"]$a[color="#007700"]);
[color="#0000bb"]check[color="#007700"]([color="#0000bb"]$b[color="#007700"]);
[color="#0000bb"]?>
[color="#000000"]
[color="#000000"]其实使用Class
Type Hints[color="#000000"]就和以下程序代码的意义一样:[color="#000000"]
[color="#0000bb"]function
[color="#0000bb"]check[color="#007700"]([color="#0000bb"]$obj)
{
if (!($obj
instanceof aClassName))
{
die("Argument
1 must be an instance of aClassName"[color="#007700"]);
}
}
[color="#0000bb"]?>
2.12 [color="#000000"]可重载的成员方法调用和属性存取(Method
calls and Property accesses)
[color="#000000"]重载[color="#000000"](Overload)[color="#000000"]一字在[color="#000000"]PHP[color="#000000"]这种Dynamic
Typing[color="#000000"]语言中的意义和「方法重载(Method
Overloading)[color="#000000"]」有些不同。在[color="#000000"]PHP[color="#000000"]你只需使用
func_num_args()[color="#000000"]和像[color="#000000"]is_int()[color="#000000"]等函数就可做到像[color="#000000"]Java/C++[color="#000000"]那些Static
Typing[color="#000000"]语言方法重载的效果。[color="#000000"]PHP[color="#000000"]的重载是指可存取或调用未经定义的成员方法式属性。这种成员方法调用和属性存取在[color="#000000"]PHP5[color="#000000"]可使用[color="#000000"]__call()[color="#000000"]、__get()
[color="#000000"]和
__set()[color="#000000"]重载,当[color="#000000"]PHP5[color="#000000"]试图使用未定义的方法或属性的时候,就会调用这些重载的方法。[color="#000000"]
[color="#000000"]让我解释一下属性[color="#000000"](Property)[color="#000000"]的意思,属性是一个抽象概念,它和成员变量是不同的。属性泛指一个类内一些非常明显、可对外开放的数据,通常是可让用户直接存取的变量。例如在一个
window_form[color="#000000"]的对象中,它的[color="#000000"]title[color="#000000"]、[color="#000000"]width[color="#000000"]、[color="#000000"]height[color="#000000"]就是最明显和重要的数据。而属性的概念通常会透过定义一套[color="#000000"]public[color="#000000"]的
setXXX()[color="#000000"]和[color="#000000"]getXXX()[color="#000000"]的成员方法实践[color="#000000"](XXX[color="#000000"]是属性名称,通常会被定为[color="#000000"]private[color="#000000"]的成员[color="#000000"])[color="#000000"]。但在[color="#000000"]PHP[color="#000000"]里,属性通是用一个数组
(array)[color="#000000"]存放,再配合[color="#000000"]__get()[color="#000000"]和[color="#000000"]__set()[color="#000000"]来统一地存取。[color="#000000"]
[color="#000000"]当你试图读取一个不存在或不可见的属性时,[color="#000000"]PHP5[color="#000000"]就会执行__get()
([color="#000000"]如有定义[color="#000000"])[color="#000000"],[color="#000000"]__get()[color="#000000"]必须设有一个参数[color="#000000"](parameter)[color="#000000"],会用来存放试图读取的属性名称;而当试图写入一个不存在或不可见的属性时,
PHP5[color="#000000"]就会执行__set()
([color="#000000"]如有定义[color="#000000"])[color="#000000"],[color="#000000"]__set()[color="#000000"]必须设有两个参数,用来存放试图写入的属性名称和属性值。以下为一个简单例子
(php5.chp1.2.12a.phps)[color="#000000"]及其运行结果
(php5.chp1.2.12a.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]myWindow [color="#007700"]{
private
$myProperties[color="#007700"]=array([color="#dd0000"]"title"[color="#007700"]=>[color="#dd0000"]"itZone.info");
function
[color="#0000bb"]__get[color="#007700"]([color="#0000bb"]$property_name[color="#007700"]){
echo('Try
to read non-exist/invisible
member:'[color="#007700"].[color="#0000bb"]$property_name[color="#007700"].',
__get() is called.
');
if
( isset([color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]myProperties[color="#007700"][[color="#0000bb"]$property_name])
){
echo("Alter
to access:\$this->myProperties[$property_name] instead:
"[color="#007700"].[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]myProperties[color="#007700"][[color="#0000bb"]$property_name[color="#007700"]].[color="#dd0000"]"
");
return
[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]myProperties[color="#007700"][[color="#0000bb"]$property_name];
}
}
function
[color="#0000bb"]__set[color="#007700"]([color="#0000bb"]$property_name[color="#007700"],[color="#0000bb"]$value[color="#007700"]){
echo('Try
to write non-exist/invisible
member:'[color="#007700"].[color="#0000bb"]$property_name[color="#007700"].',
__set() is
called.
'[color="#007700"]);
[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]myProperties[color="#007700"][[color="#0000bb"]$property_name[color="#007700"]]=[color="#0000bb"]$value[color="#007700"];
}
}
$obj
[color="#007700"]= new [color="#0000bb"]myWindow[color="#007700"]();
echo('Try
to use $obj->title:'[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]title[color="#007700"].[color="#dd0000"]'
'[color="#007700"]);
echo('Try
to use $obj->width:'[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]width[color="#007700"].[color="#dd0000"]'
'[color="#007700"]);
[color="#0000bb"]$obj[color="#007700"]->width
[color="#007700"]= [color="#0000bb"]800[color="#007700"];
echo('Try
to use
$obj->width:'[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]width[color="#007700"].[color="#dd0000"]'
'[color="#007700"]);
[color="#0000bb"]?>
[color="#000000"]
[color="#000000"]同样地,当你试图调用一个不存在[color="#000000"]/[color="#000000"]不可见的方法时,[color="#000000"]PHP5[color="#000000"]就会执行__call()
([color="#000000"]如有定义[color="#000000"])[color="#000000"],[color="#000000"]__call()[color="#000000"]必须设有两个参数,用来存放试图调用的方法名称和其参数[color="#000000"]([color="#000000"]其参数会被放入一数组中[color="#000000"])[color="#000000"]。以下为一个简单例子
(php5.chp1.2.12b.phps)[color="#000000"]及其运行结果
(php5.chp1.2.12b.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo [color="#007700"]{
private
$nums [color="#007700"]= array([color="#0000bb"]1,
[color="#0000bb"]2[color="#007700"]);
private
$text [color="#007700"]= [color="#dd0000"]"itZone";
function
[color="#0000bb"]__call[color="#007700"]([color="#0000bb"]$method_name,
[color="#0000bb"]$parameters)
{
echo('Try
to call non-exist/invisible member method:
'[color="#007700"]);
echo([color="#dd0000"]''[color="#007700"].[color="#0000bb"]$method_name[color="#007700"].[color="#dd0000"]''[color="#007700"]);
echo('
, __call() is called.
'[color="#007700"]);
echo('The
following is the array of parameters passed in:
'[color="#007700"]);
[color="#0000bb"]var_dump[color="#007700"]([color="#0000bb"]$parameters[color="#007700"]);
echo('Now
attempt to execute
'[color="#007700"]);
echo([color="#dd0000"]''[color="#007700"].[color="#0000bb"]$method_name[color="#007700"].'
:
');
switch
([color="#0000bb"]$method_name)
{
case
[color="#dd0000"]'sum':
return
([color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]nums[color="#007700"][[color="#0000bb"]0[color="#007700"]]+[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]nums[color="#007700"][[color="#0000bb"]1]);
break;
case
[color="#dd0000"]'strlen':
return
[color="#0000bb"]strlen[color="#007700"]([color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]text[color="#007700"]);
break;
default:
echo("Requested
method not
supported!
"[color="#007700"]);
break;
}
}
}
$obj
[color="#007700"]= new [color="#0000bb"]Foo[color="#007700"]();
echo('Result
of calling $obj->sum() is:
'[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]sum[color="#007700"]().[color="#dd0000"]'
'[color="#007700"]);
echo('Result
of calling $obj->strlen() is:
'[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]strlen[color="#007700"]().[color="#dd0000"]'
'[color="#007700"]);
echo('Result
of calling $obj->someMethod(1,9.9,"Text...") is:
'[color="#007700"].[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]someMethod[color="#007700"]([color="#0000bb"]1[color="#007700"],[color="#0000bb"]9.9[color="#007700"],[color="#dd0000"]"Text..."[color="#007700"]).[color="#dd0000"]'
'[color="#007700"]);
[color="#0000bb"]?>
2.13
[color="#000000"]自动加载[color="#000000"]
PHP5[color="#000000"]新增支持一个名为[color="#000000"]__autoload()[color="#000000"]的函数,凡当试图实例化一个未定义类的时候就会被调用。而那个未定义类的名称就会传入[color="#000000"]__autoload()[color="#000000"]中作为唯一的参数。使用例子如下:[color="#000000"]
[color="#0000bb"]function
[color="#0000bb"]__autoload[color="#007700"]([color="#0000bb"]$className)
{
if
([color="#0000bb"]strcmp[color="#007700"]([color="#0000bb"]$className[color="#007700"],[color="#dd0000"]"Foo"[color="#007700"])==[color="#0000bb"]0)
{
include_once
[color="#0000bb"]$className .
[color="#dd0000"]".php"[color="#007700"];
}else{
echo("Attempted
to load an undefined class!"[color="#007700"]);
}
}
$obj
[color="#007700"]= new [color="#0000bb"]someClassName[color="#007700"];
[color="#0000bb"]?>
2.14
__METHOD__ [color="#000000"]伪常数及__toString()
[color="#000000"]方法
__METHOD__
[color="#000000"]这个新的伪常数会传回其所属类及方法的值,留意它是个[color="#000000"]compile-time[color="#000000"]的值:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo {
function
[color="#0000bb"]show()
{
echo(
[color="#0000bb"]__METHOD__);
}
}
class
[color="#0000bb"]Bar extends
[color="#0000bb"]Foo [color="#007700"]{
}
[color="#0000bb"]Foo[color="#007700"]::[color="#0000bb"]show[color="#007700"](); //
outputs Foo::show
[color="#0000bb"]Bar[color="#007700"]::[color="#0000bb"]show[color="#007700"](); //
outputs Foo::show either since __METHOD__ is
//
compile-time evaluated token
function
[color="#0000bb"]test()
{
echo(
[color="#0000bb"]__METHOD__[color="#007700"]);
}
[color="#0000bb"]test[color="#007700"](); //
outputs test
[color="#0000bb"]?>
[color="#000000"]
[color="#000000"]而定义__toString()
[color="#000000"]方法就可以重载对象转化字符串的方法:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo {
function
[color="#0000bb"]__toString()
{
return
"This is
Foo..."[color="#007700"];
}
}
$obj
[color="#007700"]= new [color="#0000bb"]Foo[color="#007700"];
echo([color="#0000bb"]$obj[color="#007700"]); //
call __toString()
[color="#0000bb"]?>
[color="#000000"]来到这里,[color="#000000"]PHP5[color="#000000"]的新对象模型已经大致介绍完毕了,如果你是[color="#000000"]Java[color="#000000"]的使用者的话,以上的语法绝不陌生。相信[color="#000000"]PHP5[color="#000000"]全面投入支持[color="#000000"]OOP[color="#000000"]后,对使用[color="#000000"]PHP[color="#000000"]开发大型应用程序将有重大的帮助。在下一章,我们会看看其它[color="#000000"]PHP5[color="#000000"]的新功能,包括支持异常处理(Exception
Handling)[color="#000000"]的语法。
相关阅读 更多 +
排行榜 更多 +