2009-11-17 6 views
8

मुझे phs की mysql बेहतर लाइब्रेरी का उपयोग mysql में एक तालिका में एक पंक्ति डालना है जिसमें इसकी प्राथमिक कुंजी प्रकार VARBINARY है। इस क्षेत्र की सामग्री एक गणना sha1 हैश है।PHP- तैयार कथन का उपयोग करके mysql में बाइनरी डेटा डालने

अगर मैं क्वेरी पुराने तरीके से चलाने के यह पूरी तरह काम करता है:

$mysqli->$query("INSERT INTO table (id, field1) VALUES (0x" . $id . ",'" . $field1 . "')"); 

लेकिन जब मैं एक तैयार बयान के रूप में यह निष्पादित करने के लिए प्रयास करते हैं, मैं इसे कैसे करना है पता नहीं कर सकते हैं।

if($stmt = $mysqli->prepare("INSERT INTO table (id, field1) VALUES (?, ?)")) { 
    $stmt->bind_param('ss', "0x".$id, $field1); 
    //execute statement 
} 

यह कह रही है कि सामग्री इस क्षेत्र के लिए बहुत बड़े थे एक अपवाद फेंकता है: अगर मैं बराबर कार्यवाही नहीं करती। और अगर मैं एक बूँद क्षेत्र के रूप में सम्मिलित करने के लिए प्रयास करें:

if($stmt = $mysqli->prepare("INSERT INTO table (id, field1) VALUES (?, ?)")) { 
    $stmt->bind_param('bs', $id, $field1); 
    //execute statement 
} 

यह कोई त्रुटि देता है, पंक्ति सम्मिलित किया जाता है, लेकिन पहचानकर्ता क्षेत्र अब खाली (शून्य नहीं, खाली) है।

मुझे पता है कि मैं क्वेरी को मिश्रित कर सकता हूं और स्ट्रिंग में अन्य आईडी को तैयार कथन के बाध्य पैरामीटर के रूप में संयोजित कर सकता हूं, लेकिन मैं यह जानने के लिए कह रहा हूं कि इसे सम्मिलित करने का सही तरीका क्या है और शायद भविष्य में किसी की मदद करेगा।

+0

क्या मूल्यों आप $ आईडी के लिए है और $ फ़ील्ड 1 जब आप ऐसा करते हैं की तुलना में बड़ा नहीं है कृपया? $ आईडी एक पूर्णांक है? यदि हां, तो क्या आपने इसे बाध्य करने की कोशिश की है? 'stmt-> bind_param ('is', $ id, $ field1);' – nash

+0

$ id का मान sha1 हैश है। यह एक पूर्णांक नहीं है। अन्य फ़ील्ड समस्या पैदा नहीं कर रहे हैं लेकिन मुख्य रूप से तार हैं। –

+0

प्लस वन इस समस्या को हल करते समय तैयार वक्तव्यों की सुरक्षा को बनाए रखने की कोशिश करने के लिए। – HoldOffHunger

उत्तर

6

PHP के sha1 समारोह एक हेक्स संख्या की एक स्ट्रिंग प्रतिनिधित्व देता है।

इसका मतलब यह है कि यदि आप इसे स्क्रीन पर प्रिंट करते हैं, तो यह एक हेक्स नंबर प्रदर्शित करेगा। लेकिन स्मृति में, यह ASCII वर्णों का एक गुच्छा है।

तो, हेक्स संख्या 1A2F लें। स्मृति में ASCII के रूप में 0x31413246 होगा, 0x1A2F

MySQL का सामान्य इंटरफ़ेस सभी तर्कों को स्ट्रिंग के रूप में भेजता है। सामान्य इंटरफ़ेस का उपयोग करते समय, MySQL ASCII स्ट्रिंग को बाइनरी मान में परिवर्तित कर देगा।

नई तैयार कथन विधि बाइनरी के रूप में सबकुछ भेजती है। तो "1 ए 2 एफ" का आपका अच्छा मूल्य अब 0x31413246 के रूप में भेजा जाएगा और कॉलम में डाला जाएगा। - source: dev.mysql.com - Prepared statements

इसके बजाय, एक बाइनरी स्ट्रिंग का उपयोग करते हुए यह पैकिंग करके अपने हेक्स स्ट्रिंग परिवर्तित:

$binId = pack("H*", $id); // this string is not ASCII, don't print it to the screen! That will be uggly. 

और फिर $binId पारित MySQLi करने के लिए $ आईडी के बजाय बयान तैयार किया।

+0

आप सही हैं। इसे करने का यही तरीका है। आपका बहुत बहुत धन्यवाद। –

+0

यह खुद सोच रहा था! बस यह ध्यान रखना चाहता था कि आप 'पैक' के सुविधाजनक विकल्प के रूप में 'हेक्स 2bin' का भी उपयोग कर सकते हैं, और फिर भी डेटा को खींचते समय 'bin2hex' का उपयोग कर सकते हैं (आपके कथन में' HEX()' का उपयोग करने के बजाय)। – Haravikk

3

ऐसा करें:

if($stmt = $mysqli->prepare("INSERT INTO table (id, field1) VALUES (unhex(?), ?)") { 
    $stmt->bind_param('ss', $id, $field1); 
    //execute statement 
} 
0

टीएल; डॉ: send_long_data() देखें।

मुझे पता है कि यह एक बहुत पुराना सवाल है, लेकिन यह बिल्कुल था जो मैं करने की कोशिश कर रहा था और विफल रहा था। उपर्युक्त उत्तरों की कोशिश करने और प्रयोग करने में अधिक समय व्यतीत करने के बाद, मुझे अंततः कुछ ऐसा मिला जो प्रश्न के तरीके को काम करता है और मैं कोशिश कर रहा था।

यह भ्रामक है क्योंकि कैसे "बी" पीएचपी bind_param documentation में प्रकार के साथ आगे बढ़ने के लिए केवल संदर्भ के परोक्ष रूप से है जब डेटा की चर्चा करते हुए अनुमति पैकेट आकार (जो मैं शुरू में आप छोड़) से अधिक:

यदि एक चर के डेटा आकार अधिकतम से अधिक है। अनुमति पैकेट आकार (max_allowed_packet), तो आपको प्रकार में निर्दिष्ट और mysqli_stmt_send_long_data() पैकेट में डेटा भेजने के लिए उपयोग करने के लिए है।

यह पता चला है कि बाइनरी प्रकारों को आपके सम्मिलन को निष्पादित करने से पहले स्वयं द्वारा भेजा जाना चाहिए। मैंने इसे article from Oracle's website से बाहर पाया।

क्योंकि वे यह इतना संक्षेप समझाने, मैं सिर्फ सबसे अधिक प्रासंगिक हिस्सा व्याख्या करेंगे:

ब्लॉब

यहाँ कोड है भंडारण MySQLi का उपयोग कर एक ब्लॉब स्टोर करने के लिए:

$stmt = $mysqli->prepare("INSERT INTO images (image) VALUES(?)") 
$null = NULL; //bolded 
$stmt->bind_param("b", $null); 

$stmt->send_long_data(0, file_get_contents("osaka.jpg")); //bolded 

$stmt->execute(); 

मैंने कोड के दो टुकड़े बोल्ड किए, जो मैं वें क्योंकि bind_param() हमेशा एक दिए गए मापदंडों के लिए एक चर संदर्भ चाहता है,

$ अशक्त चर की जरूरत है: स्याही को देख के लायक हैं। इस मामले में "बी" ( ब्लॉब में) पैरामीटर। तो $ शून्य सिंटैक्स काम करने के लिए सिर्फ एक डमी है।

अगले चरण में मुझे वास्तविक डेटा के साथ अपने ब्लॉब पैरामीटर को "भरने" की आवश्यकता है। यह send_long_data() द्वारा किया जाता है। का पहला पैरामीटर यह विधि इंगित करता है कि डेटा को किस पैरामीटर से संबद्ध करना है। पैरामीटर 0 से शुरू होने वाले अंक हैं। send_long_data() का दूसरा पैरामीटर संग्रहीत करने के लिए वास्तविक डेटा शामिल है।

send_long_data का उपयोग करते समय(), सुनिश्चित करें कि ब्लॉब MySQL के max_allowed_packet

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