【问题标题】:MYSQL result not returning correctlyMYSQL 结果未正确返回
【发布时间】:2014-06-30 12:17:17
【问题描述】:

所以我有一段代码可以检查您是否关注了某个用户。如果你没有,基本上让你跟随他们。所以这里是

if($_SESSION['loggedIn'] == true){
    $result = $con->prepare("SELECT * FROM followers WHERE follow_from = :username AND follow_to = :post_id");
    $result->bindParam(':username', $username);
    $result->bindParam(':post_id', $follower);
    $result->execute();
    $reprint = $result->fetchAll(PDO::FETCH_ASSOC);
}
print_r($reprint);
if($reprint < 1){
    $stmt = $con->prepare("INSERT INTO followers (follow_from, follow_to) VALUES (:ff, :ft)");
    $stmt->bindValue(':ff', $follower, PDO::PARAM_STR);
    $stmt->bindValue(':ft', $username, PDO::PARAM_STR);
    $stmt->execute();
}
else{
    echo 'Error';
    exit();
}
//Display follower
$stmt1 = $con->prepare("SELECT COUNT(*) AS count FROM followers WHERE follow_to = :username");
$stmt1->bindValue(':username', $username, PDO::PARAM_STR);
$stmt1->execute();
$likes = $stmt1->fetchAll(PDO::FETCH_ASSOC);
print_r($likes);

所以当我运行一次时。我得到了 else 声明的回应。我的问题是为什么会发生这种情况?在数据库中我没有记录,所以我希望它会进入一次。我完全没有错误。 loggedIn 是真的。并且变量正在成功传递。 有任何想法吗?

【问题讨论】:

  • 试试if(sizeof($reprint) &lt; 1)
  • 看起来$reprint 永远不会小于1。你想知道返回的行数。
  • 您是否尝试获取提供的实际错误?不只是您自制的“错误”?您可以将代码包装到 try catch 语句中并捕获错误消息: catch (PDOException $e) { echo 'Error: ' 。 $e->getMessage(); }
  • 是的,我有@Jonast92
  • 它添加了记录,但不限于我一个,这是代码应该做的@AlbinGeorge

标签: php html mysql database pdo


【解决方案1】:

您误用了从fetchAll() 获得的结果。它是一个关联数组,而不是一个标量值。正如您可能已经猜到的那样,它可能是空的。

但是,更重要的是,您的代码存在潜在的竞争条件。如果两个不同的会话试图设置相同的followers 行会发生什么? (诚​​然,在小系统中不太可能发生,但在大系统中可能会发生)。

您实际上所做的只是INSERT 操作。如果您的followers 行在(follow_from,follow_to) 列上有一个唯一键,那么,如果该行已经存在,您将在INSERT 上收到'Duplicate entry' 错误。否则它只会发生。您可以忽略 'Duplicate entry' 错误,因为您只想将该行放入该表中。

所以你的代码应该是这样的:

$stmt = $con->prepare("INSERT 
                         INTO followers (follow_from, follow_to)
                       VALUES (:ff, :ft)");
$stmt->bindValue(':ff', $follower, PDO::PARAM_STR);
$stmt->bindValue(':ft', $username, PDO::PARAM_STR);
$result = $stmt->execute();
if ($result) {
     /* this follow pair was successfully added */
} else {
     /* MySQL may return the error 'Duplicate entry' */
     if (false == stripos($stmt->errorCode,'Duplicate')){
        echo 'Something failed in the insert: ' . '$stmt->errorCode';
     }
     else {
         /* this follow pair was already in your table */
     }
}

专业提示:不要在软件中使用SELECT *;它会弄乱查询优化;它通常会从服务器向您的程序发送比您需要的更多的数据,并且如果您更改表定义,它会使您的程序弹性降低。

专业提示:如果您必须计算与特定 WHERE 语句匹配的行数,请使用 COUNT() 而不是在客户端中获取行并计算它们。如果你得到一百万行怎么办?

【讨论】:

  • +1 用于提及竞争条件。只是一个小评论 - PDOStatement::bindValue 的默认 data_type 值是 PDO::PARAM_STR 无论如何都不需要显式指定它
【解决方案2】:

除了直接比较之外,您还想使用 count($reprint)。 $reprint 是一个数组,而不是一个数字

if(count($reprint) < 1)
{
    $stmt = $con->prepare("INSERT INTO followers (follow_from, follow_to) VALUES (:ff, :ft)");
    $stmt->bindValue(':ff', $follower, PDO::PARAM_STR);
    $stmt->bindValue(':ft', $username, PDO::PARAM_STR);
    $stmt->execute();
}
else
{
    echo 'Error';
    exit();
}

【讨论】:

  • 它仍然没有将它限制在一条记录中,所以我认为它没有检查那一步......
【解决方案3】:

PDOStatement::fetchAll

PDOStatement::fetchAll — 返回一个包含所有结果集行的数组

如果您检查数组的大小,那么您实际上会知道是否发生了什么事。

使用正确的错误处理可以告诉您是否有问题发生在深处:

try
{
    ...
}
catch (PDOException $e)
{
    echo $e->getMessage();
}

您需要启用 PDO 错误显示:

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

如果不检查数组的大小并且没有出错,那么这只是一些逻辑错误。

逻辑错误很可能是

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

没有被执行(包装错误处理应该告诉你原因),所以

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

没有给出正确的值,这意味着你总是会点击 else 语句。

编辑

您最初的问题是“所以当我运行一次时。我得到了 else 语句的回显。[...] 在数据库中我没有记录”但现在您说“它添加了记录,但没有不要只限于我一个”。

您能否更清楚地了解当前的实际问题?

【讨论】:

  • 已经像我在 cmets 中对你说的那样使用 try catch 块......
  • 另外值得一提的是 PDO 默认不会抛出异常/应该通过这种方式启用:$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  • 当它检查它时,我没有。所以它应该运行。但是当我再次运行它时,它会不断添加。
猜你喜欢
  • 1970-01-01
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多