
尽管开发和运行环境已经是php5了,但是一直没有使用php5的OO特性写代码。现在终于有机会拿着研究C++ OOP的精神,研究PHP5的OO特性。本文设计到一些细节,有些代码仅仅为了测试,有意为之,不要见笑。
- This 伪变量。
从PHP手册中看到这样一句话,一开始有些不理解。
|
$this 是一个到调用对象(通常是方法所属于的对象,但也可以是另一个对象,如果该方法是从第二个对象内静态调用的话)的引用。
源文档 <http://php.chinaunix.net/manual/zh/language.oop5.basic.php> |
于是做了这样的例子:
<?php |
发现在ClassA里面直接以ClassB::foo();的形式“静态调用”,ClassB::foo();里面的this的确是对象$A的引用。
注意是“静态调用(called statically)”而非静态方法。经过测试,静态方法内不允许this伪变量。
-
Extends
上面的特性-- 在方法被静态调用的上下文环境中,this是调用者的引用,这个特性可以应用到多级继承时,提供子类访问基类的途径:
<?php
class BaseClass
{
// Redefine the parent method
public final $abc = "Base";
function displayVar()
{
echo "this->abc:".$this->abc."\n";
echo "Base class\n";
parent::displayVar();
}
}
class SimpleClass extends BaseClass
{
public $abc = "SimpleClass";
// Redefine the parent method
function displayVar()
{
echo "this->abc:".$this->abc."\n";
echo "SimpleClass class\n";
}
}
class ExtendClass extends SimpleClass
{
public $abc = "ExtendClass";
// Redefine the parent method
function displayVar()
{
echo "this->abc:".$this->abc."\n";
echo "Extending class\n";
parent::displayVar();
BaseClass::displayVar();
}
}
$extended = new ExtendClass();
$extended->displayVar();
?>
输出:./test_extends.php
this->abc:ExtendClass
Extending class
this->abc:ExtendClass
SimpleClass class
this->abc:ExtendClass
Base class
-
construct
PHP的__construct不是太严格,甚至允许$obj->__construct , 当然这也可能是为了兼容以前的代码。
但是下面的测试很意外,ClassA::__construct()的调用引起php croe dump了。
<?php
class ClassAAA{
function __construct()
{
echo "ClassA::__construct\n";
}
};
ClassAAA::__construct();
?>我的php版本:
php -v
PHP 5.2.1 (cli) (built: Apr 28 2007 15:27:26)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
-
destruct
从手册看到一句话:
注意: 试图在析构函数中抛出一个异常会导致致命错误。
源文档 <http://php.chinaunix.net/manual/zh/language.oop5.decon.php>
这是因为对象的析构时机依赖php的实际实现,可能在php销毁对象的时候,代码块已经不在我们的try catch控制中了。
对于我下面测试的这个版本,php在一个对象的引用计数为0时,立即调用析构函数进行销毁,所以有幸能捕获到析构函数内的异常。
但是手册里面的这个“注意”是对的,因为php没有明确定义析构函数执行的时机,所以我们不应该在析构函数中抛出异常。
<?php
class MyDestructableClass {
function __construct() {
print "In constructor\n";
$this->name = "MyDestructableClass";
}
function __destruct() {
print "Destroying " . $this->name . "\n";
throw new Exception("my error");
}
}
function abc(){
try{
try{
$obj = new MyDestructableClass();
//return $obj;
}
catch(Exception $e){
echo "abc::".$e->getMessage();
}
}
catch(Exception $e){echo "abc::".$e->getMessage();}
//echo("abc fun run\n");
}
try{
abc();
}
catch(Exception $e){
echo "main::".$e->getMessage();
}
try{
unset($r);
}
catch(Exception $e){
echo "main 2::".$e->getMessage();
}
?>
【未完待续】


