基本语法

每个类的定义都以关键字 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"

results matching ""

    No results matching ""