章 13. 类与对象

目录
继承
构造函数
::
parent
序列化对象 - 会话中的对象
魔术函数 __sleep__wakeup
构造函数中的引用
PHP 4 中对象的比较
PHP 5 中对象的比较

类是变量与作用于这些变量的函数的集合。使用下面的语法定义一个类:

<?php
class Cart
{
    var
$items;  // 购物车中的项目

    // 把 $num 个 $artnr 放入车中

    
function add_item ($artnr, $num)
    {
        
$this->items[$artnr] += $num;
    }

    
// 把 $num 个 $artnr 从车中取出

    
function remove_item ($artnr, $num)
    {
        if (
$this->items[$artnr] > $num) {
            
$this->items[$artnr] -= $num;
            return
true;
        } else {
            return
false;
        }
    }
}
?>

上面的例子定义了一个 Cart 类,这个类由购物车中的商品构成的数组和两个用于从购物车中添加和删除商品的函数组成。

警告

不能将一个类的定义放到多个文件中,或多个 PHP 块中。以下用法将不起作用:

<?php
class test {
?>
<?php
    function test() {
        print 'OK';
    }
}
?>

以下警告仅用于 PHP 4。

注意

名称 stdClass 已经被 Zend 使用并保留。您不能在您的 PHP 代码中定义名为 stdClass 的类。

注意

函数名 __sleep__wakeup 在 PHP 类中是魔术函数。除非想要与之联系的魔术功能,否则在任何类中都不能以此命名函数。

注意

PHP 将所有以 __ 开头的函数名保留为魔术函数。除非想要使用一些见于文档中的魔术功能,否则建议不要在 PHP 中将函数名以 __ 开头。

在 PHP 4 中,var 变量的值只能初始化为常量。用非常量值初始化变量,您需要一个初始化函数,该函数在对象被创建时自动被调用。这样一个函数被称之为构造函数(见下面)。

<?php
/* PHP 4 中不能这样用 */
class Cart
{
    var
$todays_date = date("Y-m-d");
    var
$name = $firstname;
    var
$owner = 'Fred ' . 'Jones';
    var
$items = array("VCR", "TV");
}

/* 应该这样进行 */
class Cart
{
    var
$todays_date;
    var
$name;
    var
$owner;
    var
$items;

    function
Cart()
    {
        
$this->todays_date = date("Y-m-d");
        
$this->name = $GLOBALS['firstname'];
        
/* etc. . . */
    
}
}
?>

类也是一种类型,就是说,它们是实际变量的蓝图。必须用 new 运算符来创建相应类型的变量。

<?php
$cart
= new Cart;
$cart->add_item("10", 1);

$another_cart = new Cart;
$another_cart->add_item("0815", 3);
?>

上述代码创建了两个 Cart 类的对象 $cart$another_cart,对象 $cart 的方法 add_item() 被调用时,添加了 1 件 10 号商品。对于对象 $another_cart,3 件 0815 号商品被添加到购物车中。

$cart$another_cart 都有方法 add_item(),remove_item() 和一个 items 变量。它们都是明显的函数和变量。你可以把它们当作文件系统中的某些类似目录的东西来考虑。在文件系统中,你可以拥有两个不同的 README.TXT 文件,只要不在相同的目录中。正如从为了根目录访问每个文件你需要输入该文件的完整的路径名一样,你必须指定需要调用的函数的完整名称:在 PHP 术语中,根目录将是全局名称空间,路径名符号将是 ->。因而,名称 $cart->items$another_cart->items 命名了两个不同的变量。注意变量名为 $cart->items,不是 $cart->$items,那是因为在 PHP 中一个变量名只有一个单独的美元符号。

<?php
// 正确,只有一个 $
$cart->items = array("10" => 1);

// 不正确,因为 $cart->$items 变成了 $cart->""
$cart->$items = array("10" => 1);

// 正确,但可能不是想要的结果:
// $cart->$myvar 变成了 $cart->items
$myvar = 'items';
$cart->$myvar = array("10" => 1);
?>

在一个类的定义内部,你无法得知使用何种名称的对象是可以访问的:在编写 Cart 类时,并不知道之后对象的名称将会命名为 $cart 或者 $another_cart。因而你不能在类中使用 $cart->items。然而为了类定义的内部访问自身的函数和变量,可以使用伪变量 $this 来达到这个目的。$this 变量可以理解为“我自己的”或者“当前对象”。因而 '$this->>items[$artnr] += $num' 可以理解为“我自己的物品数组的 $artnr 计数器加 $num”或者“在当前对象的物品数组的 $artnr 计数器加 $num”。

注: 有一些不错的函数用来处理类和对象。你应该关注一下类/对象函数库