PHP - แก้ไขวัตถุปัจจุบันใน foreach loop


111

ฉันสงสัยว่าเป็นไปได้ไหมที่จะแก้ไขวัตถุปัจจุบันที่ถูกจัดการภายในforeachลูป

ฉันกำลังทำงานกับอาร์เรย์ของออบเจ็กต์$questionsและฉันต้องการตรวจสอบและค้นหาคำตอบที่เกี่ยวข้องกับวัตถุคำถามนั้นในฐานข้อมูลของฉัน ดังนั้นสำหรับแต่ละคำถามให้ดึงวัตถุคำตอบและอัปเดตปัจจุบัน$question ภายในforeachลูปของฉันเพื่อให้ฉันสามารถส่งออก / ประมวลผลที่อื่นได้

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

ตามที่ทั้ง ArtjomKurapov และ @topener แนะนำว่าฉันกำลังมองหา 'pass by reference' โดยใช้เครื่องหมาย & ขอบคุณมาก :) ขอให้มีความสุขมาก ๆ ในวันนี้
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อัปเดตอยู่เสมอ แต่ฉันจะบอกว่าคนแรกแนะนำแม้ว่าจะสั้นกว่าก็ตาม (ดูความคิดเห็นของ Paystey)

ตามเอกสารPHPforeach :

เพื่อให้สามารถแก้ไของค์ประกอบอาร์เรย์ได้โดยตรงภายในลูปที่นำหน้าค่า $ ด้วย &. ในกรณีนั้นค่าจะถูกกำหนดโดยการอ้างอิง


32
foreachไม่แนะนำให้ใช้การอ้างอิงในวิธีที่การforeachส่งผ่านไปรอบ ๆ ส่วนของค่าของลูปส่งผลให้เกิดพฤติกรรมที่ไม่สามารถคาดเดาได้ อาจนานกว่านี้ แต่คุณปลอดภัยกว่าเมื่อใช้วิธีที่ 1 ที่นี่
Paystey

1
ฉันใช้เวลาเพียงชั่วโมงเดียวในการแก้ไขปัญหาที่เกิดจากการใช้ข้อมูลอ้างอิงใน foreach ฉันใช้ชื่อตัวแปรเดิมซ้ำสำหรับการเรียก foreach ครั้งที่สอง - เมื่อฉันส่งผ่านรายการแรกโดยการอ้างอิงมันก็ยังคงแก้ไขรายการสุดท้ายในอาร์เรย์! การใช้ดัชนีที่ชัดเจนจะไม่มีปัญหานี้
Hippyjim

7
@Paystey คุณสามารถอ้างอิงแหล่งที่มาของคุณหรือให้คำอธิบายโดยละเอียดได้หรือไม่?
Nico

2
เหตุใดการจัดการข้อมูลอ้างอิงจึงไม่ปลอดภัย C / C ++ ที่คุณต้องจัดการการอ้างอิงทุกที่ที่ไม่ปลอดภัยหรือไม่? ขึ้นอยู่กับคุณว่าจะทำให้ปลอดภัยหรือไม่ไม่ใช่ภาษา
Kalzem

2
@BabyAzerty: Paystey ไม่ได้กล่าวถึงการอ้างอิง "โดยทั่วไป" แต่foreachเกี่ยวกับความสยองขวัญเช่นนี้stackoverflow.com/questions/3307409/… (@Nico, FYI ด้วย)
Sz.

6

แน่นอนว่าการใช้array_mapและหากการใช้คอนเทนเนอร์ที่นำArrayAccessไปใช้กับวัตถุเป็นเพียงวิธีที่ชาญฉลาดและมีความหมายมากกว่านี้หรือไม่?

ความหมายของแผนที่อาร์เรย์มีความคล้ายคลึงกันในภาษาและการใช้งานส่วนใหญ่ที่ฉันเคยเห็น ได้รับการออกแบบมาเพื่อส่งคืนอาร์เรย์ที่แก้ไขตามองค์ประกอบอาร์เรย์อินพุต (ระดับสูงโดยไม่สนใจการกำหนดค่าประเภทการคอมไพล์ / รันไทม์) ลูปมีไว้เพื่อใช้ตรรกะมากขึ้น

สำหรับการดึงวัตถุโดย ID / PK ขึ้นอยู่กับว่าคุณกำลังใช้ SQL หรือไม่ (ดูเหมือนจะแนะนำ) ฉันจะใช้ตัวกรองเพื่อให้แน่ใจว่าฉันได้รับอาร์เรย์ของ PK ที่ถูกต้องจากนั้นระเบิดด้วยลูกน้ำและวางลงในส่วนIN()คำสั่งSQL เพื่อ ส่งคืนผลลัพธ์ที่ตั้งไว้ ทำให้การโทรหนึ่งครั้งแทนที่จะเป็นหลาย ๆ ครั้งผ่านทาง SQL เพิ่มประสิทธิภาพบิตของ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
ใช้งานง่ายกว่าการทำ foreach - นี่คือสิ่งที่ฟังก์ชันนี้ออกแบบมาสำหรับ
benjaminhull
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.