2012-05-03 20 views
17
$sql = "SELECT * FROM table WHERE id LIKE CONCAT('%', :id, '%') 
LIMIT :limit1, :limit2"; 

मैं अभी भी इस तरह सरणी इनपुट का उपयोग करना चाहते हैं:मैं पीडीओ पैरामीटर की सरणी कैसे पास कर सकता हूं फिर भी अभी भी उनके प्रकार निर्दिष्ट कर सकता हूं?

$stmt->execute($array); 

अन्यथा मैं अपने प्रश्नों को क्रियान्वित करने के लिए एक ही विधि का पुन: उपयोग नहीं कर सकते।

इसी समय,: limit1 और: limit2 जब तक यह इस तरह में डाल दिया जाता है काम नहीं करता:

$stmt->bindParam(':limit1', $limit1, PDO::PARAM_INT); 

मैं दोनों करने की कोशिश की लेकिन यह bindParams साथ निष्पादित नहीं करता है:

$stmt->bindParam(':limit2', $limit2, PDO::PARAM_INT); 
$stmt->execute($array); 

इसके आसपास क्या तरीका है?

मैंने सोचा कि मैं पीडीओएसटेमेंट का विस्तार कर सकता हूं और एक नई विधि "बाइंडलिमिट" या कुछ जोड़ सकता हूं लेकिन मुझे पता नहीं लगा सकता कि पीडीओ एक चरम पर पैरामीटर को बांधने के लिए कौन सी आंतरिक विधि का उपयोग करता है।

+1

+1 (हालांकि मुझे यकीन नहीं है कि यह समाधान है)। – hakre

+0

क्या आप सीमा पैरा के लिए जांच नहीं कर सकते हैं और उपस्थित होने पर स्पष्ट रूप से बाध्य नहीं कर सकते हैं, लेकिन अन्यथा निष्पादन का उपयोग करें? –

+0

"अन्यथा मैं अपने प्रश्नों को निष्पादित करने के लिए एक ही विधि का पुन: उपयोग नहीं कर सकता।" क्या आप इस विधि के बारे में अधिक समझा सकते हैं? – webbiedave

उत्तर

18

यदि आप PDO::ATTR_EMULATE_PREPARES की डिफ़ॉल्ट सेटिंग बंद करते हैं, तो यह काम करेगा।मुझे अभी पता चला है कि यह सेटिंग mysql के लिए डिफ़ॉल्ट रूप से चालू है, जिसका अर्थ है कि आप वास्तव में तैयार कथन का उपयोग नहीं करते हैं, php आंतरिक रूप से आपके लिए मानकों को उद्धृत करते हुए और प्लेसहोल्डर्स को प्रतिस्थापित करने के लिए आंतरिक रूप से गतिशील एसक्यूएल बनाता है। हां, एक प्रमुख wtf।

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
$stmt = $pdo->prepare($sql); 
$stmt->execute(array(5)); //works! 

प्रदर्शन कारणों से डिफ़ॉल्ट रूप से तैयार किए जाते हैं।

रूप में अच्छी तरह PDO MySQL: Use PDO::ATTR_EMULATE_PREPARES or not?

+0

yup lol। उस सेटिंग को अक्षम करने से पहले और बाद में mysql क्वेरी लॉग की जांच करें और आप देखेंगे कि आप वास्तव में इन सभी वर्षों के बाद तैयार कथन का उपयोग नहीं कर रहे थे। – goat

+0

मुझे eggyal से सहमत होना है: डब्ल्यूटीएफ? यह सबसे बुरी चीज है जिसे मैंने कभी सुना है। – RonLugge

8

रूप PDOStatement::execute के लिए दस्तावेज़ में कहा गया है:

input_parameters

के रूप में कई तत्वों के साथ मूल्यों की एक सरणी के रूप में वहाँ एसक्यूएल बयान में मानकों बाध्य कर रहे हैं निष्पादित किया जा रहा। सभी मानों को PDO::PARAM_STR के रूप में माना जाता है।

अधिकांश भाग के लिए, यह है के रूप में MySQL के implicit type conversion बाकी संभालती पूरी तरह से किसी का ध्यान नहीं जाता है (लेकिन यह कुछ अवांछनीय व्यवहार का कारण अगर MySQL, एक विशेष रूप से अजीब कनेक्शन वर्ण सेट का उपयोग कर रहा है के लिए वापस संख्या के तार परिवर्तित करने के रूप में कर सकते हैं उनके संख्यात्मक मूल्य अपेक्षित परिणाम नहीं दे सकता है)।

आपके मामले में, MySQL LIMIT खंड निष्पादित करने का प्रयास कर रहा है जिसमें स्ट्रिंग तर्क हैं। जबकि यह अपने अंतर्निहित प्रकार रूपांतरण का उपयोग करके इसे हल करने का प्रयास कर सकता है, क्योंकि यह हर जगह करता है एक स्ट्रिंग दिखाई देता है जहां एक पूर्णांक होना चाहिए, it simply doesn't bother और इसके बजाय रोना बंद कर देता है।

तो, आपको पीडीओ को बताना होगा कि ये विशेष पैरामीटर पूर्णांक हैं। के बाद से भी पीएचपी जो भी लिखते अपनी चर हैं पता नहीं है, मुझे विश्वास है कि ऐसा करने के लिए एक ही रास्ता सीधे उन्हें या तो PDOStatement::bindParam या PDOStatement::bindValue साथ बाध्य करने के लिए के रूप में आप क्या कर रहे हैं (हालांकि यह नहीं है सख्ती से$data_type तर्क निर्दिष्ट करने की आवश्यकता $variable का एक सरल (int) कास्ट PHP के अन्यथा अनजान प्रकार सिस्टम के साथ काम करने के लिए पर्याप्त देता है)।

जहां तक ​​आंतरिक विधि पीडीओ एक चर के लिए पैरामीटर बाध्य करने के लिए उपयोग करता है, really_register_bound_param() पर एक नज़र डालें (असुरक्षित रूप से PHP के संपर्क में नहीं है, तो आपको सी में बहुत मज़ा आएगा)।

गुड लक!

0

सीमा क्यों बाँध मान देखें, जब वे उपयोगकर्ता इनपुट नहीं कर रहे हैं?

$start = 0; 
$limit = 20; 
$sql = "SELECT * FROM table WHERE id LIKE CONCAT('%', :id, '%') 
    LIMIT $start, $limit"; 

यहां तक ​​कि अगर $start और $limit उपयोगकर्ता इनपुट से निर्धारित होते हैं, एक $_GET से कहते हैं, आप is_int() साथ मूल्य परीक्षण कर सकते हैं। PDOStatement को विस्तारित करने के विचार के लिए

+0

@YourCommonSense खुद को समझाने की देखभाल करते हैं? – inorganik

+0

@YourCommonSense मुझे यह जानना अच्छा लगेगा कि आपने मेरी पोस्ट को क्यों वोट दिया। क्या आप समझा सकते हैं? – inorganik

+3

@YourCommonSense आप इंटीजर से इंजेक्शन हमले कैसे प्राप्त कर सकते हैं? उत्तर: आप नहीं कर सकते – inorganik

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

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