2010-09-10 18 views
35

पुराने सर्वर पर मैं इसका उपयोग कर रहा हूं कि मैं तैयार कथन का उपयोग नहीं कर सकता हूं, मैं वर्तमान में इसे MySQL पर भेजने से पहले उपयोगकर्ता इनपुट से पूरी तरह से बचने की कोशिश कर रहा हूं। इसके लिए मैं PHP फ़ंक्शन mysql_real_escape_string का उपयोग कर रहा हूं।MySQL जंगली कार्ड से बचने

चूंकि यह फ़ंक्शन MySQL वाइल्डकार्ड% से नहीं बचता है और _ मैं इनसे बचने के लिए addcslashes का उपयोग कर रहा हूं।

जब मैं की तरह कुछ भेजें: डेटाबेस के लिए

test_test " ' 

और फिर इसे वापस पढ़ा डेटाबेस पता चलता है:

test\_test " ' 

इस को देखते हुए मैं नहीं समझ सकता क्यों _ एक है पूर्ववर्ती बैकस्लैश लेकिन "और 'नहीं। चूंकि वे सभी \ निश्चित रूप से _' से बच निकले हैं और" सभी को समान दिखाई देना चाहिए, यानी सभी को बचने वाला चरित्र दिखाई देता है या सभी इसे दिखाई नहीं देते हैं।

\ स्वचालित रूप से

के लिए बाहर की जांच रहा है बचाव कर रहे हैं

किसी को भी इस व्याख्या कर सकते हैं?

उत्तर

79

_ और % सामान्य रूप से MySQL में वाइल्डकार्ड नहीं हैं, और उन्हें सामान्य स्ट्रिंग अक्षर में डालने के प्रयोजनों से बच नहीं जाना चाहिए। mysql_real_escape_string इस उद्देश्य के लिए सही और पर्याप्त है। addcslashes का उपयोग नहीं किया जाना चाहिए।

_ और %LIKE -matching के संदर्भ में विशेष रूप से विशेष हैं। जब आप LIKE कथन में शाब्दिक उपयोग के लिए स्ट्रिंग तैयार करना चाहते हैं, तो 100% एक सौ प्रतिशत से मेल खाता है और न केवल सौ से शुरू होने वाली कोई स्ट्रिंग, आपके पास चिंता करने के लिए भागने के दो स्तर हैं।

पहला भागने की तरह है। जैसे हैंडलिंग पूरी तरह से एसक्यूएल के अंदर होती है, और यदि आप एक शाब्दिक स्ट्रिंग को एक शाब्दिक LIKE अभिव्यक्ति में बदलना चाहते हैं तो आपको यह चरण करना होगा भले ही आप पैरामीटरयुक्त क्वेरी का उपयोग कर रहे हों!

इस योजना में, _ और % विशेष हैं और बच जाना चाहिए। बचने का चरित्र भी बच जाना चाहिए। एएनएसआई एसक्यूएल के अनुसार, इन के अलावा अन्य वर्ण से बचने के लिए नहीं होना चाहिए: \' गलत होगा। (हालांकि MySQL आमतौर पर आपको इससे दूर जाने देगा।)

ऐसा करने के बाद, आप भागने के दूसरे स्तर पर आगे बढ़ते हैं, जो सादे पुराने स्ट्रिंग शाब्दिक भागने वाला है। एसक्यूएल के बाहर यह एसक्यूएल बनाने के बाहर होता है, इसलिए जैसे बचने के चरण के बाद किया जाना चाहिए। MySQL के लिए, यह पहले के रूप में mysql_real_escape_string है; अन्य डेटाबेस के लिए एक अलग कार्य होगा, आप इसे करने से बचने के लिए केवल पैरामीटर किए गए प्रश्नों का उपयोग कर सकते हैं।

समस्या जो भ्रम की ओर ले जाती है वह यह है कि MySQL में बैकस्लैश का उपयोग दोनों घोंसले से बचने वाले चरणों के लिए एक बचने वाले चरित्र के रूप में करता है! तो यदि आप एक शाब्दिक प्रतिशत संकेत के खिलाफ एक स्ट्रिंग से मेल खाना चाहते हैं तो आपको डबल-बैकस्लैश-एस्केप करना होगा और LIKE 'something\\%' कहना होगा। या, यदि वह एक PHP " शाब्दिक में है जो बैकस्लैश एस्केपिंग का उपयोग करता है, "LIKE 'something\\\\%'"। अरे!

यह एएनएसआई एसक्यूएल के अनुसार गलत है, जो कहता है कि: स्ट्रिंग अक्षर में बैकस्लाश का अर्थ शाब्दिक बैकस्लाश और एक उद्धरण से बचने का तरीका '' है; अभिव्यक्तियों में डिफ़ॉल्ट रूप से कोई भी बचने वाला चरित्र नहीं है।

तो यदि आप पोर्टेबल तरीके से पसंद करना चाहते हैं, तो आपको डिफ़ॉल्ट (गलत) व्यवहार को ओवरराइड करना चाहिए और LIKE ... ESCAPE ... निर्माण का उपयोग करके अपना खुद का बचाना चरित्र निर्दिष्ट करना चाहिए। सैनिटी के लिए, हम लानत बैकस्लैश के अलावा कुछ और चुनेंगे!

function like($s, $e) { 
    return str_replace(array($e, '_', '%'), array($e.$e, $e.'_', $e.'%'), $s); 
} 

$escapedname= mysql_real_escape_string(like($name, '=')); 
$query= "... WHERE name LIKE '%$escapedname%' ESCAPE '=' AND ..."; 

या मानकों के साथ (जैसे पीडीओ में।):

$q= $db->prepare("... WHERE name LIKE ? ESCAPE '=' AND ..."); 
$q->bindValue(1, '%'.like($name, '=').'%', PDO::PARAM_STR); 

(आप अधिक पोर्टेबिलिटी पार्टी समय चाहते हैं, आप भी एमएस एसक्यूएल सर्वर और Sybase, जहां के लिए खाते में करने की कोशिश कर मजा कर सकते हैं [ चरित्र भी, एक LIKE बयान में खास है गलत तरीके से और फरार हो जाना है। अरे।)

+4

मैं उसे +1 फिर "लानत बैकस्लैश!"। – BoltClock

+0

धन्यवाद, बस इसे अभी अवशोषित कर रहा है ... यह वास्तव में मुझे अपने मूल ज्ञान का विस्तार करने में मदद कर रहा है। बेवकूफ, मैं% और _ से बच रहा था, भले ही मैं वास्तव में किसी भी तरह के बयान का उपयोग नहीं कर रहा हूं और जब से मुझे लगता है (कृपया पुष्टि करें) कि% और _ केवल LIKE कथन के संदर्भ में जंगली हैं, मैं वास्तव में अपना समय बर्बाद कर रहा हूं। लेकिन फिर यह मुझे सोचता है कि जब आप किसी तरह के वक्तव्य के संदर्भ में हों तो आप कभी भी% या _ से बचना क्यों चाहेंगे। निश्चित रूप से एक LIKE कथन का उपयोग करने का एकमात्र कारण यह है कि आप इसके जंगली पात्रों का उपयोग कर सकते हैं। (कृपया इस पर मेरे सीमित ज्ञान को क्षमा करें) – Columbo

+2

निश्चित रूप से, लेकिन यह एक शाब्दिक '%' या '_' चरित्र की खोज करने में सक्षम होना चाहता है। यदि कोई उपयोगकर्ता फ्रंट एंड में '50%' की खोज करता है, तो संभवतः उनका मतलब है कि वे '50%' वाली स्ट्रिंग की तलाश में हैं और इसमें केवल 50 स्ट्रिंग वाले स्ट्रिंग नहीं हैं। – bobince

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