在对象中定义方法并能访问这些方法,而不需要实例化对象。
将方法声明为static:
class Format {
public static function number($number, $decimals = 2, $decimal = '.',$thousand = ','){
return number_format($number, $decimals, $decimal, $thousand);
}
}
print Format::number(1234.567);
由于静态方法不需要对象实例,所以要使用类名而不是对象。不要在类名前加美元符($)。
静态方法不能用箭头(->)引用,而要用双冒号(::)引用,这会告诉PHP这个方法是静态的。所以在这个例子中,Format类的number()方法使用Format::number()来访问。
在定义了静态方法的类内部,要用self引用静态方法。不能在静态方法中引用$this,因为根本没有可以操作的$this。调用静态方法就像调用一个常规的函数。
self::总是引用定义这个方法的类,而不论方法是从这个类调用还是从它的一个子类调用。要改变这种行为,需要使用static::,如以下ORM示例中所示:
// 定义一个名为 Model 的基类
class Model {
// 定义一个静态方法 validateArgs,用于验证传入的参数
// 此方法被设计为在子类中重写,因此在这里抛出一个异常提示开发者
public static function validateArgs($args){
throw new Exception("You need to override this in a subclass!");
}
// 定义一个静态方法 find,用于查找或检索某些数据
// 此方法依赖于 validateArgs 方法来验证传入的参数是否有效
public static function find($args){// 调用当前类(或子类,如果此方法被子类调用)的 validateArgs 方法来验证参数// 如果 validateArgs 方法在子类中未被重写,将抛出异常static::validateArgs($args);// 获取调用 find 方法的实际类名(可能是 Model 或其子类)// 这里主要是为了演示,实际上并没有进行任何查找操作$class = get_called_class();// 注意:此代码段缺少返回或进一步处理数据的逻辑// 通常情况下,你会在这里添加代码来根据 $args 查找并返回数据
}
}
// 定义一个名为 Bicycle 的子类,继承自 Model
class Bicycle extends Model {
// 重写父类的 validateArgs 方法,以提供具体的验证逻辑
// 在这个例子中,我们简单地返回 true,表示任何参数都是有效的
// 在实际应用中,你应该在这里添加具体的验证逻辑
protected static function validateArgs($args){
return true;
}
}
PHP还有一个特性,称为静态属性。一个类的所有实例都拥有这些共同的属性。因此,静态属性相当于类命名空间中的全局变量。
使用静态属性的一个原因是可以在多个Database对象之间共享一个数据库连接。出于效率方面的原因,不要每次实例化Database时都创建数据库的一个新连接。
实际上,可以在第一次协商建立一个连接,然后对每个实例重用这个连接,如下所示:
class Database {
private static $dbh = NULL;
public function __construct($server, $username, $password){
if(self::$dbh == NULL){
self::$dbh = db_connect($server, $username, $password);
}else{
//重用现有的连接
}
}
}
$db = new Database('db.example.com', 'Web', 'jsd6w@2d');//完成大量查询
$db2 = new Database('db.example.com', 'Web', 'jsd6w@2d');//完成另外一些查询
类似于静态方法,静态属性也使用双冒号记法。要在类中引用一个静态属性,需要使用特殊前缀self。self对于静态属性和方法的作用就相当于$this对于实例化属性和方法的作用。
构造函数使用self::$dbh访问静态connection属性。实例化$db时,dbh仍设置为NULL,所以构造函数会调用dbconnect()来协商建立与数据库的一个新连接。
创建$db2时则不会这样做,因为dbh已经设置为数据库句柄。