PHP静态成员

在类成员定义的前面加上static关键字,此成员就被定义为静态成员,静态成员的特点是它属性于类,而不是某个对象。所以,我们也称静态成员为类成员,而相对应的,非静态成员则称为实例成员。

先看一个简单的示例。

class CTest  
{  
    public static num  = 0;     public static function getHex()     {         return strtoupper(dechex(self::num));  
    }  
}  

CTest::$num = 15;  
echo CTest::getHex();  // 显示F

在这个CTest类中,我们定义了静态变量num和静态方法getHex(),在此方法中,我们使用dechex()函数将静态变量num转换成十六进制字符串,而strtoupper()函数则是将字符串中的字母转换为大写形式。

请注意静态成员的访问形式:

  • 在类的内部,如getHex()函数中,我们使用self关键字表示所属的类,访问静态成员时使用“self::<成员>”的格式,请注意其中是两个冒号;如果我们在类的内部使用getHex()函数,则应该使用“self::getHex()”语句。
  • 在类的外部访问类的静态成员时,使用“<类名>::<成员>”的格式,如代码中的“CTest::$num”和“CTest::getHex()”语句。

如果把静态成员当成实例成员使用,就会产生错误,如下面的代码就是错误的。

$obj = new CTest();  
echo $obj->getHex();

此外,还有一点需要注意,在PHP中,静态和实例成员都不能同名。

单件模式

静态成员的主题就是“唯一”。无论创建多少类的实例,类的静态成员都是唯一的,根据这一特点,在开发中,我们可以将需要统一管理的资源定义为只能创建一个实例,而典型的应用就是设计模式中的“单件模式(Singleton Pattern)”。先看下面的代码。

class CSingleton  
{  
    private static singleton = null;     privateid = 0;  
    //  
    public static function getInstance()  
    {  
        if (self::singleton == null)         {             self::singleton = new CSingleton();  
        }  
        return self::singleton;     }     //     private function __construct()     {}     //     private function __clone()     {}     //     public function getId()     {         return ++this->id;  
    }  
}  

obj1 = CSingleton::getInstance();obj2 = CSingleton::getInstance();  
for (i=0;i<10; i++)  
{     echoobj1->getId(),'<br>';  
    echo $obj2->getId(),'<br>';  
}

先看CSingleton类的定义,实现单件的关键在于:

  • $singleton对象,即单件对象,它定义为私有静态成员,我们只能通过getInstance()方法来获取这个对象。
  • getInstance()方法,获取CSingleton类唯一实例的方法,同样被定义为静态成员;在这个方法中,如果$singleton对象为null则创建它,然后,返回这个对象
  • 构造函数和__clone()方法,它们都被定义为私有的,这样一来,你无法使用new关键创建CSingleton类的对象,也无法使用clone关键字复制一个新的对象。这样就进一步保证了$singleton对象是唯一的实例。
  • 最后是getId()方法,它是一实例方法,用于给出ID值,每次都会加一。请注意它的实现,我们使用了前加1运算,如果使用后加1,则相同功能的代码应该是:
public function getId()  
{  
    this->id++;     returnthis->id;  
}

再看单件的使用,我们得到一个CSingleton类的实例的唯一办法就是通过getInstance()方法;代码中,我们使用两个对象obj1和obj2分别获取CSingleton实例,但从运行的结果中,大家可以看到,显示的内容是从1到20的数值,也就是说,obj1和obj2对象实际上都是在引用CSingleton类中的$singleton对象,而不是在独立地工作。这就是一个基本的单件模式地应用,在项目中,单件的功能就是对唯一的资源进行统一的管理,避免资源出现分配混乱的问题。

__callStatic()方法

前面,我们讨论的__call()方法用于自动调用对象中没有定义过的实例方法,而对于类中没有定义的静态方法的自动调用,我们则需要使用__callStatic()方法。如下面的代码。

class CTest  
{  
    static function __callStatic(method,args)  
    {  
        return call_user_func_array(method,args);  
    }  
}  

function Add(arg1,arg2,arg3)  
{     return intval(arg1)+intval(arg2)+intval(arg3);  
}  

echo CTest::Add(1,2,3);  // 显示 6

__callStatic()方法必须被定义为静态(static)成员,而其它的应用方法则与__call()方法比较相似了,大家可以参考__call()多做测试以加深映像。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程