Rumah > pembangunan bahagian belakang > tutorial php > Bagaimana PHP dijalankan - dari kod sumber untuk diberikan

Bagaimana PHP dijalankan - dari kod sumber untuk diberikan

Jennifer Aniston
Lepaskan: 2025-02-10 10:11:11
asal
808 orang telah melayarinya

Bagaimana PHP dijalankan - dari kod sumber untuk diberikan

Artikel ini dikaji semula oleh Younes Rafie. Terima kasih kepada semua pengulas rakan sebaya SitePoint untuk membuat kandungan SitePoint yang terbaik boleh!


Diilhamkan oleh artikel baru -baru ini mengenai bagaimana kod Ruby dilaksanakan, artikel ini merangkumi proses pelaksanaan untuk kod PHP.

Bagaimana PHP dijalankan - dari kod sumber untuk diberikan Takeaways Key

Pelaksanaan kod PHP melibatkan empat peringkat: lexing, parsing, kompilasi, dan tafsiran. Setiap peringkat adalah penting dalam proses menukar kod sumber PHP ke dalam kod yang boleh dibaca mesin.
  • lexing, atau tokenizing, adalah proses mengubah rentetan (kod sumber php) ke dalam urutan token. Setiap token adalah pengenal yang dinamakan untuk nilai yang dipadankannya. Tahap ini juga menyimpan lexeme dan nombor garis token yang dipadankan.
  • Tahap parsing mengesahkan kesahihan urutan token dan menghasilkan pokok sintaks abstrak (AST). AST adalah pandangan pokok kod sumber yang digunakan semasa peringkat penyusunan.
  • Tahap kompilasi memancarkan opcode dengan melintasi AST dan melakukan pengoptimuman seperti menyelesaikan fungsi panggilan dengan hujah -hujah literal dan lipatan ekspresi matematik yang berterusan. Output tahap ini boleh diperiksa menggunakan opcache, vld, dan phpdbg.
  • Tahap tafsiran adalah peringkat akhir di mana opcode dijalankan pada enjin Zend (ZE) VM. Output tahap ini adalah apa yang dikeluarkan oleh skrip php anda melalui arahan seperti echo, cetak, var_dump, dan lain -lain
  • Pengenalan
Terdapat banyak perkara yang berlaku di bawah tudung apabila kita melaksanakan sekeping kod PHP. Secara umum, jurubahasa PHP melalui empat peringkat semasa melaksanakan kod:

lexing

    parsing
  1. kompilasi
  2. Interpretasi
  3. Artikel ini akan melewati peringkat ini dan menunjukkan bagaimana kita dapat melihat output dari setiap peringkat untuk benar -benar melihat apa yang sedang berlaku. Perhatikan bahawa walaupun beberapa sambungan yang digunakan sepatutnya menjadi sebahagian daripada pemasangan PHP anda (seperti Tokenizer dan Opcache), yang lain perlu dipasang dan didayakan secara manual (seperti PHP-AST dan VLD).
Peringkat 1 - Lexing

lexing (atau tokenizing) adalah proses mengubah rentetan (kod sumber PHP, dalam kes ini) menjadi urutan token. Token hanyalah pengenal yang dinamakan untuk nilai yang dipadankannya. PHP menggunakan RE2C untuk menghasilkan lexernya dari fail definisi Zend_Language_Scanner.l.

kita dapat melihat output tahap lexing melalui lanjutan tokenizer:

output:

$code = <<<'code'
<span><span><?php
</span></span><span><span>$a = 1;
</span></span><span>code<span>;
</span></span><span>
</span><span><span>$tokens = token_get_all($code);
</span></span><span>
</span><span><span>foreach ($tokens as $token) {
</span></span><span>    <span>if (is_array($token)) {
</span></span><span>        <span>echo "Line <span><span>{$token[2]}</span>: "</span>, token_name($token[0]), " ('<span><span>{$token[1]}</span>')"</span>, PHP_EOL;
</span></span><span>    <span>} else {
</span></span><span>        <span>var_dump($token);
</span></span><span>    <span>}
</span></span><span><span>}
</span></span>
Salin selepas log masuk
Salin selepas log masuk

Terdapat beberapa mata yang patut diberi perhatian dari output di atas. Titik pertama ialah tidak semua kepingan kod sumber dinamakan token. Sebaliknya, beberapa simbol dianggap sebagai token dalam dan dari diri mereka (seperti =,,:,?, Dll). Titik kedua adalah bahawa Lexer sebenarnya melakukan sedikit lebih daripada sekadar mengeluarkan aliran token. Ia juga, dalam kebanyakan kes, menyimpan lexeme (nilai yang dipadankan dengan token) dan nombor garis token yang dipadankan (yang digunakan untuk perkara -perkara seperti jejak stack).

Peringkat 2 - Parsing

parser juga dihasilkan, kali ini dengan bison melalui fail tatabahasa BNF. PHP menggunakan tatabahasa bebas konteks LALR (1) (lihat ke hadapan, kiri-ke-kanan). Bahagian Look Ahead hanya bermakna bahawa parser dapat melihat token N di hadapan (1, dalam kes ini) untuk menyelesaikan kekaburan yang mungkin ditemui semasa parsing. Bahagian kiri-ke-kanan bermaksud bahawa ia mengasingkan aliran token dari kiri ke kanan.

Tahap parser yang dihasilkan mengambil aliran token dari lexer sebagai input dan mempunyai dua pekerjaan. Ia terlebih dahulu mengesahkan kesahihan perintah token dengan cuba memadankan mereka terhadap mana -mana peraturan tatabahasa yang ditakrifkan dalam fail tatabahasa BNFnya. Ini memastikan bahawa pembinaan bahasa yang sah sedang dibentuk oleh token dalam aliran token. Tugas kedua parser adalah untuk menjana Abstrak Sintaks Tree (AST) - pandangan pokok kod sumber yang akan digunakan pada peringkat seterusnya (kompilasi).

kita boleh melihat bentuk AST yang dihasilkan oleh parser menggunakan lanjutan PHP-CAS. AST dalaman tidak didedahkan secara langsung kerana ia tidak "bersih" untuk bekerja dengan (dari segi konsistensi dan kebolehgunaan umum), dan oleh itu lanjutan PHP-CAS melakukan beberapa transformasi di atasnya untuk menjadikannya lebih baik untuk bekerja dengan.

mari kita lihat AST untuk sekeping kod asas:

Line 1: T_OPEN_TAG ('<?php
')
Line 2: T_VARIABLE ('$a')
Line 2: T_WHITESPACE (' ')
string(1) "="
Line 2: T_WHITESPACE (' ')
Line 2: T_LNUMBER ('1')
string(1) ";"
Salin selepas log masuk
Salin selepas log masuk

output:

$code = <<<'code'
<span><span><?php
</span></span><span><span>$a = 1;
</span></span><span>code<span>;
</span></span><span>
</span><span><span>print_r(ast<span>\parse_code</span>($code, 30));
</span></span>
Salin selepas log masuk
Salin selepas log masuk
nod pokok (yang biasanya jenis astnode) mempunyai beberapa sifat:

    jenis - nilai integer untuk menggambarkan jenis nod; Setiap mempunyai pemalar yang sepadan (mis. AST_STMT_LIST => 132, AST_ASSIGN => 517, AST_VAR => 256)
  • Bendera - Integer yang menentukan tingkah laku yang terlalu banyak (mis. Node astast_binary_op akan mempunyai bendera untuk membezakan operasi binari mana yang berlaku)
  • lineno - nombor baris, seperti yang dilihat dari maklumat token sebelumnya
  • Kanak -kanak - sub nod, biasanya bahagian nod dipecah lebih jauh (mis. Nod fungsi akan mempunyai anak -anak: parameter, jenis pulangan, badan, dll)
  • output AST tahap ini berguna untuk berfungsi untuk alat seperti penganalisis kod statik (mis. Phan).

Peringkat 3 - Kompilasi

Tahap kompilasi menggunakan AST, di mana ia memancarkan opcode dengan rekursif melintasi pokok. Tahap ini juga melakukan beberapa pengoptimuman. Ini termasuk menyelesaikan beberapa panggilan fungsi dengan hujah -hujah literal (seperti Strlen ("ABC") kepada Int (3)) dan melipat ekspresi matematik berterusan (seperti 60 * 60 * 24 ke int (86400)).

kita boleh memeriksa output opcode pada tahap ini dalam beberapa cara, termasuk dengan Opcache, VLD, dan PHPDBG. Saya akan menggunakan VLD untuk ini, kerana saya rasa output lebih mesra untuk dilihat.

Mari lihat apakah output untuk skrip file.php berikut:

$code = <<<'code'
<span><span><?php
</span></span><span><span>$a = 1;
</span></span><span>code<span>;
</span></span><span>
</span><span><span>$tokens = token_get_all($code);
</span></span><span>
</span><span><span>foreach ($tokens as $token) {
</span></span><span>    <span>if (is_array($token)) {
</span></span><span>        <span>echo "Line <span><span>{$token[2]}</span>: "</span>, token_name($token[0]), " ('<span><span>{$token[1]}</span>')"</span>, PHP_EOL;
</span></span><span>    <span>} else {
</span></span><span>        <span>var_dump($token);
</span></span><span>    <span>}
</span></span><span><span>}
</span></span>
Salin selepas log masuk
Salin selepas log masuk

Melaksanakan perintah berikut:

Line 1: T_OPEN_TAG ('<?php
')
Line 2: T_VARIABLE ('$a')
Line 2: T_WHITESPACE (' ')
string(1) "="
Line 2: T_WHITESPACE (' ')
Line 2: T_LNUMBER ('1')
string(1) ";"
Salin selepas log masuk
Salin selepas log masuk

output kami ialah:

$code = <<<'code'
<span><span><?php
</span></span><span><span>$a = 1;
</span></span><span>code<span>;
</span></span><span>
</span><span><span>print_r(ast<span>\parse_code</span>($code, 30));
</span></span>
Salin selepas log masuk
Salin selepas log masuk

jenis opcodes menyerupai kod sumber asal, cukup untuk diikuti bersama dengan operasi asas. (Saya tidak akan menyelidiki butir -butir opcode dalam artikel ini, kerana itu akan mengambil beberapa artikel keseluruhannya.) Tiada pengoptimuman digunakan pada tahap opcode dalam skrip di atas - tetapi seperti yang dapat kita lihat, fasa penyusunan telah membuat beberapa dengan menyelesaikan keadaan malar (php_version === '7.1.0-dev') kepada benar.

Opcache lebih daripada sekadar caching opcodes (dengan itu melangkaui tahap lexing, parsing, dan kompilasi). Ia juga membungkus dengan banyak tahap pengoptimuman yang berbeza. Mari kita tukar tahap pengoptimuman kepada empat pas untuk melihat apa yang keluar:

Command:

ast\Node Object (
    [kind] => 132
    [flags] => 0
    [lineno] => 1
    [children] => Array (
        [0] => ast\Node Object (
            [kind] => 517
            [flags] => 0
            [lineno] => 2
            [children] => Array (
                [var] => ast\Node Object (
                    [kind] => 256
                    [flags] => 0
                    [lineno] => 2
                    [children] => Array (
                        [name] => a
                    )
                )
                [expr] => 1
            )
        )
    )
)
Salin selepas log masuk

output:

<span>if (PHP_VERSION === '7.1.0-dev') {
</span>    <span>echo 'Yay', PHP_EOL;
</span><span>}
</span>
Salin selepas log masuk
kita dapat melihat bahawa keadaan malar telah dikeluarkan, dan kedua -dua arahan echo telah dipadatkan ke dalam satu arahan. Ini hanyalah rasa pengoptimuman Opcache yang banyak berlaku apabila melakukan pas di atas opcodes skrip. Saya tidak akan melalui pelbagai tahap pengoptimuman dalam artikel ini walaupun, kerana itu juga akan menjadi artikel dalam dirinya sendiri.

Peringkat 4 - Tafsiran

Tahap akhir adalah tafsiran opcodes. Di sinilah Opcodes dijalankan pada VM Zend Engine (ZE). Sebenarnya tidak banyak yang boleh dikatakan mengenai tahap ini (dari perspektif peringkat tinggi, sekurang-kurangnya). Output cukup banyak apa pun output skrip PHP anda melalui arahan seperti echo, cetak, var_dump, dan sebagainya.

jadi bukannya menggali apa -apa yang kompleks pada tahap ini, inilah fakta yang menyeronokkan: PHP memerlukan dirinya sebagai kebergantungan apabila menghasilkan VM sendiri. Ini kerana VM dihasilkan oleh skrip PHP, kerana ia lebih mudah untuk menulis dan lebih mudah untuk dikekalkan.

Kesimpulan

Kami telah melihat secara ringkas melalui empat peringkat yang diterjemahkan oleh penterjemah PHP semasa menjalankan kod PHP. Ini terlibat menggunakan pelbagai sambungan (termasuk Tokenizer, PHP-AST, Opcache, dan VLD) untuk memanipulasi dan melihat output setiap peringkat.

Saya harap artikel ini telah membantu memberi anda pemahaman holistik yang lebih baik mengenai penterjemah PHP, serta menunjukkan kepentingan pelanjutan Opcache (untuk kedua -dua kebolehan caching dan pengoptimumannya).

Soalan Lazim (Soalan Lazim) Mengenai Proses Pelaksanaan PHP

Apakah peranan penterjemah PHP dalam proses pelaksanaan? Ia bertanggungjawab untuk menukar kod sumber PHP ke dalam kod boleh dibaca mesin. Jurubahasa membaca garis skrip PHP mengikut baris, menafsirkan setiap baris, dan melakukan operasi yang diperlukan. Ia juga bertanggungjawab untuk menangani kesilapan dan pengecualian semasa proses pelaksanaan. Jurubahasa PHP adalah komponen utama persekitaran runtime PHP, yang juga termasuk pelayan web dan sambungan PHP. Proses pelaksanaan PHP. Ia bertanggungjawab untuk menghuraikan skrip PHP, menyusunnya ke bytecode, dan kemudian melaksanakan bytecode. Enjin PHP menggunakan proses dua langkah untuk melaksanakan skrip PHP. Pertama, ia mengutip skrip PHP dan mengubahnya menjadi pokok sintaks abstrak (AST). Kemudian, ia menyusun AST ke bytecode dan melaksanakannya. Enjin PHP juga termasuk pengurus memori dan pemungut sampah untuk menguruskan penggunaan memori semasa proses pelaksanaan. -Line Interface (CLI) dan antara muka pelayan web adalah dua cara yang berbeza untuk menjalankan skrip PHP. CLI digunakan untuk menjalankan skrip PHP dari baris arahan, manakala antara muka pelayan web digunakan untuk menjalankan skrip PHP sebagai tindak balas kepada permintaan web. Perbezaan utama antara kedua -dua antara muka adalah cara mereka mengendalikan input dan output. Dalam CLI, input dibaca dari baris arahan dan output ditulis ke konsol. Di antara muka pelayan web, input dibaca dari permintaan dan output HTTP ditulis kepada respons HTTP. mekanisme yang membolehkannya mengendalikan kesilapan semasa proses pelaksanaan. Apabila ralat berlaku, PHP menjana mesej ralat dan menghantarnya ke pengendali ralat. Pengendali ralat boleh memaparkan mesej ralat, log, atau mengabaikannya, bergantung pada tetapan pelaporan ralat. PHP juga menyokong pengendalian pengecualian, yang membolehkannya mengendalikan kesilapan dengan cara yang lebih berstruktur dan terkawal.

Apakah peranan sambungan PHP dalam proses pelaksanaan? Mereka dimuatkan ke dalam persekitaran runtime PHP semasa proses pelaksanaan dan boleh digunakan untuk melaksanakan pelbagai tugas, dari akses pangkalan data ke pemprosesan imej. Sambungan PHP ditulis dalam C dan disusun menjadi kod mesin, yang menjadikannya sangat cepat dan cekap. Mereka adalah komponen utama ekosistem PHP dan menyumbang kepada fleksibiliti dan kuasa.

Bagaimana PHP mengoptimumkan proses pelaksanaan? Salah satu daripada teknik ini ialah Caching Opcode, yang melibatkan menyimpan bytecode yang dihasilkan oleh enjin PHP dalam ingatan supaya ia boleh digunakan semula dalam eksekusi berikutnya. Ini menghapuskan keperluan untuk menghuraikan dan menyusun skrip PHP setiap kali ia dilaksanakan, mengakibatkan peningkatan prestasi yang signifikan. PHP juga menggunakan kompilasi Just-in-Time (JIT), yang melibatkan penyusun bytecode ke dalam kod mesin semasa runtime untuk meningkatkan prestasi. PHP mempunyai pengurus memori terbina dalam yang mengendalikan peruntukan memori dan deallocation semasa proses pelaksanaan. Pengurus memori memperuntukkan memori untuk pembolehubah dan struktur data seperti yang diperlukan, dan memori deallocates apabila ia tidak lagi diperlukan. PHP juga mempunyai pemungut sampah yang secara automatik membebaskan memori yang tidak lagi digunakan. Ini membantu mengelakkan kebocoran memori dan mengekalkan penggunaan memori di bawah kawalan.

Apakah peranan pelayan web dalam proses pelaksanaan PHP?

proses. Ia bertanggungjawab untuk mengendalikan permintaan HTTP, menjalankan skrip PHP sebagai tindak balas kepada permintaan ini, dan menghantar respons HTTP kembali kepada pelanggan. Pelayan web berfungsi rapat dengan penterjemah PHP dan enjin PHP untuk melaksanakan skrip PHP dan menghasilkan laman web dinamik. Pelayan web yang paling biasa digunakan untuk PHP adalah Apache dan Nginx. MySQL, PostgreSQL, dan SQLite. Ia menggunakan sambungan khusus pangkalan data untuk berinteraksi dengan pangkalan data ini semasa proses pelaksanaan. Sambungan ini menyediakan satu set fungsi yang boleh digunakan untuk menyambung ke pangkalan data, melaksanakan pertanyaan SQL, mengambil keputusan, dan mengendalikan kesilapan. PHP juga menyokong lanjutan PDO (PHP Data Objects), yang menyediakan antara muka pangkalan data-agnostik untuk interaksi pangkalan data.

Bagaimanakah PHP mengendalikan pengurusan sesi semasa proses pelaksanaan? Apabila sesi dimulakan, PHP mencipta ID sesi yang unik dan menyimpannya dalam kuki pada penyemak imbas pelanggan. ID sesi ini kemudiannya dihantar kembali ke pelayan dengan setiap permintaan berikutnya, yang membolehkan PHP mengenal pasti klien dan mengambil data sesi yang sepadan. Ciri -ciri pengurusan sesi PHP memudahkan untuk melaksanakan pengesahan pengguna, kereta belanja, dan ciri -ciri lain yang lain dalam aplikasi web.

Atas ialah kandungan terperinci Bagaimana PHP dijalankan - dari kod sumber untuk diberikan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan