PHP - वर्तमान ऑब्जेक्ट को foreach लूप में संशोधित करें


111

मैं सोच रहा था कि क्या यह संभव है कि वर्तमान वस्तु को एक foreachलूप के भीतर संभाला जाए

मैं वस्तुओं की एक सरणी के साथ काम कर रहा हूं $questionsऔर मैं अपने db में उस प्रश्न ऑब्जेक्ट से जुड़े उत्तरों की तलाश करना चाहता हूं। इसलिए प्रत्येक प्रश्न के लिए उत्तर वस्तुओं को लाएं और अपने लूप के $question अंदर करंट को अपडेट करें foreachताकि मैं कहीं और आउटपुट / प्रोसेस कर सकूं।

foreach($questions as $question){
    $question['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}

जैसा कि ArtjomKurapov और @topener दोनों ने सुझाव दिया था कि मैं & साइन का उपयोग करके 'संदर्भ द्वारा पास' की तलाश कर रहा था। धन्यवाद chaps :) का दिन शुभ है
Garbit

जवाबों:


207

इसे करने के 2 तरीके हैं

foreach($questions as $key => $question){
    $questions[$key]['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}

इस तरह आप कुंजी को सहेजते हैं, इसलिए आप इसे मुख्य $questionsचर में फिर से अपडेट कर सकते हैं

या

foreach($questions as &$question){

जोड़ने से अपडेट &रहेगा $questions। लेकिन मैं कहूंगा कि यह छोटा होने के बावजूद पहले की सिफारिश की गई है (पेस्ते द्वारा टिप्पणी देखें)

प्रति पीएचपी foreachप्रलेखन :

लूप के भीतर सरणी तत्वों को सीधे संशोधित करने में सक्षम होने के लिए $ & के साथ पूर्ववर्ती मूल्य। उस स्थिति में मान को संदर्भ द्वारा असाइन किया जाएगा।


32
में संदर्भ foreachवास्तव में अनुशंसित नहीं है, जिस तरह foreachसे लूप के मूल्य भाग के आसपास से गुजरता है, अप्रतिसादी व्यवहार होता है। यह अधिक लंबा हो सकता है, लेकिन आप यहां विधि 1 का उपयोग करके अधिक सुरक्षित हैं।
पेस्टी

1
मैं सिर्फ एक परेशान एक संदर्भ में एक संदर्भ का उपयोग कर के कारण एक डिबगिंग घंटे बिताया। मैंने दूसरे फॉर्च्यूस कॉल के लिए उसी वैरिएबल नाम का फिर से उपयोग किया - जैसा कि मैंने संदर्भ द्वारा पहला पास किया है, यह सरणी में अंतिम आइटम को संशोधित करता रहा! एक स्पष्ट सूचकांक का उपयोग करने से यह समस्या नहीं होती।
हिप्पीजिम

7
@Paystey आप अपने स्रोतों का हवाला दे सकते हैं या एक विस्तृत विवरण दे सकते हैं?
निको

2
हेरफेर करने वाले संदर्भ असुरक्षित क्यों होंगे? क्या C / C ++ है जहाँ आपको असुरक्षित हर जगह संदर्भों में हेरफेर करना है? यह आप पर निर्भर है कि आप इसे सुरक्षित कर सकते हैं या नहीं, भाषा को नहीं।
कालजिम

2
@BabyAzerty: Paystey ने संदर्भों को "सामान्य रूप से" नहीं कहा, लेकिन foreachइस तरह के डरावने संबंध में: stackoverflow.com/questions/3307409/… (@Nico, FYI, too।)
Sz।

6

निश्चित रूप से उपयोग करना array_mapऔर अगर ArrayAccessवस्तुओं को प्राप्त करने के लिए लागू करने वाले कंटेनर का उपयोग करना इस बारे में जाने का सिर्फ एक चालाक, अर्थपूर्ण तरीका है?

सरणी मानचित्र शब्दार्थ अधिकांश भाषाओं और कार्यान्वयनों के समान हैं जिन्हें मैंने देखा है। यह इनपुट एरे तत्व (उच्च स्तरीय भाषा संकलन / रनटाइम प्रकार की प्राथमिकता की अनदेखी) के आधार पर एक संशोधित सरणी वापस करने के लिए डिज़ाइन किया गया है; एक लूप अधिक तर्क प्रदर्शन करने के लिए है।

आईडी / पीके द्वारा वस्तुओं को प्राप्त करने के लिए, यदि आप एसक्यूएल का उपयोग कर रहे हैं या नहीं (यह सुझाव दिया गया लगता है) के आधार पर, मैं यह सुनिश्चित करने के लिए एक फिल्टर का उपयोग करूंगा कि मुझे वैध पीके की एक सरणी मिलती है, फिर अल्पविराम के साथ निहित करें और एसक्यूएल IN()क्लॉज में जगह दें परिणाम-सेट लौटाएँ। यह एसक्यूएल के माध्यम से कई के बजाय एक कॉल करता है, थोड़ा सा call->waitचक्र को अनुकूलित करता है। सबसे महत्वपूर्ण बात यह है कि मेरा कोड किसी भी भाषा के किसी व्यक्ति के पास योग्यता की डिग्री के साथ अच्छी तरह से पढ़ा होगा और हम परिवर्तनशीलता की समस्याओं में नहीं चलते हैं।

<?php

$arr = [0,1,2,3,4];
$arr2 = array_map(function($value) { return is_int($value) ? $value*2 : $value; }, $arr);
var_dump($arr);
var_dump($arr2);

बनाम

<?php

$arr = [0,1,2,3,4];
foreach($arr as $i => $item) {
    $arr[$i] = is_int($item) ? $item * 2 : $item;
}
var_dump($arr);

यदि आप जानते हैं कि आप क्या कर रहे हैं तो आपको कभी भी म्यूटेबिलिटी की समस्या नहीं होगी (यदि आप ओवर राइटिंग का इरादा रखते हैं तो आप $arrहमेशा $arr = array_mapस्पष्ट और स्पष्ट हो सकते हैं ।


2
फॉरच्यू करने की तुलना में बहुत अधिक सहज - यह वही है जो इस फ़ंक्शन के लिए डिज़ाइन किया गया है।
बेंजामिनहॉल 12
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.