เหตุใดการอ้างอิงถึงไม่ค่อยมีใช้ใน PHP


26

ฉันมีความรู้ C ++ และรู้ว่ามีการใช้พอยน์เตอร์ทั่วไป แต่ฉันเริ่มดูซอร์สโค้ด PHP และฉันไม่เคยเห็นโค้ดที่ใช้อ้างอิงในวิธีการ

แต่รหัสจะใช้ค่าที่ส่งคืนแทนการส่งการอ้างอิงไปยังตัวแปรไปยังเมธอดซึ่งจะเปลี่ยนค่าของตัวแปรนั้นและส่งคืนค่านั้น

ฉันได้อ่านแล้วว่าการใช้การอ้างอิงใช้หน่วยความจำน้อยลงดังนั้นทำไมจึงไม่ใช้ใน PHP


19
การใช้พารามิเตอร์ Pass-by-Reference คือ "การเขียนโปรแกรมผลข้างเคียง" - การใช้ฟังก์ชั่นเพื่อส่งกลับค่าเดียวมีความชัดเจนมากขึ้นเมื่ออ่านโค้ด ที่กล่าวว่าฟังก์ชั่นหลักของ PHP ค่อนข้างน้อยใช้การอ้างอิง
halfer

3
PHP ส่งผ่านวัตถุโดยการอ้างอิงโดยค่าเริ่มต้น

2
เรียงลำดับอาร์เรย์เป็น exanmple ที่สำคัญของฟังก์ชั่นหลักของ PHP ที่ผ่านการอ้างอิง
Mark Baker

2
การอ้างอิง PHP ไม่ใช่ตัวชี้และมักจะมีความเจ็บปวดในตูดหากคุณไม่ได้คาดหวังอย่างเต็มที่ว่าจะปรากฏที่ใด
lanzz

2
หากคุณต้องการผลตอบแทนหลายรายการreturn array($foo, $bar);และlist($A, $B) = foobar();
Izkata

คำตอบ:


49

การยืนยันของคุณว่าการอ้างอิงที่ใช้บ่อยครั้งนั้นไม่ถูกต้อง เป็นคนอื่น ๆ ได้กล่าวแล้วมีตันของฟังก์ชั่นพื้นเมืองที่ใช้การอ้างอิงตัวอย่างที่โดดเด่นรวมถึงอาร์เรย์เรียงลำดับฟังก์ชั่นและ/preg_match() preg_match_all()หากคุณกำลังใช้ฟังก์ชั่นใด ๆ เหล่านี้ในรหัสของคุณคุณกำลังใช้การอ้างอิงด้วย

ต่อไปการอ้างอิงใน PHP ไม่ใช่ตัวชี้ ตั้งแต่คุณมาจาก c ++ พื้นหลังฉันสามารถเข้าใจความสับสน แต่อ้างอิง PHP เป็นสัตว์ที่แตกต่างอย่างสิ้นเชิงพวกเขามีชื่อแทนไปยังตารางสัญลักษณ์ ประสิทธิภาพใด ๆ ที่คุณอาจได้รับจากการอ้างอิง C ++ นั้นไม่ได้ใช้กับการอ้างอิง PHP

ในความเป็นจริงในสถานการณ์ส่วนใหญ่ที่ส่งผ่านค่าจะเร็วกว่าและมีหน่วยความจำน้อยกว่าการส่งต่อโดยอ้างอิง Zend Engine ซึ่งเป็นแกนกลางของ PHP ใช้กลไกการออปติไมซ์แบบคัดลอกตามการเขียนที่ไม่ได้สร้างสำเนาของตัวแปรจนกว่าจะมีการแก้ไข การส่งต่อโดยการอ้างอิงมักจะแบ่งรูปแบบการคัดลอกเมื่อเขียนและต้องมีการคัดลอกไม่ว่าคุณจะแก้ไขค่าหรือไม่

อย่ากลัวที่จะใช้การอ้างอิงใน PHP เมื่อคุณต้องการ แต่อย่าเพิ่งทำมันเป็นการพยายามเพิ่มประสิทธิภาพขนาดเล็ก โปรดจำไว้ว่าการเพิ่มประสิทธิภาพก่อนวัยอันควรเป็นรากของความชั่วร้ายทั้งหมด

อ่านเพิ่มเติม:


ขอบคุณสำหรับการแก้ไข @NikiC คำตอบที่ขี้เกียจนิด ๆ นี้ ...
yannis

เพื่อให้คำตอบเสร็จสมบูรณ์มันเป็นการดีที่จะชี้ให้เห็นว่าวัตถุทั้งหมดถูกส่งผ่านโดยการอ้างอิงใน PHP
Florian Margaine

@ FlorianMargaine นั้นไม่ถูกต้องทั้งหมด (ดูลิงก์ที่สองในการอ่านเพิ่มเติม)
yannis

2
@ FlorianMargaine ไม่ทั้งสองแตกต่างกันมากและเป็นเรื่องสำคัญที่จะต้องตระหนักว่าทำไมถึงเป็นเช่นนั้น
phant0m

3
@FlorianMargaine ไม่มีวัตถุสมมติว่าถูกส่งผ่านโดยการอ้างอิงใน PHP: f($obj)ได้รับfunction f($x) { $x = new X; }จะต้อง$objหมายถึงแตกต่างกันf()วัตถุกว่าก่อนการเรียกร้องให้ อย่างไรก็ตามเนื่องจากวัตถุไม่ได้ถูกส่งผ่านโดยอ้างอิง $ obj จะไม่ได้รับการแก้ไขหากคุณต้องดำเนินการนี้ด้วย PHP ด้วยวิธีนี้ PHP ทำเช่นเดียวกับ Java
phant0m

8

PHP ทำสิ่งที่คัดลอกแล้วเขียนซึ่งมันไม่ได้สร้างคุณค่าใหม่จนกว่าคุณจะเปลี่ยนแปลงบางสิ่งบางอย่างดังนั้นจึงมีหน่วยความจำไม่มากนักที่บันทึกโดยใช้การอ้างอิง การทำเช่นนั้นสามารถทำให้ยุ่งเหยิงกับบางสิ่งที่ PHP ทำภายในเพื่อลดการใช้หน่วยความจำ

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

โดยทั่วไปฉันเพียงต้องการหาผ่านโดยอ้างอิงที่มีประโยชน์สำหรับ "ออก" พารามิเตอร์หมายถึงตัวแปรที่ฉันคาดหวังที่จะได้รับกลับมาจากการทำงานมากกว่าผ่านในลา'spreg_match &$matchesแม้สำหรับฟังก์ชั่นที่ปรับเปลี่ยนวัตถุที่กำลังส่งผ่านอย่างชัดเจนsortหรือarray_popรู้สึกว่ามันค่อนข้างลำบาก แต่ก็เป็นสิ่งที่เรายึดติดอยู่


5

PHP เป็นภาษาที่มุ่งเน้นเว็บ
หน้าเว็บที่แสดงผลเร็วและควรมีน้ำหนักเบา
โปรแกรม PHP ปกติใช้เวลาเพียงเสี้ยววินาทีและกินหน่วยความจำไม่กี่ร้อยกิโลไบท์
ไม่มีประโยชน์สำหรับการเพิ่มประสิทธิภาพดังกล่าว


1
นี้. ไม่ต้องการตัวชี้ / การอ้างอิงเนื่องจากมันไม่ได้ยุ่งกับระดับต่ำเช่น C ++
Kenneth Worden

8
ทำไมโพสต์นี้ถึง 5+ ??? มันไม่ก) ไม่ได้ตอบคำถามข) ไม่ถูกต้อง

1
ดังนั้นการอ้างอิงจึงช้าและใช้หน่วยความจำมากเกินไป?
Rocket Hazmat

1
@RocketHazmat ใช่แปลกพอจริง
yannis

3

เหตุผลบางอย่างในทันที:

  • PHP เป็นภาษาสคริปต์และไม่ได้ตั้งเป้าที่จะใช้เป็นซอฟต์แวร์ฝังตัวหลัก (โดยทั่วไปหน่วยความจำจะถูกลบทิ้งในตอนท้ายของสคริปต์)
  • ตั้งแต่ PHP5 การอ้างอิงแบบ pass-by-reference นั้นมีความหมายสำหรับพารามิเตอร์ของวัตถุ (ดังนั้น PHP จึงใช้การอ้างอิงแบบ pass-by-reference "in your back")

1
ดูที่: php.net/manual/th/language.oop5.references.phpสำหรับจุดที่สองของคุณ
yannis

2

ฉันคิดว่านี่เป็นเพียงทางเลือกของนักพัฒนาไม่มีส่วนเกี่ยวข้องกับภาษา มีโค้ด PHP มากมาย (ในตัวและไม่ใช่) ใช้การอ้างอิง ลองดูฟังก์ชั่นอาร์เรย์ใน PHP ซึ่งมีการอ้างอิงการใช้งานมากมาย preg_matchใช้การอ้างอิง

ฉันคิดว่าหนึ่งในเหตุผลที่นักพัฒนาเลือกที่จะไม่ใช้การอ้างอิงเป็นเพราะอาจทำให้เกิดความสับสน คุณเรียกใช้ฟังก์ชันและหนึ่งในตัวแปรอาจ (หรืออาจไม่) ได้รับการปรับปรุงเพราะมันเป็นข้อมูลอ้างอิง ดังนั้นเมื่อคุณดีบักอาจไม่ชัดเจนว่าทำไมค่าของ$xjsut จึงเปลี่ยนไปอย่างน่าอัศจรรย์


1

ปัญหาพื้นฐานของคำถามของคุณคือคุณคิดว่านี่เป็นเรื่องปกติใน C ++ เช่นกัน มันไม่ใช่ เราไม่ชอบพารามิเตอร์เอาท์พุทและใช้ให้น้อยที่สุดเท่าที่จะเป็นไปได้ - มันเป็นเรื่องธรรมดามากใน C-style API


0

ฉันรู้ว่าฟังก์ชั่น php มากมายที่ทำเช่นนั้น ลองดูpreg_match()ตัวอย่าง $matchesจะถูกส่งผ่านโดยการอ้างอิง

หากคุณต้องการเขียนฟังก์ชั่นสำหรับตัวคุณเองที่รับอาร์กิวเมนต์โดยการอ้างอิงจากนั้นใช้ไวยากรณ์ต่อไปนี้

function byref(&$a, &$b, $c) {
    $a += $c;
    $b += $c;
    return $a * $b;
}

$ a และ $ b ถูกส่งผ่านโดยการอ้างอิง $ c ถูกส่งผ่านโดยค่า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.