【问题标题】:mysqli bind_param not setting string to nullmysqli bind_param 未将字符串设置为空
【发布时间】:2014-06-16 04:02:27
【问题描述】:

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

  1. 如果用户使用我提供的注册表单进行注册,请将数据库中的用户密码设置为他们想要的密码(当然是散列和加盐);

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

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

$password = null;

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

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

非常感谢所有帮助!

编辑: 这是密码列的结构...... 字段:密码, 类型:varchar(255), 空:是的, 钥匙:, 默认值:空, 补充:

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 使空值为空。在转义之前检查变量是否为空。

【问题讨论】:

  • 显示空列而不是null是完全正常的,即使是...
  • @chility 即使我使用“从密码为空的用户中选择 *;”它不显示任何密码列为空的行。
  • 不过,您将需要显示更多代码 -- DB Schema 将与执行查询的实际代码一起提供帮助。

标签: php mysql sql parameters mysqli


【解决方案1】:

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

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

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

因此,要回答您的问题,只需要其中的代码:

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

它会绑定空值。

【讨论】:

    【解决方案2】:

    经过进一步研究,PHP bind_params with nullmysqli prepared statements, insert NULL using bind params 都表明您的问题应该得到解决目前为止提出的,因此您的代码问题中不存在其他问题导致意外行为。

    您的更新给出了答案。当你 real_escape_string 你的 null 值时,你会导致你的空结果。

    采用这个测试数据库结构:

    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))
    

    满足您的需求。

    【讨论】:

    • 在将值与参数绑定时,您永远不应该使用real_escape_string。这个答案有多个问题!
    猜你喜欢
    • 2016-08-22
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 2017-11-05
    • 2016-01-31
    相关资源
    最近更新 更多