PHP5新功能初探系列一
时间:2007-02-08 来源:shiyaowen
PHP5新功能初探系列一
[color="#000000"]PHP5[color="#000000"]新功能初探系列一
1.
[color="#000000"]新对象模型(Object
Model)
2. [color="#000000"]异常处理机制(Exception
Handling)
3. [color="#000000"]新的扩充程序库(Extensions)
4.
[color="#000000"]由[color="#000000"]PHP4[color="#000000"]升级到PHP5
5.
PHP5[color="#000000"],未来会是如何?[color="#000000"]
[color="#000000"]本篇文章的目录
1.
[color="#000000"]从前[color="#000000"]PHP[color="#000000"]的OO
2.
PHP5[color="#000000"]全新的对象模型(Object
Model)
1.
[color="#000000"]将对象以[color="#000000"]Pass-by-reference[color="#000000"]形式传递
2.
private[color="#000000"]、[color="#000000"]protected[color="#000000"]、[color="#000000"]public[color="#000000"]存取限制修饰符
3.
[color="#000000"]使用[color="#000000"]static[color="#000000"]修饰符表示类成员
4.
[color="#000000"]使用[color="#000000"]abstract[color="#000000"]表示抽象类和抽象方法
5.
[color="#000000"]使用[color="#000000"]final[color="#000000"]修饰符表示终结成员和终结类
6.
[color="#000000"]使用[color="#000000"]const[color="#000000"]修饰符表示常数
7.
[color="#000000"]界面
Interface
8.
[color="#000000"]统一化的构造方法和析构方法(Constructor
& Destructor)
9.
[color="#000000"]对象复制(Objects
Cloning)
10.
Dereference[color="#000000"]从函数返回的对象
11.
instanceof[color="#000000"]关键词及类型提示(Class
Type Hints)
12.
[color="#000000"]可重载的成员方法调用和属性存取(Method
calls and Property accesses)
13.
[color="#000000"]自动加载
14.
__METHOD__ [color="#000000"]伪常数及__toString()
[color="#000000"]方法
0.
[color="#000000"]前言[color="#000000"]
[color="#000000"]经过年多的期待,[color="#000000"]PHP5[color="#000000"]终于在[color="#000000"]2004[color="#000000"]年[color="#000000"]7[color="#000000"]月[color="#000000"]13[color="#000000"]日推出正式的版本。这个万众期待的全新版本,到底有甚么新的功能呢?我们会在本系列[color="#000000"]PHP5[color="#000000"]新功能初探的文章中窥探一下,第一炮我们会先看看[color="#000000"]PHP5[color="#000000"]的全新对象模型(Object
Model)[color="#000000"]。
1.
[color="#000000"]从前[color="#000000"]PHP[color="#000000"]的[color="#000000"]OO
[color="#000000"]其实早在[color="#000000"]PHP3[color="#000000"]及[color="#000000"]PHP4[color="#000000"]的年代,[color="#000000"]PHP[color="#000000"]已经支持类[color="#000000"](Class)[color="#000000"]和对象[color="#000000"](Object)([color="#000000"]或称对象,本文统称「对象」[color="#000000"])[color="#000000"],但那仍然不能谈得上是支持[color="#000000"]OOP([color="#000000"]对象导向编程[color="#000000"])[color="#000000"]。主要的原因,是[color="#000000"]PHP4[color="#000000"]视对象和普通的基本类型(primitive
data type)[color="#000000"]如[color="#000000"]integer[color="#000000"]一样。而[color="#000000"]PHP4[color="#000000"]在传递参数给子程序[color="#000000"](sub-routine)[color="#000000"]是采用按值传递(pass
by
value)[color="#000000"]的方法,所以除非你显式地把对象的地址作参数传递[color="#000000"]([color="#000000"]语法:[color="#000000"]&object_name)[color="#000000"],否则你就只会把对象复制出一份副本传入子程序中,这对实行[color="#000000"]OOP[color="#000000"]是大大的不利。另外,[color="#000000"]PHP4[color="#000000"]也不支持[color="#000000"]public[color="#000000"]、[color="#000000"]protected[color="#000000"]、[color="#000000"]private[color="#000000"]等修饰符[color="#000000"](Modifier)[color="#000000"],缺乏这些对对象内部数据的封装[color="#000000"](Encapsulation)[color="#000000"]也会对支持[color="#000000"]OOP[color="#000000"]造成很大障碍。还有很多如abstract
class[color="#000000"]、final
member[color="#000000"]、static
member[color="#000000"]等的修饰符也是没有支援的。[color="#000000"]
[color="#000000"]此例
(php5.chp1.1.phps) ([color="#000000"]为方便大家阅读源码,本文其它范例亦可如此打开源码档[color="#000000"])[color="#000000"]会示范[color="#000000"]PHP4[color="#000000"]中对象传递的问题,按此
(php5.chp1.1.php)[color="#000000"]可看运行结果,你会发现在子程序内不会修改原来[color="#000000"]$myObject[color="#000000"]内的数据。
OOP
[color="#000000"]是目前最流行、也最为重要的编程概念,同时[color="#000000"]OO[color="#000000"]也是软件工程中的重要一环,它使团队开发和设计大型系统变得比以前容易,详情我也不会多说了,市面上有很多很好的书籍或网页说明这点。由于[color="#000000"]PHP4[color="#000000"]缺乏对[color="#000000"]OOP[color="#000000"]的全面支持,令[color="#000000"]PHP[color="#000000"]的用者很难开发出高度模块化、具弹性、高可重用性、甚至是大规模的应用程序,縰然有如
PEAR [color="#000000"]或
PHP Classes [color="#000000"]等程序库,开发[color="#000000"]PHP[color="#000000"]程序依然得花上不少时间,甚至每次重头进行开发……
2.
PHP5[color="#000000"]全新的对象模型(Object
Model)
PHP5[color="#000000"]采用了全新的
Zend Engine
II[color="#000000"],彻底改革了它的对象模型,使[color="#000000"]PHP5[color="#000000"]可以追得上时代。不过,所谓改革也许是模仿[color="#000000"]Java[color="#000000"]才对,因为现在的[color="#000000"]PHP5[color="#000000"]的对象模型几乎有近[color="#000000"]80%[color="#000000"]是和[color="#000000"]Java[color="#000000"]差不多的,原果你是[color="#000000"]Java[color="#000000"]的熟手,你定不会陌生。[color="#000000"]Zend[color="#000000"]模仿[color="#000000"]Java[color="#000000"]有它的原因,也许我会在迟些再撰文讲述。[color="#000000"]
[color="#000000"]在此补充下一些[color="#000000"]PHP5[color="#000000"]中的基本[color="#000000"]OO[color="#000000"]语法:
*
[color="#000000"]在一个类内定义的变量就是其成员变量(member
variable)[color="#000000"],在其内定义的函数就是其成员方法(member
method)[color="#000000"]。
*
self[color="#000000"]和[color="#000000"]parent[color="#000000"]两个pseudo
variable[color="#000000"]的作用:[color="#000000"]self[color="#000000"]代表正执行该句[color="#000000"]statement[color="#000000"]的所属类,[color="#000000"]parent[color="#000000"]代表正执行该句[color="#000000"]statement[color="#000000"]的所属类的父类。
*
$this[color="#000000"]这pseudo
variable[color="#000000"]代表正执行该句[color="#000000"]statement[color="#000000"]的所属对象。
*
extends[color="#000000"]关键词语法:class
ClassName extends ParentClass{ // ...
}[color="#000000"]。代表[color="#000000"]ClassName[color="#000000"]类继承[color="#000000"]ParentClass[color="#000000"]类。
*
new[color="#000000"]关键词:$obj_handler
= new
ClassName();[color="#000000"]。如是者会创建一个[color="#000000"]ClassName[color="#000000"]类的实例[color="#000000"](instance)[color="#000000"],由[color="#000000"]$obj_handler[color="#000000"]储存此新创建的对象[color="#000000"](object)[color="#000000"]的[color="#000000"]reference[color="#000000"]。
*
[color="#000000"]调用成员方法[color="#000000"]/[color="#000000"]变量的语法是:[color="#000000"]$obj_handler->member_var[color="#000000"]或[color="#000000"]$obj_handler->member_func()[color="#000000"]。
2.1
[color="#000000"]将对象以[color="#000000"]Pass-by-reference[color="#000000"]形式传递[color="#000000"]
[color="#000000"]在第[color="#000000"]1[color="#000000"]节中提过的问题已在[color="#000000"]PHP5[color="#000000"]得到解决,现在存放[color="#000000"]Object[color="#000000"]的[color="#000000"]variable[color="#000000"]所储的是对象的[color="#000000"]reference[color="#000000"],那在参数传递时便不会复制副本,于是你可以直接对传入的对象造成修改。请看看
(php5.chp1.1.phps)[color="#000000"]在一个运行[color="#000000"]PHP5[color="#000000"]的Testing
server[color="#000000"]的运行结果
(php5.chp1.1.php)[color="#000000"],请留意今次和上次[color="#000000"]PHP4[color="#000000"]的结果是不同的。
2.2
private[color="#000000"]、[color="#000000"]protected[color="#000000"]、[color="#000000"]public[color="#000000"]存取限制修饰符(Accesibility
Modifier)
OO[color="#000000"]第一重要特征是其封装性[color="#000000"](Encapsulation)[color="#000000"],[color="#000000"]PHP5[color="#000000"]加入了[color="#000000"]private[color="#000000"]、[color="#000000"]protected[color="#000000"]、[color="#000000"]public[color="#000000"]这些[color="#000000"]keyword[color="#000000"],令你可修改类中的member
variable[color="#000000"]和member
method[color="#000000"]的可视性。
*
private[color="#000000"]的[color="#000000"]variable[color="#000000"]或[color="#000000"]function[color="#000000"]只有拥有它的类才可以存取。
*
protected[color="#000000"]的[color="#000000"]variable[color="#000000"]或[color="#000000"]function[color="#000000"]可被拥有它的类以及其子类[color="#000000"](subclass)[color="#000000"]存取。
*
public[color="#000000"]的[color="#000000"]variable[color="#000000"]或[color="#000000"]function[color="#000000"]可被任何其它类存取。
*
[color="#000000"]为了和[color="#000000"]PHP4[color="#000000"]达到向后兼容,没加上存取限制修饰符的[color="#000000"]variable[color="#000000"]或[color="#000000"]function[color="#000000"]会被视为[color="#000000"]public[color="#000000"]。[color="#000000"]
[color="#000000"]大家可开启下例
(php5.chp1.2.2.phps)[color="#000000"]。此例示范了存取限制修饰符的使用,同时也显示了动态绑定(Dynamic
binding)[color="#000000"]的运作。此例有点复杂,大家要细心留意,在testing
server[color="#000000"]的运行结果:
(php5.chp1.2.2.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Book[color="#007700"]{
private
$ClassName [color="#007700"]= [color="#dd0000"]"Book"[color="#007700"];
protected
$Title [color="#007700"]= [color="#dd0000"]"PHP5"[color="#007700"];
protected
$Price [color="#007700"]= [color="#0000bb"]100[color="#007700"];
public
function
[color="#0000bb"]printBook[color="#007700"](){
echo("Inside
printBook()...
"[color="#007700"]);
echo("Book::printBook()
- ClassName:
"[color="#007700"].[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]ClassName[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
echo("Book::printBook()
- Title:
"[color="#007700"].[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]Title[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
echo("Book::printBook()
- Price: "[color="#007700"].[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]Price[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
echo("End
printBook()");
}
}
class
[color="#0000bb"]ComputerBook extends
[color="#0000bb"]Book[color="#007700"]{
protected
$Price [color="#007700"]= [color="#0000bb"]200[color="#007700"];
public
function
[color="#0000bb"]printComputerBook[color="#007700"](){
echo("Inside
printComputerBook()...
"[color="#007700"]);
//
printBook() is inherited from Book, thus can access
ClassName
//
Note that $Price is
overriden
[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]printBook[color="#007700"]();
//
ClassName is not inherited, can't be accessed here
//
(so just like printing undeclared
variable)
[color="#007700"]echo("ComputerBook::printBook()
- ClassName: "[color="#007700"].[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]ClassName[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
//
Title and Price are inherited from Book, so can be
accessed
[color="#007700"]echo("ComputerBook::printBook()
- Title:
"[color="#007700"].[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]Title[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
echo("ComputerBook::printBook()
- Price: "[color="#007700"].[color="#0000bb"]$this[color="#007700"]->[color="#0000bb"]Price[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
echo("End
printComputerBook()"[color="#007700"]);
}
}
$book
[color="#007700"]= new [color="#0000bb"]Book[color="#007700"]();
//
Uncomment this 2 lines will cause fatal error since ClassName and
Price are invisible from outside.
//
echo($book->ClassName);
//
echo($book->Price);
[color="#0000bb"]$book[color="#007700"]->[color="#0000bb"]printBook[color="#007700"]();
$book
= new
[color="#0000bb"]ComputerBook[color="#007700"]();
[color="#0000bb"]$book[color="#007700"]->[color="#0000bb"]printComputerBook[color="#007700"]();
[color="#0000bb"]?>
2.3
[color="#000000"]使用[color="#000000"]static[color="#000000"]修饰符表示类成员(class
member)
[color="#000000"]使用[color="#000000"]static[color="#000000"]修饰符,这些变量及方法就可以在没有将类实例化[color="#000000"](instantiate)[color="#000000"]的情况下直接被调用或存取。留意调用这种类变量(class
variable)[color="#000000"]及类方法(class
method)[color="#000000"]的语法分别为[color="#000000"]classname::$var_name[color="#000000"]及[color="#000000"]classname::func_name()[color="#000000"]。请参考以下例子
(php5.chp1.2.3.phps)[color="#000000"]以及其运行结果
(php5.chp1.2.3.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo{
static
[color="#0000bb"]$number =
[color="#0000bb"]10[color="#007700"];
public
$letter [color="#007700"]= [color="#dd0000"]'c'[color="#007700"];
public
static function
[color="#0000bb"]setMember[color="#007700"](){
[color="#0000bb"]self[color="#007700"]::$number
[color="#007700"]= [color="#0000bb"]30[color="#007700"];
//
Cannot use $this in static function
//
$this->letter = 'a'; // This is WRONG!
[color="#007700"]}
}
//
Accessing static
member
[color="#007700"]echo([color="#0000bb"]Foo[color="#007700"]::[color="#0000bb"]$number[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
[color="#0000bb"]Foo[color="#007700"]::$number
=
[color="#0000bb"]99[color="#007700"];
echo([color="#0000bb"]Foo[color="#007700"]::[color="#0000bb"]$number[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
[color="#0000bb"]Foo[color="#007700"]::[color="#0000bb"]setMember[color="#007700"]();
echo([color="#0000bb"]Foo[color="#007700"]::[color="#0000bb"]$number[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
//
Accessing normal (public) member
$obj
= new
[color="#0000bb"]Foo[color="#007700"]();
echo([color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]letter[color="#007700"].[color="#dd0000"]"
"[color="#007700"]);
[color="#0000bb"]?>
2.4
[color="#000000"]使用[color="#000000"]abstract[color="#000000"]表示抽象类和抽象方法[color="#000000"]
[color="#000000"]在[color="#000000"]OO[color="#000000"]设计中,最顶层的类多是些较抽象概念的代表,使用抽象方法(abstract
method)[color="#000000"]可只大约定出类及其子类所需的蓝图而暂时不用实践。[color="#000000"]PHP5[color="#000000"]中,只要加上[color="#000000"]abstract[color="#000000"]修饰符就可建立抽象方法,抽象方法不需要给出实现源码,而含抽象方法的类必须被指定为抽象类(abstract
class)[color="#000000"],抽象类不能被实例化[color="#000000"](instantiate)([color="#000000"]即不能被「[color="#000000"]new[color="#000000"]」,否则会有fatal
error)[color="#000000"]。请参考以下的简单例子
(php5.chp1.2.4.phps)[color="#000000"]及其运行结果
(php5.chp1.2.4.php)[color="#000000"]:[color="#000000"]
[color="#007700"]class LivingThing
[color="#007700"]{
abstract
public function
[color="#0000bb"]printText[color="#007700"]();
public
[color="#007700"]function [color="#0000bb"]printText2[color="#007700"](){
//
Can still got some non-abstract method
[color="#007700"]echo("Call
at LivingThing::printText2(): Hi
World!!
");
}
}
class
[color="#0000bb"]Human extends
[color="#0000bb"]LivingThing [color="#007700"]{
public
[color="#007700"]function [color="#0000bb"]printText()
{
echo("Call
at Human::printText(): I am a
Human!!!
"[color="#007700"]);
}
}
$obj
= new
[color="#0000bb"]Human[color="#007700"]();
[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]printText[color="#007700"]();
[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]printText2[color="#007700"]();
[color="#0000bb"]?>
2.5
[color="#000000"]使用[color="#000000"]final[color="#000000"]修饰符表示终结成员和终结类[color="#000000"]
[color="#000000"]有时你不想你的方法[color="#000000"]/[color="#000000"]类再被重写[color="#000000"](override)/[color="#000000"]继承,就可以使用[color="#000000"]final[color="#000000"]修饰符。加上[color="#000000"]final[color="#000000"]的方法将不能被其子类重写[color="#000000"](override)[color="#000000"],而加上[color="#000000"]final[color="#000000"]的类就不能再被继承[color="#000000"]([color="#000000"]故此不需为其成员加上[color="#000000"]final)[color="#000000"]。请看下例:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo [color="#007700"]{
final
[color="#007700"]function [color="#0000bb"]foobar()
{
//
...
[color="#007700"]}
}
final
[color="#007700"]class Bar
[color="#007700"]{
//
class definition
[color="#007700"]}
//
the next line is wrong
// class NewBar
extends Bar {}
[color="#0000bb"]?>
2.6
[color="#000000"]使用[color="#000000"]const[color="#000000"]修饰符表示常数[color="#000000"]
PHP5[color="#000000"]加入支持在类内定义常数[color="#000000"](Constant)[color="#000000"],定义及调用方法如下:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Foo {
const
[color="#0000bb"]myname =
[color="#dd0000"]"itZone";
function
[color="#0000bb"]showmsg[color="#007700"](){
//
Access directly inside
class
[color="#007700"]echo([color="#0000bb"]myname[color="#007700"]);
}
}
//
Access like static variable outside class
[color="#007700"]echo("Foo::constant
= " [color="#007700"]. [color="#0000bb"]Foo[color="#007700"]::constant
[color="#007700"]. [color="#dd0000"]"\n"[color="#007700"]);
[color="#0000bb"]?>
2.7
[color="#000000"]界面
Interface
[color="#000000"]有些如[color="#000000"]C++[color="#000000"]和[color="#000000"]Eiffel[color="#000000"]这些[color="#000000"]OO[color="#000000"]语言支持多重继承(Multiple
Inheritance)[color="#000000"],虽然可使继承更具力量,但却会使Class
Hierarchy[color="#000000"]变得混乱起来。[color="#000000"]PHP5[color="#000000"]并不支持多重继承,取而代之的是和[color="#000000"]Java[color="#000000"]一样支持接口[color="#000000"](Interface)[color="#000000"]。接口有点像类,但却没有实体[color="#000000"](implementation)[color="#000000"],它只定义一个类的接口,并要求实现[color="#000000"](implement)[color="#000000"]这接口的类补上它的实体。这样的好处是既可以支持单一继承,又可以达到和多重继承差不多的效果。一个类可以实现多个接口,也可同时继承一个类,但接口不能有成员变量。请参考以下的简单例子
(php5.chp1.2.7.phps)[color="#000000"]及其运行结果
(php5.chp1.2.7.php)[color="#000000"]:[color="#000000"]
[color="#0000bb"]class
[color="#0000bb"]Human {
function
[color="#0000bb"]sayWord[color="#007700"](){
echo("
I am Human......
"[color="#007700"]);
}
}
interface
Dad [color="#007700"]{
//
The next line is wrong!
//
private $num;
function
[color="#0000bb"]paint[color="#007700"]([color="#0000bb"]$just_param[color="#007700"]);
}
interface
Mum {
function
[color="#0000bb"]cook[color="#007700"]();
}
//
Each class can extend 0 or 1 class, and can implement 0 or more
interfaces
class
[color="#0000bb"]Son extends
[color="#0000bb"]Human implements Dad,
[color="#0000bb"]Mum {
function
[color="#0000bb"]paint[color="#007700"]([color="#0000bb"]$just_param)
{
echo([color="#0000bb"]$just_param[color="#007700"]);
echo("
Dad teaches me to paint!
");
}
function
[color="#0000bb"]cook()
{
echo("
Mum teaches me to cook!
"[color="#007700"]);
}
}
$obj
= new
[color="#0000bb"]Son[color="#007700"]();
[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]sayWord[color="#007700"]();
[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]paint[color="#007700"]([color="#dd0000"]"Hi"[color="#007700"]);
[color="#0000bb"]$obj[color="#007700"]->[color="#0000bb"]cook[color="#007700"]();
[color="#0000bb"]?>
[color="#000000"]
后续..................PHP新功能初探系列二
[color="#000000"]
相关阅读 更多 +
排行榜 更多 +