载入中
自定义HTML载入中... loading
细致学习php5的OO特性[1] [原创 2007-08-22 09:47:17]  删除... 
字体变小 字体变大

尽管开发和运行环境已经是php5了,但是一直没有使用php5的OO特性写代码。现在终于有机会拿着研究C++ OOP的精神,研究PHP5的OO特性。本文设计到一些细节,有些代码仅仅为了测试,有意为之,不要见笑。

  • This 伪变量。

从PHP手册中看到这样一句话,一开始有些不理解。

$this 是一个到调用对象(通常是方法所属于的对象,但也可以是另一个对象,如果该方法是从第二个对象内静态调用的话)的引用。

 

源文档 <http://php.chinaunix.net/manual/zh/language.oop5.basic.php>

于是做了这样的例子:

<?php
    
class ClassB{
        const 
NAME "Class B";
        public    
$a ClassB::NAME;
        public function 
foo(){
            echo 
$this->a.":: foo call\n";
            echo 
"'this' is a {$this->a} object\n";
        }
    };
    
    class 
ClassA{
    
        const    
NAME "class A";
        public    
$a ClassA::NAME;

        public function 
createB(){
            return new 
ClassB();
        }
        
        public  function 
foo(){
            echo 
$this->a.":: foo call\n";
            
            echo 
"\n\nCall a object function\n";
            
$this->createB()->foo();
            
            echo 
"\n\n function called statically \n";
            
ClassB::foo();

        }
    }

    
$A = new ClassA();
    
$A->foo();

?>

 

发现在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();
    }
    

?>

 

【未完待续】

 

分类: php/shell/other
票数:
什么是“我顶”?
点击数:    评论数:
本文章引用通告地址(TrackBack Ping URL)为:
本文章尚未被引用。
发表评论
大 名:
(不填写则显示为匿名者)
网 址:
(您的网址,可以不填)
标 题:
内 容:
请根据下图中的字符输入验证码:
(您的评论将有可能审核后才能发表)
和讯个人门户 v1.0 | 和讯部落 | 客服中心