要解决PDO NULL问题,请在PHPMyAdmin中将字段更改为NULL或在代码中检查NULL,如果是,请设置为空字符串?

时间:2017-08-03 17:00:17

标签: php mysql pdo phpmyadmin

我的PHP网站有一个使用PDO将数据插入mysql的表单。例如,表单上的一个字段是" email"。

不需要。所以在提交时,我在插入之前设置了电子邮件变量:

$email=$_POST['email'];

然后我插入使用PDO准备好的声明。之前,当使用mysqli插入时,它会插入为空白没问题。但是现在有了PDO,如果他们把它留空,就会导致:

Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'email' cannot be null in...

我研究过,似乎PDO不允许插入NULL值,除非MySQL被告知它可以接收它们。所以看起来我有两个选择......

1.  In MySQL (via PHPMyAdmin), check the "Null" checkbox for that column under "Structure"
2.  In the code, add a small snippet like this:

if (empty($email)) {
$email="";  //set it equal to blank, which allows it to get inserted into the database without needing to mark the field as NULL in MySQL
}

我想知道选项#1或#2的优点/缺点是什么?我有时可能会有很多表单选项可以留空,所以在这方面,#2可以为所有这些选项添加if (empty())片段。

#1是最好的选择吗?

或者我还有其他选择吗?

3 个答案:

答案 0 :(得分:1)

您获得的错误来自数据库,而不是PDO,PDO只是访问数据库的一种方式。

回到你的问题,显而易见的答案是,如果你的应用程序中有一个可选字段,你应该将其列设置为可为空。

如果您选择其他选项,即:

if (empty($email)) {
   $email="";  
}

我不会说它很糟糕,但想象一下,在某些时候你需要为你的应用程序添加更多字段,而且大多数都是可选的,你打算这样做吗?他们每个人的可空性测试?

如果我是你,我不会这样做。

答案 1 :(得分:0)

您应该始终验证提交给您的应用程序的每个字段。不仅要确保每个条目符合数据库完整性,还要帮助防止SQL注入(PDO也极大地帮助了)跨站点脚本甚至数据的有效性。虽然电子邮件地址可能是可选的,但为什么不确保有人提供格式正确的电子邮件地址,并且输入中没有无关的字符(如空格)?

例如:

if( empty( $_POST["email"] ) )
{
    $email = "";
} else
{
    $email = strtolower( cleanInput( $_POST["email"] ) );

    // check if e-mail address syntax is valid or not
    if ( !preg_match( "/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/", $email ) )
    {
        $emailError = "Invalid email format";
    }
}

/*
* Function to clean input prior to processing
*/
function cleanInput( $data )
{
    $data = trim( $data );
    $data = stripslashes( $data );
    $data = htmlspecialchars( $data );
    return $data;
}

答案 2 :(得分:0)

选项1 :此PDO插入语句应与NULL值一起使用:

$row = [
    'email' => $_POST['email']
];
$sql = "INSERT INTO users SET email=:email;";
$status = $pdo->prepare($sql)->execute($row);

if ($status) {
    echo "OK";
}

选项2 :自动检测正确的PDO数据类型参数。

function get_pdo_type($value)
{
    switch (true) {
        case is_bool($value):
            $dataType = PDO::PARAM_BOOL;
            break;
        case is_int($value):
            $dataType = PDO::PARAM_INT;
            break;
        case is_null($value):
            $dataType = PDO::PARAM_NULL;
            break;
        default:
            $dataType = PDO::PARAM_STR;
    }
    return $dataType;
}

// Usage
$email = $_POST['email'];

$pdo = new PDO('dsn', 'username', 'password');
$sql = 'INSERT INTO users SET email=:email;';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':email', $email, get_pdo_type($email));
$stmt->execute();