【问题标题】:PHP mySql update works fine on localhost but not when livePHP mySql 更新在本地主机上运行良好,但在实时运行时不行
【发布时间】:2011-03-21 08:37:39
【问题描述】:

我有一个更新 mySql 数据库的 php 页面,它在我的 mac(使用 mamp 的本地主机)上运行良好

我检查了它是否连接,但似乎有连接

 <?php require_once('connection.php'); ?>

 <?php  
  $id = $_GET['id'];
  $collumn = $_GET['collumn'];
  $val = $_GET['val'];
 // checking if there is a connection
 if(!$connection){
     echo "connectioned failed";
   }
  ?>


 <?php 
    $sqlUpdate = 'UPDATE plProducts.allPens SET '. "{$collumn}".' = '."'{$val}'".' WHERE allPens.prodId = '."'{$id}'".' LIMIT 1';
    mysql_query($sqlUpdate);
    // testing for errors
   if ($sqlUpdate === false) {
      // Checked this and echos NO errors.
     echo "Query failed: " . mysql_error();
    }

if (mysql_affected_rows() == 1) {
  echo "updated";
} else {
  echo "failed";
}?>

在我传入参数的 URL 中,它看起来像这样:http://pathToSite.com/updateDB.php?id=17&collumn=prodid&val=4

也许这与托管有关?这不是简单的 PHP mySql 数据库更新吗?这里有什么问题?

为什么在本地主机上它确实有效?

为什么在实时服务器上没有?

【问题讨论】:

  • 当查询失败时,尝试mysql_error(); 的输出,另外,对于较新的项目,您可能想尝试非常出色的mysqliPDO_MySQL 库。
  • 谢谢,我在哪里添加mysql_error();
  • 紧跟在 mysql_query() 语句之后。
  • @Samuel 查看更新的代码。 mysql_error(); 的位置正确吗?
  • mysql_query($sqlUpdate) or die(mysql_error());

标签: php mysql live


【解决方案1】:

您对mysql_query() 的呼叫有问题;你正在检查你传入的变量的内容,但函数调用不是这样工作的。它返回一个您应该检查的值。如果查询失败,则返回false。如果它返回数据(比如来自SELECT),它会返回一个资源句柄。如果成功但不返回数据(例如来自INSERT),则返回true。

您在构建 SQL 时也遇到了一些问题。 @Charles 提到 SQL 注入并建议准备好的语句。如果你还想构造一个查询字符串,那么你需要使用mysql_real_escape_string()。 (但我建议您阅读 mysqli 扩展并改用这些功能。)

其次,您使用嵌入式替换连接字符串。这很愚蠢。改为这样做:

 $sqlUpdate = 'UPDATE plProducts.allPens SET '.$collumn.' = \''.$val.'\' 
        WHERE allPens.prodId = '.intval($id).' LIMIT 1';

如果您必须在查询字符串中接受它,您还应该在使用它之前检查$collumn 是否设置为有效值。如果不是,则发出和错误页面。同样,检查$id 是否会变成一个数字(使用is_numeric())。这一切都被称为防御性编程

【讨论】:

    【解决方案2】:

    让我们从解决您的确切问题开始。您的查询由于某种原因失败。我们可以通过检查从 mysql_query 返回的内容来找出问题所在,如果它是布尔值 false,则询问 mysql_error 出了什么问题:

    $sh = mysql_query($sqlUpdate);
    if($sh === false) {
        echo "Query failed: " . mysql_error();
        exit;
    }
    

    您还有其他问题。最大的问题是您的代码受到an SQL Injection vulnerability 的影响。假设您的脚本名为foo.php。如果我要求:

    foo.php?collumn=prodId = NULL -- 
    

    那么您的 SQL 将如下所示:

    UPDATE plProducts.allPens SET prodId = NULL -- = "" WHERE allPens.prodId = "" LIMIT 1
    

    -- 是一条 SQL 注释。

    我刚刚成功删除了您表中的所有产品 ID。

    阻止 SQL 注入的最有效方法是使用准备好的语句占位符。 PHP 中的“mysql”扩展不支持它们,因此您还需要切换到必须更好的mysqli 扩展或PDO 扩展。

    让我们使用 PDO 准备好的语句来确保您的查询安全。

    // Placeholders only work for *data*.  We'll need to validate 
    // the column name another way.  A list of columns that can be
    // updated is very safe.
    $safe_columns = array('a', 'b', 'c', 'd');
    if(!in_array($collumn, $safe_columns))
        die "Invalid column";
    // Those question marks are the placeholders.
    $sqlUpdate = "UPDATE plProducts.allPens SET $column = ? WHERE allPens.prodId = ? LIMIT 1";
    $sh = $db->prepare($sqlUpdate);
    // The entries in the array you pass to execute() are substituted
    // into the query, replacing the placeholders.
    $success = $sh->execute(array( $val, $id ));
    // If PDO is configured to use warnings instead of exceptions, this will work.
    // Otherwise, you'll need to worry about handling the exception...
    if(!$success)
        die "Oh no, it failed!  MySQL says: " . join(' ', $db->errorInfo());
    

    【讨论】:

      【解决方案3】:

      如果遇到错误,大多数 mysql 函数都会返回 FALSE。您应该检查错误条件,如果发生错误,则输出错误消息。这将使您更好地了解问题发生在哪里以及问题的性质。

      令人惊讶的是,尽管 PHP 文档中有很多示例,但仍有许多程序员从不检查错误状态。

      $link = mysql_connect(...);
      if ($link === false) {
          die(mysql_error());
      }
      
      $selected = mysql_select_db(...);
      if ($selected === false) {
          die(mysql_error());
      }
      
      $result = mysql_query(...);
      if ($result === false) {
          die(mysql_error());
      }
      

      【讨论】:

      • 忽略检查错误是我称之为See No Evil的反模式。
      • 谢谢,看起来错误只在错误日志中可见?我怎样才能回应他们?在浏览器中查看它们。
      • 除了将值传递给die()之外,您还可以echo。但仅供参考,我认为将错误诊断发送到日志是一种很好的做法,以便您可以阅读它,但您的网络应用程序的公共用户不能。泄露太多关于您的代码或数据库的信息会使恶意用户更容易利用您的系统。
      • 谢谢,请查看更新的代码。我没有看到任何错误(浏览器没有回显错误。
      • @adardesign:不,你要检查函数返回的值,而不是你传递给它的原始 SQL 查询。
      猜你喜欢
      • 2011-05-24
      • 2020-02-25
      • 2017-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      相关资源
      最近更新 更多