☰
一个 `.php` 文件从你敲下命令到屏幕上输出结果,中间经历了哪些步骤?
2026/9/26 12:46:44 网站建设 项目流程

场景:命令行执行php test.php(CLI模式,不是网页访问,区分FPM)
前提:系统环境已经安装PHP解释器,并且把php可执行文件加入环境变量PATH

根因

PHP本身是解释型语言,不是直接CPU执行。敲下php命令后,操作系统、PHP内核、Zend引擎依次完成:找到程序、读取源码、词法语法分析、编译成中间字节码、Zend虚拟机执行字节码,最终输出字符到终端屏幕。

完整分步拆解

步骤1:Shell接收你输入的命令php test.php

你在终端敲回车,shell(bash/zsh/cmd)读取整行字符串。

  1. Shell拆分命令:程序名php,参数test.php
  2. 在系统PATH环境变量目录中搜索,找到php这个可执行二进制程序(php-cli)
  3. 操作系统调用系统调用fork创建新进程,exec加载php-cli程序,启动PHP进程。

步骤2:PHP内核启动,接收参数,定位目标php文件

PHP进程启动,初始化内核、加载php.ini配置:加载扩展(mysqli、json等)、设置内存上限、错误等级。
读取传入参数test.php:

  • 判断文件名是否存在、是否可读;文件不存在直接抛出No such file or directory报错。
  • 打开文件,通过操作系统read系统调用,把test.php源码文本读取到内存。源码此时仍然是纯文本字符串(<?php ... ?>)。

步骤3:词法分析(Lex 词法扫描)

Zend引擎的词法分析器扫描源码字符流。
把连续文本切割成Token(标记):关键字if、echo、变量$a、数字、字符串、分号、括号。
简单理解:把文章切成一个个词语,剔除空格、注释。
遇到语法字符错误,这一步就报词法错误。

步骤4:语法分析(Yacc 语法解析)

拿到Token流,按照PHP语法规则,构建抽象语法树 AST。
AST是树形结构,代表代码逻辑:哪一段是表达式、哪一段是分支、哪一段是函数调用。
这一步会检查语法,少写分号、括号不匹配,在这里抛出语法解析错误。

步骤5:编译:AST → Zend 字节码(opcode)

Zend引擎遍历AST,翻译成Opcode(操作码)。
Opcode是Zend虚拟机能识别的指令,类似Java的bytecode,不是机器码,不能直接交给CPU运行。

开启opcache之后,会把编译好的Opcode缓存,下次执行直接跳过词法语法编译,直接拿缓存字节码,提升速度。本次第一次执行,无缓存。

步骤6:Zend虚拟机执行Opcode

Zend VM逐条解释执行Opcode:

  • 开辟内存,创建变量、数组、对象;
  • 运算、函数调用;
  • 遇到echo这类输出指令,不会直接写屏幕,先交给PHP内核输出缓冲区(output buffer);
  • 代码过程中,执行IO操作(读文件、数据库连接)会发起对应的操作系统系统调用。

步骤7:输出缓冲区刷新,操作系统输出到终端

echo输出内容先写入PHP输出缓冲区。脚本执行结束,自动刷新buffer。
PHP调用操作系统write系统调用,把文本数据写入标准输出stdout。
操作系统内核把stdout的数据交给终端程序,终端渲染字符,在显示器屏幕展示文字结果。

步骤8:脚本执行完毕,资源回收,进程退出

  1. 释放变量内存,关闭打开的文件、数据库连接;
  2. PHP做垃圾回收(GC,回收无引用对象);
  3. PHP进程退出,操作系统回收进程占用内存、文件描述符等资源。

【区分补充】如果是浏览器访问 http://xxx/test.php(FPM模式,和CLI不一样)

  1. 浏览器发起HTTP请求 → Nginx/Apache接收请求
  2. Web服务器识别后缀.php,转发请求给PHP-FPM
  3. FPM子进程接收请求,读取php源码,同样走词法→语法→AST→Opcode→Zend VM执行
  4. echo输出内容组装成HTTP响应报文,回传给Nginx,再返回浏览器,浏览器渲染页面。

误区澄清

误区1:PHP源码直接翻译成CPU机器码执行。
纠正:PHP是Zend虚拟机解释Opcode,不是直接编译成机器码。只有HHVM这类JIT模式,才会把Opcode动态编译成机器码。

误区2:echo直接写屏幕。
纠正:echo写入PHP输出缓冲区,脚本结束才一次性输出,减少系统调用次数。

一句话总结
Shell找到php-cli程序创建进程,PHP读取php源码;经过词法切Token、语法生成AST,编译成Zend字节码,虚拟机执行指令;输出内容写入缓冲区,刷新后通过系统调用输出到终端,执行结束释放资源,进程退出。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询