基本语法
属性的定义要使用 `#[...]` 语法,并且可以附带参数。下面是一些常见的使用场景:
1. 类属性上使用
php
class User {
#[Column(type: "string", length: 100)]
public string $name;
#[Column(type: "integer")]
public int $age;
}
2. 方法参数上使用
php
class Validator {
public function validate(
#[Required] #[MaxLength(50)] string $email,
#[Required] #[Min(18)] int $age
) {
// 验证逻辑
}
}
3. 类和方法上使用
php
#[Route(path: "/users", method: "GET")]
class UserController {
#[Cache(duration: 3600)]
public function getUsers() {
// 获取用户数据
}
}
创建自定义属性
你能够通过定义实现 `Attribute` 接口的类来自定义属性:
php
#[Attribute]
class Column {
public function __construct(
public string $type,
public int $length = 255
) {}
}
借助 `#[Attribute]` 声明,这个类就可以当作属性来使用了。
读取属性
在运行时,可以利用反射 API 来读取属性信息:
php
$reflectionClass = new ReflectionClass(User::class);
$property = $reflectionClass->getProperty('name');
$attributes = $property->getAttributes(Column::class);
foreach ($attributes as $attribute) {
$column = $attribute->newInstance();
echo "Type: {$column->type}, Length: {$column->length}";
}
属性的特性
- **目标限制**:可以通过 `#[Attribute(Attribute::TARGET_METHOD)]` 这样的方式来限制属性的使用位置。
- **重复使用**:设置 `#[Attribute(Attribute::IS_REPEATABLE)]` 后,属性能够在同一个元素上重复使用。
- **参数传递**:属性支持位置参数、命名参数以及常量表达式。
应用场景
- **ORM 映射**:可以把数据库表字段和类属性关联起来。
- **路由定义**:能够直接在控制器方法上定义路由规则。
- **验证规则**:可以为表单字段添加验证约束条件。
- **依赖注入**:能够声明服务的注入方式。
示例:路由属性实现
php
// 定义路由属性
#[Attribute(Attribute::TARGET_METHOD)]
class Route {
public function __construct(
public string $path,
public string $method = "GET"
) {}
}
// 使用路由属性
class BlogController {
#[Route(path: "/posts", method: "GET")]
public function listPosts() { /* ... */ }
#[Route(path: "/posts/{id}", method: "GET")]
public function getPost(int $id) { /* ... */ }
}
// 路由解析逻辑
function registerRoutes(string $controllerClass) {
$reflection = new ReflectionClass($controllerClass);
foreach ($reflection->getMethods() as $method) {
foreach ($method->getAttributes(Route::class) as $attr) {
$route = $attr->newInstance();
// 注册路由到框架中
Router::add($route->method, $route->path, [$controllerClass, $method->getName()]);
}
}
}
PHP 属性让代码的元数据变得更加结构化,使框架和库的设计更加简洁,还能减少样板代码。它已经成为现代 PHP 开发中一个非常重要的组成部分。