强大的PHP代码生成器

2024-09-17 12:34:50 浏览数 (2)

安装

代码语言:javascript复制
composer require nette/php-generator

从一个使用ClassType创建类的示例开始:

代码语言:javascript复制
$class = new NettePhpGeneratorClassType('Demo');

$class
 ->setFinal()
 ->setExtends(ParentClass::class)
 ->addImplement(Countable::class)
 ->addComment("Class description.nSecond linen")
 ->addComment('@property-read NetteFormsForm $form');

// generate code simply by typecasting to string or using echo:
echo $class;

这将返回

代码语言:javascript复制
/**
 * Class description
 * Second line
 *
 * @property-read NetteFormsForm $form
 */
final class Demo extends ParentClass implements Countable
{
}

要生成代码,您还可以使用所谓的printClass,与echo $class不同,它可以进一步配置:

代码语言:javascript复制
$printer = new NettePhpGeneratorPrinter;
echo $printer->printClass($class);

您可以添加常量和属性

代码语言:javascript复制
$class->addConstant('ID', 123)
 ->setProtected() // constant visibility
 ->setType('int')
 ->setFinal();

$class->addProperty('items', [1, 2, 3])
 ->setPrivate() // or setVisibility('private')
 ->setStatic()
 ->addComment('@var int[]');

$class->addProperty('list')
 ->setType('?array')
 ->setInitialized(); // outputs '= null'

这将生成

代码语言:javascript复制
final protected const int ID = 123;

/** @var int[] */
private static $items = [1, 2, 3];

public ?array $list = null;

您可以添加方法

代码语言:javascript复制
$method = $class->addMethod('count')
 ->addComment('Count it.')
 ->setFinal()
 ->setProtected()
 ->setReturnType('?int') // return types for methods
 ->setBody('return count($items ?: $this->items);');

$method->addParameter('items', []) // $items = []
 ->setReference()           // &$items = []
 ->setType('array');        // array &$items = []

结果是

代码语言:javascript复制
/**
 * Count it.
 */
final protected function count(array &$items = []): ?int
{
 return count($items ?: $this->items);
}

PHP 8.0 中引入的提升参数可以传递给构造函数

代码语言:javascript复制
$method = $class->addMethod('__construct');
$method->addPromotedParameter('name');
$method->addPromotedParameter('args', [])
 ->setPrivate();

结果是

代码语言:javascript复制
public function __construct(
 public $name,
 private $args = [],
) {
}

Readonly 属性和类使用setReadOnly()函数进行标记。如果已存在添加的属性、常量、方法或参数,则会引发异常。

可以使用removeProperty()removeConstant()、 removeMethod()removeParameter()删除类成员。

您还可以将现有的MethodPropertyConstant对象添加到类中:

代码语言:javascript复制
$method = new NettePhpGeneratorMethod('getHandle');
$property = new NettePhpGeneratorProperty('handle');
$const = new NettePhpGeneratorConstant('ROLE');

$class = (new NettePhpGeneratorClassType('Demo'))
 ->addMember($method)
 ->addMember($property)
 ->addMember($const);

您还可以使用cloneWithName()以不同的名称克隆现有方法、属性和常量:

代码语言:javascript复制
$methodCount = $class->getMethod('count');
$methodRecount = $methodCount->cloneWithName('recount');
$class->addMember($methodRecount);

接口或Traits

您可以创建接口和Trait(类InterfaceTypeTraitType

代码语言:javascript复制
$interface = new NettePhpGeneratorInterfaceType('MyInterface');
$trait = new NettePhpGeneratorTraitType('MyTrait');

使用 trait

代码语言:javascript复制
$class = new NettePhpGeneratorClassType('Demo');
$class->addTrait('SmartObject');
$class->addTrait('MyTrait')
 ->addResolution('sayHello as protected')
 ->addComment('@use MyTrait<Foo>');
echo $class;

输出

代码语言:javascript复制
class Demo
{
 use SmartObject;
 /** @use MyTrait<Foo> */
 use MyTrait {
  sayHello as protected;
 }
}

枚举

你可以很容易地创建 PHP 8.1 中引入的枚举,如下所示

代码语言:javascript复制
$enum = new NettePhpGeneratorEnumType('Suit');
$enum->addCase('Clubs');
$enum->addCase('Diamonds');
$enum->addCase('Hearts');
$enum->addCase('Spades');

echo $enum;

输出结果

代码语言:javascript复制
enum Suit
{
 case Clubs;
 case Diamonds;
 case Hearts;
 case Spades;
}

您还可以定义标量等效项并创建一个 “backed” 枚举:

代码语言:javascript复制
$enum->addCase('Clubs', '♣');
$enum->addCase('Diamonds', '♦');

对于每种情况,您可以使用 addComment()addAttribute() 添加注释或属性

匿名类

将 null 作为名称传递,您将得到一个匿名类:

代码语言:javascript复制
$class = new NettePhpGeneratorClassType(null);
$class->addMethod('__construct')
 ->addParameter('foo');

echo '$obj = new class ($val) ' . $class . ';';

输出结果

代码语言:javascript复制
$obj = new class ($val) {

 public function __construct($foo)
 {
 }
};

全局函数

函数的代码由GlobalFunction类生成:

代码语言:javascript复制
$function = new NettePhpGeneratorGlobalFunction('foo');
$function->setBody('return $a   $b;');
$function->addParameter('a');
$function->addParameter('b');
echo $function;

// or use the PsrPrinter for output compliant with PSR-2 / PSR-12 / PER
// echo (new NettePhpGeneratorPsrPrinter)->printFunction($function);

输出结果

代码语言:javascript复制
function foo($a, $b)
{
 return $a   $b;
}

Github:https://github.com/nette/php-generator

0 人点赞