hostnet / accessor-generator-plugin-lib
动态生成get、set、add、remove方法。
Requires
- php: ^8.1
- composer-plugin-api: ^2.0
- ext-bcmath: *
- ext-json: *
- doctrine/annotations: ^1.14.3
- doctrine/collections: ^1.8.0
- doctrine/dbal: ^3.7.2
- doctrine/inflector: ^2.0.8
- doctrine/orm: ^2.17.2
- symfony/filesystem: ^5.4||^6.0
- twig/twig: ^3.9.3
Requires (Dev)
- composer/composer: ^2.0.0
- hostnet/phpcs-tool: ^9.0.0
- phpspec/prophecy: ^1.17
- phpspec/prophecy-phpunit: ^2.1
- phpunit/phpunit: ^9.6.0
- dev-master
- 6.0.4
- 6.0.3
- 6.0.2
- 6.0.1
- 6.0.0
- 5.0.19
- 5.0.18
- 5.0.17
- 5.0.16
- 5.0.15
- 5.0.14
- 5.0.13
- 5.0.12
- 5.0.11
- 5.0.10
- 5.0.9
- 5.0.8
- 5.0.7
- 5.0.6
- 5.0.5
- 5.0.4
- 5.0.3
- 5.0.2
- 5.0.1
- 5.0.0
- 4.0.4
- 4.0.3
- 4.0.2
- 4.0.1
- 4.0.0
- 3.1.0
- 3.0.0
- 2.9.0
- 2.8.6
- 2.8.5
- 2.8.4
- 2.8.3
- 2.8.2
- 2.8.1
- 2.8.0
- 2.7.4
- 2.7.3
- 2.7.2
- 2.7.1
- 2.6.1
- 2.6.0
- 2.5.2
- 2.5.1
- 2.5.0
- 2.4.4
- 2.4.3
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.0
- 2.2.0
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.5
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.2
- 1.3.1
- 1.3.0
- 1.2.5
- 1.2.4
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.1
- 1.1.0
- 1.0.0
- 0.1.1
- 0.1.0
- 0.0.6
- 0.0.5
- 0.0.4
- 0.0.3
- 0.0.2
- 0.0.1
- dev-error-handling-fix
- dev-iltar-patch-1
This package is auto-updated.
Last update: 2024-09-14 11:10:18 UTC
README
欢迎使用Accessor Generator composer插件。
目标
此插件的目标是为基于我们可从文档注释中读取的信息的类提供动态生成的get、set、add、remove访问器方法。目前我们可以处理Doctrine ORM注解。
由于代码是自动生成的,你不需要对其进行(单元)测试,并且它将与大量附加的样板代码非常一致,如果不幸使用错误的类型或参数数量使用生成的函数,你的代码将会在早期失败。
限制
- 不支持通过分组
use
语句进行导入。(https://wiki.php.net/rfc/group_use_declarations)
安装
将hostnet/accessor-generator-plugin-lib
添加到你的composer.json
,并运行composer require hostnet/accessor-generator-plugin-lib
如果你想在安装后调用生成,你可以运行php composer.phar dump-autoload
。向dump-autoload命令添加-vv
以获得更多详细输出。
用法
<?php namespace Hostnet\Product\Entity; use Doctrine\ORM\Mapping as ORM; use Hostnet\Component\AccessorGenerator\Annotation as AG; /** * @ORM\Entity * @ORM\Table(name="periode") */ class Period { use Generated\PeriodMethodsTrait; // This is the file that is generated with the // accessor methods inside. /** * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(name="id", type="integer") * @AG\Generate // Here you ask methods to be generated * */ private int $id; // ... }
文件将在当前文件相对的子目录和命名空间(Generated)中生成。此文件可以包含为特质。
指定要生成的函数
你可以通过在注解中指定它们来禁用某些访问器方法的生成。
/** * @AG\Generate(add="none",set="none",remove="none",get="none",is="none") */
Is
是get的别名。如果你的属性是布尔类型,则将生成isProperty
方法而不是getProperty
方法。对于ORM\GeneratedValue
属性,不会生成setter。**注意,上述示例将不会生成任何代码**。
如果没有指定配置,则默认行为是对于所有标量类型属性,都会生成get和set方法。当类型是可迭代的(例如,DoctrineCollection或数组)时,将生成adders和removers。
加密
要在列的值上使用非对称加密,请将'encryption_alias'字段添加到Generate
注解中。同时请确保数据库列的类型有足够大的长度。密钥和IV至少需要1064个字符,加上加密数据的长度。
/** * @AG\Generate(encryption_alias="database.table.column") */ private $encrypted_variable;
在该处使用的别名应添加到应用程序的composer.json
中,如下所示
"extra": {
"accessor-generator": {
<encryption_alias>: {
"public-key": <public_key_file>
"private-key": <private_key_file>
...
为了加密或解密数据,必须指定有效的私钥和公钥。
- **公钥**用于加密数据。
- **私钥**用于解密数据。
为了开始加密数据,需要一个公钥。但是,你需要一个私钥才能从中提取公钥。我们可以使用openssl
工具来做。
创建密钥
$ openssl genrsa -out database.table.column.private_key.pem 2048
从私钥中提取公钥
$ openssl rsa -in database.table.column.private_key.pem -pubout > database.table.column.public_key.pem
如果应用程序需要加密,添加公钥。如果应用程序需要解密,添加私钥。如果应用程序需要两者都做,添加两者。
<public_key_file>
和<private_key_file>
的值必须包含相对于composer.json文件的密钥的文件路径。
不要忘记在构造函数中使用setter方法来触发给定值的加密,而不是直接将该值赋给属性。
<?php class MyEntity { /** * @AG\Generate(encryption_alias="<encryption_alias>") */ private $my_value; public function __construct(string $my_value) { $this->my_value = $my_value; // No encryption is taking place. $this->setMyValue($my_value); // The value is now encrypted in the field. } }
使用ENUM类参数
自2.8.0版本起,增加了对参数化集合访问器生成的支持。由于需要PHP 7.1中新增的ReflectionConstant
,因此增加了对PHP 7.1的支持。
想象一下有一个实体持有另一个实体的ArrayCollection
,该实体持有参数。例如
$task = new Task(); $task->setParam(MyParamEnum::I_CLIENT_ID, 123456); echo $task->getParam(MyParamEnum); // 12345
正如你可能注意到的,尽管参数名以I_
前缀开头——这表明我们正在处理整数——但只要setParam
的实现支持,你仍然可以设置任何你想要的数据类型。如果你在一个大型团队或大型项目中工作,可能并不是每个人都意识到存在一个枚举类,该类定义了整个应用程序中应该用于此实体的所有常用参数名。
2.8.0版本引入了生成枚举类访问器的功能。
要求
拥有实体——上面的例子中的Task
——必须实现一个类型为ArrayCollection
的属性,该属性
与Parameter
实体定义了一个OneToMany
关系。
class Task { // ... /** * @ORM\OneToMany(targetEntity="Parameter", cascade={"persist"}) */ private $parameters; // ... }
Parameter
实体必须实现以下
use Hostnet\Component\AccessorGenerator\Enum\EnumeratorCompatibleEntityInterface; class Parameter implements EnumeratorCompatibleEntityInterface { /** * @ORM\ManyToOne(targetEntity="Task") */ private $owner; /** * @ORM\Column(type="string") */ private $name; /** * @ORM\Column(type="string") * @AG\Generate() */ private $value; // This signature is a requirement for enum accessor generation. public function __construct($task, string $name, ?string $value) { $this->owner = $task; $this->name = $name; $this->value = $value; } }
枚举类
"枚举类"仅包含使用前缀命名的公共常量,该前缀表示它们在数据库中持有的值的类型。
以下类型受到支持
现在,让我们以以下枚举类示例为例,其中包含一些参数
class MyTaskParamNames { /** * Represents the client if the task is currently runnnig for. */ public const I_CLIENT_ID = 'CLIENT_ID'; /** * An awesome URL. */ public const S_AWESOME_URL = 'https://www.hostnet.nl/'; }
现在我们已经有了三个类(《Task》、《Parameter》和《MyTaskParamNames》),我们可以开始生成代码。
"枚举器"注解
2.8.0版本带来了Enumerator
注解,可以在现有的Generate
注解中使用。
从2.8.0升级到2.8.1:注解中的"名称"设置已更改为"属性",以提高一致性。从2.8.1版本开始,增加了通过其他类属性添加内联枚举器的功能。更多信息请见下文。
通过修改我们上面示例中编写的代码,我们可以通过修改我们的Task
类的parameters
属性的注解来为MyTaskParamNames
生成一个访问器方法。
class Task { use Generated\TaskMethodsTrait; /** * @ORM\OneToMany(targetEntity="Parameter", cascade={"persist"}) * @AG\Generate(enumerators={ * @AG\Enumerator("MyTaskParamNames", property="my_params") * }) */ private $property; /** * @var Generated\MyTaskParamNamesEnum */ private $my_params; }
一旦生成代码,你将现在有一个新创建的名为MyTaskParamNamesEnum
的类,位于相对于MyTaskParamNames
命名空间的Generated
目录(和命名空间)中。使用TaskMethodsTrait
中的property
设置生成该类的访问器。
根据上面的代码,此枚举的访问器将被称为getMyParams()
。你可以给它任何你想要的名称,只要它适合一个方法名。
一旦生成代码,你将可以访问每个参数5个方法
$task = new Task(); // hasClientId() will check if a parameter with the name I_CLIENT_ID exists in the collection of parameters belonging to // this Task instance. if (! $task->getMyParams()->hasClientId()) { // Create the I_CLIENT_ID parameter with a value of 1234. $task->getMyParams()->setClientId(1234); } // Update the value of the existng parameter. $task->getMyParams()->setClientId(999); // Retrieve the value $client_id = $task->getMyParams()->getClientId(); // Clear the value (keeps the element in the collection, but nullifies the value). // hasClientId() will now return FALSE as if the parameter doesn't exist. $task->getMyParams()->clearClientId(); // Remove the element entirely, effectively dropping the record from the database. $task->getMyParams()->removeClientId();
所有方法都是根据枚举类中的前缀进行严格类型化的。
请查看ParamNameEnum类,以查看生成的代码示例。
警告:如果使用枚举器,访问器方法(get/is/set/add/remove)的默认可见性将设置为
none
。如果您仍然需要生成这些方法,您必须明确指定它们。
多个枚举器
正如你可能已经注意到的,Generate
注解的enumerators
属性接受一个包含一个或多个Enumerator
注解的列表。您可以指定一个或多个使用相同"存储"集合的枚举类。
如果您的注解看起来像这样
/** * @AG\Generate(enumerators={ * @AG\Enumerator("MyTaskParamNames", property="my_params"), * @AG\Enumerator("BetterParamNames", property="better_params") * }); */ private $parameters; /** * @var Generated\MyTaskParamNamesEnum */ private $my_params; /** * @var Generated\BetterParamNamesEnum */ private $better_params;
生成器现在将为这些参数枚举器创建两个访问器,您可以像这样使用它们
$task->getMyParams()->hasClientId(); // From MyTaskParamNames $task->getBetterParams()->setFoobar(1234); // From BetterParamNames
分离的枚举器访问器生成
您也可以在 @Generate
注解外部定义枚举器。如果与 entity-plugin-lib
结合使用,可以定义一个包含枚举属性的特性,该属性引用您实体上的集合。
假设我们想要向之前已经编写过的 - 已存在的 - Task 实体添加一个额外的枚举器。
use Hostnet\Component\AccessorGenerator\Annotation as AG; trait TaskTrait { use Generated\TaskTraitMethodsTrait; /** * @AG\Enumerator("\My\Namespace\MyExtraParamName", name="parameters") * @var \My\Namespace\Generated\MyExtraParamNameEnum */ private $some_extra_params; }
name
设置指的是包含该实体所有参数的 ArrayCollection 属性。
一旦代码生成,您现在可以像调用其他枚举器一样调用它。
<?php $task = new Task(); $task->getSomeExtraParams()->... // Whilst still having access to the already existing enumerators that we defined before. $task->getMyParams(); $task->getBetterParams();
请确保将特性 Generated\TaskTrait
- 或您实体使用的任何名称 - 包含在任务实体中以便此操作生效。所以,
<?php class Task { use Generated\TaskMethodsTrait; }
变成了
<?php class Task { use Generated\TaskTrait; use Generated\TaskMethodsTrait; }
请参阅 entity-plugin-lib 获取更多信息。