2010-10-08 12 views
5

के साथ तैयार पीडीओ स्टेटमेंट निष्पादित करना मैं PHP के लिए नया हूं, और परीक्षण MySQL डीबी से कनेक्ट करने के लिए पीडीओ का उपयोग करना सीखने की कोशिश कर रहा हूं। मैं निम्नलिखित है:इसी तरह के क्लॉज

try { 
    $db = new PDO('mysql:dbname=MYDBNAME;host=MYHOST', 'USERNAME', 'PASSWORD'); 

    $query = "select * from books where ? like '%?%'"; 
    $stmt = $db->prepare($query); 
    $stmt->execute(array($searchtype, $searchterm)); 
} catch(PDOException $e) { 
    echo 'PDOException: ' . $e->getMessage(); 
} 

जब मैं यह कोशिश मैं निम्न चेतावनी: चेतावनी: PDOStatement :: निष्पादित() [pdostatement.execute]: SQLSTATE [HY093]: अमान्य पैरामीटर संख्या: बाध्य चर की संख्या टोकन की संख्या से मेल नहीं खाता

जब मैं इस तरह के खंड को हटाता हूं, और $ searchterm param, तो यह परिणाम ठीक से देता है। मैंने सोचा - जैसे '%?%' - इस क्वेरी को डबल कोट्स के तहत बनाने का कानूनी तरीका नहीं हो सकता है, इसलिए मैंने भागने की कोशिश की, जो काम नहीं कर सका। मैं एक समाधान के लिए चारों ओर देखा, और पाया कि कोई '% और%' ले जाया गया जहां $ SEARCHTERM है करने के लिए नीचे:

$query = "select * from books where ? like ?"; 
... 
$stmt->execute(array($searchtype, '\'%'.$searchterm.'%\'')); 

मैं एक ही परिणाम मिला।
किसी भी मदद की सराहना की है। धन्यवाद!

/ अद्यतन ****/ मैं http://us3.php.net/manual/en/pdo.prepared-statements.php

उदाहरण # 12 प्लेसहोल्डर का अमान्य उपयोग के उदाहरण 12 पर पाया

<?php 
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE '%?%'"); 
$stmt->execute(array($_GET['name'])); 

// Below is What they suggest is the correct way. 
// placeholder must be used in the place of the whole value 
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE ?"); 
$stmt->execute(array("%$_GET[name]%")); 
?> 

मैं इस की कोशिश की, और भले ही मुझे अब चेतावनी नहीं मिली है, मुझे कोई परिणाम नहीं मिला है। हालांकि जब मैं सीधे क्वेरी निष्पादित करता हूं तो मुझे कुछ परिणाम मिलेंगे। कोई विचार?

+0

मुझे वही समस्या मिली, जैसा कि मैंने सोचा था कि '%' जहां मूल्यों के बजाय क्वेरी संरचना का एक हिस्सा है;) – Strae

उत्तर

2
$stmt->execute(array($searchtype, '\'%'.$searchterm.'%\'')); 

यह पैरामीटरयुक्त क्वेरी कैसे काम नहीं करती है। सम्मिलित पैरामीटर पहले से ही शाब्दिक तारों के रूप में कार्य करते हैं, आपको उनके चारों ओर उद्धरण डिलीमीटर जोड़ने की ज़रूरत नहीं है या उनसे बचें (यह पूरी बात है), और यदि आप कोशिश करते हैं, तो आप सचमुच स्ट्रिंग सिंगल-कोट-सर्चेटर-सिंगल- बोली।

परिणामस्वरूप यदि आप (जैसा कि मुझे संदेह है) एक शाब्दिक स्ट्रिंग के खिलाफ किसी विशेष कॉलम की तुलना करने का इरादा रखते हैं, तो आप कॉलम नाम को पैरामीटर नहीं करते हैं। फिलहाल आप एक शाब्दिक स्ट्रिंग की तुलना किसी अन्य शाब्दिक स्ट्रिंग से कर रहे हैं, इसलिए पंक्ति में डेटा के बावजूद यह हमेशा सत्य या हमेशा गलत होगा!

तो मुझे लगता है कि तुम क्या शायद मतलब है:

$query= "SELECT * FROM books WHERE $searchtype LIKE ?"; 
$like= "%$searchterm%"; 
$stmt->execute(array($like)); 

सोचा स्वाभाविक रूप से आप बहुत सावधान कि $searchtype ज्ञात-सही एसक्यूएल इंजेक्शन से बचने के लिए है होना होगा। आम तौर पर आप इसका उपयोग करने से पहले स्वीकार्य कॉलम नामों की एक सूची के खिलाफ इसकी तुलना करेंगे।

(एक तरफ: वहाँ है एक स्कीमा नाम है कि आप एक स्तंभ के लिए उपयोग कर सकते हैं में मनमाने ढंग से तार डालने का एक तरीका है, लेकिन यह कष्टप्रद है, डेटाबेस में भिन्न होती है और इसके लिए एक मानक बचने कार्य नहीं है MySQL में। , आप बैकक्लैश चरित्र, उद्धरण और बैकस्लाश से बचते हैं और बैकक्वॉट्स के साथ नाम को घेरते हैं। एएनएसआई एसक्यूएल में आप डबल-कोट्स का उपयोग दोगुनी-डबल-कोट्स के साथ करते हैं। SQL सर्वर में आप स्क्वायर ब्रैकेट का उपयोग करते हैं। हालांकि वास्तविकता में आपको शायद ही कभी आवश्यकता होती है इनमें से कोई भी ऐसा करने के लिए क्योंकि वास्तव में आप केवल कुछ पूर्व परिभाषित कॉलम नामों को अनुमति देना चाहते हैं।)

(एक और एक तरफ: यदि आप शाब्दिक percents के साथ $searchterm मूल्यों अनुमति देने के लिए सक्षम होना चाहते हैं, को रेखांकित करता है या बैकस्लैश में तो उपयोगकर्ता इन-आप के लिए है किसी भी स्ट्रिंग मिलान के बिना के लिए "100%" खोज सकते हैं 100 साथ एक स्पष्ट भागने चरित्र है, जो थोड़ा कठिन :) का उपयोग

$query= "SELECT * FROM books WHERE $searchtype LIKE ? ESCAPE '+'"; 
$like= str_replace(array('+', '%', '_'), array('++', '+%', '+_'), $searchterm); 
$stmt->execute(array("%$like%")); 
+1

'सरणी' ('++', '+%', '+ _') 'सर' ('\ +', '\%', '\\ _') ', या यहां तक ​​कि 'सरणी' नहीं होगा \% ',' \\ _ ')' (क्यों बचें +)? (वैसे, मार्कडाउन यहां \\ _ 'से _ में परिवर्तित क्यों होता है?) –

+0

यह काम करता है !!! लेकिन अंतरिक्ष को कैसे ट्रिम करें? – user1775888

3

जब तैयार चर बाध्यकारी उद्धरण जोड़ें और बाँध स्तंभ नाम न मत

$query = sprintf("select * from books where %s like ?", $searchtype); 
... 
$stmt->execute(array($searchtype, '%'.$searchterm.'%')); 
+0

मैंने कोशिश की और यह काम नहीं किया। मुझे लगता है कि बॉबेंस के रूप में समस्या ने इसे एक और जवाब में रखा है कि यह वाइल्डकार्ड के रूप में% नहीं लेता है, बल्कि एक शाब्दिक '%' है, जो मेरा इरादा नहीं है। – Elle

2

समस्या जो मैं देखता हूं वह यह है कि यदि आपने पीडीओ के लिए एक रैपर लिखा था, तो आपको किसी भी तरह इसे अलग से संभालना होगा। जो जवाब मैंने पाया और प्यार किया वह आपकी क्वेरी लिखता था और पैरामीटर में% को जोड़ता था। यानी "कॉलम जैसे कॉलम ('%',: कुछ, '%')"

संबंधित मुद्दे