递归PHP函数中的PDO连接错误

时间:2014-10-28 17:51:32

标签: php function recursion pdo

我已经编写了以下功能,可以从商店随机抽取少量商品。最终的项目数组大约在用户投入的价值50美元之内(在这种情况下为300美元)。

<? 
include $_SERVER['DOCUMENT_ROOT'] . '/../../pdocon.inc.php'; 
$pdo->exec("USE database_waww");

$userValue = 300;
$resultArray = array();

function pullItem($spaceleft,&$resultArray){
    global $pdo;

    if ($spaceleft > 50) {
        $getItem=$pdo->query("SELECT id,price FROM items WHERE price < $spaceleft ORDER BY rand() LIMIT 1");
        $itemFound = $getItem->rowCount();

        if ($itemFound == 1) {
            $results = $getItem->fetchAll();
            foreach ($results as $row){
                $spaceleft = $spaceleft-$row["price"];
                $resultArray[]=$row["id"];
                pullItem($spaceleft,$resultArray);
            }
        }
    }
    else {
        $spaceleft = 0;
        pullItem($spaceleft,$resultArray);}
    }
    return $resultArray;
}

$findAllItems = pullItem($userValue,$resultArray);
print_r($findAllItems);
?>

我在递归函数中遇到PDO连接问题。在运行该函数几次后,它返回以下内容:

PHP Warning:  PDO::query(): SQLSTATE[42000]: Syntax error or access violation: 1461 Can't create more than max_prepared_stmt_count statements (current value: 16382)

我相信这是因为pdo连接在递归过程中会成倍增加,但我不确定。我该如何防止这种情况发生?

2 个答案:

答案 0 :(得分:1)

Try using $getItem->closeCursor() before each recursive call to pullItem否则您将从准备好的结果中获得大量未获取的行。如果您仍然需要从$getItem获取项目,则应使用fetchAll将其填充到数组中,而不是为PDO提供大量未获取结果。但是,您应该知道此时的内存限制。

function pullItem($spaceleft,&$resultArray){
    global $pdo;

    if ($spaceleft > 50) {
        $getItem=$pdo->query("SELECT id,price FROM items WHERE price < $spaceleft ORDER BY rand() LIMIT 1");
        $itemFound = $getItem->rowCount();

        if ($itemFound == 1) {
            $results = $getItem->fetchAll();
            $getItem->closeCursor();
            unset($getItem);
            foreach ($results as $row) {
                $spaceleft = $spaceleft-$row["price"];
                $resultArray[]=$row["id"];
                pullItem($spaceleft,$resultArray);
        } else { // In case ($itemFound == 1) isn't satisfied
            $getItem->closeCursor();
            unset($getItem);
        }
    }
    else {
        $spaceleft = 0;
        pullItem($spaceleft,$resultArray);}
    }
    return $resultArray;
}

You should also be safely binding your user-input values to the queries to prevent SQL injection并充分利用PDO库

答案 1 :(得分:0)

销毁一些旧的陈述对象。尝试取消设置$getItem

这里:

if ($spaceleft > 50) {
 unset($getItem);
 // ... Further code