本文目录导读:

- 严格类型模式(
declare(strict_types=1)) - 标量类型声明 (Scalar Type Declarations)
- 返回类型声明(Return Types)
- 联合类型(Union Types, PHP 8+)
- 类型注解与静态分析(PHPDoc + Psalm/phpstan)
verify辅助函数(运行时验证)- Trusted Proxy(如果你指 Laravel)
- 总结:如何构建“可信类型”体系
在 PHP 中,“可信类型”(Trusted Types)通常指的是 PHP 的类型声明系统,特别是 严格类型模式(strict_types) 和 类型注解,但如果你指的是 浏览器端的 Trusted Types API(用于防御 DOM XSS),那在 PHP 中主要是 输出编码 和 安全上下文 的配合。
我假设你问的是 PHP 的类型安全机制,下面是详细解释:
严格类型模式(declare(strict_types=1))
这是 PHP 中最重要的“可信类型”机制,它决定了类型强制转换的严格程度。
默认(弱类型)模式:
<?php
function add(int $a, int $b): int {
return $a + $b;
}
// 弱类型下,PHP 会尝试转换
echo add("5", 3); // 输出 8 (字符串 "5" 被强制转为 int)
严格模式:
<?php
declare(strict_types=1); // 必须在文件第一行
function add(int $a, int $b): int {
return $a + $b;
}
// 严格模式下,类型不匹配会直接报 TypeError
// echo add("5", 3); // TypeError: Uncaught TypeError: add(): Argument #1 ($a) must be of type int, string given
echo add(5, 3); // 正常输出 8
关键点:
strict_types必须在 调用方文件 的第一行声明,而不是在定义函数的文件。- 它只影响 标量类型(int, float, string, bool)。
- 不会影响类、数组、可调用类型(这些本来就是强制的)。
标量类型声明 (Scalar Type Declarations)
PHP 7 引入了标量类型声明,配合 strict_types 使用:
<?php
declare(strict_types=1);
function process(
int $num,
float $price,
string $name,
bool $flag
): string {
return "处理: $num, $price, $name, " . ($flag ? '真' : '假');
}
返回类型声明(Return Types)
确保函数返回特定类型:
<?php
declare(strict_types=1);
function fetchUser(int $id): ?array
{
// 必须返回 array 或 null
if ($id <= 0) {
return null;
}
return ['id' => $id];
}
联合类型(Union Types, PHP 8+)
允许声明多个可能类型:
<?php
declare(strict_types=1);
function process(int|float|string $value): int|float
{
// 根据类型做不同处理
if (is_string($value)) {
return strlen($value);
}
return $value * 2;
}
类型注解与静态分析(PHPDoc + Psalm/phpstan)
这是“可信类型”概念中 最实用的部分,通过 PHPDoc 注解让工具帮你做静态类型检查:
<?php
/**
* 计算订单总价
*
* @param array<array{price: float, qty: int}> $items 商品列表
* @param float $discount 折扣
* @return float 折后总价
*
* @throws InvalidArgumentException 当价格或数量为负数时
*/
function calcTotal(array $items, float $discount): float
{
$total = 0;
foreach ($items as $item) {
if ($item['price'] < 0 || $item['qty'] < 0) {
throw new InvalidArgumentException('价格或数量不能为负数');
}
$total += $item['price'] * $item['qty'];
}
return $total * (1 - min(1, max(0, $discount)));
}
使用 PHPStan 或 Psalm 来检查:
vendor/bin/phpstan analyse src --level=max
verify 辅助函数(运行时验证)
如果你需要更严格的运行时类型检查(不仅限于标量):
<?php
declare(strict_types=1);
class UserValidator
{
public static function verifyArrayOfObjects(array $data, string $className): void
{
foreach ($data as $item) {
if (!$item instanceof $className) {
throw new TypeError("期望 {$className},收到 " . gettype($item));
}
}
}
public static function verifyEmail(string $email): void
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException("无效的邮箱地址");
}
}
}
Trusted Proxy(如果你指 Laravel)
如果你在 Laravel 中使用 TrustedProxy,那是关于 HTTP 代理信任 的配置:
// config/trustedproxy.php
return [
'proxies' => '*', // 信任所有代理
'headers' => [
Illuminate\Http\Request::HEADER_FORWARDED,
Illuminate\Http\Request::HEADER_X_FORWARDED_FOR,
],
];
如何构建“可信类型”体系
<?php
declare(strict_types=1); // 1. 启用严格模式
class OrderService
{
// 2. 明确的参数类型 + 联合类型
public function createOrder(
int $userId,
int|float $amount,
string $currency = 'CNY'
): Order {
// 3. 运行时验证
if ($amount <= 0) {
throw new DomainException('金额必须大于0');
}
// 4. 返回值类型明确
return new Order($userId, $amount, $currency);
}
}
// 5. 静态分析工具(PHPStan/Psalm)保证未调用前就发现问题
// 6. 单元测试(PHPUnit)验证边界情况
推荐组合:
- 开发期:PHPStan/Psalm(静态分析)+ strong typing
- 运行期:
strict_types+ 类型声明 + 自定义验证 - 边界防御:框架的验证器(Laravel validation, Symfony Validator)
这样你就拥有了完整的“可信类型”保障,如果还有具体场景需要细化,可以告诉我。