菜鸟科技网

PHP代码执行流程是怎样的?

为了让你更好地理解,我们先用一个生活中的比喻,然后再深入技术细节。

PHP代码执行流程是怎样的?-图1
(图片来源网络,侵删)

生活中的比喻:餐厅点餐

想象一下你去一家西餐厅:

  1. 你(程序员):写下了一份详细的菜单(PHP源代码文件,如 index.php,上面用中文(PHP语法)写着:

    • “一份牛排”
    • “牛排要七分熟”
    • “配一份黑胡椒酱”
    • “再加一杯可乐”
  2. 餐厅里的法国厨师(PHP解释器/Zend引擎):他只懂法语,完全看不懂中文,他的工作就是:

    • 读取你的菜单。
    • 逐行翻译:把“牛排”翻译成法语 steak,“七分熟”翻译为 à point,“黑胡椒酱”翻译为 sauce poivre
    • 执行指令:根据翻译好的法语指令,他开始烹饪、摆盘、制作饮料。
  3. 出餐(生成HTML输出):厨师把做好的牛排和可乐(最终生成的纯HTML内容)端给你,你作为食客(浏览器),看到的只是一份美味的牛排,完全不知道厨师是怎么把它从你的中文菜单变出来的,浏览器只负责“吃”(显示)这份最终的食物。

    PHP代码执行流程是怎样的?-图2
    (图片来源网络,侵删)

在这个比喻中:

  • 菜单 = PHP 源代码
  • 中文菜单 = .php 文件
  • 法国厨师 = PHP 解释器,特别是其核心 Zend 引擎
  • 翻译和烹饪过程 = PHP 的执行过程
  • 做好的牛排 = 发送给浏览器的 HTML 输出

技术层面的详细执行流程

我们把这个比喻转换成计算机科学的专业术语,一个 .php 文件从被请求到最终返回给浏览器,需要经过以下几个关键步骤:

第1步:请求发起

用户在浏览器中输入一个网址,https://www.example.com/index.php,或者点击了一个链接,浏览器会向指定的Web服务器(如 Apache 或 Nginx)发送一个HTTP请求,请求获取 index.php 这个文件。

第2步:Web服务器接收请求

Web服务器(如 Apache)接收到这个请求,它会检查请求的文件后缀是 .php,因为 .php 是一个需要特殊处理的文件类型,所以服务器不会直接把 index.php 的文本内容发送给浏览器。

PHP代码执行流程是怎样的?-图3
(图片来源网络,侵删)

第3步:启动PHP解释器

Web服务器会把这个请求“委托”给PHP解释器来处理,这个过程通常通过 CGI (通用网关接口) 或更高效的 PHP-FPM (FastCGI Process Manager) 来完成。

  • 简单理解:Web服务器就像一个前台,看到是 .php 文件,就立刻呼叫后台的“专家”(PHP解释器)来处理。

第4步:PHP解释器核心工作(最关键的一步)

PHP解释器(通常是 Zend 引擎及其相关模块)现在开始正式工作,它主要包括以下几个子步骤:

a. 词法分析

  • 解释器会逐个字符地读取 index.php 文件的内容。
  • 它会把字符流“切分”成一个个有意义的“单词”,这些“单词”在PHP中被称为 Token(令牌)。
  • 代码 $a = "hello"; 会被切分成以下 Token:
    • T_VARIABLE ($a)
    • T_WHITESPACE (空格)
    • T_EQUAL ()
    • T_CONSTANT_ENCAPSED_STRING ("hello")
    • T_SEMICOLON ()

b. 语法分析

  • 词法分析器产生的 Token 序列会被传递给语法分析器。
  • 语法分析器会根据PHP的“语法规则”(就像英语的语法一样)来检查这些 Token 的顺序是否正确,形成一个“语法树”(也叫抽象语法树,AST)。
  • 如果代码写错了,$a = "hello (少了个引号),语法分析器就会发现错误并报告“语法错误”。

c. 编译

  • 这是PHP一个非常重要的特性:PHP是一种编译型脚本语言
  • 语法分析器生成的“语法树”会被编译成一种叫做 Opcode(操作码) 的中间语言,你可以把 Opcode 理解成一种非常底层的、CPU能更好理解的“指令集”。
  • 这个编译过程是即时的,每次请求都会发生,虽然PHP是解释型语言给人的印象,但它内部有一个编译成字节码的步骤,这比纯解释执行要快得多。

d. 执行

  • 编译好的 Opcode 会被 Zend 引擎的 执行器 逐条读取并执行。
  • 在执行过程中,如果代码需要访问数据库、读写文件、调用其他服务等,Zend 引擎会调用相应的 PHP 扩展(如 mysqli 扩展、curl 扩展)来完成这些任务。
  • 所有这些操作的结果都会被整合起来。

第5步:生成输出

  • 在执行PHP代码的过程中,所有的 echoprint 语句,或者直接嵌入在 HTML 中的代码块(<?php ... ?>),其输出的内容都会被收集起来。
  • PHP解释器将所有这些输出内容合并成一个单一的纯文本流(绝大多数情况下是HTML)。

第6步:返回结果并关闭

  • PHP解释器将这个最终的文本流(HTML内容)返回给最初调用它的Web服务器(Apache 或 Nginx)。
  • Web服务器再将这个HTML响应通过HTTP协议发送回用户的浏览器。
  • 浏览器接收到这个纯HTML后,开始渲染页面,显示给用户。
  • PHP解释器在完成任务后,会释放内存,等待下一次请求。

一个重要的优化:OPcache

在上面的第4步中,每次请求都会重新读取文件、词法分析、语法分析、编译成Opcode,这是一个相对耗时的过程。

为了解决这个问题,PHP提供了 OPcache 扩展

  • 工作原理:OPcache 会将在硬盘上编译生成的 Opcode 缓存到服务器的内存中。
  • 效果:当下一次再有用户请求同一个 .php 文件时,PHP解释器会直接从内存中读取缓存的 Opcode 来执行,而跳过了前面所有耗时的“读取文件 -> 词法分析 -> 语法分析 -> 编译”步骤。
  • 开启 OPcache 能极大地提升PHP应用的性能,几乎是所有生产环境的标配。
步骤 描述 对应比喻 关键技术点
请求 浏览器向服务器请求 .php 文件 顾客点餐 HTTP请求
服务器接收 Web服务器识别出是PHP文件,不直接返回 前台服务员识别需要厨师处理的订单 Web Server (Apache/Nginx)
启动解释器 服务器将任务交给PHP解释器 呼叫厨师 CGI / PHP-FPM
核心执行 解释器读取、分析、编译、执行代码 厨师翻译菜单并烹饪 Zend引擎: 词法分析 -> 语法分析 -> 编译成Opcode -> 执行
生成输出 将代码执行结果(HTML)整合起来 厨师把做好的菜端出来 echo, print, HTML输出
返回结果 服务器将HTML返回给浏览器 服务员把菜端给顾客 HTTP响应
优化 缓存编译后的Opcode,避免重复编译 厨师把翻译好的菜单存起来,下次直接用 OPcache

希望这个从比喻到技术的详细解释,能让你彻底明白PHP是如何执行的!

分享:
扫描分享到社交APP
上一篇
下一篇