【问题标题】:PHP sql using PDO使用 PDO 的 PHP sql
【发布时间】:2014-04-27 19:46:15
【问题描述】:

我正在尝试学习如何使用 PDO,这样我的表单就不会被 SQL 注入。 我对如何为我的插入代码编写执行函数感到困惑。

这是我的代码:

$db = new PDO('mysql:host=x;dbname=x;charset=utf8', 'x', 'x');
if ( !$db )
{
die('Could not connect: ' . mysql_error());
}
$ipaddress = $_SERVER['REMOTE_ADDR'];
$mail = $_POST['mail'];

$stmt = $db->prepare("SELECT * FROM ucm_signup WHERE email =? ") or exit(mysql_error());
$stmt->bindValue(1, $mail, PDO::PARAM_STR);
$stmt->execute();
$num_rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

if($num_rows == 0) 
{ 
//if there are no duplicates...insert

$sql = $db->prepare("INSERT INTO ucm_signup company, address1, address2, city, province, zip, fname, lname, email, phone, session, iama, buyfrom, group1, ipaddress )
VALUES ( '$_POST[company]','$_POST[address1]','$_POST[address2]','$_POST[city]', '$_POST[province]','$_POST[zip]','$_POST[fname]','$_POST[lname]','$_POST[mail]', '$_POST[phone]','$_POST[session]','$_POST[iama]','$_POST[buyfrom]','$_POST[group1]', '$ipaddress')");
$sql->execute(array(':company' => I AM LOST))
} 

我什至关闭 INSERT 吗?谢谢

【问题讨论】:

  • 不,你不是。为什么不使用与 SELECT 相同的 prepared statement 原则?
  • 将您的$_POST[fields] 放入execute(array(...)),将它们与:placeholder 名称相关联,您将其放入INSERT 语句中以代替引用的文字变量。
  • 如果您想学习 PDO,请阅读教程并关注它们至 THere, read this
  • VALUES(:foo) 然后execute(array(":foo" => "bar")) 在你的情况下bar$_POST['bar']..
  • $field1 将在两行之间读取。您需要以$field1=$_POST['company']; 为例。你不会为你的价值观做那种插入。 @DDDD

标签: php mysql pdo insert


【解决方案1】:

您应该检查rowCount(),而不是获取行并检查零。您的第一个查询是正确的,但第二个查询需要更改,您还需要在此处使用准备好的语句并绑定您的参数,您可以使用例如

$num_rows = $stmt->rowCount();
if($num_rows == 0) 
{ 
    $sql = $db->prepare("INSERT INTO ucm_signup company, address1, address2, city, province, zip, fname, lname, email, phone, session, iama, buyfrom, group1, ipaddress )
    VALUES (:company,:address1,:address2, .....)");
    $sql->bindParam(':company',$_POST[company],PDO::PARAM_STR);
    $sql->bindParam(':address1',$_POST[address1],PDO::PARAM_STR);
    $sql->bindParam(':address2',$_POST[address2],PDO::PARAM_STR);
    //and so on
    $sql->execute();
} 

【讨论】:

    【解决方案2】:

    不!不要这样做!总是绑定你的参数。通过直接将 $_POST['company'] 放入,某人可以通过 post 提交来注入 SQL 代码。这是一个更好的解决方案:

    $sql = $db->prepare("INSERT INTO ucm_signup company, address1, address2, city, province, zip, fname, lname, email, phone, session, iama, buyfrom, group1, ipaddress
    VALUES ( :company, :address1, :address2,:city, :province, :zip, :fname, :lname, :mail, :phone, :session, :iama, :buyfrom, :group1, :ipaddress)");
    $sql->bindValue(":company", $_POST['company']);
    $sql->bindValue(":address1", $_POST['address1']);
    //...
    $sql->bindValue(":ipaddress", $ipaddress);
    $sql->execute()
    }
    

    原因是,PDO 将准备好的语句和参数分开发送。通过这样做,它会自动防止 SQL 注入。用户可以将 ANYTHING 放入这些变量中,但由于 PDO 使用参数化语句的方式,它仍然不会注入 SQL。

    【讨论】:

      【解决方案3】:

      您使用 SELECT 查询做得很好。你为什么不对 INSERT 做同样的事情?

      我没有调试你的代码,所以可能不只是复制粘贴:

      // first of all count($num_rows)!
      if(count($num_rows) == 0) 
      { 
          // you forgot "()" in column names and ":" in the binds On column values
          $sql = $db->prepare("INSERT INTO ucm_signup (column, another_column) VALUES (:value1, :value2)");
          $sql->execute(
              array(
                  "value1" => $_POST['value1'],
                  "value2" => $_POST['value2'],
              )
          );
      } 
      

      除此之外,还有几点值得注意:PDO 就像是第一步。它没有做很多复杂的数据库层所做的事情。即使您正在阻止注入,您也不应该直接在绑定中使用 $_POST。它仍然缺乏验证。如果你正在学习,这是一个好的开始。但是对于类似于生产代码的东西,我建议您查看一些抽象层,例如Doctrine DBAL。我不是在谈论 ORM。 DBAL 是 PDO 之上的一个薄层。

      【讨论】:

        【解决方案4】:

        这将更具可读性和易于理解。

        $ipaddress = $_SERVER ['REMOTE_ADDR'];
        $email = $_POST ['mail'];
        $stmt = $db->prepare ( "SELECT * FROM ucm_signup WHERE email =:email " );
        $stmt->bindParam(":email", $mail);
        $stmt->execute ();
        
        if ($stmt->rowCount()==0) {
            // if there are no duplicates...insert
        
            $sql = $db->prepare ( "INSERT INTO ucm_signup(company, address1, address2, city, province, zip, fname, lname, email, phone, session, iama, buyfrom, group1, ipaddress)
                VALUES (:company,:address1,:address2,:city,:province,:zip,:fname,:lname,:email,:phone,:session,:iama,:buyfrom,:group1,:ipaddress)" );
            $sql->bindParam(":company", $_POST['company']);
            $sql->bindParam(":address1", $_POST['address1']);
            $sql->bindParam(":city", $_POST['city']);
            $sql->bindParam(":province", $_POST['province']);
            $sql->bindParam(":zip", $_POST['zip']);
            $sql->bindParam(":fname", $_POST['fname']);
            $sql->bindParam(":lname", $_POST['lname']);
            $sql->bindParam(":email", $_POST['email']);
            $sql->bindParam(":phone", $_POST['phone']);
            $sql->bindParam(":session", $_POST['session']);
            $sql->bindParam(":imea", $_POST['imea']);
            $sql->bindParam(":buyfrom", $_POST['buyfrom']);
            $sql->bindParam(":imea", $_POST['imea']);
            $sql->bindParam(":group1", $_POST['group1']);
            $sql->bindParam(":ipaddress", $_POST['ipaddress']);
        
            $sql->execute ();
            if($sql->rowCount()==1){
                //successfully inserted
            }else{
                //oops, some error occured.
            }
        }    
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多