twithers/laravel-php-attributes
Composer 安装命令:
composer require twithers/laravel-php-attributes
包简介
Use PHP 8 Attributes easily inside of your Laravel application
关键字:
README 文档
README
This package will help you create and use your own PHP 8 Attributes inside of a Laravel application without having to worry about writing your own loaders, reflection methods, and data caching.
By default, all attributes in your app directory are automatically loaded and cached, with an accessor provided to look up attributes as needed.
The package can be configured to limit directories as well as attributes to speed up loading and minimize caching.
Installation
Require this package with composer using the following command:
composer require twithers/laravel-php-attributes
You can publish the config file with:
php artisan vendor:publish --provider="TWithers\LaravelAttributes\AttributesServiceProvider" --tag="config"
These are the contents of the published config file:
return [ /** * Caching will make use of Laravel's built-in file caching. Using caching will be a massive performance benefit * as no directories and files need to be scanned for attributes and attribute usages */ 'use_cache' => true, /** * By default this will scan your listed directories below for all attributes and then search for them. * * If you want to avoid the initial search, you can list your attribute classes below: * 'App\Attributes\Foo', * App\Attributes\Bar::class, * */ 'attributes' => [ ], /** * By default this will scan all files inside your app folder for attributes. * * If you want to limit the folders, you can adjust the namespace and the files: * 'App\Http\Controllers' => app_path('Http/Controllers') */ 'directories' => [ 'App' => app_path(), ], ];
You can disable caching, but it is not recommended as each request would scan for and establish the attribute collection.
You can limit attributes to a specific list by declaring them. The empty array indicates that ALL attributes found in the listed directories will be scanned for.
You can narrow down the directory search, or list multiple separate directories to find attributes and their usage. Ensure your
array is structured with $namespace => $directoryPath to ensure files are correctly found and accessed.
Attributes in PHP 8
First attributes are defined and namespaced. An Attribute attribute is then applied to it.
After defining an attribute, we can then add it to anything we want: classes, methods, functions, properties, etc.
Below is a example of how you would define and use an attribute.
#[Attribute] class SampleAttribute { public string $name; public string $label; public function __construct( string $name, string $label ){ $this->name = name; $this->label = label; } } #[SampleAttribute(name: 'SampleClass', label: 'My Sample Class Label')] class SampleClass { #[SampleMethod(name: 'sampleMethod', label: 'My Sample Method Label')] public function sampleMethod(): bool { return true; } }
We have a defined attribute SampleAttribute that requires a name and a label.
We have a SampleClass that uses that attribute, as well as the method sampleMethod() that also uses that attribute.
Looking up Attributes in PHP 8+
Attributes by themselves do nothing. PHP currently doesn't give you a super easy way to capture attributes and values. You are left using PHP Reflection, which may not be something you have ever used. Reflection is just that, reflecting on the code. You pass in some information, such as class names, methods names, etc, and the Reflection API will give you all the info you need to know about it... including attributes.
Below is how you would currently use the Reflection API to look up attributes.
$reflectionClass = new ReflectionClass(SampleClass::class); $attributes = $reflectionClass->getAttributes(SampleMethod::class); if (count($attributes)){ $attribute = $attributes[0]->newInstance(); dump($attribute->name); // "SampleClass" dump($attribute->label); // "My Sample Class Label" } $reflectionClass = new ReflectionClass(SampleClass::class); $reflectionMethod = $reflectionClass->getMethod('sampleMethod'); $attributes = $reflectionMethod->getAttributes(SampleMethod::class); if (count($attributes)){ $attribute = $attributes[0]->newInstance(); dump($attribute->name); // "Sample Method" dump($attribute->label); // "My Sample Method" }
This isn't much code to write and pretty easy to follow. If you are using attributes throughout your application, however, you will soon find yourself repeating this code in many places.
Enter Laravel PHP Attributes
Usage
Accessing the AttributeCollection API
This package provides the Attributes facade to help you access the stored attribute collection data after it is processed.
You can also type-hint the AttributeCollection class throughout your app and Laravel will autoload the initialized attribute
collection.
The Attributes facade and AttributeCollection provides the following useful methods:
Attributes::findByClass(string $className): ?AttributeTarget Attributes::findByClassMethod(string $className, string $methodName): ?AttributeTarget Attributes::findByClassProperty(string $className, string $propertyName): ?AttributeTarget Attributes::findTargetsWithAttribute(string $attributeName): AttributeTarget[]
An AttributeTarget is the class, method, or property that the attribute is attached to.
The AttributeTarget has the following structure:
- int $type: Indicates if the target is a class, method, or property
- string $className: The full namespaced name of the class that was targeted or contains the attribute
- ?string $identifier: The name of the method or property
- allAttributes(): AttributeInstance[]: The method to retrieve a list of all attached attributes (
$nameand instantiated$instance)
Here is how the code from above could be rewritten:
$attributes = Attributes::findByClass(SampleClass::class)->allAttributes(); dump($attributes[0]->instance->name); // "SampleClass" dump($attributes[0]->instance->label); // "My Sample Class Label" $attributes = Attributes::findByClassMethod(SampleClass::class, 'sampleMethod')->allAttributes(); dump($attributes[0]->instance->name); // "Sample Method" dump($attributes[0]->instance->label); // "My Sample Method"
AttributeTarget API
The AttributeTarget class exposes a few helpful methods as well for finding specific attributes:
AttributeTarget::allAttributes(): AttributeInstance[] AttributeTarget::hasAttribute(string $attributeName): bool AttributeTarget::findByName(string $attributeName): AttributeInstance[]
Standalone Usage
If you do not want to utilize the Laravel service provider's automatic loading and caching of attributes, you can remove it from
the list of loaded service providers. You will be able to use the AttributeAccessor class to look up attributes if you know the
pertinent info. Here are the methods that are available:
AttributeAccessor::forClass(string $className): ?AttributeInstance[] AttributeAccessor::forClassMethod(string $className, string $methodName): ?AttributeInstance[] AttributeAccessor::forClassProperty(string $className, string $propertyName): ?AttributeInstance[]
If the class, method, or property are not found, it will return null, otherwise, each of those static functions will look up
all attached attributes and return an array of AttributeInstances which have both the $name and $instance of the attribute
for your use.
Clearing Attribute Cache
By default, attributes will be found and processed, with the results cached on the first request. Subsequent requests will utilize
the cached data to avoid costly processing time. This means that changes to attributes or methods that are using attributes will require
the cache to be cleared. By default (unless your environment is set to store files in a different location), the cached file is stored in bootstrap\cache\attributes.php and can be manually deleted. You can also
use the following command:
php artisan attributes:clear
It would be pertinent to use this command in your deployment process to ensure any added attributes will be properly cached.
Testing
./vendor/bin/phpunit
Contributing
All contributions are welcome.
Thank you!
Made with contrib.rocks.
License
The MIT License (MIT). Please see License File for more information.
twithers/laravel-php-attributes 适用场景与选型建议
twithers/laravel-php-attributes 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.71k 次下载、GitHub Stars 达 3, 最近一次更新时间为 2022 年 09 月 20 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「attributes」 「php-attributes」 「php8-attributes」 「laravel-php-attributes」 「laravel-php8-attributes」 「attribute-caching」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 twithers/laravel-php-attributes 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 twithers/laravel-php-attributes 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 twithers/laravel-php-attributes 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A library that allows you to easily use the PHP-VCR library in your PHPUnit tests.
This Package provides some usefully console features like the attribute syntax for arguments and options, validation, auto ask and casting.
Symfony bundle for extending Doctrine ORM entities with custom attribute-driven metadata — cacheable mapping, embedded entity support, and autoconfigured drivers
Symfony bundle for automatic sort order management in Doctrine ORM entities. Recalculates positions on flush with grouped ordering, second-level cache support, and PHP attribute configuration.
HookPress is a Laravel package that uses Composer hooks to automatically discover, filter, and cache classes, traits, and interfaces in your application
统计信息
- 总下载量: 1.71k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 3
- 点击次数: 10
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2022-09-20