GraphDB查询结果在PHP中执行算术运算报错的解决咨询
你遇到的问题其实很好解决——核心原因是GraphDB返回的数值并不是PHP原生的整数,而是被EasyRdf库封装成了EasyRdf_Literal_Integer对象,PHP没法直接把这个对象当成int来做算术运算,所以才会抛出那个转换错误。下面给你两种靠谱的解决思路:
解决方法
方法一:在PHP中转换对象为原生整数
这是最直接简便的方式,不需要修改SPARQL查询,只需要在做算术运算前,把EasyRdf的字面量对象转换成PHP原生的int类型。
EasyRdf的Literal对象自带getValue()方法可以获取原生值,你也可以直接用强制类型转换。修改你的循环代码即可:
$generalTotal = 0; $sql = "PREFIX c: <http://chinde.ro#> select ?titlu ?numeAutor ?pret ?nrBuc ((?pret * ?nrBuc) as ?total) where { GRAPH c:Vanzari { ?idV c:carte ?idCarte. ?idV c:bucati ?nrBuc. ?idV c:idTranz c:'.$idTranzactie.'. } GRAPH c:Carti { ?idCarte c:titlu ?titlu. ?idCarte c:autor ?idAutor. ?idCarte c:pret ?pret. } GRAPH c:Autori { ?idAutor c:numeAutor ?numeAutor. } }"; $res = $client->query($sql); foreach($res as $row){ print "Total: ".$row->total; // 两种转换方式选其一即可 $generalTotal += $row->total->getValue(); // 方法1:用getValue()获取原生数值 // $generalTotal += (int)$row->total; // 方法2:强制类型转换为int } print $generalTotal;
这样就能正常做算术运算了,因为现在你操作的是PHP原生的整数,而不是EasyRdf的对象。
方法二:让SPARQL直接计算汇总值
如果数据量比较大,让GraphDB直接帮你计算总和会更高效,减少PHP端的循环运算。你可以修改SPARQL查询,用SUM()聚合函数直接得到总金额:
方式1:同时获取明细和总金额
如果需要同时展示每一行的明细和最终总和,可以用窗口函数OVER (),让每一行都返回相同的总金额:
PREFIX c: <http://chinde.ro#> SELECT ?titlu ?numeAutor ?pret ?nrBuc ((?pret * ?nrBuc) as ?total) (SUM(?pret * ?nrBuc) OVER () as ?generalTotal) WHERE { GRAPH c:Vanzari { ?idV c:carte ?idCarte. ?idV c:bucati ?nrBuc. ?idV c:idTranz c:'.$idTranzactie.' . } GRAPH c:Carti { ?idCarte c:titlu ?titlu. ?idCarte c:autor ?idAutor. ?idCarte c:pret ?pret. } GRAPH c:Autori { ?idAutor c:numeAutor ?numeAutor. } }
之后你只需要在循环结束后,取任意一行的$row->generalTotal并转换为原生整数即可得到总金额。
方式2:单独查询总金额
如果只需要最终的总金额,可以把明细查询和汇总查询分开,逻辑更清晰:
// 先查询并展示明细 $sqlDetails = "PREFIX c: <http://chinde.ro#> select ?titlu ?numeAutor ?pret ?nrBuc ((?pret * ?nrBuc) as ?total) where { GRAPH c:Vanzari { ?idV c:carte ?idCarte. ?idV c:bucati ?nrBuc. ?idV c:idTranz c:'.$idTranzactie.'. } GRAPH c:Carti { ?idCarte c:titlu ?titlu. ?idCarte c:autor ?idAutor. ?idCarte c:pret ?pret. } GRAPH c:Autori { ?idAutor c:numeAutor ?numeAutor. } }"; $resDetails = $client->query($sqlDetails); foreach($resDetails as $row){ print "Total: ".$row->total; } // 单独查询总金额 $sqlTotal = "PREFIX c: <http://chinde.ro#> SELECT (SUM(?pret * ?nrBuc) as ?generalTotal) WHERE { GRAPH c:Vanzari { ?idV c:carte ?idCarte. ?idV c:bucati ?nrBuc. ?idV c:idTranz c:'.$idTranzactie.'. } GRAPH c:Carti { ?idCarte c:pret ?pret. } }"; $resTotal = $client->query($sqlTotal); $generalTotal = $resTotal[0]->generalTotal->getValue(); // 转换为原生整数 print $generalTotal;
这种方式能利用数据库的聚合能力提升性能,尤其适合数据量较大的场景。
内容的提问来源于stack exchange,提问作者Cosmin Ch
相关产品推荐
相关产品推荐

