类
每个类的定义都以class关键字开头,后面跟着类名,后面跟着一对花括号,里面包含有类的属性与方法的定义。类名可以是PHP保留字以外的任何合法字符,类名应以字母或者下划线开头,后面跟着若干字母、数字或下划线。一个类可以有属于自己的常量、变量(属性)和函数(方法)。类中的方法调用时有一个可用的伪变量$this,$this是一个到主叫对象的引用,即该方法所从属的类的对象,PHP5中,如果是从第二个对象静态调用时,$this也可能引用的是另一个对象。PHP7中则没有此问题。
<?php
class A
{
function foo()
{
if (isset($this)) {
echo '$this is defined ('.get_class($this).")\n";
} else {
echo "\$this is not defined.\n";
}
}
}
class B
{
function bar()
{
A::foo();
}
}
$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>
以上代码在PHP5的运行结果如下:
$this is defined (A)
$this is not defined.
$this is defined (B)
$this is not defined.
在PHP7的运行结果如下:
$this is defined (A)
$this is not defined.
$this is not defined.
$this is not defined.
自PHP5起,class关键字还可以用于类名解析,通过className::class可以获得一个包含类名className的完全限定名的字符串。
<?php
namespace test{
class A{
public $var = 'a default value';
public function displayVar() {
echo $this->var;
}
}
echo A::class;
}
?>
对象
创建类的对象需要使用new关键字。如果在new关键字之后是一个包含类名的字符串,则会创建这个类的实例。如果该类属于一个名字空间,则必须使用其完整名称。当把一个已经创建的实例赋给一个新变量时,新变量会访问同一个实例,此时改变旧变量的引用不会改变新变量的引用,新变量仍然指向之前的实例。如果是通过引用传递的方式赋给新变量,则改变旧变量的引用会改变新变量的引用。
<?php
class A{
public $var = 'a default value';
public function displayVar() {
echo $this->var;
}
}
$className="A";
$ins1=new A();
echo $ins1->displayVar()."\n";
$ins2=new $className();
echo $ins2->displayVar()."\n";
$ins3=$ins1;
$ins4=&$ins1;
var_dump($ins3===$ins1);
var_dump($ins4===$ins1);
$ins1=new A();
var_dump($ins3===$ins1);
var_dump($ins4===$ins1);
?>
继承
一个类可以在声明中用extends关键字继承另一个类的方法和属性。PHP不支持多重继承,一个类只能继承一个基类。被继承的方法和属性可以通过用同样的名字重新声明被覆盖。但是如果父类定义方法时使用了final,则该方法不可被覆盖。可以通过parent::来访问被覆盖的方法或属性。当覆盖方法时,参数必须保持一致否则PHP将发出E_STRICT级别的错误信息。但构造函数例外,构造函数可在被覆盖时使用不同的参数。如果一个类扩展了另一个,则父类必须在子类之前被声明。
<?php
class A{
public $var = 'a default value';
public function displayVar() {
echo $this->var;
}
}
class B extends A{
public function displayVar(){
echo "class B:";
parent::displayVar();
}
}
$b=new B();
$b->displayVar();
?>