PHP PDO破坏了我的$ _POST值?

时间:2014-05-29 21:21:00

标签: php mysql pdo

编辑:编辑原始代码:(我将if更改为" if($ _ POST [' Break']!="")"测试它并且它不起作用,我尝试过的任何其他变量都没有。

if($_SERVER['REQUEST_METHOD'] != 'POST')
{
    echo '<form method="post" action="">
        Category name: <input type="text" name="cat_name" />
        Category description: <textarea name="cat_description" /></textarea>
        <input type="checkbox" value="Break">Is Table Break?<br>
        <input type="submit" value="Add category" />
     </form>';
}


$sql= 'INSERT INTO categories(cat_name, cat_description, isheader) VALUES (:cat_name, :cat_description, :isheader)';
         $stmt = $DBH->prepare($sql);
          if($_POST['Break'] != ""){
          $isbreak = true;
          }
          else{
          $isbreak = false;
          }         
        $stmt->bindParam(':cat_name', $_POST['cat_name']); 
        $stmt->bindParam(':cat_description', $_POST['cat_description']);
        $stmt->bindParam(':isheader', $isbreak);
        try{
           $stmt->execute();
           header('Location: /testpage.php');
        }
        catch(PDOexception $e){
          $e->getMessage();
        }

上面的代码应该插入到我的数据库中,使用Column&#34; Break&#34;选中复选框后设置为&#34; True&#34;(或1)。它没有。我已经尝试过以下if语句而没有修复它:

if(isset($_POST['Break']) == 1)
if(($_POST['Break']) == "Break")  - ("Break" being the name of my checkbox.
if(($_POST['Break']) === "Break") 
if(($_POST['Break']) == 'Break') 

现在我知道这段代码应该工作,因为在我转换为PDO php之前它正在运行。这是我以前的代码看起来像什么。这是我100%的工作方式:

if(isset($_POST['Break']) == 1){
   $isbreak = true;
}
else{
    $isbreak = false;
}
$sql = "INSERT INTO categories(cat_name, cat_description, isheader)
           VALUES('" . mysql_real_escape_string($_POST['cat_name']) . "',
                 '" . mysql_real_escape_string($_POST['cat_description']) . "', ". $isbreak.")";

 $result = mysql_query($sql);
    if(!$result)
    {
        echo 'Error' . mysql_error();
    }
    else
    {
        header('Location: /testpage.php');
    };

我知道一些$ _POST数据有效,因为我的数据库填充了正确的&#34; cat_name&#34;和&#34; cat_description&#34;使用PDO代码。我在我的网站上转换它的每个页面都有这个问题。我设法找到每个页面特定的愚蠢的小工作,但我不能想出这个。我只是想知道为什么这样做是按原样行事。

当我执行print_r($ _ POST)并选中我的复选框时,它会返回值&#34; Break&#34;。我不明白。

1 个答案:

答案 0 :(得分:4)

  

为什么我为$ isbreak使用字符串值。无论如何它都会以字符串的形式放入sql语句中,因此无关紧要。

是的,这很重要。

整数上下文中的字符串'true'在MySQL中的值为0。隐式发生的任何字符串到整数转换都会从字符串中获取前导数字字符,如果没有,则字符串的值为零。

而关键字true恰好等于整数1。

这是转化的演示。我正在添加+ 0以强制将值转换为整数。

mysql> select 'true' + 0;
+------------+
| 'true' + 0 |
+------------+
|          0 |
+------------+

mysql> select true + 0;
+----------+
| true + 0 |
+----------+
|        1 |
+----------+

在旧代码中,将true关键字放入INSERT语句中,因此MySQL服务器最终看到以下内容:

INSERT INTO categories(cat_name, cat_description, isheader)
    VALUES('name', 'description', true)

true插入整数列时,插入的值为1.

但是当将字符串作为参数传递时,它们将作为字符串发送,因此它与以下类似*:

INSERT INTO categories(cat_name, cat_description, isheader)
    VALUES('name', 'description', 'true')

'true'插入整数列时,插入的值为0。


重新评论:

如果您正在使用PDO或非PDO,则没有任何区别。如果将不带引号的字符串插入到SQL语句中,则会将其解析为关键字。如果将字符串作为参数传递,则类似于将引用的字符串插入到SQL语句中,因此'true'在整数上下文中变为0。


我编写了一个更全面的测试脚本。我猜你得到了答案,它实际上是一个HTML表单问题,而不是SQL问题。但是我会在这里发布我的测试脚本以供将来参考。

<?php

$pdo = new PDO(..., array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION));
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

$stmt = $pdo->prepare("INSERT INTO foo (test, boolcol) VALUES ('test 1: literal true', true)");
$stmt->execute();

$stmt = $pdo->prepare("INSERT INTO foo (test, boolcol) VALUES ('test 2: literal \'true\'', 'true')");
$stmt->execute();

$stmt = $pdo->prepare("INSERT INTO foo (test, boolcol) VALUES ('test 3: literal 1', 1)");
$stmt->execute();

$stmt = $pdo->prepare("INSERT INTO foo (test, boolcol) VALUES ('test 4: literal \'1\'', '1')");
$stmt->execute();

$stmt = $pdo->prepare("INSERT INTO foo (test, boolcol) VALUES ('test 5: param true', ?)");
$stmt->execute(array(true));

$stmt = $pdo->prepare("INSERT INTO foo (test, boolcol) VALUES ('test 6: param \'true\'', ?)");
$stmt->execute(array('true'));

$stmt = $pdo->prepare("INSERT INTO foo (test, boolcol) VALUES ('test 7: param 1', ?)");
$stmt->execute(array(1));

$stmt = $pdo->prepare("INSERT INTO foo (test, boolcol) VALUES ('test 8: param \'1\'', ?)");
$stmt->execute(array('1'));

结果如下:

+------------------------+---------+
| test                   | boolcol |
+------------------------+---------+
| test 1: literal true   |       1 |
| test 2: literal 'true' |       0 |
| test 3: literal 1      |       1 |
| test 4: literal '1'    |       1 |
| test 5: param true     |       1 |
| test 6: param 'true'   |       0 |
| test 7: param 1        |       1 |
| test 8: param '1'      |       1 |
+------------------------+---------+

* 参数永远不会与SQL语法结合,它们在执行期间与查询逻辑的内部表示相结合,但在SQL已经被解析之后。这就是我说&#34;类似的原因。&#34;