PDO混合未命名和命名参数

时间:2012-03-12 00:57:28

标签: php pdo

我正在尝试将此用于分页的基本搜索:

$construct = '? AND ? AND..';

$query = $database->prepare('SELECT * FROM something WHERE something LIKE ' . $construct . ' LIMIT :offset, :results');

我混合它们的唯一原因是因为未明确的参数因为PHP错误而不能具有int值:https://bugs.php.net/bug.php?id=44639

但是,如果我不混合它们,我如何使用绑定搜索可变数量的术语?

更新

在搞乱它之后,我使用命名参数和一些循环或多或少地解决了它:

    // build prepared statement
    $construct = '';
    for ($x = 0; $x <= $searchArrayCount; $x++) {
        $construct .= ($x < $searchArrayCount)
                    ? ":var$x OR name LIKE "
                    : ":var$x LIMIT :start, :perPage";
    }

    $query = $database->prepare('SELECT something FROM something WHERE name LIKE ' . $construct);

    // bind parameters
    for ($x = 0; $x <= $searchArrayCount; $x++) {
        $searchArray[$x] = "%$searchArray[$x]%";
        $query->bindParam(":var$x", $searchArray[$x]);
    }

    $query->bindParam(':start', $searchArrayCount, PDO::PARAM_INT);
    $query->bindParam(':perPage', $perPage, PDO::PARAM_INT);

如果有更好的解决方法,我很乐意被告知。

2 个答案:

答案 0 :(得分:1)

未命名的参数可以包含int值。只需在bind函数中定义显式类型。

变量数据类型可能存在问题。最好在之前使用intval()函数。

您的未命名数据类型的解决方案如下所示:

$counter = 0;

//build prepared statement

$query = $database->prepare('SELECT something FROM something WHERE 0 OR '.
implode(' OR ', array_fill(0 , $searchArrayCount, 'name LIKE ?')).
        ' LIMIT ?, ?');

// bind parameters
foreach($searchArray as $value)
{
    $counter++;
    $query->bindValue($counter, ('%'.$value.'%'), PDO::PARAM_STR);
}

$query->bindValue(($counter+1), ($page*$perPage), PDO::PARAM_INT);
$query->bindParam(($counter+2), $perPage, PDO::PARAM_INT);

注意我在bindValue()之前使用了bindParam()。 请注意LIMIT的第一个参数。如果计数在此处,则选择将从数据末尾开始,不会返回任何行。

答案 1 :(得分:0)

面对类似的问题,最后我在LIMIT子句中跳过了绑定参数:

sprintf('LIMIT %d, %d', $offset, $size);

另一种解决方法(如果您的系统支持它)是切换到本机参数绑定。显然,它是表现出这种行为的仿真层:

$database->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);