Phpdoc - определение переменных возвращаемого объекта для метода
Я искал это некоторое время, и либо я не использую правильные условия поиска, либо что-то не хватает.
Я пытаюсь выяснить, можно ли использовать 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;
}
}
Вопрос в том, есть ли аналогичная вещь для определения выходных переменных объекта, возвращаемого рассматриваемым методом, чтобы другой программист не должен был открывать этот класс и вручную заглядывать в метод, чтобы увидеть, что возвращается возвращаемый объект
Ответы
Ответ 1
Здесь 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:
Создайте общий тип типа Struct
, предложенный Gordon и расширьте его как свой объект данных, используя @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
}
Ответ 2
У вас есть только два способа документировать структуру класса результата.
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;
}
}
На мой взгляд, этот способ лучше, чем описание в текстовом комментарии, потому что это делает код более очевидным
Ответ 3
Например, с помощью json_decode
сложнее использовать собственные классы вместо stdClass
, но в моем случае я просто создал фиктивный файл с определениями классов, который действительно не загружен, и я добавляю собственные классы как @return
(работает для intelephense в vscode),
PHPdocObjects.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 {}
SomeClass.php
/**
* 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;
}
}