Php 如何从支持IDE自动完成的函数返回多个值?

Php 如何从支持IDE自动完成的函数返回多个值?,php,data-transfer-objects,Php,Data Transfer Objects,假设您有一个从数据库表中选择数据的函数,使用如下查询: select count(id), sum(amount) from payments group by amount; 然后,它将结果传递给另一个函数,该函数循环遍历结果并返回一个数组,数组中的每个元素都引用结果中的一行。例如: private function packageResults(array $results) { $ret = []; foreach ($results as $result) {

假设您有一个从数据库表中选择数据的函数,使用如下查询:

select count(id), sum(amount) from payments group by amount;
然后,它将结果传递给另一个函数,该函数循环遍历结果并返回一个数组,数组中的每个元素都引用结果中的一行。例如:

private function packageResults(array $results)
{
    $ret = [];
    foreach ($results as $result) {
        // add $result['sum'] and $result['count'] to something, then add it to the $ret array
    }

    return $ret;
}
现在,如果在
foreach
循环中,我将结果添加到关联数组或
StdClass
,然后将其添加到
$ret
,您将必须阅读
foreach
中的我的代码,以找出结构(即
StdClass
上设置的属性,或关联数组上设置的键)。我的意思是,由于这两种数据类型都是自由格式的,这意味着它们的键/属性没有文档记录在任何地方,因此使用我的代码的人首先必须转储输出,以了解此函数返回的内容

我可以用什么来告诉用户(和他们的IDE)我返回的数据的结构是什么,这样他们就不必翻阅我的代码来找到它?数据传输对象是为这些东西制作的吗?我之所以考虑数据传输对象,是因为它们是具有自己属性的类,这可以用来知道我的函数究竟返回什么。但是,从软件设计的角度来看,我不确定这是否是正确的方法。

一般来说,要向其他人(IDE)提示函数返回的构造,请使用
@var array$results
phpdoc注释,f.e

/** @var BlahBlah $someVar */
$someVar = new BlahBlah();
$someVar->... (IDE will show you available things with context help now).
要显示用foreach do填充的数组中的对象类型,请执行以下操作:

/** @var BlahBlah[] $someArray */
$someArray = array();

$someArray[1] = new BlahBlah(); // (IDE should help you with context help if you use it later
您也可以在需要的地方调用它:

$x = 0;
foreach ($someArray as $value) {
    /** @var BlahBlah $value */
    $x += $value->getSomeValue(); // (IDE will help you with context help).
}
至于您的情况,如果您知道它将是一个数组,并且您的函数的用户将需要特定的值,那么您可以并且应该为它使用一个新类(DTO,如您所愿)(反正我从来都不喜欢关联数组)。如果正确填充对象的字段,则可以提示用户返回的类型(这些字段也可以进行注释,例如$price将是stdClass,$SomethingElse等),用户无需查看函数内部,因为您返回给他的内容将作为一种接口为他工作

但请记住,这并不是严格意义上的DTO模式。DTO用于f.e.Web服务之间的昂贵通信。我在这里使用这个术语只是为了简化排序。如果你想了解更多关于DTO的信息,你应该在谷歌上搜索关于DTO的信息(无论你走到哪里都有大量的信息)


这里您需要的是一个对象,它是各种数据的接口,它将聚合您需要从数据库获取、操作并传递到前端的值,因此或多或少您需要一个POPO(普通的旧PHP对象,相当于Java的POJO)。

“我可以用什么来告诉用户(以及他们的IDE)我返回的数据的结构是什么,这样他们就不必翻阅我的代码来找到它”——解释你正在使用的数据结构。如果您不想让他们深入研究代码,您需要文档。这回答了你的问题吗?看起来您已经有了解决方案。我可以编写一个PHPDoc,其中包含我返回的每个StdClass上设置的所有属性,或者我返回的关联数组中设置的键。然而,问题是,随着数据结构的变化,PHPDoc可能会过时。我的想法是,当你有一些僵硬的东西,比如一个有自己属性的类,你的代码会记录自己。你明白我的意思吗?代码永远是最好的文档,只是看起来我有点误解了你所说的“不必通过我的代码来找到它”。如果您想从不同的角度解决复制(代码+文档)问题,可以使用代码生成技术为生成的代码和文档使用公共源。。或者从代码中提取文档。。反之亦然。对于一个特定的问题,哪一个是最好的方法完全取决于实际问题。你能给我一个答案中的例子,这样我就可以确保我正确地理解你了吗?假设您正在填写
foreach
。是否创建具有预定义属性的对象?从注释创建对象?等等?你们有单元测试吗?您可以从那里提取文档。您不仅可以显示键(字段),还可以显示每个字段的样本值。不幸的是,正如我所说,我返回的是StdClass数组或关联数组数组。这意味着我没有使用类,我不能说
BlahBlah[]
来说明我返回的是
BlahBlah
s数组。我返回的是StdClass或关联数组。我可以将其更改为其他类型,但我的问题是,它应该是什么?您可以将stdClass用作任何其他类型(因此在我的示例中,只需使用
stdClass
而不是
BlahBlah
)。也可以根据需要嵌套它(对于多维数组)。但我认为您的问题在于,您实际上并不确定返回的是什么(因为它是数组或其他东西——在编写代码时您不知道)。如果不在phpdoc中明确描述它,您将无法提示其他开发人员这是什么。我想IDE在这里帮不了什么忙。我确切地知道我返回的是什么:我返回一个数组,每个元素包括从数据库中检索到的总和和计数。我的问题是,每个元素应该是什么,这样用户就不必
var\u dump()
My返回值来查看它包含什么?我编辑了我的问题,以使我的问题更清楚。我认为这里的问题是我的英语:)如果您知道它将是一个数组,并且您的函数的用户将需要特定的值,那么您可以并且应该为它使用一个新类(
DTO
,如您所愿)(反正我从来都不是关联数组的粉丝)。如果您正确地填充了对象的字段,那么可以提示用户您选择的类型