PHP รวบรวมหรือตีความหรือไม่?


คำตอบ:


127

PHP เป็นภาษาที่ตีความ ไบนารีที่ให้คุณแปล PHP ถูกคอมไพล์ แต่สิ่งที่คุณเขียนถูกตีความ

คุณสามารถดูเพิ่มเติมได้ที่หน้า Wikipedia สำหรับภาษาที่ตีความ


26
เขาหมายถึงการรวบรวมยูทิลิตี้ที่เรียกว่า php (หรือบน windows php.exe) ถูกรวบรวม
sepp2k

7
@nicky หมายความว่าโปรแกรมที่ใช้ในการแปล PHP ถูกคอมไพล์ แต่ PHP นั้นถูกตีความ
Andrew Song

5
แต่ทำไมมันถึงพูดถึงเรื่องนี้ในวิกิพีเดีย? goo.gl/YOwZ ตั้งแต่ PHP 4 ตัวแยกวิเคราะห์ PHP จะรวบรวมอินพุตเพื่อสร้าง bytecode สำหรับการประมวลผลโดย Zend Engine ซึ่งให้ประสิทธิภาพที่เหนือกว่าล่ามรุ่นก่อน
kiranvj

5
@kiranvj มันถูกรวบรวมเพื่อการแสดงที่ดีขึ้น แต่ในขณะรันไทม์ คิดว่า "รวบรวมภาษา" เป็น "รวบรวมไว้ล่วงหน้า" และแปลภาษาเป็น "รวบรวมเมื่อทำงาน" มันเป็นข้อแตกต่างระหว่างสองสิ่งนี้: - JIT ("ทันเวลา") ซึ่งมีการรวบรวมเฉพาะรหัสที่จำเป็นเมื่อจำเป็น (หมายเหตุอย่างไรก็ตามหลังจากที่ล่ามหยุดทำงานรหัสที่รวบรวมจะมีจำนวนมาก) - AOT (" ข้างหน้าของเวลา ") ซึ่งรหัสทั้งหมดจะถูกรวบรวมก่อนที่จะถูกเรียกใช้
Thibault Martin-Lagardette

4
@kiranvj: ฉันเชื่อว่า OP ต้องการทราบว่า PHP ได้รับการคอมไพล์ด้วยโค้ดเนมหรือไม่ รวบรวมไปยัง bytecode ซึ่งจะถูกตีความอีกครั้งโดย Zend อยู่ที่ไหนสักแห่งที่อยู่ตรงกลางในแง่ของต้นทุนการรวบรวมและประสิทธิภาพรันไทม์ ฮ่า ๆ นี่เป็นเรื่องที่ค่อนข้างเก่าเพิ่งรู้ตัว
Groo

66

ทั้งสอง PHP ถูกคอมไพล์ลงไปเป็น bytecode ระดับกลางซึ่งตีความโดยโปรแกรมรันไทม์

หน้าที่ของคอมไพเลอร์ PHP คือการแยกวิเคราะห์รหัส PHP ของคุณและแปลงเป็นรูปแบบที่เหมาะสมสำหรับเอ็นจิ้นรันไทม์ ระหว่างงาน:

  • ละเว้นความคิดเห็น
  • แก้ไขตัวแปรชื่อฟังก์ชันและอื่น ๆ และสร้างตารางสัญลักษณ์
  • สร้างแผนผังไวยากรณ์แบบนามธรรมของโปรแกรมของคุณ
  • เขียน bytecode

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

เอ็นจินรันไทม์เดินตาม AST และ bytecode เมื่อสคริปต์ถูกเรียก ตารางสัญลักษณ์ใช้เพื่อเก็บค่าของตัวแปรและระบุที่อยู่ bytecode สำหรับฟังก์ชั่น

กระบวนการของการคอมไพล์ไปยัง bytecode และการตีความที่รันไทม์เป็นปกติสำหรับภาษาที่รันบนเครื่องรันไทม์เสมือนบางประเภทรวมถึง Perl, Java, Ruby, Smalltalk และอื่น ๆ


การรวมตัวแปรเกิดขึ้นที่รันไทม์ไม่ใช่เวลารวบรวม
jrockway

PHP ไม่ได้พยายามแก้ไขชื่อที่อยู่ในขอบเขตในเวลารวบรวม?
Barry

17

โดยทั่วไปจะมีการตีความ แต่บางครั้งสามารถใช้เป็นข้อมูลรวบรวมและเพิ่มประสิทธิภาพจริงๆ เครื่องมือโอเพนซอร์สเพื่อดำเนินการนี้: hhvm.com


15

PHP เป็นภาษาที่ตีความ แม้ว่ามันสามารถคอมไพล์ด้วย bytecode โดยเครื่องมือของบุคคลที่สามได้


2
"bytecode" เป็นคำที่ใช้สำหรับคำสั่งหลอกเฉพาะของ VM ซึ่งไม่ใช่แบบดั้งเดิมดังนั้นจึงไม่ถือว่าเป็น "การรวบรวม" ในบริบทนี้
Sedat Kapanoglu

7
"รหัสวัตถุ" เป็นเพียงโค้ดไบต์สำหรับตัวถอดรหัสคำสั่งของ CPU (คุณไม่คิดว่าซีพียูจริงมีคำแนะนำพื้นเมืองเช่น "CMPSB" ใช่ไหม?)
jrockway

11

รหัสเรียบเรียงสามารถดำเนินการได้โดยตรงโดย CPU ของคอมพิวเตอร์ นั่นคือรหัสที่ปฏิบัติการได้จะถูกระบุในภาษาดั้งเดิมของ CPU

รหัสของภาษาที่แปลต้องแปลในเวลาทำการจากรูปแบบใด ๆ ไปยังคำแนะนำของเครื่อง CPU การแปลนี้ทำโดยล่าม

มันจะไม่เหมาะสมที่จะบอกว่าภาษาถูกตีความหรือเรียบเรียงเพราะการตีความและการรวบรวมเป็นทั้งคุณสมบัติของการใช้งานของภาษานั้น ๆ และไม่ใช่คุณสมบัติของภาษาเอง ดังนั้นภาษาใด ๆ ที่สามารถรวบรวมหรือตีความ - มันขึ้นอยู่กับว่าการใช้งานเฉพาะที่คุณใช้ทำอะไร

PHP การดำเนินการใช้กันอย่างแพร่หลายมากที่สุดคือการขับเคลื่อนด้วยZend เครื่องยนต์และเป็นที่รู้จักแค่ในฐานะ PHP.The Zend เครื่องยนต์รวบรวมแหล่ง PHP ในรูปแบบที่จะสามารถดำเนินการจึงZend เครื่องยนต์ทำงานเป็นล่าม


2
" นั่นคือรหัสที่ปฏิบัติการได้ถูกระบุไว้ในภาษาดั้งเดิมของ CPU " .. รหัสปฏิบัติการไม่ได้ระบุไว้ในภาษาดั้งเดิมของ CPUแต่ในรูปแบบไบนารีภาษาดั้งเดิมของ CPU อาจเป็นอะไรก็ได้และเมื่อซอฟต์แวร์ไบนารีไม่ได้เป็นแบบนี้ CPU หรือ CPU ว่า .. รวบรวมอย่างเต็มที่และรหัสปฏิบัติการจะอยู่ในรูปแบบไบนารี ..
hagrawal

10

นี่เป็นคำถามที่ไร้ความหมาย PHP ใช้ yacc (bison) เช่นเดียวกับ GCC yacc เป็น "คอมไพเลอร์คอมไพเลอร์" ผลลัพธ์ของ yacc เป็นคอมไพเลอร์ ผลลัพธ์ของคอมไพเลอร์คือ "รวบรวม" PHP ถูกแยกวิเคราะห์โดยผลลัพธ์ของ yacc ดังนั้นจึงเป็นคำจำกัดความที่รวบรวม

หากไม่เป็นไปตามที่ควรพิจารณา ทั้ง php (ไบนารี) และ gcc อ่านซอร์สโค้ดของคุณและสร้างทรีไวยากรณ์ที่เป็นนามธรรม ในเวอร์ชัน 4 และ 5 php จะเดินแผนผังเพื่อแปลโปรแกรมเป็น bytecode (ขั้นตอนการรวบรวม) ท่านสามารถเข้าดู bytecode แปลเพื่อ opcodes (ซึ่งคล้ายกับการชุมนุม) โดยใช้วัลลอจิก Dumper ในที่สุด php (โดยเฉพาะ Zend engine) ตีความ bytecode gcc ในการเปรียบเทียบเดินต้นไม้และการชุมนุมเอาท์พุท; มันยังสามารถเรียกใช้แอสเซมเบลอร์และลิงเกอร์เพื่อทำให้กระบวนการเสร็จสิ้น การเรียกโปรแกรมที่จัดการโดย "ตีความ" และอีกโปรแกรมที่จัดการโดย "รวบรวม" อีกโปรแกรมหนึ่งนั้นไม่มีความหมาย ท้ายที่สุดแล้วโปรแกรมต่างก็ทำงานผ่าน "คอมไพเลอร์" พร้อมทั้งสองอย่าง

คุณควรถามคำถามที่คุณต้องการถามแทน ("ฉันต้องจ่ายค่าปรับประสิทธิภาพเนื่องจาก PHP คอมไพล์ซอร์สโค้ดของฉันสำหรับทุกคำขอหรือไม่" ฯลฯ )


5
Tokenizing ซอร์สโค้ดไม่ได้รวบรวม แม้แต่ VBScript ก็ถือได้ว่าเป็นภาษาที่คอมไพล์ด้วยคำจำกัดความของคุณ
Sedat Kapanoglu

5
ฉันใช้ jrockway กับสิ่งนี้แม้ว่ามันจะไม่ได้ตอบคำถามของ OP มันเป็นการดึงดูดให้สร้างอนุกรมวิธานของภาษาที่ทุกภาษาถูกจัดวางอย่างเรียบร้อยในแต่ละหมวดหมู่ แต่ความจริงก็ไม่เรียบร้อย เกือบทุกภาษาเป็นการผสมผสานของลักษณะเฉพาะ นอกจากนี้เมื่อคุณลงไปถึงตัวประมวลผลดั้งเดิมก็จะถูก "ตีความ" โดยโปรเซสเซอร์
Barry Brown

4
การยืนยันระดับสูงของคุณถูกต้องนี่เป็นคำถามที่ไม่มีความหมาย การโต้เถียงของคุณไม่เป็นประโยชน์มากนักสิ่งที่คุณทำทั้งหมดนั้นเป็นคำจำกัดความที่คลุมเครือและทำให้พวกเขาสุดขั้ว การคอมไพล์คือการแปลงซอร์สโค้ดเป็นรหัสวัตถุ ใช่คุณสามารถพิจารณาการแปลงแหล่งที่มาเป็นโครงสร้างการรวบรวมที่เป็นรูปธรรม / นามธรรม แต่นั่นไม่ใช่สิ่งที่คนส่วนใหญ่หมายถึง? โดยไม่คำนึงถึงนี้เป็นคำถามที่ไร้ความหมายเพราะภาษาไม่ได้โดยเนื้อแท้รวบรวมหรือตีความ implmentations ของภาษาเป็นข้อมูลที่รวบรวมหรือการตีความ
Falaina

6
อย่าดูแลว่าคนนั้นเป็นผู้เริ่มต้น สิ่งนี้ทำให้ฉันตีความคำถามว่า "การใช้ Zend ทำให้เกิดรหัสพื้นเมืองจากแหล่ง PHP หรือไม่" ตรวจสอบคำตอบของฉัน ฉันคิดว่าคุณเข้มงวดเกินไปเกี่ยวกับวิธีการถามคำถาม คุณก็รู้เรากำลังพยายามช่วยไม่ใช่มือใหม่บางคน
Sedat Kapanoglu

3
ฉันเห็นด้วยอย่างเต็มที่กับ Sedat คุณสามารถแบ่งปันความรู้ของคุณโดยไม่ต้องดิ๊กกับผู้ถาม
Alexandre Bourlier

10

ฉันรู้ว่าคำถามนี้เก่า แต่มันเชื่อมโยงกันทั่วสถานที่และฉันคิดว่าคำตอบทั้งหมดที่นี่ไม่ถูกต้อง (อาจเป็นเพราะพวกเขาแก่)

นอกจากนี้ไม่มีสิ่งเช่นแปลภาษาหรือภาษาที่รวบรวม ภาษาการเขียนโปรแกรมใด ๆ ที่สามารถตีความและ / หรือรวบรวม

ก่อนอื่นภาษาเป็นเพียงชุดของกฎดังนั้นเมื่อเรากำลังพูดถึงการรวบรวมเราหมายถึงการใช้งานเฉพาะของภาษานั้น

ตัวอย่างเช่นHHVMคือการนำ PHP ไปใช้ มันใช้การรวบรวม JIT เพื่อแปลงรหัสเป็น HipHop bytecode ระดับกลางแล้วแปลเป็นรหัสเครื่อง มันเพียงพอแล้วหรือยังที่จะบอกว่ามันถูกรวบรวม? Java implementations (ไม่ใช่ทั้งหมด) ก็ใช้ JIT เช่นกัน Google V8 ยังใช้ JIT

การใช้คำจำกัดความเก่าของการรวบรวมกับการตีความไม่ได้ทำให้รู้สึกในปัจจุบัน

"PHP คอมไพล์แล้วหรือยัง?" เป็นคำถามที่ไม่ไวต่อความรู้สึกเนื่องจากไม่มีตัวคั่นที่ชัดเจนและตกลงกันระหว่างสิ่งที่เป็นภาษาที่คอมไพล์เทียบกับภาษาที่แปล

วิธีหนึ่งที่เป็นไปได้ในการกำหนดเขตเหล่านั้นคือ (ฉันไม่พบความหมายใด ๆ ในขั้วต่อนี้):

ภาษาที่คอมไพล์ใช้การรวบรวมล่วงหน้า (C, C ++)

ภาษาที่แปลใช้การรวบรวมแบบทันเวลาหรือไม่มีการรวบรวมเลย (Python, Ruby, PHP, Java)


Java ไม่ได้ใช้การรวบรวมล่วงหน้าในกรณีส่วนใหญ่ใช่ไหม? ฉันเป็นนักพัฒนา Java ที่ค่อนข้างใหม่และเรามักจะรวบรวมวิธีโค้ดของเราก่อนรันไทม์
aCarella

@ aCarella in most casesใช่ ในทุกกรณีไม่มี ดังนั้นคุณจึงไม่สามารถวาดเส้นที่มีความหมายและตกลงกันได้
Claudiu Creanga

2

อย่างน้อยมันก็ไม่ได้คอมไพล์ (หรือฉันควรจะบอกว่าการเพิ่มประสิทธิภาพ) โค้ดมากที่สุดเท่าที่หนึ่งอาจต้องการมัน

รหัสนี้ ...

for($i=0;$i<100000000;$i++);
echo $i;

... โปรแกรมล่าช้ามากเท่า ๆ กันในแต่ละครั้งที่เรียกใช้

อาจตรวจพบว่าเป็นการคำนวณที่ต้องทำในครั้งแรกเท่านั้น


ตอนนี้เรามีตัวเลือกที่เรียกว่าเครื่องกำเนิดไฟฟ้า
Ankit Vishwakarma

1

คำตอบที่ยอมรับนั้นเป็นเท็จอย่างโจ๋งครึ่ม รวบรวม PHP IS ตอนจบของเรื่อง. อาจไม่ใช่คำสั่งพื้นฐาน แต่แปลโดยรหัสที่แปล

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