mysqli bind_param没有将字符串设置为null

时间:2014-06-16 04:02:28

标签: php mysql sql parameters mysqli

我正在尝试在我的网站中使用mysqli bind_param函数来注册用户。我想做两件事:

  1. 如果用户使用我提供的注册表注册,请将数据库中的用户密码设置为所需的密码(当然是哈希和盐渍);

  2. 如果他们使用Facebook注册,请将密码字段设置为NULL。

  3. 我意识到我可以将数据库中密码列的默认值设置为NULL,并且在注册时根本不在语句中指定它,但是这个问题也会继续到网站的其他方面,这是不实际的分辨率。

    $password = null;
    
    $stmt->bind_param('ssssss', $email, $password, $fullname,
             $prof_image_url, $splash_image_url, $facebook_id);
    

    出于测试目的,我在调用语句之前直接将变量$password设置为null,但仍然会发生。执行查询时,它会导致一行密码列为空,而不是在我通过命令行查看时为NULL。

    非常感谢所有帮助!

    编辑: 这是密码列的结构...... 字段:密码, 输入:varchar(255), 空:是的, 键:, 默认值:NULL, 额外:

    function user_add($mysqli, $email, $password, $fullname, $prof_image_url = null, $splash_image_url = null, $facebook_id = null) {
        if ($mysqli == null) throw new Exception('Could not connect to database.');
        if ($email == null || $email == '') throw new Exception('Email is required.', 1);
        if ($password != null && $password == '') throw new Exception('Password is required.', 1);
        if ($fullname == null || $fullname == '') throw new Exception('Name is required.', 1);
        if ($prof_image_url == null) $prof_image_url = IMAGE_PATH . '/profile_default.png';
        if ($splash_image_url == null) $splash_image_url = IMAGE_PATH . '/splash_bg_1.jpg';
    
        $email = $mysqli->real_escape_string($email);
        $password = $mysqli->real_escape_string($password);
        $fullname = $mysqli->real_escape_string($fullname);
        $facebook_id = $mysqli->real_escape_string($facebook_id);
    
        $stmt = $mysqli->prepare('INSERT INTO users(`email`, `password`, `full_name`, `prof_image_url`, `splash_image_url`, `facebook_id`) VALUES(?, ?, ?, ?, ?, ?);');
    
        if (!$stmt) {
            throw new Exception('Could not connect to database.');
        }
    
        $stmt->bind_param('ssssss', $email, $password, $fullname, $prof_image_url, $splash_image_url, $facebook_id);
    
        if (!$stmt->execute()) {
            throw new Exception('Could not register user.', 1);
        }
    
        return $mysqli->insert_id;
    }
    

    这就是我所说的功能:

    function account_facebook_register($mysqli, $code){
        $token_url = "https://graph.facebook.com/oauth/access_token?"
        . "client_id=" . FACEBOOK_APP_ID
        . "&redirect_uri=" . urlencode(FACEBOOK_REDIRECT_URL)
        . "&client_secret=" . FACEBOOK_APP_SECRET
        . "&code=" . $code
        . "&scope=email";
    
        $response = @file_get_contents($token_url);
    
        $params = null;
        parse_str($response, $params);
        $token = $params['access_token'];
    
        $graph_url = "https://graph.facebook.com/me?access_token=" . $token;
    
        $user = json_decode(file_get_contents($graph_url));
    
        if (!isset($user->email)){
            $_SESSION['error'] = 'Invalid email on Facebook account.';
            $_SESSION['error_level'] = 1;
            header('Location: ' . WEB_ROOT . '/account/register.php');
            die;
        }
    
        $user_exists = user_getByEmail($mysqli, $user->email);
    
        if ($user_exists == null){
            $mysqli = mysql_create();
            $password = null;
            $uid = user_add($mysqli, $user->email, $password, $user->name, 'https://graph.facebook.com/' . $user->id . '/picture?type=large', null, $user->id);
    
            $token = facebook_get_long_token($token);
            token_add($mysqli, $uid, 'facebook', $token, $user->id);
    
            $_SESSION['fb_token'] = $token;
            $_SESSION['uid'] = $uid;
            $_SESSION['success'] = "Registration Successful!";
        }else{
            account_facebook_login($mysqli, $user_exists->uid);
        }
    }
    

    mysql_create函数只是设置数据库以便访问并按预期工作。 谢谢!

    答案: mysqli-> real_escale_string使空值为空。在转义变量之前检查变量是否为空。

2 个答案:

答案 0 :(得分:5)

绑定值时,根本不应使用real_escape_string

这使得您的初始问题不是真正的问题 - 如果您确实将null值传递给此函数,而没有任何中间操作,则根本不存在任何问题。

编辑版本也不合法,因为它要求检查您的代码,找到错误,提出问题并回答它。虽然前两个动作你必须自己完成。

因此,要回答你的问题,只需要它的代码:

$password = null;
$stmt->bind_param('ssssss', $email, $password, $fullname,
         $prof_image_url, $splash_image_url, $facebook_id);

它将正确绑定null值。

答案 1 :(得分:4)

经过进一步研究,PHP bind_params with nullmysqli prepared statements, insert NULL using bind params都表示您的问题应该在目前为止中解决,所以在您的问题中还有其他内容不存在关于导致意外行为的代码。

您的更新给出了答案。如果real_escape_string为空值,则会导致空结果。

采用此测试数据库结构:

CREATE TABLE `example` (
  `example_id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `non_null_val` char(64) NOT NULL,
  `null_val` char(64) DEFAULT NULL,
  PRIMARY KEY (`example_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

然后,运行此PHP代码:

<?php
  $mysqli = new mysqli('localhost', 'demo', 'exampledemo', 'demo');
  if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
  }

  $stmt = $mysqli->prepare("INSERT INTO example (non_null_val, null_val) VALUES (?, ?)");
  $non_null_val = 'ABC';
  $null_val = null;
  $stmt->bind_param('ss', $non_null_val, $null_val);
  $stmt->execute();

  $non_null_val = 'DEF';
  $null_val = null;
  $stmt->bind_param('ss', $non_null_val, $mysqli->real_escape_string($null_val));
  $stmt->execute();

  $stmt->close();

  $mysqli->close();
?>

您会看到ABC行有一个NULL条目,而DEF有一个空白条目。唯一的区别是real_escape_string

所以详细说明,

$password = (is_null($password)?null:$mysqli->real_escape_string($password))

提供您所需要的。