2008-08-15 19 views
7

एक प्रोजेक्ट में जिसे मैं लपेटने वाला हूं, मैंने PHP के लिए ऑब्जेक्ट-रिलेशनल मैपिंग समाधान लिखा और कार्यान्वित किया है। दुश्मनों और सपने देखने वालों से पहले "पृथ्वी पर कैसे?" रोते हैं, आराम करो - मुझे देर से स्थिर बाध्यकारी काम करने का कोई रास्ता नहीं मिला है - मैं बस इसके आसपास काम कर रहा हूं कि मैं संभवतया कर सकूं।PHP + MYSQLI: तैयार कथन के साथ परिवर्तनीय पैरामीटर/परिणाम बाध्यकारी

वैसे भी, मैं वर्तमान में पूछताछ के लिए तैयार बयानों का उपयोग नहीं कर रहा हूं, क्योंकि मैं bind_params() या bind_result() विधियों के लिए तर्कों की एक चर संख्या को पारित करने के तरीके से नहीं आ सकता था।

मुझे तर्कों की एक चर संख्या का समर्थन करने की आवश्यकता क्यों है, आप पूछते हैं? क्योंकि मेरे मॉडल के सुपरक्लास (हैक-अप PHP ActiveRecord wannabe के रूप में मेरे समाधान के बारे में सोचें) जहां क्वेरीिंग परिभाषित की गई है, और इसलिए खोज() विधि, उदाहरण के लिए, यह नहीं जानती कि इसे कितने पैरामीटर को बांधना होगा ।

अब, मैंने पहले से ही एक तर्क सूची बनाने और eval() को एक स्ट्रिंग पास करने के बारे में सोचा है, लेकिन मुझे यह समाधान बहुत पसंद नहीं है - मैं बस अपनी सुरक्षा जांच को लागू करना चाहता हूं और पास करना चाहता हूं बयान।

क्या किसी को यह करने के तरीके के बारे में कोई सुझाव (या सफलता की कहानियां) है? यदि आप इस पहली समस्या को हल करने में मेरी मदद कर सकते हैं, तो शायद हम परिणाम सेट को बाध्य करने से निपट सकते हैं (मुझे लगता है कि कुछ संदेह होगा, या कम से कम अधिक संसाधन-गहन होगा यदि इसमें तालिका संरचना निर्धारित करने के लिए प्रारंभिक क्वेरी शामिल है)।

उत्तर

13

PHP में आप call_user_func_array का उपयोग कर किसी फ़ंक्शन या विधि में तर्कों की एक चर संख्या को पास कर सकते हैं। एक विधि के लिए एक उदाहरण होगा:

call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params); 

फ़ंक्शन को अपने स्वयं के तर्क के रूप में पारित सरणी में प्रत्येक सदस्य के साथ बुलाया जाएगा।

+0

मुझे लगता है कि समारोह नाम '' बजाय bindparams' की bind_param' किया जाना चाहिए। कम से कम मेरे 'mysqli' संस्करण के साथ मैं इसे' $ stmt-> bind_param() 'टाइप कर रहा हूं,' $ stmt-> bindparams() '। चीयर्स! –

1

मैं संपादित करने की अनुमति नहीं कर रहा हूँ, लेकिन मैं कोड

call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params); 

$ stmt के सामने संदर्भ आवश्यक नहीं है में विश्वास करते हैं। चूंकि $stmt ऑब्जेक्ट है और bindparams उस ऑब्जेक्ट में विधि है, संदर्भ आवश्यक नहीं है। यह होना चाहिए:

call_user_func_array(array($stmt, 'bindparams'), $array_of_params); 

अधिक जानकारी के लिए Callback Functions पर पीएचपी मैनुअल देखें "

0
call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params); 

मेरी वातावरण में मेरे लिए काम नहीं किया था, लेकिन इस सवाल का जवाब मुझे सही रास्ते पर सेट क्या।। वास्तव में काम किया था: यह सुनिश्चित करें कि $ array_of_params चर को लिंक की सरणी है बनाने के लिए

$sitesql = ''; 
$array_of_params = array(); 
foreach($_POST['multiselect'] as $value){ 
    if($sitesql!=''){ 
     $sitesql .= "OR siteID=? "; 
     $array_of_params[0] .= 'i'; 
     $array_of_params[] = $value; 
    }else{ 
     $sitesql = " siteID=? "; 
     $array_of_params[0] .= 'i'; 
     $array_of_params[] = $value; 
    } 
} 

$stmt = $linki->prepare("SELECT IFNULL(SUM(hours),0) FROM table WHERE ".$sitesql." AND week!='0000-00-00'"); 
call_user_func_array(array(&$stmt, 'bind_param'), $array_of_params); 
$stmt->execute(); 
2

आप मिल गया है, नहीं मान mselves। होना चाहिए:

$array_of_params[0] = &$param_string; //link to variable that stores types 

और फिर ...

$param_string .= "i"; 
$user_id_var = $_GET['user_id'];// 
$array_of_params[] = &$user_id_var; //link to variable that stores value 

अन्यथा (यदि यह मूल्यों की सारणी है) आप प्राप्त करेंगे:

पीएचपी चेतावनी: पैरामीटर 2 mysqli_stmt को :: bind_param() एक संदर्भ


होने की उम्मीद

एक और उदाहरण:

$bind_names[] = implode($types); //putting types of parameters in a string 
for ($i = 0; $i < count($params); $i++) 
{ 
    $bind_name = 'bind'.$i; //generate a name for variable bind1, bind2, bind3... 
    $$bind_name = $params[$i]; //create a variable with this name and put value in it 
    $bind_names[] = & $$bind_name; //put a link to this variable in array 
} 

और BOOOOOM:

call_user_func_array(array ($stmt, 'bind_param'), $bind_names);