PHP được biên dịch hay giải thích?


142

PHP được biên dịch hay giải thích?

Câu trả lời:


127

PHP là một ngôn ngữ được giải thích. Nhị phân cho phép bạn diễn giải PHP được biên dịch, nhưng những gì bạn viết được diễn giải.

Bạn có thể xem thêm trên trang Wikipedia cho các ngôn ngữ được giải thích


26
Ông có nghĩa là tiện ích được gọi là php (hoặc trên windows php.exe) được biên dịch.
sepp2k

7
@nicky Điều đó có nghĩa là chương trình được sử dụng để giải thích PHP được biên dịch, nhưng bản thân PHP được diễn giải.
Andrew Song

5
Nhưng tại sao nó lại được đề cập như thế này trong wikipedia? goo.gl/YOwZ Kể từ PHP 4, trình phân tích cú pháp PHP biên dịch đầu vào để tạo mã byte để xử lý bởi Zend Engine, giúp cải thiện hiệu năng so với phiên bản trước của trình thông dịch.
kiranvj

5
@kiranvj Nó thực sự được biên soạn để cải thiện hiệu suất, nhưng trong thời gian chạy. Hãy nghĩ về "ngôn ngữ được biên dịch" là "được biên dịch trước" và giải thích các ngôn ngữ là "Biên dịch khi chạy". Đó là sự khác biệt giữa hai điều này: - JIT ("Vừa đúng lúc"), trong đó chỉ có mã cần được biên dịch khi cần (tuy nhiên, lưu ý rằng sau khi trình thông dịch thoát, mã được biên dịch rất nhiều) - AOT (" Trước thời gian "), trong đó tất cả các mã được biên dịch trước khi nó được chạy.
Thibault Martin-Lagardette

4
@kiranvj: Tôi tin rằng OP muốn biết nếu PHP được biên dịch thành mã gốc. Biên dịch nó thành mã byte, sau đó được Zend giải thích lại, nằm ở đâu đó ở giữa về chi phí biên dịch và hiệu năng thời gian chạy. Lol, đây là một chủ đề khá cũ, chỉ cần nhận ra nó.
Groo

66

Cả hai. PHP được biên dịch thành mã byte trung gian, sau đó được giải thích bởi công cụ thời gian chạy.

Công việc của trình biên dịch PHP là phân tích mã PHP của bạn và chuyển đổi nó thành một biểu mẫu phù hợp với công cụ thời gian chạy. Trong số các nhiệm vụ của nó:

  • Bỏ qua ý kiến
  • Giải quyết các biến, tên hàm, v.v. và tạo bảng ký hiệu
  • Xây dựng cây cú pháp trừu tượng của chương trình của bạn
  • Viết mã byte

Tùy thuộc vào thiết lập PHP của bạn, bước này thường được thực hiện chỉ một lần, lần đầu tiên tập lệnh được gọi. Đầu ra của trình biên dịch được lưu trữ để tăng tốc truy cập vào các lần sử dụng tiếp theo. Tuy nhiên, nếu tập lệnh được sửa đổi, bước biên dịch được thực hiện lại.

Công cụ thời gian chạy đi bộ AST và mã byte khi tập lệnh được gọi. Bảng ký hiệu được sử dụng để lưu trữ các giá trị của các biến và cung cấp địa chỉ mã byte cho các hàm.

Quá trình biên dịch thành mã byte và giải thích nó khi chạy là điển hình cho các ngôn ngữ chạy trên một số loại máy chạy ảo bao gồm Perl, Java, Ruby, Smalltalk và các ngôn ngữ khác.


Liên kết biến xảy ra trong thời gian chạy, không biên dịch thời gian.
jrockway

PHP thậm chí không cố gắng giải quyết tên nào trong phạm vi tại thời gian biên dịch?
Barry Brown

17

Nói chung, nó được giải thích, nhưng đôi khi có thể sử dụng nó như được biên dịch và nó thực sự làm tăng hiệu suất. Công cụ nguồn mở để thực hiện thao tác này: hhvm.com


15

PHP là một ngôn ngữ được giải thích. Mặc dù vậy, nó có thể được biên dịch sang mã byte bởi các công cụ của bên thứ ba.


2
"Mã byte" là một thuật ngữ được sử dụng cho các hướng dẫn giả cụ thể của VM, không phải là nguồn gốc do đó không thể được coi là "biên dịch" trong ngữ cảnh này.
Sedat Kapanoglu

7
"Mã đối tượng" chỉ là mã byte cho bộ giải mã lệnh của CPU. (Bạn không nghĩ rằng CPU thực sự có các hướng dẫn riêng như "CMPSB", phải không?)
jrockway

11

Một mã được biên dịch có thể được thực thi trực tiếp bởi CPU của máy tính. Đó là, mã thực thi được chỉ định bằng ngôn ngữ bản địa của CPU

Mã của các ngôn ngữ được dịch phải được dịch trong thời gian chạy từ bất kỳ định dạng nào sang hướng dẫn máy CPU. Bản dịch này được thực hiện bởi một thông dịch viên.

Sẽ không đúng khi nói rằng một ngôn ngữ được diễn giải hoặc biên dịch bởi vì giải thích và biên dịch là cả hai thuộc tính của việc thực hiện ngôn ngữ cụ thể đó và không phải là một thuộc tính của chính ngôn ngữ đó. Vì vậy, bất kỳ ngôn ngữ nào cũng có thể được biên dịch hoặc diễn giải - nó chỉ phụ thuộc vào việc triển khai cụ thể mà bạn đang sử dụng.

Việc triển khai PHP được sử dụng rộng rãi nhất được cung cấp bởi Zend Engine và được gọi đơn giản là PHP. Zend Engine biên dịch nguồn PHP thành định dạng mà nó có thể thực thi, do đó công cụ Zend hoạt động như một trình thông dịch .


2
" Nghĩa là, mã thực thi được chỉ định bằng ngôn ngữ bản địa của CPU " .. Mã thực thi không được chỉ định bằng ngôn ngữ bản địa của CPU nhưng ở định dạng nhị phân, ngôn ngữ gốc của CPU có thể là bất cứ điều gì và khi các nhị phân phần mềm không giống như vậy CPU hoặc CPU đó .. Mã được biên dịch đầy đủ và có thể thực thi sẽ ở định dạng nhị phân ..
hagrawal

10

Đây là một câu hỏi vô nghĩa. PHP sử dụng yacc (bison), giống như GCC. yacc là một "trình biên dịch trình biên dịch". Đầu ra của yacc là một trình biên dịch. Đầu ra của một trình biên dịch được "biên dịch". PHP được phân tích cú pháp bởi đầu ra của yacc. Vì vậy, theo định nghĩa, được biên soạn.

Nếu điều đó không thỏa mãn, hãy xem xét những điều sau đây. Cả php (nhị phân) và gcc đều đọc mã nguồn của bạn và tạo ra một cây cú pháp trừu tượng. Trong phiên bản 4 và 5, php sau đó đi trên cây để dịch chương trình sang mã byte (bước biên dịch). Bạn có thể thấy mã byte được dịch sang opcodes (tương tự như lắp ráp) bằng cách sử dụng Trình quét logic Vulcan . Cuối cùng, php (đặc biệt là công cụ Zend) diễn giải mã byte. gcc, trong so sánh, đi bộ cây và đầu ra lắp ráp; nó cũng có thể chạy các trình biên dịch và trình liên kết để kết thúc quá trình. Gọi một chương trình được xử lý bởi một "phiên dịch" và một chương trình khác được xử lý bởi "biên dịch" khác là vô nghĩa. Rốt cuộc, các chương trình đều chạy qua một "trình biên dịch" với cả hai.

Thay vào đó, bạn thực sự nên hỏi câu hỏi bạn muốn hỏi. ("Tôi có phải trả tiền phạt hiệu suất khi PHP biên dịch lại mã nguồn của tôi cho mọi yêu cầu không?", V.v.)


5
Mã thông báo mã nguồn không được biên dịch. Ngay cả VBScript có thể được coi là một ngôn ngữ được biên dịch với định nghĩa của bạn.
Sedat Kapanoglu

5
Tôi với jrockway về điều này, mặc dù nó không thực sự trả lời câu hỏi của OP. Thật hấp dẫn khi tạo ra một phân loại ngôn ngữ trong đó mọi ngôn ngữ được sắp xếp sạch sẽ vào từng danh mục. Nhưng thực tế không quá gọn gàng. Hầu như mọi ngôn ngữ là sự pha trộn của các đặc điểm. Ngoài ra, khi bạn truy cập thẳng vào nó, ngay cả mã máy gốc cũng được bộ xử lý "diễn giải".
Barry Brown

4
Khẳng định cấp cao của bạn là chính xác, đây một câu hỏi vô nghĩa. Tuy nhiên, đối số của bạn không hữu ích lắm, tất cả những gì bạn đã thực hiện được đưa ra các định nghĩa mờ và đưa chúng đến mức cực đoan. Biên dịch là sự chuyển đổi nguồn thành mã đối tượng. Có, bạn có thể coi việc chuyển đổi nguồn thành một cây cú pháp cụ thể / trừu tượng là một phần tổng hợp, nhưng đó không phải là ý nghĩa của hầu hết mọi người? Bất kể, đây là một câu hỏi vô nghĩa vì một ngôn ngữ không vốn đã biên soạn hoặc giải thích, implmentations của một ngôn ngữ được biên dịch hoặc giải thích.
Falaina

6
Chúng ta đừng giám sát rằng anh chàng là người mới bắt đầu. điều này khiến tôi diễn giải câu hỏi là "việc triển khai Zend có tạo ra mã gốc từ nguồn PHP không?". kiểm tra câu trả lời của tôi Tôi nghĩ rằng bạn đang quá khắt khe về cách đặt câu hỏi. bạn biết đấy, chúng tôi đang cố gắng giúp đỡ, không bash một số người mới.
Sedat Kapanoglu

3
Tôi hoàn toàn đồng ý với Sedat. Bạn có thể chia sẻ kiến ​​thức của mình mà không phải là một người tinh ranh với người hỏi
Alexandre Bour trước

10

Tôi biết câu hỏi này đã cũ nhưng nó được liên kết ở mọi nơi và tôi nghĩ tất cả các câu trả lời ở đây đều không chính xác (có thể vì chúng đã cũ).

NO những điều như một ngôn ngữ giải thích hoặc một ngôn ngữ biên dịch. Bất kỳ ngôn ngữ lập trình có thể được giải thích và / hoặc biên dịch.

Trước hết, một ngôn ngữ chỉ là một bộ quy tắc, vì vậy khi chúng ta nói về việc biên dịch, chúng ta đề cập đến việc triển khai cụ thể của ngôn ngữ đó.

HHVM , ví dụ, là một triển khai của PHP. Nó sử dụng trình biên dịch JIT để chuyển đổi mã thành mã byte trung gian HipHop và sau đó được dịch thành mã máy. Có đủ để nói nó được biên dịch? Một số triển khai Java (không phải tất cả) cũng sử dụng JIT. V8 của Google cũng sử dụng JIT.

Sử dụng các định nghĩa cũ của biên dịch so với giải thích ngày nay không có ý nghĩa.

"PHP có được biên dịch không?" là một câu hỏi không nhạy cảm được đưa ra rằng không còn sự phân định rõ ràng và đồng ý giữa ngôn ngữ được biên dịch so với ngôn ngữ được dịch.

Một cách có thể để phân định chúng là (Tôi không tìm thấy bất kỳ ý nghĩa nào trong cách phân đôi này):

ngôn ngữ biên dịch sử dụng biên dịch trước thời gian (C, C ++);

các ngôn ngữ được giải thích sử dụng biên dịch Just in Time hoặc không biên dịch gì cả (Python, Ruby, PHP, Java).


Mặc dù vậy, Java không sử dụng biên dịch trước thời gian trong hầu hết các trường hợp? Tôi là một nhà phát triển Java khá mới và chúng tôi thường biên dịch mã theo cách của chúng tôi trước khi chạy.
aCarella

@aCarella in most cases, vâng. trong mọi trường hợp, không. vì vậy bạn không thể vẽ một dòng có ý nghĩa về mặt ngữ nghĩa và được đồng ý.
Claudiu Creanga

2

Ít nhất là nó không biên dịch (hoặc tôi nên nói là tối ưu hóa) mã nhiều như người ta có thể muốn nó.

Mã này ...

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

... trì hoãn chương trình nhiều như nhau mỗi lần nó chạy.

Nó có thể đã phát hiện ra rằng đó là một tính toán chỉ cần được thực hiện lần đầu tiên.


Bây giờ chúng ta có một tùy chọn được gọi là máy phát điện.
Ankit Vishwakarma

1

Câu trả lời được chấp nhận là sai một cách trắng trợn. PHP được biên dịch. Kết thúc câu chuyện. Có thể không phải là hướng dẫn riêng mà là mã byte được giải thích.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.