|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
不懂的问题有很多高手帮你解决。但不要认为你是新手,就不能帮助别人,比如今天你学会了怎样安装PHP,明天还可能有朋友会问这个问题,你就可以给他解答,不要认为这是浪费时间,忙别人其实就是帮助自己。php5|对象 Php5.0申明 ------为面向对象而生的php5
为面向对象而生的PHP5
---------------------------------------------
[摘要]今朝开辟中的PHP5,其面向对象的性能已被大幅度的强化了。下一代的PHP将会是如何的一种言语呢?上面咱们来具体解说一下今朝宣布的PHP5的beta release。
(一) Zend 2.0的出生
如今的PHP4所利用的根基文法是被称之为Zend 引擎的剧本编译引擎。这个就是PHP4的优秀性能的缘由之一,是作为对PHP3的改善而生成的一种言语。人人一向以为,PHP4的功能依据现在的方针,比PHP3有了很大的提拔,在收集编程的世界里占有了很大的份额。
开辟了Zend 引擎的Zend公司是在开辟PHP4的同时,由PHP3的次要开辟者Zeev Suraski和Andi Gutmans所创建的企业兼并而来的。Zend的称号是由Zeev和Andi的名字合起来构成的。Zend公司的贸易形式是,延续不休的为open source供应zend 引擎的PHP内核 (core),同时提拔周边产物开辟和销售的好处。以open source software作为基盘的贸易,活着界局限内大多半正在苦战的企业中,算是对照好的典范例子了。
■PHP4的局限
托PHP4胜利的福,这个用处的合用局限逐步变广起来。作为企业级的用处而利用PHP的说法时有所闻。因而,就有了如许一个成绩,修建大范围网站的时分,代码的再使用性非常差。详细来讲就是,PHP4的面向对象功能很弱,因而习气于利用Java等的手艺人员对此有良多的埋怨。
慢慢的改良PHP4的面向对象的功能,大幅度的更改根基文法,开辟者告竣了更新PHP记叙办法的开辟目标。
■Zend 2.0入手下手开辟
随后,Zend公司PHP中间的开辟者们在2001年7月宣布了作为下一代PHP言语引擎的Zend 2.0引擎的构思。以[Zend Engine version 2.0: Feature Overview and Design]
(http://www.zend.com/engine2/ZendEngine-2.0.pdf)作为方针的同时,面向对象的功能大幅度的强化了。
今朝的PHP4 Zend 引擎的扩大情形与往日的PHP3千篇一律。这就意味着,要提拔新的言语引擎的主版本号,明白办法方针,迎接来自开辟整体的夸奖。
Ze2的开辟,与以往的Zend引擎一样,都是运转在open source的形式下的。最新的源代码在CVS上被周全的公然,由于是面向开放的开辟者的,关于开辟的群情十分的活泼。
如今Ze2被决意采取于PHP的下一个版本PHP5中。终究宣布的工夫如今还不决,然而假设依据Zend公司2003年4月1日宣布的Newsletter的话,如今的应当就是Beta Release了。
(二) PHP5的新特征
接上去请依照按次看一下被强化的PHP5的功能。起首是最为主要的面向对象功能,类的实体特征在大幅度的被修正着。这里说的仅是关于类的新特征。
・ 对象的参照过渡是默许的(default)
・ 引入会见属性的限制
・ 引入会见办法的限制
・ 笼统类和笼统办法
・ 接口
・ final声明
・ 名空间
・ 类内常量
・ 类变量
・ 一致构建器
・ 析构函数(Distructor)
・ 其他从属特征
以上内容是依据2003年4月22日CVS上登录版本材料所写的,在正式的宣布之前,也有变化的能够性。
■对象的默许参照过渡
在PHP4中,在以变量$var1为类的实体对象的时分,假如$var2 = $var1;那末,在$var2中,$var1的复制被代入。分明的,$var2为了指向与$var1不异的对象,就要写成$var2 =& $var1,必需要加上&作为参照。
而在PHP5,对象的代入将成为主动的参照过渡。也就是说,
$var2=$var1,二者指向不异的对象。假如想要同php4一样,带入copy,那末就会应用到导入__clone()的办法。
$var2 = $var1->__clone();此处,clone后面是两个一连的“_”
(这仅仅是类的实体的特征)
■引入会见属性的限制
在PHP4的类中,连同属性和办法在内,可以自在的会见类的表里任何中央,而没无限制。因而,用户就没法提防属性的有意中的更改。
而在PHP5中,同C++和Java一样,导入了private, protected, public三个品级的会见限制,使得类的设计者可以对属性和办法的利用办法停止限制。以下是各类会见限制的意思。
・ Public: 可以自在的在类的表里任何中央停止参照、变动
・ Private: 只能在这个类的办法中停止参照、变动
・ Protected:可以在这个类和承继了这个类的另外一个类的办法中停止参照、变动。别的,在承继的类中,可以写入会见指定。
在PHP4中的“var”,同以往一样与public有着不异的意思。上面就来举一个例子,让咱们来看看会见限制是如何起感化的。
PHP代码:--------------------------------------------------------------------------------
class Hoge1 {
private $var1 = 'A';
protected $var2 = 'B';
protected $var3 = 'C';
function setLower() {
$this->var1 = 'a';
$this->var2 = 'b';
$this->var3 = 'c';
}
function var1() {
return $this->var1;
}
function var2() {
return $this->var2;
}
function var3() {
return $this->var3;
}
}
--------------------------------------------------------------------------------
在这个类中,带有$var1, $var2, $var3三个属性。$var1被声明为private, $var2和$var3是protected.在此处
PHP代码:--------------------------------------------------------------------------------
$hoge=new Hoge1;
echo’var1:’.$hoge->var1.”
n”
--------------------------------------------------------------------------------
假如测验考试参照不答应从内部停止会见的private属性,那末就会呈现以下毛病:
Fatal error: Cannot access private property hoge1::$var1 in /path/to/script.php on line XX
关于protected的$var2也是不异的。
然而,由于$hoge的办法是没有private和protected的,所以上面的代码可以正常运作,前往外部公有和回护变量的值。
PHP代码:--------------------------------------------------------------------------------
echo 'var1: ' . $hoge->var1() . "
\n"; // var1: A
echo 'var2: ' . $hoge->var2() . "
\n"; // var2: B
echo 'var3: ' . $hoge->var3() . "
\n"; // var3: C
$hoge->setLower();
echo 'var1: ' . $hoge->var1() . "
\n"; // var1: a
echo 'var2: ' . $hoge->var2() . "
\n"; // var2: b
echo 'var3: ' . $hoge->var3() . "
\n"; // var3: c
--------------------------------------------------------------------------------
其次,为了可以看到protected的属性的形态,咱们试着发明了承继了Hoge1的类Hoge2
PHP代码:--------------------------------------------------------------------------------
class Hoge2 extends Hoge1 {
public $var3 = '3';
function d_var1() {
return $this->var1;
}
function d_var2() {
return $this->var2;
}
function d_var3() {
return $this->var3;
}
}
--------------------------------------------------------------------------------
在类Hoge2中,只要$var3被声明为public。在属性是protected的情形下,从子类停止会见有何种限制,是由子类的属性声明决意的。在Hoge2中,由于$var3被声明是public,因而不管是从何处都可以会见Hoge2的$var3(实体是Hoge1的$var3)。由于$var1在Hoge1中是private,因而,在Hoge2子类中Hoge1的$var1不会被承继,而在Hoge2中有能够会做知名为$var1的属性,因而,必需要明白辨别Hoge1::$var1和Hoge2::$var1。
PHP代码:--------------------------------------------------------------------------------
$hoge = new Hoge2;
echo 'var1: ' . $hoge->var1 . "
\n"; // var1:
// echo 'var2: ' . $hoge->var2 . "
\n"; // Error
echo 'var3: ' . $hoge->var3 . "
\n"; // var3: 3
echo 'var1: ' . $hoge->d_var1() . "
\n"; // var1:
echo 'var2: ' . $hoge->d_var2() . "
\n"; // var2: B
echo 'var3: ' . $hoge->d_var3() . "
\n"; // var3: 3
--------------------------------------------------------------------------------
$hoge->var1是与Hoge1::var1没有关系的变量,因而不会有任何显示,由于var2有protected会见限制,所以假如欠亨过method就直接参照$var2,就会呈现致命毛病。
■引入会见办法的限制
与上述不异,此处也分为private, protected, public三种。
・ Public: 可以从任何中央挪用
・ Private: 只可以从这个类的method内挪用
・ Protected: 只可以从这个类和subclass的method中挪用
此处的意思同Java和C++不异,请不要弄混。
■笼统(abstract)的类和笼统的办法
撑持与Java不异的笼统类和笼统办法。笼统办法只供应了办法名的挪用体例,而没有供应实体。别的,持有笼统办法的类,必需笼统宣言类自己。假如想要直接作成笼统类的对象,那末就会呈现以下的致命毛病。
Fatal error: Cannot instantiate abstract class ClassName
发生毛病的实践的例子以下所示:
PHP代码:--------------------------------------------------------------------------------
abstract class MyAbstract {
abstract public function test();
public function test2() {
echo "MyAbstract::test2() called.
\n";
}
}
class MyImplement extends MyAbstract {
public function test() {
echo "MyImplement::test() called.
\n";
}
}
$obj = new MyImplement;
$obj->test();
?>
--------------------------------------------------------------------------------
■接口(interface)
撑持与Java不异的接口(interface)。接口是合适所描写的内部挪用模式而设计组合起来的。
接口的实体不克不及够纪录。相反的,完成接口的类必需持有与这个接口的办法绝对应的实体。别的,类可以完成多个接口,因而,有能够完成多重承继。
PHP代码:--------------------------------------------------------------------------------
interface Throwable {
public function getMessage();
}
interface Serializable {
public function toString();
}
class MyException implements Throwable, Serializable {
public function getMessage() {
return 'this is MyException message';
}
public function toString() {
return 'MyException: this is MyException message';
}
}
$e = new MyException;
echo $e->getMessage();
echo $e->toString();
?>
--------------------------------------------------------------------------------
■final声明
同Java一样,PHP5撑持final声明。假如关于一个办法追加final声明,这个办法将一定在子类不克不及重载(Override)。假如办法被final声了然,然而还在子类中重载,就会呈现以下毛病:
PHP代码:--------------------------------------------------------------------------------
Fatal error: Cannot override final method fuga::foo()
--------------------------------------------------------------------------------
发生毛病的例子:
PHP代码:--------------------------------------------------------------------------------
class Fuga {
final function foo() {
echo "this is final function\n";
}
}
class Hoge extends Fuga {
function foo() {
echo "this is not final function\n";
}
}
?>
--------------------------------------------------------------------------------
(三) PHP5的新特征(续)
PHP5的宣布企图
在后面的文章中咱们提到,“依据ZEND公司2003年4月1日宣布的讯息的话,如今的应当就是Beta Release了”,然而开辟者外部会商的了局是,Beta为时髦早,并且有能够不是Beta Release.
对这方面意向有乐趣的可以参照 news://news.php.net/ 上所发布的信息 php.version5.dev:372
在这个文件中,PHP5的宣布企图又从头回到了一张白纸,而另外一方面,Zend Engine2的开辟正在着手停止中。PHP5的Release其实大体就是企望着“快点到年关吧”。
PHP5的新特征
接着咱们来看一下在后面所讲到的其他一些关于类的新增的性能
■名空间
PHP5撑持名空间。因而,咱们可以在名空间内装入类、变量、常量、函数。
在PHP4的Scope中,只要global、函数内、类内这三个品种,所以要出格注重假如不注重的话,将会很轻易“净化”global空间。假设利用名空间的话咱们就可以够在package里分别变量定名空间,因而应当就可以对照轻易的做成自力的package。
利用实例以下:
PHP代码:--------------------------------------------------------------------------------
namespace This {
class Hoge {
}
const aConstant = 'This Constant';
function aFunction() {}
var $aVariable = 'This Variable';
}
$obj = new This::Hoge;
echo This::aConstant . "
\n";
This::aFunction();
echo This::$aVariable . "
\n";
--------------------------------------------------------------------------------
假定要会见名空间内的对象的话,就应当如许做:
名空间名::对象名
然而PHP5的名空间不会套入与C++相异的模样。
■Class内常量
利用关头字const,可以在类、名空间内界说常量。这里由于是常量,因而必定要在常量名的后面加上$。Class内的常量,比这个类中的global常量的优先级要高。
在这里const是预定语,因而在class名和函数名中利用const的时分要做需要的修改。
PHP代码:--------------------------------------------------------------------------------
define('constant_value', 'global constant');
class MyClass {
const constant_value = 'class constant';
function printConstant() {
print constant_value;
}
}
echo MyClass::constant_value . "
\n";
MyClass:rintConstant();
?>
--------------------------------------------------------------------------------
在这个例子里,MyClass:rintConstant()是显示常量constant_value的值,然而,constant_value存在于global空间和Class内这两个中央。在这类情形下,MyClass内的常量constant_value的优先级较高,被显示为「class constant」。
■对象变量
即便是在类没有被实例化形态下,对象变量也能正确的依照指定的值被初始化。会见的办法以下:
类名::$变量名
PHP代码:--------------------------------------------------------------------------------
class Hoge {
static $my_static = 5;
}
print Hoge::$my_static;
?>
--------------------------------------------------------------------------------
■一致构建器
在生成对象的时分,可以主动被挪用的办法被称作“构建器”。
PHP4中的构建器,是与Class名不异的办法名。这是与Java和C++不异的中央,因而,关于一些用惯了的人来讲,不会有别扭感。然而,假如要从子类中挪用父类的构建器的话,在PHP中就必需特地写上父类的名字。
在PHP中,父类的构建器不克不及被主动挪用,因而,情形就对照多。
在PHP5中,一致采取了__constructor这个构建器称号,不论class名是甚么,但凡被称为__construct()的,都被看成构建器来处置。
别的,思索到同PHP4的交换性,假设存在于Class名不异的之前的构建器名,那末,优先利用谁人构建器。
PHP代码:--------------------------------------------------------------------------------
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
}
$obj = new BaseClass();
$obj = new SubClass();
?>
--------------------------------------------------------------------------------
■析构函数
与构建器相反,可以在对象释放时主动被挪用的办法被称为析构函数。
PHP4撑持析构函数,经由过程登录在PHP运转终止时用register_shutdown_function()挪用的函数,只要相似的实施办法。PHP5正式撑持析构函数,可以在类中指定对象释放时的举措。
析构函数就是名为__destruct的办法。当对象外部的参照计数器酿成0的时分,__destruct()被挪用,然后对象所利用的内存被释放出来。
PHP代码:--------------------------------------------------------------------------------
class MyDestructableClass {
function __construct() {
print "In constructor\n";
$this->name = 'MyDestructableClass';
}
function __destruct() {
print 'Destroying ' . $this->name . "\n";
}
}
$obj = new MyDestructableClass();
?>
--------------------------------------------------------------------------------
别的,与构建器不异的中央是,父类的析构函数不克不及被主动的挪用,需要的时分,需求用号令:
parent::__destruct();
■会见
在PHP4中,假如会见了一个不存在的属性,那末体系就会主动生成与之绝对应的新属性。
PHP代码:--------------------------------------------------------------------------------
class Hoge {
}
$obj = new Hoge;
$obj->prop = "This is new property";
--------------------------------------------------------------------------------
如上所示,当把值代入一个不存在的属性时,谁人代入点就会主动生成一个新属性。一样的,会见一个不存在的属性,就好像被代入NULL值的变量一样,不会产生毛病。
在PHP5中追加了一点,就是可以对会见恣意的属性停止掌握。在类中假如存在__set()、__get()如许的办法,替换上述的举措此处的办法将可以被挪用。例如:
PHP代码:--------------------------------------------------------------------------------
class Hoge {
function __set($name, $value) {
print "__set() is called with ($name, $value)\n";
$this->$name = $value;
}
}
$obj = new Hoge;
$obj->a = '123';
$obj->a = '456';
$obj->b = '789';
?>
--------------------------------------------------------------------------------
在这里,__set 办法被作为不决义属性的代入办法,在显示值以后将值代入不决义属性。
PHP代码:--------------------------------------------------------------------------------
$obj->a = '123';
--------------------------------------------------------------------------------
履行这一句时,由于在这个时分不存在属性a,因而,作为取代,__set 办法被挪用。
__set() is called with (a, 123)
其次,
$obj->a = '456';
再一次的代入$obj->a,这一次,因为属性a已存在,所以__set 没有被挪用,和凡是一样把值代入到了属性a中去了。
$obj->b = '789';
这一回,咱们把值代入另外一个属性b中,同a的第一次情形一样,
__set() is called with (b, 789)
同__set 办法相反,__get 办法是在对不存在的属性的援用时挪用的。将这二者联合起来,再来看一下关于属性的会见,实践上,使用它可以写出在分歧的场所都能做出分歧呼应的类来。
PHP代码:--------------------------------------------------------------------------------
class Hoge {
public $properties;
function __set($name, $value) {
$this->properties[$name] = $value;
}
function __get($name) {
return $this->properties[$name];
}
}
$obj = new Hoge;
$obj->a = '123';
$obj->b = '456';
echo $obj->a;
echo $obj->b;
print_r($obj);
?>
--------------------------------------------------------------------------------
在这个例子里,对类中一切属性的会见被装入了$properties中,如许,使咱们到场的属性不直接的附在对象之下。这是个不太能轻易了解的例子,例如,试着把这个例子中的保留到$properties改成存入文件或是数据库会很风趣吧。实践上,在对象外面,咱们可以复杂的完成让很多的庞杂的操作。
与__set, __get几何有些分歧,然而__call也能用来书写不存在的办法,当咱们向以下例子一样挪用对象的办法的时分,
$object->methodname();
假如这个类中不存在methodname这个办法,凡是情形下,就会呈现以下毛病:
Fatal error: Call to undefined method Class::methodname()
然而,假如这个类中存在__call这个办法,作为替换,__call就被挪用。__call的参数有两个,第一个参数是被叫出的办法名,第二个参数是坚持了的被挪用的参数的数组。思索到有良多的利用办法,除以下的例子外,还可使用其它的办法。
PHP代码:--------------------------------------------------------------------------------
class Proxy {
private $object;
function __call($name, $params) {
if (isset($this->object)) {
if (method_exists($this->object, $name)) {
return call_user_func_array(array($this->object, $name), $params);
}
else {
return "method not exists.";
}
}
}
function __construct($object) {
$this->object = $object;
}
}
class Hoge {
function add($var1, $var2) {
return $var1 + $var2;
}
}
$p = new Proxy(new Hoge);
$result = $p->add(1, 2);
echo "result: $result
\n";
$result = $p->sub(5, 3);
echo "result: $result
\n";
?>
全新的对象模子
PHP中的对象处置局部已完整重写,具有更佳的功能和更多的功效。在PHP的之前版本中,对象与内建变量类型(如integer和string)的处置办法不异,其坏处是当变量被赋值为对象或对象作为参数传递时,失掉的是对象复成品。而在新版本中,对象经由过程句柄停止援用,而不是经由过程它的值。(句柄可以认是为是对象的标识符)
良多PHP法式员能够未意想到之前的对象模子的“复制怪癖”,因而之前的PHP法式将不需求做任何更改,或只做很小的修改便可运转
公有和回护成员
PHP 5引入了公有和回护成员变量,它们可以界说类属性在什么时候可以被会见。
例
类的回护成员变量能在该类的扩大类中被会见,而公有成员变量只能在本类中被会见。
class MyClass {
private $Hello = "Hello, World!\n";
protected $Bar = "Hello, Foo!\n";
protected $Foo = "Hello, Bar!\n";
function printHello() {
print "MyClass::printHello() " . $this->Hello;
print "MyClass::printHello() " . $this->Bar;
print "MyClass::printHello() " . $this->Foo;
}
}
class MyClass2 extends MyClass {
protected $Foo;
function printHello() {
MyClass::printHello(); /* Should print */
print "MyClass2::printHello() " . $this->Hello; /* Shouldn't print out anything */
print "MyClass2::printHello() " . $this->Bar; /* Shouldn't print (not declared)*/
print "MyClass2::printHello() " . $this->Foo; /* Should print */
}
}
$obj = new MyClass();
print $obj->Hello; /* Shouldn't print out anything */
print $obj->Bar; /* Shouldn't print out anything */
print $obj->Foo; /* Shouldn't print out anything */
$obj->printHello(); /* Should print */
$obj = new MyClass2();
print $obj->Hello; /* Shouldn't print out anything */
print $obj->Bar; /* Shouldn't print out anything */
print $obj->Foo; /* Shouldn't print out anything */
$obj->printHello();
?>
公有和回护办法
在PHP 5(ZEND引擎2)中,还引入了公有和回护办法。
例:
class Foo {
private function aPrivateMethod() {
echo "Foo::aPrivateMethod() called.\n";
}
protected function aProtectedMethod() {
echo "Foo::aProtectedMethod() called.\n";
$this->aPrivateMethod();
}
}
class Bar extends Foo {
public function aPublicMethod() {
echo "Bar::aPublicMethod() called.\n";
$this->aProtectedMethod();
}
}
$o = new Bar;
$o->aPublicMethod();
?>
之前代码中的用户自界说类或办法中虽不决义"public," "protected" 或 "private"等关头字,但无需编纂便可运转。
笼统类和办法
PHP 5还引入了笼统类和办法。笼统办法只声明办法界说, 不供实践运转。包括笼统办法的类需求声明为笼统类。
例:
abstract class AbstractClass {
abstract public function test();
}
class ImplementedClass extends AbstractClass {
public function test() {
echo "ImplementedClass::test() called.\n";
}
}
$o = new ImplementedClass;
$o->test();
?>
笼统类不克不及实例化。之前代码中的用户自界说类或办法中虽不决义"abstract”关头字,但无需编纂便可运转。
接口
ZEND引擎2.0引入了接口。一个类可以运转恣意的接口列表。
Example
例:
interface Throwable {
public function getMessage();
}
class Exception implements Throwable {
public function getMessage() {
// ...
}
?>
之前代码中的用户自界说类或办法中虽不决义"interface”关头字,但无需编纂便可运转。
类类型界说
在保存类无需界说类型的同时,PHP 5引入了类类型界说来声明但愿把哪一个类经由过程参数传递给一个办法。
Example
例:
interface Foo {
function a(Foo $foo);
}
interface Bar {
function b(Bar $bar);
}
class FooBar implements Foo, Bar {
function a(Foo $foo) {
// ...
}
function b(Bar $bar) {
// ...
}
}
$a = new FooBar;
$b = new FooBar;
$a->a($b);
$a->b($b);
?>
这些类类型界说在不象一些需求类型预界说的言语在编译中停止反省,而是在运转时停止。这意味着:
function foo(ClassName $object) {
// ...
}
?>
等价于:
function foo($object) {
if (!($object instanceof ClassName)) {
die("Argument 1 must be an instance of ClassName");
}
}
?>
本语法只用于对象或类,不合用于内建类型。
final
PHP 5引入了“final”关头字界说在子类中不克不及被掩盖的成员或办法。
例:
class Foo {
final function bar() {
// ...
}
}
?>
之前代码中的用户自界说类或办法中虽不决义"final"关头字,但无需编纂便可运转。
对象克隆
PHP 4在对象被复制时,用户不克不及决意拷贝的机制。在复制时,PHP 4只一名一名地复制一个和本来对象如出一辙的复成品。
咱们并非每次都要创立一个完整一样的复成品。一个很好的需求一种复制机制的例子是,当有一个代表一个GTK窗口的对象,它具有该窗口的一切资本,当你创立一个拷贝时,你能够需求一个新的窗口,它具有原窗口的一切属性,但需求具有新窗口的资本。别的一个例子是你有一个对象援用了别的一个对象,当你复制父对象时,你但愿创立谁人援用对象的新实例,以使复成品援用它。
对一个对象的拷贝经由过程挪用对象的__clone()办法完成:
$copy_of_object = $object->__clone();
?>
当开辟者恳求创立一个对象的新的拷贝时,ZEND引擎会反省是不是界说了__clone()办法。假如不决义的话,它会挪用一个默许的__clone()办法来复制该对象的一切属性。假如界说了该办法,该办法会担任在拷贝中设置需要的属性。为便利起见,引擎会供应一个函数从源对象中导入一切的属性,如许它就能够先失掉一个具有值的源对象拷贝,只需求对需求改动的属性停止掩盖便可。
例:
class MyCloneable {
static $id = 0;
function MyCloneable() {
$this->id = self::$id++;
}
function __clone() {
$this->name = $that->name;
$this->address = "New York";
$this->id = self::$id++;
}
}
$obj = new MyCloneable();
$obj->name = "Hello";
$obj->address = "Tel-Aviv";
print $obj->id . "\n";
$obj = $obj->__clone();
print $obj->id . "\n";
print $obj->name . "\n";
print $obj->address . "\n";
?>
一致的机关办法名
ZEND引擎答应开辟者界说类的机关办法。具有机关办法的类在新建时会起首挪用机关办法,机关办法合用于在正式利用该类行进行的初始化。
在PHP4中,机关办法的称号与类名不异。因为在派生类中挪用父类的作法对照广泛,因而招致在PHP4中当类在一个大型的类承继中停止挪动时,处置体例有点愚笨。当一个派生类被挪动到一个分歧的父类中时,父类的机关办法名必定是分歧的,如许的话派生类中的有关挪用父类机关办法的语句需求改写。
PHP 5 introduces a standard way of declaring constructor methods by calling them by the name __construct().
PHP5引入了办法名__construct()来界说机关办法。
Example
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
}
$obj = new BaseClass();
$obj = new SubClass();
?>
为向下兼容,PHP5当在类不克不及找到__construct()办法时,会经由过程老的办法也就是类名来查找机关办法。这意味着独一能够发生兼容性成绩的是在之前的代码中已利用了一个名为__construct()的办法名。
析构办法
界说析构办法是非常有效的。析构办法可以纪录调试信息,封闭数据库毗连,还有做其它的收尾任务。PHP4中并没有此机制,虽然PHP已撑持注册在恳求停止时需求运转的函数。
PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as Java: When the last reference to an object is destroyed the object's destructor, which is a class method name %__destruct()% that recieves no parameters, is called before the object is freed from memory.
PHP5引入了与其它面向对象言语如Java言语类似的析构办法:当最初一个该对象的援用被排除时,体系将会在该对象从内存中释放前挪用名为__destruct()的析构办法。
例:
class MyDestructableClass {
function __construct() {
print "In constructor\n";
$this->name = "MyDestructableClass";
}
function __destruct() {
print "Destroying " . $this->name . "\n";
}
}
$obj = new MyDestructableClass();
?>
和机关办法类似,引擎将不挪用父类的析构办法,为挪用该办法,你需求在子类的析构办法中经由过程parent::__destruct()语句停止挪用。
常量
PHP 5 引入了类常量界说:
class Foo {
const constant = "constant";
}
echo "Foo::constant = " . Foo::constant . "\n";
?>
PHP5答应常量中有表达式,但在编译经常量中的表达式将被盘算.,因而常量不克不及在运转中改动它的值。
class Bar {
const a = 1<<0;
const b = 1<<1;
const c = a | b;
}
?>
之前代码中的用户自界说类或办法中虽不决义"const”关头字,但无需编纂便可运转。
破例
PHP 4 had no exception handling. PHP 5 introduces a exception model similar to that of other programming languages.
PHP4中无破例处置,PHP5援用了与其它言语类似的破例处置模子。
例:
class MyExceptionFoo extends Exception {
function __construct($exception) {
parent::__construct($exception);
}
}
try {
throw new MyExceptionFoo("Hello");
} catch (MyException $exception) {
print $exception->getMessage();
}
?>
之前代码中的用户自界说类或办法中虽不决义'catch', 'throw' 和 'try'关头字,但无需编纂便可运转。
函数前往对象值
In PHP 4 it wasn't possible to dereference objects returned by functions and make further method calls on those objects. With the advent of Zend Engine 2, the following is now possible:
在PHP4中,函数不成能前往对象的值并对前往的对象停止办法挪用,经由过程ZEND引擎2中,这一切变得能够:
class Circle {
function draw() {
print "Circle\n";
}
}
class Square {
function draw() {
print "Square\n";
}
}
function ShapeFactoryMethod($shape) {
switch ($shape) {
case "Circle":
return new Circle();
case "Square":
return new Square();
}
}
ShapeFactoryMethod("Circle")->draw();
ShapeFactoryMethod("Square")->draw();
?>
静态类中的静态成员变量如今可初始化
Example
class foo {
static $my_static = 5;
}
print foo::$my_static;
?>
静态办法
PHP5引入了关头字'static'来界说一个静态办法,如许可以从对象外停止挪用。
例:
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
?>
虚拟变量$this在静态办法中有效。
instanceof
PHP5引入了关头字instanceof来肯定一个对象是不是是某一个对象的实例,或某一个对象的派生,或利用了某一个接口。
例:
class baseClass { }
$a = new baseClass;
if ($a instanceof basicClass) {
echo "Hello World";
}
?>
静态函数变量
一切的静态变量如今在编译时停止处置,这答应开辟者经由过程援用来指定静态变量。这个变更进步了效力但意味着不成能对静态变量停止直接援用。
函数中经由过程按地址传送体例的参数答应界说默许值
例:
function my_function(&$var = null) {
if ($var === null) {
die("$var needs to have a value");
}
}
?>
__autoload()
在初始化一个不决义的类时,引擎将主动挪用__autoload()拦阻器函数。该类名将作为__autoload()拦阻器函数独一参数传递给它。
例:
function __autoload($className) {
include_once $className . ".php";
}
$object = new ClassName;
?>
办法和属性挪用的重载
通用 __call(), __get() 和 __set()办法可以停止办法和属性挪用的重载。
例: __get() 和 __set()
class Setter {
public $n;
public $x = array("a" => 1, "b" => 2, "c" => 3);
function __get($nm) {
print "Getting [$nm]\n";
if (isset($this->x[$nm])) {
$r = $this->x[$nm];
print "Returning: $r\n";
return $r;
} else {
print "Nothing!\n";
}
}
function __set($nm, $val) {
print "Setting [$nm] to $val\n";
if (isset($this->x[$nm])) {
$this->x[$nm] = $val;
print "OK!\n";
} else {
print "Not OK!\n";
}
}
}
$foo = new Setter();
$foo->n = 1;
$foo->a = 100;
$foo->a++;
$foo->z++;
var_dump($foo);
?>
例: __call()
class Caller {
var $x = array(1, 2, 3);
function __call($m, $a) {
print "Method $m called:\n";
var_dump($a);
return $this->x;
}
}
$foo = new Caller();
$a = $foo->test(1, "2", 3.4, true);
var_dump($a);
?>
到现在,对排版还是不很熟练,经常会排不好。 |
|