基本语法
每个类的定义都以关键字 class
开头,后面跟着类名,后面跟着一对花括号,里面包含有类的属性与方法的定义。类名可以是任何非 PHP 保留字的合法标签。一个合法类名以字母或下划线开头,后面跟着若干字母,数字或下划线。一个类可以包含有属于自己的常量,变量(属性)以及函数(方法)。
<?php
class Foo
{
/**
* Just a test property.
*
* @var string
*/
public string $property = 'foo';
/**
* Just a test method.
*
* @param void
* @return void
*/
public function method()
{
//
}
}
当一个方法在类定义内部被调用时,有一个可用的伪变量 $this
。 $this
是一个到主叫对象的引用(通常是该方法所从属的对象,但如果是从第二个对象静态调用时也可能是另一个对象)。
<?php
class Foo
{
/**
* Just a test property.
*
* @var string
*/
public string $property = 'foo';
/**
* Return the specified property.
*
* @param void
* @return string
*/
public function method(): string
{
return $this->property;
}
}
$foo = new Foo();
var_dump($foo->method()); // string(3) "foo"
要创建一个类的实例,必须使用 new
关键字。当创建新对象时该对象总是被赋值,除非该对象定义了构造函数并且在出错时抛出了一个异常。类应在被实例化之前定义(某些情况下则必须这样)。如果在 new
之后跟着的是一个包含有类名的字符串,则该类的一个实例被创建。如果该类属于一个命名空间,则必须使用其完整名称。
<?php
class Foo
{
//
}
$foo = new Foo();
var_dump($foo); // object(Foo)#1 (0) { }
$foo = 'Foo';
$foo = new $foo;
var_dump($foo); // object(Foo)#1 (0) { }
$foo = new Foo();
$foo = new $foo;
var_dump($foo); // object(Foo)#1 (0) { }
在类定义内部,可以用 new self
创建新对象。
<?php
class Foo
{
/**
* Return an instance of the current class.
*
* @param void
* @return Foo
*/
public static function method(): Foo
{
return new self;
}
}
var_dump(Foo::method()); // object(Foo)#1 (0) { }
在类定义内部,可以用 new parent
创建新对象。
<?php
class Foo
{
//
}
class Bar extends Foo
{
/**
* Return an instance of the parent class.
*
* @param void
* @return Foo
*/
public static function method(): Foo
{
return new parent;
}
}
var_dump(Bar::method()); // object(Foo)#1 (0) { }
在类定义内部,可以用 new static
创建新对象。
<?php
class Foo
{
/**
* Return an instance of the late static binding class.
*
* @param void
* @return Foo
*/
public static function method(): Foo
{
return new static;
}
}
class Bar extends Foo
{
//
}
$foo = Foo::method();
var_dump($foo); // object(Foo)#1 (0) { }
$bar = Bar::method();
var_dump($bar); // object(Bar)#2 (0) { }
当把一个对象已经创建的实例赋给一个新变量时,新变量会访问同一个实例,就和用该对象赋值一样。
<?php
class Foo
{
//
}
$foo = new Foo();
$bar = $foo;
$baz = &$foo;
$foo = null;
var_dump($foo); // NULL
var_dump($bar); // object(Foo)#1 (0) { }
var_dump($baz); // NULL
可以通过一个表达式来访问新创建对象的成员。
<?php
class Foo
{
/**
* Just a test property.
*
* @var string
*/
public string $property = 'foo';
}
var_dump((new Foo())->property); // string(3) "foo"
类中的属性和方法存在于单独的“名称空间”中,因此可以使用具有相同名称的属性和方法。
<?php
class Foo
{
/**
* Just a test property.
*
* @var string
*/
public string $test = 'property';
/**
* Return a string.
*
* @param void
* @return string
*/
public function test(): string
{
return 'method';
}
}
$foo = new Foo();
var_dump($foo->test); // string(8) "property"
var_dump($foo->test()); // string(6) "method"
调用存储在属性中的匿名函数。
<?php
class Foo
{
/**
* Store an anonymous function.
*
* @var callable
*/
public $property;
/**
* Store an anonymous function to the property.
*
* @param void
* @return void
*/
public function __construct()
{
/**
* Return a string.
*
* @param void
* @return string
*/
$this->property = function (): string {
return 'foo';
};
}
}
$foo = new Foo();
$method = $foo->property;
var_dump($method()); // string(3) "foo"
var_dump(($foo->property)()); // string(3) "foo"
一个类可以在声明中用 extends
关键字继承另一个类的方法和属性。 PHP 不支持多重继承,一个类只能继承一个基类。被继承的方法和属性可以通过用同样的名字重新声明来覆盖。但是如果父类定义方法时使用了 final
,则该方法不可被覆盖。可以通过 parent::
来访问被覆盖的方法或属性。当覆盖方法时,参数必须保持一致否则 PHP 将发出 E_STRICT
级别的错误信息。但构造函数例外,构造函数可在被覆盖时使用不同的参数。
<?php
class Foo
{
/**
* Return a string.
*
* @param void
* @return void
*/
public function method(): string
{
return 'foo';
}
}
class Bar extends Foo
{
/**
* Override the parent method.
*
* @param void
* @return string
*/
public function method(): string
{
return 'bar';
}
}
$bar = new Bar();
var_dump($bar->method()); // string(3) "bar"
关键字 class
也可用于类名的解析。使用关键字 class
可以获取一个字符串,包含了类的完全限定名称。这对使用了命名空间的类尤其有用。
<?php
namespace Foo;
class Bar
{
//
}
var_dump(Bar::class); // string(7) "Foo\Bar"