如何在准备查询时删除任何字符串的引号


how to remove quotes of any string when preparing queries

$desc = 'DESC';
$getRecords = $conn->prepare('SELECT * FROM `courses` ORDER BY `id` :sort LIMIT :limitInc, :limit ');
$getRecords->bindValue(':limit',$limit,PDO::PARAM_INT);  // working
$getRecords->bindValue(':limitInc',$limitInc,PDO::PARAM_INT); // working
// *** The line below isn't working ***
$getRecords->bindValue(':sort', $desc ,PDO::PARAM_STR); // not working
$getRecords->execute();

我正试图在我的准备查询中调用$desc .

致命错误:未捕获的异常'PDOException'带有消息'SQLSTATE[42000]: Syntax error or access violation: 1064SQL语法错误;请查阅与您的产品相对应的手册MySQL服务器版本的正确语法使用附近的" DESC " LIMIT 0,5' at line 1' in C:'xampp'htdocs'portfolio'nasiraan'try'index .php:89C:'xampp'htdocs'portfolio'nasiraan'try'indexx.php(89):PDOStatement->execute() #1 {main}抛出C:'xampp'htdocs'portfolio'nasiraan'try'indexx.php on line 89

我确信解决办法是……从字符串$desc中删除引号…但是怎么做??

恐怕您必须使用文字字符串,因为占位符不能包含诸如排序顺序(以及其他)的关键字:

$query = sprintf('SELECT * FROM `courses` ORDER BY `id` %s LIMIT :limitInc, :limit ', 
    strcasecmp($desc, 'DESC') === 0 ? 'DESC' : 'ASC')
);
$getRecords = $conn->prepare($query);

以这种方式构建查询并不是那么糟糕,因为只有两个选项。

参数标记只能用于应该出现数据值的地方,而不能用于SQL关键字、标识符等。

准备语法

不能使用预处理语句。

  • 如果你想使用简单的绑定值语法,你可以使用

    SELECT * FROM `courses` ORDER BY `id`*:sort LIMIT :limitInc, :limit 
    

则绑定有符号号码值。但是这个查询不会被MySQL优化。

  • 如果你想"吞下"错误的顺序,你可以使用@Jack的解决方案,但方向输入错误可能会得到错误的结果。如果顺序很重要,则必须检查两个值:

    strcasecmp($desc, 'DESC') && strcasecmp($desc, 'ASC') ? error() : $desc;
    

你也可以包装PDO,并添加特殊方法prepare_ordered($query, $order);或更复杂的东西,并在那里放置比较。

或者您可以使用没有问题的外国库。但是你必须学习它的API。

注:

我总是扩展PDO并添加一些我自己方便的东西。首先你像这样扩展:

<?php
    //Database class
    class db extends Pdo{
        public function __construct(){
            global $conf;
            try
                {   
                    parent::__construct('DBTYPE:dbname=DBNAME;host=DBHOST', 'DBUSER', 'DBPASS');
                        $this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
                        $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                }
            catch(PDOException $e){
                throw new myPdoException($e);
            }
        }
        public function quest($queryString){
            try
                {
                    $query = $this->query($queryString);
                        return $query;                      
                }
            catch(PDOException $e){
                throw new myPdoException($e);
            }
        }
        public function doPrepare($queryString, $param){
            try
                {
                    $query = $this->prepare($queryString);
                    $query->execute($param);
                        return $query;
                }
            catch(PDOException $e)
            {
                throw new myPdoException($e);
            }
        }
        public function doPrepareBind($queryString, $param){
            try
                {
                    $query = $this->prepare($queryString);
                        foreach($param as $par){
                            switch($par[2]):
                                case 'int':
                                    $query->bindParam($par[0], $par[1], PDO::PARAM_INT);
                                break;
                                case 'str':
                                    $query->bindParam($par[0], $par[1], PDO::PARAM_STR);
                                break;
                                case 'blob':
                                    $query->bindParam($par[0], $par[1], PDO::PARAM_LOB);
                                break;
                                default:
                                    $query->bindParam($par[0], $par[1], PDO::PARAM_STR);
                                break;
                            endswitch;
                        }
                    $query->execute();
                        return $query;
                }
            catch(PDOException $e)
            {
                throw new myPdoException($e);
            }
        }
    }
    class myPdoException extends PdoException{
        private $_debug = DB_DEBUG;
        public function __construct($e){
            parent::__construct($e);
                $this->showException();
        }
        private function showException(){
            if($this->_debug){
                echo
                "<div id='transparant'><div id='error'><br /><br />" . 
                     $this->message
                . "<br /><br /><br /></div></div>";
            }
            else{
                echo    "<div id='transparant'><div id='error'><br /><br />
                            Er is iets mis gegaan, probeer later nog eens.<br />Sorry voor het ongemak.
                        <br /><br /><br /></div></div>";
            }
        }
    }
?>

您可以在第9行看到父构造函数。您必须在大写字母的位置添加您的数据库信息。

注意,DBTYPE是您正在使用的数据库服务的类型。可能只是mysql。

现在我是这样使用它来灭菌一系列字符串的:

//first include db class I made above.
$db = new db();
$query = "INSERT INTO `database`.`users` (`id`, `naam`, `email`, `pass`, `key`, `status`) VALUES (NULL, :name, :mail, :pass, '$key', '0')";
$param = array(
                    array(':name', $_POST['name']),
                    array(':mail', $_POST['mail']),
                    array(':pass', $pass_hash)
                );
$query = $db->doPrepareBind($query, $param);

$query = 'SELECT * FROM courses ORDER BY id '。$desc .' LIMIT: LIMIT,:limitInc';

$getRecords = $conn->prepare($query);//将查询存储在变量名$query中,并在其中传入变量..现在我不需要绑定它了。

getRecords -> bindValue(美元:限制,限制,PDO:: PARAM_INT);

getRecords -> bindValue (: limitInc, limitInc美元,PDO:: PARAM_INT);

getRecords -> execute (),