2013-04-05 152 views
4
$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如何刪除任何字符串的報價..準備查詢

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''DESC' LIMIT 0, 5' at line 1' in C:\xampp\htdocs\portfolio\nasiraan\try\indexx.php:89 Stack trace: #0 C:\xampp\htdocs\portfolio\nasiraan\try\indexx.php(89): PDOStatement->execute() #1 {main} thrown in C:\xampp\htdocs\portfolio\nasiraan\try\indexx.php on line 89

我相信解決辦法是..從字符串$desc刪除引號...但是怎麼樣?

+0

只要執行'$ getRecords-> bindValue(':sort',DESC,PDO :: PARAM_STR);'? – 2013-04-05 06:56:45

+2

綁定僅適用於「參數」,它不能用於「構造」SQL查詢。 – Passerby 2013-04-05 06:59:08

+0

當給予:'key'時,你不能使用'':'key'就是這樣做的:'key'。綁定函數會爲你提供這樣的照顧。 – botenvouwer 2013-04-05 07:34:07

回答

6

你將不得不使用文本字符串我很害怕,因爲佔位符不能包含關鍵字,如那些排列順序(其中包括):

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

構建查詢這種方式是不是這樣不好,因爲只有兩個選擇。

+0

+1,最簡單的解決方案。但爲了避免將來出現問題,用'strtoupper($ desc)'代替'$ desc'。 – Narek 2013-04-05 07:02:49

+0

@Narek我想這是公平的:) – 2013-04-05 07:05:02

+0

'strcasecmp($ desc,'DESC')? '':$ desc'射手了一下。更好?不知道:) – sectus 2013-04-05 07:46:20

2

Parameter markers can be used only where data values should appear, not for SQL keywords, identifiers, and so forth.

PREPARE Syntax

不能使用準備好的語句與它。

  • 如果你想使用綁定值的簡單的語法,你可以使用

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

然後綁定簽署數值。但是這個查詢will not be optimized by MySQL

  • 如果你想「吞下」錯誤的命令,你可以用@傑克的解決方案,但在方向錯誤輸入可能會得到錯誤的結果。如果順序很重要,你必須檢查這兩個值:

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

而且你可以用PDO,並添加特殊的方法prepare_ordered($query, $order);或更復雜的東西,並把比較有。

或者您可以使用與其沒有任何問題的外來教堂。但是你必須學習它的API。

P.S.我看到你正在使用準備好的陳述的模擬。

+1

雖然這個答案是正確的,它是沒有用的OP – 2013-04-05 07:58:53

+0

@YourCommonSense,你是對的...給我一個時間。 – sectus 2013-04-05 08:02:37

+0

@YourCommonSense,請檢查 – sectus 2013-04-05 10:08:20

-1

我總是擴展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行看到一個父構造函數。你必須添加你的db信息來代替大寫字母。

請注意,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); 
+0

恐怕你沒有得到的問題點 – 2013-04-05 08:02:18

+0

爲什麼倒票。即使我沒有回答這個問題,我仍然給出的答案不是一堆廢話。 – botenvouwer 2013-04-05 09:52:59

-1

$查詢= 'SELECT * FROM courses ORDER BY id' $遞減「。 LIMIT:limit,:limitInc';

$ getRecords = $ conn-> prepare($ query); //將我的查詢存儲在變量名稱$ query中,並在其中傳遞我的變量..所以現在我不需要綁定它..

$ getRecords-> bindValue(':limit',$ limit,PDO :: PARAM_INT);

$ getRecords-> bindValue(':limitInc',$ limitInc,PDO :: PARAM_INT);

$ getRecords-> execute();

+0

在你的問題中沒有提供針對SQL注入的解決方案。 – 2013-04-05 08:02:49