composer require nette/php-generator
从一个使用ClassType
创建类的示例开始:
$class = new Nette\PhpGenerator\ClassType('Demo');
$class
->setFinal()
->setExtends(ParentClass::class)
->addImplement(Countable::class)
->addComment("Class description.\nSecond line\n")
->addComment('@property-read Nette\Forms\Form $form');
// generate code simply by typecasting to string or using echo:
echo $class;
这将返回
/**
* Class description
* Second line
*
* @property-read Nette\Forms\Form $form
*/
final class Demo extends ParentClass implements Countable
{
}
要生成代码,您还可以使用所谓的printClass
,与echo $class
不同,它可以进一步配置:
$printer = new Nette\PhpGenerator\Printer;
echo $printer->printClass($class);
您可以添加常量和属性
$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'
这将生成
final protected const int ID = 123;
/** @var int[] */
private static $items = [1, 2, 3];
public ?array $list = null;
您可以添加方法
$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 = []
结果是
/**
* Count it.
*/
final protected function count(array &$items = []): ?int
{
return count($items ?: $this->items);
}
PHP 8.0 中引入的提升参数可以传递给构造函数
$method = $class->addMethod('__construct');
$method->addPromotedParameter('name');
$method->addPromotedParameter('args', [])
->setPrivate();
结果是
public function __construct(
public $name,
private $args = [],
) {
}
Readonly 属性和类使用setReadOnly()
函数进行标记。如果已存在添加的属性、常量、方法或参数,则会引发异常。
可以使用removeProperty()
、removeConstant()、
removeMethod()
或 removeParameter()
删除类成员。
您还可以将现有的Method
、Property
或Constant
对象添加到类中:
$method = new Nette\PhpGenerator\Method('getHandle');
$property = new Nette\PhpGenerator\Property('handle');
$const = new Nette\PhpGenerator\Constant('ROLE');
$class = (new Nette\PhpGenerator\ClassType('Demo'))
->addMember($method)
->addMember($property)
->addMember($const);
您还可以使用cloneWithName()
以不同的名称克隆现有方法、属性和常量:
$methodCount = $class->getMethod('count');
$methodRecount = $methodCount->cloneWithName('recount');
$class->addMember($methodRecount);
您可以创建接口和Trait(类InterfaceType
和TraitType
:
$interface = new Nette\PhpGenerator\InterfaceType('MyInterface');
$trait = new Nette\PhpGenerator\TraitType('MyTrait');
使用 trait
$class = new Nette\PhpGenerator\ClassType('Demo');
$class->addTrait('SmartObject');
$class->addTrait('MyTrait')
->addResolution('sayHello as protected')
->addComment('@use MyTrait<Foo>');
echo $class;
输出
class Demo
{
use SmartObject;
/** @use MyTrait<Foo> */
use MyTrait {
sayHello as protected;
}
}
你可以很容易地创建 PHP 8.1 中引入的枚举,如下所示
$enum = new Nette\PhpGenerator\EnumType('Suit');
$enum->addCase('Clubs');
$enum->addCase('Diamonds');
$enum->addCase('Hearts');
$enum->addCase('Spades');
echo $enum;
输出结果
enum Suit
{
case Clubs;
case Diamonds;
case Hearts;
case Spades;
}
您还可以定义标量等效项并创建一个 “backed” 枚举:
$enum->addCase('Clubs', '♣');
$enum->addCase('Diamonds', '♦');
对于每种情况,您可以使用 addComment()
或 addAttribute()
添加注释或属性
将 null 作为名称传递,您将得到一个匿名类:
$class = new Nette\PhpGenerator\ClassType(null);
$class->addMethod('__construct')
->addParameter('foo');
echo '$obj = new class ($val) ' . $class . ';';
输出结果
$obj = new class ($val) {
public function __construct($foo)
{
}
};
函数的代码由GlobalFunction类生成:
$function = new Nette\PhpGenerator\GlobalFunction('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 Nette\PhpGenerator\PsrPrinter)->printFunction($function);
输出结果
function foo($a, $b)
{
return $a + $b;
}
Github:https://github.com/nette/php-generator