价值绑定未按预期工作。为什么?

时间:2018-03-30 18:52:33

标签: php symfony doctrine-orm

我正在使用Symfony 3.4.6 + Doctrine - 这些是我的主要“工具”。

用MySQL编写的两个相同的查询给出了不同的结果。为什么?我不知道。希望有人能帮助我。

首先(工作版):

$connection = $this->getEntityManager()->getConnection();
        $result = $connection->fetchAll('
        SELECT *
        FROM payment_transaction
        LEFT JOIN `user` ON `user`.`id` = payment_transaction.from_id
        WHERE payment_transaction.to_id = :user
              AND payment_transaction.type IN ("' . implode('", "', $type) . '")
              AND payment_transaction.registered_at >= :from
              AND payment_transaction.registered_at <= :to
        ', [
            "user" => $user->getId(),
            "from" => $from->format("Y-m-d H:i:s"),
            "to" => $to->format("Y-m-d H:i:s"),
        ]);

第二(给出不正确的结果):

$connection = $this->getEntityManager()->getConnection();
        $result = $connection->fetchAll('
        SELECT *
        FROM payment_transaction
        LEFT JOIN `user` ON `user`.`id` = payment_transaction.from_id
        WHERE payment_transaction.to_id = :user
              AND payment_transaction.type IN (:types)
              AND payment_transaction.registered_at >= :from
              AND payment_transaction.registered_at <= :to
        ', [
            "user" => $user->getId(),
            "from" => $from->format("Y-m-d H:i:s"),
            "to" => $to->format("Y-m-d H:i:s"),
            "types" => '"' . implode('", "', $type) . '"',
        ]);

第三(给出不正确的结果):

$connection = $this->getEntityManager()->getConnection();
        $result = $connection->fetchAll('
        SELECT *
        FROM payment_transaction
        LEFT JOIN `user` ON `user`.`id` = payment_transaction.from_id
        WHERE payment_transaction.to_id = :user
              AND payment_transaction.type IN (:types)
              AND payment_transaction.registered_at >= :from
              AND payment_transaction.registered_at <= :to
        ', [
            "user" => $user->getId(),
            "from" => $from->format("Y-m-d H:i:s"),
            "to" => $to->format("Y-m-d H:i:s"),
            "types" => "\"" . implode("\", \"", $type) . "\"",
        ]);

第四次(给出错误 - Array to string conversion):

$connection = $this->getEntityManager()->getConnection();
        $result = $connection->fetchAll('
        SELECT *
        FROM payment_transaction
        LEFT JOIN `user` ON `user`.`id` = payment_transaction.from_id
        WHERE payment_transaction.to_id = :user
              AND payment_transaction.type IN (:types)
              AND payment_transaction.registered_at >= :from
              AND payment_transaction.registered_at <= :to
        ', [
            "user" => $user->getId(),
            "from" => $from->format("Y-m-d H:i:s"),
            "to" => $to->format("Y-m-d H:i:s"),
            "types" => $types,
        ]);

如果我使用:types函数生成的结果替换implode,则第二次和第三次查询工作正常。

问题出在哪里 - INimplode?结合?

谢谢。

更新(22:29)

最新的代码段:

public function history(User $user, \DateTime $from, \DateTime $to,
                            array $type = [PaymentTransaction::PAYMENT_TRANSACTION_TYPE_SYSTEM,
                                PaymentTransaction::PAYMENT_TRANSACTION_TYPE_PARTNERSHIP,
                                PaymentTransaction::PAYMENT_TRANSACTION_TYPE_PERSONAL]): array
    {
        $connection = $this->getEntityManager()->getConnection();
        $result = $connection->fetchAll('
        SELECT payment_transaction.*, `user`.`first_name` as `user_first_name`, `user`.`last_name` as `user_last_name`, `user`.`email` as `user_email`
        FROM payment_transaction
        LEFT JOIN `user` ON `user`.`id` = payment_transaction.from_id
        WHERE payment_transaction.to_id = :user
              AND payment_transaction.type IN (:types)
              AND payment_transaction.registered_at >= :from
              AND payment_transaction.registered_at <= :to
        ORDER BY payment_transaction.id DESC
        ', [
            "user" => $user->getId(),
            "from" => $from->format("Y-m-d H:i:s"),
            "to" => $to->format("Y-m-d H:i:s"),
            "types" => $type,
        ], [
            \PDO::PARAM_INT,
            \PDO::PARAM_STR,
            \PDO::PARAM_STR,
            Connection::PARAM_STR_ARRAY,
        ]);

        return $result;
    }

它仍然给我一个错误:

' with params [134, ["system"], "2018-02-28 21:24:47", "2018-03-30 21:24:47"]:
Notice: Array to string conversion

更新(22:50)

在用?符号替换占位符后,查询正在运行。问题仍然存在 - 为什么它不与:name - 占位符合作?

2 个答案:

答案 0 :(得分:1)

'... AND type IN (:types) ...' // sql query

要使用DBAL API对其进行存档,您需要按原样绑定元素数组:

"types" => $types, // $types = ['A', 'B', 'C'] or [1, 2, 3]

传递第三个参数的类型:

Connection::PARAM_STR_ARRAY // or ::PARAM_INT_ARRAY for integer list

示例:

use Doctrine\DBAL\Connection; // don't forget this

// ...

$connection = $this->getEntityManager()->getConnection();
$result = $connection->fetchAll('
    SELECT *
    FROM payment_transaction
    LEFT JOIN `user` ON `user`.`id` = payment_transaction.from_id
    WHERE payment_transaction.to_id = :user
          AND payment_transaction.type IN (:types)
          AND payment_transaction.registered_at >= :from
          AND payment_transaction.registered_at <= :to
    ', [
        "user" => $user->getId(),
        "from" => $from->format("Y-m-d H:i:s"),
        "to" => $to->format("Y-m-d H:i:s"),
        "types" => $types,
    ], [
        \PDO::PARAM_INT,
        \PDO::PARAM_STR,
        \PDO::PARAM_STR,
        Connection::PARAM_STR_ARRAY,
    ]);

答案 1 :(得分:0)

通过将PDO - 类型替换为DBAL - 类型来解决。

[
            "userId" => $user->getId(),
            "types" => $type,
            "from" => $from->format("Y-m-d H:i:s"),
            "to" => $to->format("Y-m-d H:i:s"),
        ], [
            "userId" => Type::INTEGER,
            "types" => Type::SIMPLE_ARRAY,
            "from" => Type::STRING,
            "to" => Type::STRING,
        ]

感谢GitHub的Ocramius:https://github.com/doctrine/doctrine2/issues/7166