PHP 构造函数是一个名为 __construct() 的方法。当你写 new ClassName(...) 时,PHP 会自动调用它,括号里的参数会成为它的参数,所以对象一创建出来,各项值就已经设置好了。
<?php
class User
{
public string $name;
public int $age;
public function __construct(string $name, int $age)
{
$this->name = $name;
$this->age = $age;
}
}
$ada = new User('Ada', 36);
echo "{$ada->name} is {$ada->age}\n";
如果没有构造函数,你得先创建一个空对象,再逐个设置属性,而且没有任何机制能阻止你漏掉一个。有了构造函数,不带参数的 new User() 就会抛出 ArgumentCountError。
PHP 没有构造函数重载:一个类只有一个 __construct。当对象可以由不同的输入构建时(日期字符串、数组、时间戳),可以添加有名字的静态方法,由它们准备好参数并调用 new static(...)。把构造函数设为 private,就能强制所有人都通过工厂方法创建对象。
<?php
class Color
{
private function __construct(
public readonly int $r,
public readonly int $g,
public readonly int $b,
) {}
public static function fromRgb(int $r, int $g, int $b): static
{
return new static($r, $g, $b);
}
public static function fromHex(string $hex): static
{
[$r, $g, $b] = sscanf(ltrim($hex, '#'), '%02x%02x%02x');
return new static($r, $g, $b);
}
public function css(): string
{
return "rgb({$this->r}, {$this->g}, {$this->b})";
}
}
echo Color::fromRgb(255, 128, 0)->css(), "\n";
echo Color::fromHex('#1e90ff')->css(), "\n";
现在从类外部调用 new Color(1, 2, 3) 会抛出 Error(“Call to private Color::__construct() from global scope”)。static 页面解释了这里为什么用 new static 而不是 new self。
<?php
class Vehicle
{
public function __construct(
protected string $brand,
protected int $wheels = 4,
) {}
public function describe(): string
{
return "{$this->brand} with {$this->wheels} wheels";
}
}
class Truck extends Vehicle
{
public function __construct(string $brand, private int $capacityKg)
{
parent::__construct($brand, 6);
}
public function describe(): string
{
return parent::describe() . ", carries {$this->capacityKg} kg";
}
}
echo (new Vehicle('Fiat'))->describe(), "\n";
echo (new Truck('Volvo', 18000))->describe(), "\n";