Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 哪里有问题_Php_Mysql_Doctrine Orm_Doctrine_Silex - Fatal编程技术网

Php 哪里有问题

Php 哪里有问题,php,mysql,doctrine-orm,doctrine,silex,Php,Mysql,Doctrine Orm,Doctrine,Silex,在开始之前,我相信我已经尝试了上一篇文章中的所有内容: 因此,我有一个Silex应用程序通过composer使用条令连接到MySQL数据库(条令/dbal 2.2.*) 我尝试运行的查询生成器如下所示: $qb = $this->db->createQueryBuilder(); $stmt = $qb->select('DAY(datefield1) x, COUNT(*) value') ->from('table1', 's') ->join

在开始之前,我相信我已经尝试了上一篇文章中的所有内容:

因此,我有一个Silex应用程序通过composer使用条令连接到MySQL数据库(条令/dbal 2.2.*)

我尝试运行的查询生成器如下所示:

$qb = $this->db->createQueryBuilder();

$stmt = $qb->select('DAY(datefield1) x, COUNT(*) value')
    ->from('table1', 's')
    ->join('s', 'table2', 't', 't.key=s.key')
    ->where('MONTH(datefield1) = :billMonth')
    ->andWhere('YEAR(datefield1) = :billYear')
    ->andWhere('t.key IN (:keylist)')
    ->groupBy('x')
    ->orderBy('x', 'asc')
    ->setParameter(':billMonth', $month)
    ->setParameter(':billYear', $year)
    ->setParameter(':keylist', implode(",", $keylist))
    ->execute();

return $stmt->fetchAll(\PDO::FETCH_ASSOC);
参数为(月=8)(年=2014)(键列表=数组(1,2,3,4))

查询没有失败,但奇怪的是,它没有包含它应该包含的所有数据

我尝试了->setParameter(':keylist',$keylist)来使用原始数组,但没有成功

我也尝试过这种语法:

$qb->add('where',$qb->expr()->in('r.winner',数组('1'))

但是,这引发了一个错误,因为in方法在expression builder类中不可用


有人能帮我看一下这一点,省得我硬编码SQL吗?

DB占位符/参数用于单个值。由于在数组上调用
内爆()
,您正在传入一个单片字符串
1,2,3,4
。鉴于:

WHERE t.key IN (:keylist)
然后,此查询将作为

WHERE t.key IN ('1,2,3,4')
                ^-------^---note the quotes
WHERE t.key = '1,2,3,4'
因为它是一个字符串,并且在
in
子句中只有一个字符串,所以它是

WHERE t.key IN ('1,2,3,4')
                ^-------^---note the quotes
WHERE t.key = '1,2,3,4'
而不是

WHERE (t.key = 1 OR t.key = 2 OR ....)
你希望是这样。设置多个参数,数组中的每个值对应一个参数,或者直接将字符串嵌入查询中

->andWhere('t.key IN (' . implode(',', $keylist) . ')')

这当然会使您面临sql注入攻击漏洞。

DB占位符/参数用于单个值。由于在数组上调用
内爆()
,您正在传入一个单片字符串
1,2,3,4
。鉴于:

WHERE t.key IN (:keylist)
然后,此查询将作为

WHERE t.key IN ('1,2,3,4')
                ^-------^---note the quotes
WHERE t.key = '1,2,3,4'
因为它是一个字符串,并且在
in
子句中只有一个字符串,所以它是

WHERE t.key IN ('1,2,3,4')
                ^-------^---note the quotes
WHERE t.key = '1,2,3,4'
而不是

WHERE (t.key = 1 OR t.key = 2 OR ....)
你希望是这样。设置多个参数,数组中的每个值对应一个参数,或者直接将字符串嵌入查询中

->andWhere('t.key IN (' . implode(',', $keylist) . ')')

这当然会使您面临sql注入攻击漏洞。

在子句中处理此类
的正确方法非常简单:

$qb = $this->db->createQueryBuilder();

$stmt = $qb->(...)
    ->andWhere('t.key IN (:keylist)')
    ->setParameter(':keylist', $keylist)
    ->getQuery()
    ->getArrayResult();
我已经用过十几次了,它很有效——doctrine足够聪明,可以处理你的
$keylist
数组

另一件事是,我不知道为什么要使用这里冗余的
fetchAll
方法-
execute()
就足够了。也许这是你问题的根源


我的建议是:尝试在开发模式(
app\u dev.php
)下启动操作,并检查您的
app/logs/dev.log
——您将发现所有sql查询都已执行。验证数据库是否返回您期望从条令中得到的数据。

子句中处理此类
的正确方法尽可能简单:

$qb = $this->db->createQueryBuilder();

$stmt = $qb->(...)
    ->andWhere('t.key IN (:keylist)')
    ->setParameter(':keylist', $keylist)
    ->getQuery()
    ->getArrayResult();
    ->add('where', $qb->expr()->andX(                    
                        $qb->expr()->in('r.winner', ':winner')
                    ))
                ->setParameters(array(
                        "winner" => $winners,
                        "billMonth", $month,
                     // add all params here
                    ));
我已经用过十几次了,它很有效——doctrine足够聪明,可以处理你的
$keylist
数组

另一件事是,我不知道为什么要使用这里冗余的
fetchAll
方法-
execute()
就足够了。也许这是你问题的根源


我的建议是:尝试在开发模式(
app\u dev.php
)下启动操作,并检查您的
app/logs/dev.log
——您将发现所有sql查询都已执行。验证数据库是否返回您期望从条令中得到的数据。

如果您自己构建sql查询,则可以使用DBAL的PARAM_INT_数组类型:

    ->add('where', $qb->expr()->andX(                    
                        $qb->expr()->in('r.winner', ':winner')
                    ))
                ->setParameters(array(
                        "winner" => $winners,
                        "billMonth", $month,
                     // add all params here
                    ));
use Doctrine\DBAL\Connection as DB;

$db->executeQuery('SELECT DAY(datefield1) x, COUNT(*) value
FROM table1 s
JOIN table2 t ON t.key=s.key
WHERE MONTH(datefield1) = :billMonth
    AND YEAR(datefield1) = :billYear
    AND t.key IN (:keylist)
GROUP BY x
ORDER BY x ASC',
array(':billMonth' => $month, ':billYear' => $year, ':keylist' => $keylist),
array(':billMonth' => \PDO::PARAM_INT, ':billYear' => \PDO::PARAM_INT, ':keylist' => DB::PARAM_INT_ARRAY
)->fetchAll(\PDO::FETCH_ASSOC);

如果您自己构建sql查询,则可以使用DBAL的PARAM_INT_数组类型:

use Doctrine\DBAL\Connection as DB;

$db->executeQuery('SELECT DAY(datefield1) x, COUNT(*) value
FROM table1 s
JOIN table2 t ON t.key=s.key
WHERE MONTH(datefield1) = :billMonth
    AND YEAR(datefield1) = :billYear
    AND t.key IN (:keylist)
GROUP BY x
ORDER BY x ASC',
array(':billMonth' => $month, ':billYear' => $year, ':keylist' => $keylist),
array(':billMonth' => \PDO::PARAM_INT, ':billYear' => \PDO::PARAM_INT, ':keylist' => DB::PARAM_INT_ARRAY
)->fetchAll(\PDO::FETCH_ASSOC);

您应该通过如下所示的querybuilder使用in表达式,并更改设置参数的方式:

->andWhere($qb->expr()->in('t.key', ':keylist'))
完整代码:

$qb = $this->db->createQueryBuilder();
$stmt = $qb->select('DAY(datefield1) x, COUNT(*) value')
    ->from('table1', 's')
    ->join('s', 'table2', 't', 't.key=s.key')
    ->where('MONTH(datefield1) = :billMonth')
    ->andWhere('YEAR(datefield1) = :billYear')
    ->andWhere('t.key')
    ->andWhere($qb->expr()->in('t.key', ':keylist'))
    ->groupBy('x')
    ->orderBy('x', 'asc')
    ->setParameter(':billMonth', $month)
    ->setParameter(':billYear', $year)
    ->setParameter(':keylist', $keylist)
    ->execute();

return $stmt->fetchAll(\PDO::FETCH_ASSOC);

您应该通过如下所示的querybuilder使用in表达式,并更改设置参数的方式:

->andWhere($qb->expr()->in('t.key', ':keylist'))
完整代码:

$qb = $this->db->createQueryBuilder();
$stmt = $qb->select('DAY(datefield1) x, COUNT(*) value')
    ->from('table1', 's')
    ->join('s', 'table2', 't', 't.key=s.key')
    ->where('MONTH(datefield1) = :billMonth')
    ->andWhere('YEAR(datefield1) = :billYear')
    ->andWhere('t.key')
    ->andWhere($qb->expr()->in('t.key', ':keylist'))
    ->groupBy('x')
    ->orderBy('x', 'asc')
    ->setParameter(':billMonth', $month)
    ->setParameter(':billYear', $year)
    ->setParameter(':keylist', $keylist)
    ->execute();

return $stmt->fetchAll(\PDO::FETCH_ASSOC);

好的,自从我上次查看以来,这个旧线程已经看到了一些动作,我想确认这个问题已经解决很久了-setParameter中的第三个参数允许您通知Doctrine如何处理数组:

    $qb = $this->db->createQueryBuilder();

    $stmt = $qb
        ->select('*')
        ->from(self::DB_TABLE, 'x')
        ->where('x.service IN (:services)')
        ->orderBy('x.session_end', 'DESC')
        ->addOrderBy('x.direction', 'DESC')
        ->setParameter(':services', $services, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY)
        ->setFirstResult($offset)
        ->setMaxResults($count)
        ->execute();

    $result = $stmt->fetchAll(\PDO::FETCH_ASSOC);

好的,自从我上次查看以来,这个旧线程已经看到了一些动作,我想确认这个问题已经解决很久了-setParameter中的第三个参数允许您通知Doctrine如何处理数组:

    $qb = $this->db->createQueryBuilder();

    $stmt = $qb
        ->select('*')
        ->from(self::DB_TABLE, 'x')
        ->where('x.service IN (:services)')
        ->orderBy('x.session_end', 'DESC')
        ->addOrderBy('x.direction', 'DESC')
        ->setParameter(':services', $services, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY)
        ->setFirstResult($offset)
        ->setMaxResults($count)
        ->execute();

    $result = $stmt->fetchAll(\PDO::FETCH_ASSOC);

嗨,马克,谢谢你的回答。我可以看到我对内爆的明显疏忽,并感谢你指出这一点。我不确定谁应该对否决票负责——也许他们会有更好的答案,但现在我将使用你建议的方法,因为它对我很有效。阵列在其他地方硬编码,因此无需注入afaik!谢谢你的回答。我可以看到我对内爆的明显疏忽,并感谢你指出这一点。我不确定谁应该对否决票负责——也许他们会有更好的答案,但现在我将使用你建议的方法,因为它对我很有效。阵列在其他地方硬编码,因此无需注入afaik!谢谢->setParameter(':keylist',$keylist)是正确的语法。D2足够聪明,可以处理参数数组。您确定没有获取所有数据吗?您可以尝试将生成的sql粘贴到数据库连接器中。是的,我已经尝试过了,它会生成不同的数据。事实上,它不返回任何数据,即查询失败:(可能它也受到int/string转换问题的困扰?如果去掉其他where条件,你会得到$keylist记录吗?t.key是字符串还是整数?你没有名为key的数据库列吗?因为这是一个保留字,会导致选择问题。当你说查询失败时,你得到的是实际的sql e吗错误或只是没有记录?您使用的是条令连接对象,而不是orm实体管理器。因此,有一个名为key的列是一个no no。D2不会转义列名。我实际上没有一个名为key的列,对混淆表示歉意-我试图概括该语句,但看看这是如何使它看起来像一个问题的(我不经常在这里发帖)这个专栏叫som