INSERT INTO SQL导致插入空元素

时间:2013-08-17 10:02:23

标签: php sql

这是我的代码:

function register($user, $pass) {
    //check if username exists
    $login = query("SELECT username FROM login WHERE username='%s' limit 1", $user);
    if (count($login['result'])>0) {
        errorJson('Username already exists');
    }
       //try to register the user
       $result = query("INSERT INTO login (username, pass) VALUES('%s','%s')", $user, $pass); 
        if (! $result['error']) {
        //success
        login($user, $pass);
        } else {
    //error
         //errorJson('Registration failed');
              errorJson($result['error']);
        }
}



function login($user, $pass) {
    $result = query("SELECT IdUser, username FROM login WHERE username='%s' AND pass='%s' limit 1", $user, $pass);

    if (count($result['result'])>0) {
        //authorized
        $_SESSION['IdUser'] = $result['result'][0]['IdUser'];
        print json_encode($result);
    } else {
        //not authorized
        errorJson('Authorization failed');
    }
}

我使用用户名和密码调用register,并且DB中的两个字段都是空的。插入通常是因为自动递增的主键正在增加 - 只是字段为空。

这就是我创建用户名的方式。

CREATE TABLE `login` (
  `IdUser` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(45) NOT NULL,
  `pass` varchar(45) NOT NULL,
  PRIMARY KEY (`IdUser`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

这是我的查询功能:

//executes a given sql query with the params and returns an array as result
function query() {
    global $link;
    $debug = false;

    //get the sql query
    $args = func_get_args();
    $sql = array_shift($args);

    //secure the input
    for ($i=0;$i<count($args);$i++) {
        $args[$i] = urldecode($args[$i]);
        $args[$i] = mysql_real_escape_string($link, $args[$i]);
    }

    //build the final query
    $sql = vsprintf($sql, $args);

    if ($debug) print $sql;

    //execute and fetch the results
        $result = mysql_query($sql, $link);
    if (mysql_errno($link)==0 && $result) {

        $rows = array();

        if ($result!==true)
        while ($d = mysql_fetch_assoc($result)) {
            array_push($rows,$d);
        }

        //return json
        return array('result'=>$rows);

    } else {

        //error
        return array('error'=>'Database error');
    }
}

我已经批准$ user和$ pass在执行INSERT INTO之前包含正确的值。

2 个答案:

答案 0 :(得分:1)

您没有在数据库中获得结果,因为您在不调用sprintf的情况下使用sprintf语法。尝试:

$sql=sprintf("INSERT INTO login (username, pass) VALUES('%s','%s')", $user, $pass);

$result = query($sql);

编辑:进一步检查时,您的查询功能似乎正在做一些不寻常的事情。我猜你的$ args数组没有你期望的值。在$ args上做一个print_r,看看它是不是和你期望的一样。

答案 1 :(得分:0)

在查询中使用它们之前,应该在变量上使用某种转义以避免注入攻击。此外,你真的不应该使用纯文本密码,它确实是非常糟糕的安全方法,即使使用md5或sha,也不再被认为是安全的(虽然比纯文本更好,但由于许多词典只有非常强的密码)。

  `pass` varchar(45) NOT NULL,

自PHP 5.5.0起,不推荐使用扩展$query$mysql_real_escape_string(等),您应该使用mysqli或PDO。 使用mysqli(或PDO)也有助于解决您在函数中遇到的问题,因为它们提供了PHP库中已有的方法来将查询封装在类中。此外,在您使用准备好的陈述的同时,您将解决您的安全问题。

我知道这并没有直接回答你的问题(我可能会因此而被投票)我觉得交换到mysqli或PDO会解决你的问题,因为这是一个更好的方法,它更安全,一旦你知道它使用起来同样容易,而且它们都是在库中构建的,因此未来的PHP更新中将包含安全更新和新功能等。

PDO vs mysqli是基于要求(等)的选择,但是我使用mysqli并且在学习曲线时,最终发现它很容易。我将它与crypt / blowfish一起使用,并使用salt在数据库中保存密码。每个密码都应该有自己独特的随机盐,并使用加密密码保存在数据库中(不需要隐藏盐)。

它被Wordpress,Drupal和大多数其他专业软件和网络公司使用,因为它是最强大,最安全的密码管理系统。

Blowfish消除了制作盐和散列的痛苦,因为所有这些都是一次性返回密码创建的。它创建加密密码salt,并返回您刚存储在DB中的整个字符串。 然后使用已经提供的功能,您可以检查登录密码等。

有关为何从MD5等进行更改的信息: http://php.net/manual/en/faq.passwords.php

这很简单,例如:

require('PasswordHash.php');//you download this file, and just include it
//it contains all the hashing engine etc

// $PostPassword is the one they entered in a form (etc)
$CreateHash = new PasswordHash(8, FALSE);
$HashPassword = $CreateHash->HashPassword($PostPassword);

// $HashPassword is the hashed and salted password you store in the db
// (should always be 60 chars, check with strlen)
// Don't use your own salt, it's not worth it 
// and you end up having to use it/store it/remember it
// when checking their password for login etc.
// just use the built in blowfish random salting algos


// Then to check their pass (ie login)
// Query and select their password from DB ($DbPass)
// with their username entered in the login form
// Check it against the password they entered in form
// (once hashed again of course to match the salted/hashed DB one)

$CreateHash = new PasswordHash(8, FALSE);

$CheckPass = $CreateHash->CheckPassword($PostPassword, $DbPass);
if ($CheckPass)
  {
    // password matches
  }
else
  {
    //not match, tell them to try again etc
  }

// you can use various checks on this, mainly check if the 
// library exists (to avoid php errors etc)
if(defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) 
  {
    // do all your password stuff
  }

非常简单!