2008-10-14 11 views
7

मुझे गतिशील एसक्यूएल की लचीलापन पसंद है और मुझे सुरक्षा + तैयार वक्तव्य के बेहतर प्रदर्शन पसंद है। तो मैं वास्तव में क्या चाहता हूं गतिशील तैयार वक्तव्य है, जो परेशान करने के लिए परेशानी है क्योंकि bind_param और bind_result तर्कों की "निश्चित" संख्या स्वीकार करते हैं। इसलिए मैंने इस समस्या को हल करने के लिए एक eval() कथन का उपयोग किया। लेकिन मुझे लगता है कि यह एक बुरा विचार है। मेरा मतलब है कि मेरा मतलब हैगतिशील तैयार वक्तव्य खराब हैं? (php + mysqli के साथ)

// array of WHERE conditions 
$param = array('customer_id'=>1, 'qty'=>'2'); 
$stmt = $mysqli->stmt_init(); 

$types = ''; $bindParam = array(); $where = ''; $count = 0; 

// build the dynamic sql and param bind conditions 
foreach($param as $key=>$val) 
{ 
    $types .= 'i'; 
    $bindParam[] = '$p'.$count.'=$param["'.$key.'"]'; 
    $where .= "$key = ? AND "; 
    $count++; 
} 

// prepare the query -- SELECT * FROM t1 WHERE customer_id = ? AND qty = ? 
$sql = "SELECT * FROM t1 WHERE ".substr($where, 0, strlen($where)-4); 
$stmt->prepare($sql); 

// assemble the bind_param command 
$command = '$stmt->bind_param($types, '.implode(', ', $bindParam).');'; 

// evaluate the command -- $stmt->bind_param($types,$p0=$param["customer_id"],$p1=$param["qty"]); 
eval($command); 

क्या आखिरी eval() कथन एक बुरा विचार है? मैंने परिवर्तनीय नाम $ param के पीछे मूल्यों को encapsulating द्वारा कोड इंजेक्शन से बचने की कोशिश की।

क्या किसी के पास कोई राय या अन्य सुझाव हैं? क्या ऐसे मुद्दे हैं जिनके बारे में मुझे अवगत होना चाहिए?

+0

आप अपने प्रश्न अलग तरीके से व्यक्त करने के लिए चाहते हो सकता है थोड़ा सा शीर्षक, इसलिए अन्य लोग आपका प्रश्न अधिक आसानी से पा सकते हैं। – Tomalak

उत्तर

13

मुझे लगता है कि यहां eval() का उपयोग करना खतरनाक है।

इस प्रयास करें:

  • पैरामीटर सरणी पुनरावृति कि
  • उपयोग call_user_func_array() पर प्रश्न चिह्न के साथ एसक्यूएल स्ट्रिंग "SELECT * FROM t1 WHERE p1 = ? AND p2 = ?"
  • कॉल prepare() का निर्माण करने के bind_param() को कॉल करने के लिए, गतिशील पैरामीटर में पारित सरणी।

कोड:

call_user_func_array(array($stmt, 'bind_param'), array($types)+$param); 
+2

'सरणी ($ प्रकार) + $ param' से सावधान रहें। यदि $ param 0 की अनुक्रमणिका वाला एक सरणी है, तो $ param में वह मान $ प्रकार के पक्ष में गिरा दिया जाएगा, और आपको अपनी स्ट्रिंग में इंगित किए गए कम चर के लिए त्रुटि मिलेगी। http://php.net/manual/en/language.operators.array.php – Tushar

-1

आप वास्तव में नहीं है, तैयार बयानों और बाध्य तर्क की जरूरत है क्योंकि आप हमेशा mysql_real_escape_string उपयोग कर सकते हैं()। और तुम सही हो; गतिशील रूप से जेनरेट किया गया एसक्यूएल कहीं अधिक लचीला और मूल्यवान है।

यहाँ नियमित mysql_ * इंटरफ़ेस का उपयोग कर एक सरल उदाहरण है:

// Array of WHERE conditions 
$conds = array("customer_id" => 1, "qty" => 2); 

$wherec = array("1"); 
foreach ($conds as $col=>$val) $wherec[] = sprintf("`%s` = '%s'", $col, mysql_real_escape_string($val)); 

$result_set = mysql_query("SELECT * FROM t1 WHERE " . implode(" AND ", $wherec); 
बेशक

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

function insert($table, $record) { 
    $cols = array(); 
    $vals = array(); 
    foreach (array_keys($record) as $col) $cols[] = sprintf("`%s`", $col); 
    foreach (array_values($record) as $val) $vals[] = sprintf("'%s'", mysql_real_escape_string($val)); 

    mysql_query(sprintf("INSERT INTO `%s`(%s) VALUES(%s)", $table, implode(", ", $cols), implode(", ", $vals))); 
} 

// Use as follows: 
insert("customer", array("customer_id" => 15, "qty" => 86)); 
+2

बाउंड पैरामीटर भागने से परे अतिरिक्त सुरक्षा जोड़ता है। इनका उपयोग करना एक अच्छा अभ्यास है। – troelskn

+1

क्या आप कृपया मुझे दिखा सकते हैं कि वे कौन सी अतिरिक्त सुरक्षा प्रदान करते हैं? बाध्य पैरामीटर बनाम मेरे समाधान से आपको किस तरह का हमला किया जाएगा? क्योंकि यदि आप प्रोग्रामर की गलतियों को करने की क्षमता का जिक्र कर रहे हैं, तो मेरे पास टूल को बाधित करने के बजाय अधिक शक्तिशाली टूल होंगे। – rix0rrr

+0

+1 धन्यवाद आदमी! यह एक अच्छा समाधान है! – RubyDubee

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