อัปเดตสำหรับ PHP 7.2
PHP 7.2 นำเสนอการเปลี่ยนแปลงพฤติกรรมในการแปลงคีย์ตัวเลขในออบเจ็กต์และอาร์เรย์ซึ่งแก้ไขความไม่สอดคล้องกันนี้โดยเฉพาะและทำให้ตัวอย่างต่อไปนี้ทั้งหมดทำงานตามที่คาด
น้อยเรื่องที่จะสับสน!
คำตอบเดิม (ใช้กับเวอร์ชันก่อนหน้า 7.2.0)
PHP มีหุ้นของตรอกซอกซอยมืดที่คุณจริงๆไม่ต้องการที่จะพบว่าตัวเองอยู่ภายใน คุณสมบัติของวัตถุที่มีชื่อเป็นตัวเลขเป็นหนึ่งในนั้น ...
สิ่งที่พวกเขาไม่เคยบอกคุณ
ข้อเท็จจริง # 1:คุณไม่สามารถเข้าถึงคุณสมบัติที่มีชื่อที่ไม่ใช่ชื่อตัวแปรตามกฎหมายได้อย่างง่ายดาย
$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->123foo;
ข้อเท็จจริง # 2:คุณสามารถเข้าถึงคุณสมบัติดังกล่าวได้ด้วยไวยากรณ์ปีกกา
$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->{'123foo'};
ข้อเท็จจริง # 3:แต่ไม่ใช่ถ้าชื่อคุณสมบัติเป็นตัวเลขทั้งหมด!
$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->{'123foo'};
echo $o->{'123'};
ตัวอย่างสด
ข้อเท็จจริง # 4:เว้นแต่ว่าวัตถุนั้นไม่ได้มาจากอาร์เรย์ตั้งแต่แรก
$a = array('123' => '123');
$o1 = (object)$a;
$o2 = new stdClass;
$o2->{'123'} = '123';
echo $o1->{'123'};
echo $o2->{'123'};
ตัวอย่างสด
ใช้งานง่ายดีคุณไม่เห็นด้วย?
คุณสามารถทำอะไรได้บ้าง
ตัวเลือก # 1: ทำด้วยตนเอง
แนวทางที่เป็นประโยชน์ที่สุดคือเพียงแค่โยนวัตถุที่คุณสนใจกลับเข้าไปในอาร์เรย์ซึ่งจะช่วยให้คุณสามารถเข้าถึงคุณสมบัติ:
$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
$a = (array)$o;
echo $o->{'123'};
echo $a['123'];
น่าเสียดายที่การดำเนินการนี้ไม่สามารถทำงานซ้ำได้ ดังนั้นในกรณีของคุณคุณต้องทำสิ่งต่างๆเช่น:
$highlighting = (array)$myVar->highlighting;
$data = (array)$highlighting['448364']->Data;
$value = $data['0'];
ตัวเลือก # 2: ตัวเลือกนิวเคลียร์
อีกทางเลือกหนึ่งคือการเขียนฟังก์ชันที่แปลงวัตถุเป็นอาร์เรย์แบบวนซ้ำ:
function recursive_cast_to_array($o) {
$a = (array)$o;
foreach ($a as &$value) {
if (is_object($value)) {
$value = recursive_cast_to_array($value);
}
}
return $a;
}
$arr = recursive_cast_to_array($myVar);
$value = $arr['highlighting']['448364']['Data']['0'];
อย่างไรก็ตามฉันไม่มั่นใจว่านี่เป็นตัวเลือกที่ดีกว่าในกระดานเพราะมันจะถูกส่งไปยังอาร์เรย์ของคุณสมบัติทั้งหมดที่คุณไม่สนใจรวมทั้งคุณสมบัติที่คุณเป็นอยู่โดยไม่จำเป็น
ตัวเลือก # 3: เล่นอย่างชาญฉลาด
อีกทางเลือกหนึ่งของตัวเลือกก่อนหน้านี้คือการใช้ฟังก์ชัน JSON ในตัว:
$arr = json_decode(json_encode($myVar), true);
$value = $arr['highlighting']['448364']['Data']['0'];
ฟังก์ชัน JSON ทำการแปลงแบบวนซ้ำเป็นอาร์เรย์โดยไม่จำเป็นต้องกำหนดฟังก์ชันภายนอกใด ๆ อย่างไรก็ตามรูปลักษณ์นี้เป็นที่ต้องการ แต่ก็มีข้อเสีย "nuke" ของตัวเลือก # 2 และนอกจากนี้ข้อเสียคือหากมีสตริงใด ๆ ในวัตถุของคุณสตริงเหล่านั้นจะต้องเข้ารหัสเป็น UTF-8 (นี่เป็นข้อกำหนดของjson_encode
)