我正在使用(简化的)类布局构建一个可组合的表单构建器,如下所示:
Field.php <- parent class
Boolean.php
Choice.php
Fieldset.php
Form.php
Text.php
我喜欢以流利的方式撰写一份与此相似的表格:
$form = new Form('data');
$form->children([
Field::Text('username')->label('username'),
Field::Text('password')->label('password'),
Field::Boolean('remember')->label('remember me')
]);
为了实现Field::Fieldtype()->...
语法糖实例化,而不是(new FieldType())->...
,我有一个__callStatic()
方法,如下所示:
abstract class Field
{
/**
* @param $name
* @param $arguments
* @return Field
* @throws FormsException
*/
public static function __callStatic($name, $arguments)
{
$className = __NAMESPACE__ . '\\' . ucfirst($name);
if (!class_exists($className)) {
throw new FormsException('Class ' . $name . ' is not a registered field type');
}
$reflect = new ReflectionClass($className);
return $reflect->newInstanceArgs($arguments);
}
...
}
这是正常的,为了使IDE能够使用它,我有以下docblock:
/**
* @method static \Forms\Boolean Boolean(string $name='')
* @method static \Forms\Choice Choice(string $name='')
* @method static \Forms\Fieldset Fieldset(string $name='')
* @method static \Forms\File File(string $name='')
* @method static \Forms\Text Text(string $name='')
* @method static \Forms\MultipleChoice MultipleChoice(string $name='')
* @method static \Forms\JSON JSON(string $name='')
* @method static \Forms\TextArray TextArray(string $name='')
* @method static \Forms\Submit Submit(string $name='')
*/
这也正常运行,使用体面的IDE时,编码体验非常令人满意。
我还想做的是(在开发期间的某个时刻)自动生成此docblock,它会扫描给定目录中的类,并生成这些docblock提示,这样如果我展开Field类型在应用程序的另一部分,新的字段类型还将告知IDE它们的存在以及每个添加的类的返回类型。
问题在于我不希望在我的类文件中写入代码,原因显而易见,所以唯一合乎逻辑的替代方法是将docblock放在文件外部并以某种方式包含在IDE有意义的方式中它的。
所以我的问题是:有没有办法在PHP中解耦docblocks及其引用类,这样IDE仍然可以将两个和两个放在一起并理解这个docblock是指那个班级?