popphp / pop-code
Pop PHP 框架的 Pop Code 组件
5.0.2
2024-02-14 22:48 UTC
Requires
- php: >=8.1.0
Requires (Dev)
- phpunit/phpunit: ^10.0.0
README
概览
pop-code
提供了动态生成 PHP 代码以及在运行时解析和修改现有 PHP 代码的能力。
pop-code
是 Pop PHP 框架 的一个组件。
安装
使用 Composer 安装 pop-code
。
composer require popphp/pop-code
或者,在你的 composer.json 文件中引入它
"require": {
"popphp/pop-view" : "^5.0.0"
}
快速开始
创建一个简单的函数
在这个例子中,创建了一个函数并将其渲染为字符串
use Pop\Code\Generator; $function = new Generator\FunctionGenerator('sayHello'); $function->addArgument('name', 'null', 'string'); $function->setBody("echo 'Hello ' . \$name;"); $function->addReturnType('void'); $function->setDesc('This is the first function'); echo $function;
/** * This is the first function * * @param string|null $name * @return void */ function sayHello(string|null $name = null): void { echo 'Hello ' . $name; }
创建一个简单的类
在这个例子中,创建了一个类并将其保存到文件中
use Pop\Code\Generator; // Create the class object and give it a namespace $class = new Generator\ClassGenerator('MyClass'); $class->setNamespace(new Generator\NamespaceGenerator('MyApp')); // Create a new protected property with a default value $prop = new Generator\PropertyGenerator('foo', 'string', null, 'protected'); // Create a method and give it an argument, body and docblock description $method = new Generator\MethodGenerator('setFoo', 'public'); $method->addArgument('foo', null, 'string') ->setBody('$this->foo = $foo;') ->addReturnType('void') ->setDesc('This is the method to set foo.'); // Add the property and the method to the class code object $class->addProperty($prop); $class->addMethod($method); // Save the class to a file $code = new Generator($class); $code->writeToFile('MuClass.php');
文件内容将如下所示
<?php /** * @namespace */ namespace MyApp; class MyClass { /** * @var string */ protected string|null $foo = null; /** * This is the method to set foo. * * @param string $foo * @return void */ public function setFoo(string $foo): void { $this->foo = $foo; } }
生成代码
有一些单独的代码生成器可用于管理各种类型代码块的创建和输出。以下类型的代码都有相应的代码生成器
- 类
- 接口
- 特质
- 方法
- 函数
- 常量
- 属性
- 命名空间
- 文档块
- 代码体(一般代码块)
创建一个包含一些函数的文件
use Pop\Code\Generator; $function1 = new Generator\FunctionGenerator('sayHello'); $function1->addArgument('name', null, 'string') ->setBody("echo 'Hello ' . \$name;") ->setDesc('This is the first function') ->addReturnType('void'); $function2 = new Generator\FunctionGenerator('sayGoodbye'); $function2->addArgument('name', null, 'string') ->setBody("echo 'Goodbye ' . \$name;") ->setDesc('This is the second function') ->addReturnType('void'); $code = new Generator(); $code->addCodeObjects([$function1, $function2]); $code->writeToFile('functions.php');
上面的代码将生成一个名为 functions.php
的文件,其中包含以下代码
<?php /** * This is the first function * * @param string $name * @return void */ function sayHello(string $name): void { echo 'Hello ' . $name; } /** * This is the second function * * @param string $name * @return void */ function sayGoodbye(string $name): void { echo 'Goodbye ' . $name; }
解析代码
此 pop-code
组件还提供了解析现有代码的能力,这对于获取有关代码的信息或修改并保存新代码非常有用。
在这个例子中,我们使用了上面创建的类。反射对象提供了一个像上面那样的代码生成器对象,以便您可以从解析的代码中添加或删除内容。
use Pop\Code\Reflection; use Pop\Code\Generator; $class = Reflection::createClass('MyApp\MyClass'); // Create the new method that you want to add to the existing class $method = new Generator\MethodGenerator('hasFoo', 'public'); $method->addArgument('foo', null, 'string') ->setBody('return ($this->foo !== null);') ->setDesc('This is the method to see if foo is set.') ->addReturnType('bool'); // Access the generator and it's code object to add the new method to it $class->addMethod($method); // Echo out the code $code = new Generator($class); $code->writeToFile('MyClass.php');
修改后的类将如下所示,包括新的 hasFoo()
方法
<?php /** * @namespace */ namespace MyApp; class MyClass { /** * @var string */ protected string|null $foo = null; /** * This is the method to set foo. * * @param string $foo * @return void */ public function setFoo(string $foo): void { $this->foo = $foo; } /** * This is the method to see if foo is set. * * @param string $foo * @return bool */ public function hasFoo(string $foo): bool { return ($this->foo !== null); } }