【问题标题】:Updating to database using php使用 php 更新数据库
【发布时间】:2017-04-28 15:05:48
【问题描述】:

我让它工作的唯一方法是使用empty。然而,这不是我想要的。如果必须的话,我希望能够留下一些空的东西。有谁知道我应该如何更改代码才能使其正常工作?

编辑页面:

<form name="homePage" action="update.php" method="POST">
<Strong>Change home title:</Strong>
<p>
    <input style="width: 300px;" type="text" name="homeTitleChange" value="<?php echo $homeTitle ?>">
    <input type="hidden" name="rowHomeID" value="<?php echo $getHomeID?>">
</p>

<Strong>Change home subtitle:</Strong>
<p>
    <input style="width: 600px;" type="text" name="homeSubtitleChange" value="<?php echo $homeSubtitle ?>">
    <input type="hidden" name="rowHomeID" value="<?php echo $getHomeID?>">
</p>
<input type="submit" class="btn btn-skin" name="homepage" value="save" />
</form>

查询页面:-

include("../conn.php");
include("../conn.php");
if(isset($_POST['homepage'])){
    if(
        !empty($_POST["homeTitleChange"])&& 
        !empty($_POST["homeSubtitleChange"]) &&  
        !empty($_POST["rowHomeID"])
    ){
        $homeTitleUpdate = $_POST["homeTitleChange"];
        $homeSubtitleUpdate = $_POST["homeSubtitleChange"]; 
        $homeEditRow = $_POST["rowHomeID"];
        $query = "UPDATE Home SET 
            title = '$homeTitleUpdate', 
            subtitle ='$homeSubtitleUpdate' 
            WHERE homeID = '$homeEditRow' ";
        $result = mysqli_query($conn, $query) or die(mysqli_error($conn));

        if ($result) {
            echo "<p> - Success!</p>";
        }else{
            echo "<p> - Something went wrong</p>";
        }
    }
}

谢谢!

【问题讨论】:

标签: php html database


【解决方案1】:

前体:

  • 您已包含两次连接脚本。
  • 您将隐藏表单字段&lt;input type="hidden" name="rowHomeID" value="&lt;?php echo $getHomeID?&gt;"&gt; 包含两次。这是低效的。
  • 您的表单应该有 enctype='multipart/form-data'Read Here

如果没有看到您的 MySQL 错误,我们无法绝对诊断您的问题,因此我将向您提供我知道需要修复的部分:

默认情况下,PHP 字符串类型将包含一个空字符串 '' 而不是 NULL 值,因此我认为您的问题不是错误地插入了空值(至少,不像您的问题中描述的那样)。

$homeEditRow 是唯一的必需值。因为UPDATE table SET column=value WHERE column=&lt;empty&gt; 会导致错误(或者至少不会更新)。

因此替换:

if(
    !empty($_POST["homeTitleChange"])&& 
    !empty($_POST["homeSubtitleChange"]) &&  
    !empty($_POST["rowHomeID"])
 )

与:

if(!empty($_POST["rowHomeID"]){
     //run MySQL Update query.
}

此外,如果该值是整数,您可以简单地这样做:

$homeEditRow = (int)$_POST['rowHomeID']; //force to int.
if($homeEditRow > 0 ){
  //run MySQL Update query.
}

如果您愿意,您的其他两个值可以为空,这很好。

这些值不能包含 MySQL 中未转义的特殊字符,通常(但绝不是唯一)`、'--# 字符。

因此,最好从用户输入中清除不安全的字符。

永远不要相信用户输入是“安全的”

$homeTitleUpdate = mysqli_real_escape_string($conn,$_POST["homeTitleChange"]);
$homeSubtitleUpdate = mysqli_real_escape_string($conn,$_POST["homeSubtitleChange"]); 
//assuming to be integer required
$homeEditRow = (int)$_POST["rowHomeID"];

这意味着任何单引号或其他不安全字符都不会干扰您的查询执行。使用 Prepared statements 比这种方法安全得多,并且是 推荐的方法 做这些事情,你可以使用 PDO or MySQLi 并且在这些系统的 Stack Overflow 上有很多很多很好的例子。


如果您达到这一点并且仍然遇到问题,那么您需要阅读您的 MySQL 错误输出对您说的内容:

 //after your query regardless of outcome:
var_dump(mysqli_error($conn));

您可能会遇到一些问题,例如您的主索引列包含两个非唯一值(etc,etc)。但在您输出 MySQL 错误之前,我们无法确定。


最后,请小心检查您的 IF 语句是否执行了更新查询,因为如果没有任何更改,则更新没有更改,MySQL 将不会运行查询,因此当一切实际上运行正确时,可能会返回 false。

【讨论】:

    【解决方案2】:

    如果不指定您的错误,我们只能假设您的问题。只有您可以调试您的程序,所以为了将来的通知,请在您的脚本顶部执行以下代码行并告诉我们您的错误。

    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);
    

    继续,您的脚本包含一个条件,该条件检查$_POST 中索引处的值是否为!empty(),但不会环绕您的查询。这意味着,无论值是否为空或已设置,您的查询都会执行。

    假设您只想在设置了值时运行查询,您可以用 if 表达式包装它:

     // an array of all the index's
    $index = ['homeSubtitleChange', 'homeTitleChange', 'rowHomeID'];
    
     // loop through each index and check they're not empty
    foreach($index as $_index)
    {
        if( empty( $_POST[$_index] ) && !isset( $_POST['homepage'] ) )
        {
             // if empty - halt the program with an error
            die("Expected POST index: $_index or homepage.");
        }
    }
    unset($_index); //cleanup
    
     // if it got here - all index's have values
     // as Martin said in the comments, I assume you can wrap mysqli_real_escape_string()
     // and intval() ensuring the value is type (int) to protect
     // your database against SQL attacks
    $subtitle = mysqli_real_escape_string($conn, $_POST[$index[0]]);
    $title    = mysqli_real_escape_string($conn, $_POST[$index[1]]);
    $row_id   = intval($_POST[$index[2]]);
    
     // consider upgrading to a PDO driver and using prepare() statements
     // this SQL statement is prone to SQL injections
    
    $sql      = "UPDATE Home SET title = '$title', subtitle = '$subtitle' WHERE homeID = '$row_id'";
    
    if( mysqli_query( $conn, $query ) )
    {
        die("Success.");
    }
    
    die("Failed.");
    

    【讨论】:

    • 我真的很想 +1 你的答案,但你甚至没有草率地修复 SQL 注入漏洞。你不需要 PDO 来使用参数化查询......或者你甚至可以使用 mysqli_real_escape_string
    • 我更新了保护对应的答案。我不与MySQLi_* 合作,所以很抱歉;如果您知道更好的保护方法,请随时更新答案。 @马丁
    • 唯一真正的改进应该是让 OP 像其他人在 cmets 中所说的那样实现准备好的语句。
    • foreach() 循环之后,我从未遇到过执行unset() 的情况。我喜欢'clean up'的原理。 @马丁
    • 它在文档中,一旦循环完成,变量值就会被留下。
    【解决方案3】:

    如果我理解正确,您希望允许空字符串作为输入。 如果是这样,你想要的是isset() 而不是!empty()

    所以,代码中的这一部分:

    !empty($_POST["homeTitleChange"])&& 
    !empty($_POST["homeSubtitleChange"]) &&  
    !empty($_POST["rowHomeID"])
    

    用这个替换它:

    isset($_POST["homeTitleChange"],$_POST["homeSubtitleChange"],$_POST["rowHomeID"])
    

    你可以走了。

    【讨论】:

      【解决方案4】:

      正如其他人所说,清理您的用户输入;这样直接放到数据库里是很不安全的。

      至于你的问题,据我所知,你正在努力确保设置值 ,但你也希望能够传递一个 empty em> 字符串!?

      如果是这样,我想你想要isset

      //...
          if(
              isset($_POST["homeTitleChange"])&&
              isset($_POST["homeSubtitleChange"]) &&
              isset($_POST["rowHomeID"])
          ){
      //...
      

      这将确保您设置了POST,如果他们提交了表单,它们无论如何都应该设置;但是,如果$_POST["rowHomeID"] = 0,它也会返回true,这可能不是你想要的,所以你可能想回到使用!empty,这意味着它不能是空字符串或等于0

      【讨论】:

        猜你喜欢
        • 2021-12-19
        • 2014-01-04
        • 2023-04-02
        • 2015-01-31
        • 1970-01-01
        • 1970-01-01
        • 2013-09-17
        • 1970-01-01
        相关资源
        最近更新 更多