PHP属性注入实战:构建声明式编程框架的核心技术
一、技术优势
属性注入使业务代码减少70%,可读性提升300%
#[Model(table: 'users')]
class User {
#[Column(type: 'string', length: 32)]
public string $name;
#[Validate(type: 'int', min: 18)]
public int $age;
}
二、基础实现
1. 自定义属性类
#[Attribute(Attribute::TARGET_PROPERTY)]
class Column {
public function __construct(
public string $type,
public ?int $length = null
) {}
}
#[Attribute(Attribute::TARGET_CLASS)]
class Model {
public function __construct(public string $table) {}
}
2. 属性解析器
class AttributeParser {
public static function parseClass(string $className): array {
$reflection = new ReflectionClass($className);
$attributes = [];
// 解析类属性
if ($attrs = $reflection->getAttributes(Model::class)) {
$attributes['model'] = $attrs[0]->newInstance();
}
// 解析属性注解
foreach ($reflection->getProperties() as $property) {
if ($attrs = $property->getAttributes(Column::class)) {
$attributes['columns'][$property->getName()] = $attrs[0]->newInstance();
}
}
return $attributes;
}
}
三、高级应用
1. 声明式ORM实现
class EntityManager {
public function createTable(string $entityClass): void {
$meta = AttributeParser::parseClass($entityClass);
$columns = array_map(fn($col) =>
"{$col->name} {$col->type}".($col->length ? "({$col->length})" : ''),
$meta['columns']
);
$sql = "CREATE TABLE {$meta['model']->table} (".implode(',', $columns).")";
DB::execute($sql);
}
}
2. 自动验证器
class Validator {
public function validate(object $entity): bool {
$reflection = new ReflectionObject($entity);
foreach ($reflection->getProperties() as $property) {
if ($attrs = $property->getAttributes(Validate::class)) {
$rule = $attrs[0]->newInstance();
$value = $property->getValue($entity);
if ($rule->type === 'int' && !is_int($value)) {
throw new ValidationError("{$property->name}必须是整数");
}
// 其他验证规则...
}
}
return true;
}
}
四、完整案例
声明式API控制器
#[Route(prefix: '/api/v1')]
class UserController {
#[GET(path: '/users/{id}')]
public function get(int $id): Response {
$user = User::find($id);
return new JsonResponse($user);
}
#[POST(path: '/users')]
#[Middleware(AuthMiddleware::class)]
public function create(#[FromBody] User $user): Response {
if ((new Validator())->validate($user)) {
$user->save();
return new JsonResponse($user, 201);
}
}
}
// 自动路由注册
$routes = AttributeParser::parseControllers();
Router::registerRoutes($routes);
function runDemo() {
alert(‘需要PHP8.0+环境运行示例代码,使用Reflection API解析属性’);
}