我试图弄清楚是否可以使用 PHPdoc 来定义函数或对象方法返回的对象属性。
假设我有以下课程:
class SomeClass {
public function staffDetails($id){
$object = new stdClass();
$object->type = "person";
$object->name = "dave";
$object->age = "46";
return $object;
}
}
现在,定义输入参数就很容易了。
/**
* Get Staff Member Details
*
* @param string $id staff id number
*
* @return object
*/
class SomeClass {
public function staffDetails($id){
$object = new stdClass();
$object->type = "person";
$object->name = "dave";
$object->age = "46";
return $object;
}
}
问题是定义相关方法返回的输出对象(stdClass)的属性是否有类似的事情。这样另一个程序员就不必打开此类并手动查看该方法来查看返回对象返回了什么?
现在已经过去了 4 年,但似乎仍然没有一种方法可以像您的问题中最初描述的那样注释 stdClass 对象的属性。
在 PSR-5 中提出了集合,但似乎已被否决:https://github.com/php-fig/fig-standards/blob/211063eed7f4d9b4514b728d7b1810d9b3379dd1/proposed/phpdoc.md#collections
似乎只有两个选项可用:
选项1:
创建一个表示数据对象的普通类并注释属性。
class MyData
{
/**
* This is the name attribute.
* @var string
*/
public $name;
/**
* This is the age attribute.
* @var integer
*/
public $age;
}
选项2:
按照
Gordon的建议创建一个通用的
Struct
类型类,并将其扩展为您的数据对象,使用@property注释来定义可以使用__get
和__set
访问哪些通用值。
class Struct
{
/**
* Private internal struct attributes
* @var array
*/
private $attributes = [];
/**
* Set a value
* @param string $key
* @param mixed $value
*/
public function __set($key, $value)
{
$this->attributes[$key] = $value;
}
/**
* Get a value
* @param string $key
* @return mixed
*/
public function __get($key)
{
return isset($this->attributes[$key]) ? $this->attributes[$key] : null;
}
/**
* Check if a key is set
* @param string $key
* @return boolean
*/
public function __isset($key)
{
return isset($this->attributes[$key]) ? true : false;
}
}
/**
* @property string $name
* @property integer $age
*/
class MyData extends Struct
{
// Can optionally add data mutators or utility methods here
}
您只有两种方法来记录结果类的结构。
1.可以描述评论文本的结构。例如:
class SomeClass
{
/**
* Getting staff detail.
* Result object has following structure:
* <code>
* $type - person type
* $name - person name
* $age - person age
* </code>
* @param string $id staff id number
*
* @return stdClass
*
*/
public function staffDetails($id){
$object = new stdClass();
$object->type = "person";
$object->name = "dave";
$object->age = "46";
return $object;
}
}
2.可以创建一个继承stdClass的数据类型,并且它会有一个结果对象的注释。例如:
/**
* @property string $type Person type
* @property string $name Person name
* @property integer $age Person age
*/
class DTO extends stdClass
{}
并在其他课程中使用它
class SomeClass {
/**
* Getting staff detail.
*
* @param string $id staff id number
*
* @return DTO
*
*/
public function staffDetails($id){
$object = new DTO();
$object->type = "person";
$object->name = "dave";
$object->age = "46";
return $object;
}
}
在我看来,这种方式比文字注释中的描述更好,因为它使代码更加明显
如果您使用 PHP 7,您可以定义匿名类。
class SomeClass {
public function staffDetails($id){
$object = (new class() extends stdClass {
public /** @var string */ $type;
public /** @var string */ $name;
public /** @var int */ $age;
});
$object->type = "person";
$object->name = "dave";
$object->age = 46;
return $object;
}
}
它适用于我的 IDE(在 NetBeans 中测试)
我在 PhpStorm 中用于自动完成的 hack:
<?php
/*
meta.php
never included
*/
/**
* @property string $type
* @property string $name
* @property string $age
*/
class StaffDetails_meta {}
<?php
/*
SomeClass.php
eventually included
*/
class SomeClass
{
/**
* Get Staff Member Details
*
* @param string $id staff id number
*
* @return StaffDetails_meta
*/
public function staffDetails($id)
{
$object = new stdClass();
$object->type = "person";
$object->name = "dave";
$object->age = "46";
return $object;
}
}
(new SomeClass)->staffDetails('staff_id')->
P.S.:我知道,差不多10年过去了,但仍然是现实
例如,使用自己的类而不是
json_decode
更难,但在我的例子中,我只是创建了带有类定义的虚拟文件,该文件实际上没有加载,我将自己的类添加为stdClass
(适用于 vscode 上的 intelephense)。PHPdocObjects.php
@return
SomeClass.php
/**
* class only for PHPdoc (do not include)
*/
class Member {
/** @var string */
public $type;
/** @var string */
public $name;
/** @var string */
public $age;
}
/**
* Other format
*
* @property string $type;
* @property string $name;
* @property string $age;
*/
class MemberAlt {}
。 PHPStorm 据说支持这种语法,但我在测试中得到的结果非常复杂,所以 YMMV。
/**
* Get Staff Member Details
*
* @param string $id staff id number
*
* @return Member I'm in fact stdClass
*/
class SomeClass {
public function staffDetails($id){
$object = json_decode('{"type":"person","name":"dave","age":"46"}');
return $object;
}
}