使用准备语句的简单PHP选择显示无结果

时间:2017-08-01 00:34:39

标签: php mysql sql

我正在尝试创建一个简单的PHP脚本,使用预准备语句选择数据。目前,我使用this教程作为来源。当我调用我的脚本时,我在error.log中没有错误,但是没有显示数据。这是我的剧本:

<?php
$servername = "xxx";
$username = "xxx";
$password = "xxx";
$dbname = "xxx";  

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 

$stmt = $conn->prepare("SELECT * FROM Regions WHERE id=?");
$stmt->bind_param("i", $_POST['id']);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows > 0) {
  while($row = $result->fetch_assoc()) {
    $name[] = $row['name'];
    $center[] = $row['center'];
    $content_string[] = $row['content_string'];

  }
}
$stmt->close();
echo $name;
echo $center;
echo $content_string;

$conn->close();
?>

我的结构如下:

enter image description here

我试图通过调用来访问输出 http://URL/php/protected.php?id=1http://URL/php/protected.php无济于事。我已经缩小了错误发生的原因,因为if($result->num_rows > 0)永远不会被评估。从那以后,我认为错误必须在我的SQL语句中。

3 个答案:

答案 0 :(得分:4)

我实际上是该教程的作者大声笑。你检查了错误处理部分吗?您应该能够通过以下方式获得有意义的信息。

例如

if ( !$stmt = $conn->prepare("SELECT * FROM Regions WHERE id=?") ) 
 echo "Prepare Error: ($conn->errno) $conn->error";
if ( !$stmt->bind_param("i", $_POST['id']) )
  echo "Binding Parameter Error: ($conn->errno) $conn->error";
if ( !$stmt->execute() ) 
 echo "Execute Error: ($stmt->errno)  $stmt->error";
if ( !$stmt->get_result() ) //Only for select with get_result()
 echo "Getting Result Error: ($conn->errno) $conn->error";
if ( !$stmt->store_result() ) //Only for select with bind_result()
 echo "Storing Result Error: ($conn->errno) $conn->error";
$stmt->close();

编辑:更优雅的方法是使用异常处理。请记住,如果在创建连接之前使用 ,那么它将在出错时输出数据库密码。无论如何,您应该使用mysqli_report()或自定义异常处理程序打印到错误日志,但值得指出。另外,请确保在php.ini

中执行try/catchdisplay_errors = Off
log_errors = On

但正如RichGoldMd指出的那样,你也应该做类似下面的事情,这是我经历中出错的一个非常常见的原因。

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$stmt = $conn->prepare("SELECT * FROM Regions WHERE id=?");
$stmt->bind_param("i", $_POST['id']);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows > 0) {
  while($row = $result->fetch_assoc()) {
    $name[] = $row['name'];
    $center[] = $row['center'];
    $content_string[] = $row['content_string'];

  }
}
$stmt->close();

答案 1 :(得分:0)

您是否拥有正在运行的服务器(VPS或专用),或者这是一个共享托管环境?当我尝试运行你的代码时,我收到了这个错误:

PHP Fatal error:  Call to undefined method mysqli_stmt::get_result()

get_result行上的致命错误肯定会阻止评估if($result->num_rows > 0)。该错误消息导致我this question,这表明如果没有安装mysqlnd扩展,您将无法使用get_result。在Debian / Ubuntu上使用PHP 5,这将是php5-mysqlnd包。

如果您无法安装该扩展程序,这确实是您的问题,那么您将无法使用get_result,这意味着您需要使用更为丑陋的bind_result方法,看起来像这样:

<?php
$servername = "xxx";
$username = "xxx";
$password = "xxx";
$dbname = "xxx";  

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 

$stmt = $conn->prepare("SELECT name, center, content_string FROM Regions WHERE id=?");
$stmt->bind_param("i", $_POST['id']);
$stmt->execute();
$stmt->bind_result($row_name, $row_center, $row_content_string);
if($result->num_rows > 0) {
  while($row = $result->fetch_assoc()) {
    $name[] = $row_name;
    $center[] = $row_center;
    $content_string[] = $row_content_string;

  }
}
$stmt->close();
echo $name;
echo $center;
echo $content_string;

$conn->close();
?>

最好不要在使用SELECT *时使用bind_result,因为数据库返回的列顺序很重要。

就个人而言,我建议使用PDO而不是mysqli,因为我认为语法比mysqli更友好,并且与我上面描述的那些相比,“陷阱”要少得多。 Here's一个体面的教程,向您介绍PDO。

答案 2 :(得分:-1)

您正在使用查询参数调用脚本 - 如果您在浏览器中执行此操作可能是GET,但是从$ _POST中检索值 - 此外,您应该确保在绑定之前存在数组索引 - 这可能是问题,当你调用bind_param()时$ _POST ['id']不存在。

在运行查询之前,您应该测试它:

if (isset($_POST['id']) {
   // ... do the query...
}