PHP 内核之旅系列

一、SAPI是什么?

1.1 理解SAPI

(1)SAPI是PHP框架的接口层。有很多种服务器的SAPI的实现,代码在sapi文件夹下。常见的接口抽象层实现有:cgi,apache2,cli,embed,fpm。

(2)各个服务器遵循着相同的约定,每个服务器的SAPI实现都有一套自己的实现。由于很多操作都是相同的,所以有一部分使用的是默认方法。

(3)SAPI类似面向对象中的模板方法模式的应用。 SAPI.c和SAPI.h文件所包含的一些函数就是模板方法模式中的抽象模板, 各个服务器对于sapi_module的定义及相关实现(cli,fpm,apache2)则是一个个具体的模板。

sapi在源代码中的路径如下:

1.2 调用SAPI实现的接口的示意图

上层调用可以是命令行窗口执行php脚本,然后到SAPI接口层,然后具体执行php脚本的是cli(Command Line Interface)接口的方法。

我们就以最简单的SAPI接口Cli来讲SAPI的实现。

二、Cli是什么?

Cli即命令行接口,当在命令行窗口下执行php脚本时,则会调用Cli。

2.1 直接执行脚本文件

在命令行窗口执行test.php脚本
$ php test.php

还可以传递一些指定的参数,比如

2.2 -r: 直接执行php代码

设置变量$a = 123,然后打印变量$a的值,并回车换行
$ php -r '$a=123; echo $a . "\r\n";'
打印结果:123

2.3 -v: 打印php的版本号

user@wt01084-048:~$ php -v
PHP 7.2.2-3+ubuntu14.04.1+deb.sury.org+1 (cli) (built: Feb 6 2018 16:35:00) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.2-3+ubuntu14.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies

三、Cli的执行流程?

Cli是单进程模式。处理完请求就关闭了。

生命周期:

核心代码:

main函数位于文件:\sapi\cli\php_cli.c

伪代码如下:

 main()
{
// 1.初始化变量
... // 2.定义sapi_module,它是记录SAPI信息的主要结构。
// 结构体类型为_sapi_module_struct,在\main\SAPI.h定义了结构体_sapi_module_struct类型。
sapi_module_struct *sapi_module = &cli_sapi_module; // 3.初始化sapi_module
sapi_startup(sapi_module); //sapi_startup函数位于\main\SAPI.c // 4.模块初始化阶段
sapi_module->startup(sapi_module); //这里的startup在结构体_sapi_module_struct类型中有定义,
//而Cli定义的cli_sapi_module的结构体中php_cli_startup指向了startup,所以其实就是调用了php_cli_startup
//而php_cli_startup直接调用了php_module_startup() // 5.请求初始化及执行请求
do_cli();
// 5.1 根据命令行指定的参数执行相应的操作,如果是查询系统信息之类的请求(-i、-m、-v),则会跳过请求初始化阶段
switch ($args) {
...
}
// 5.2 请求初始化
php_request_startup()
// 5.3 执行脚本
switch (behavior) {
case PHP_MODE_STANDARD: //标准执行模式,执行脚本文件
php_execute_script(&file_handle);
break;
case ...//其他执行模式
}
// 5.4.请求关闭阶段
out:
php_request_shutdown((void *) ); // 6.模块关闭阶段
php_module_shutdown();
sapi_shutdown();
}

参考资料:http://www.php-internals.com/

作  者:
Jackson0714

出  处:http://www.cnblogs.com/jackson0714/

关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教!

版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信

声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1apoiadc013o2

PHP内核之旅-2.SAPI中的Cli的更多相关文章

  1. PHP内核之旅-3.变量

    PHP 内核之旅系列 PHP内核之旅-1.生命周期 PHP内核之旅-2.SAPI中的Cli PHP内核之旅-3.变量 一.弱类型语言 php是弱类型语言.一个变量可以表示任意数据类型. php强大的一 ...

  2. PHP内核之旅-6.垃圾回收机制

    回收PHP 内核之旅系列 PHP内核之旅-1.生命周期 PHP内核之旅-2.SAPI中的Cli PHP内核之旅-3.变量 PHP内核之旅-4.字符串 PHP内核之旅-5.强大的数组 PHP内核之旅-6 ...

  3. PHP内核之旅-5.强大的数组

    PHP 内核之旅系列 PHP内核之旅-1.生命周期 PHP内核之旅-2.SAPI中的Cli PHP内核之旅-3.变量 PHP内核之旅-4.字符串 PHP内核之旅-5.强大的数组 PHP内核之旅-6.垃 ...

  4. PHP内核之旅-4.可变长度的字符串

    PHP 内核之旅系列 PHP内核之旅-1.生命周期 PHP内核之旅-2.SAPI中的Cli PHP内核之旅-3.变量 PHP内核之旅-4.字符串 PHP内核之旅-5.强大的数组 PHP内核之旅-6.垃 ...

  5. MOOC Linux内核之旅小结【转】

    转自:https://blog.csdn.net/titer1/article/details/45345123 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csd ...

  6. ArcGIS Engine开发之旅03--ArcGIS Engine中的控件

    原文:ArcGIS Engine开发之旅03--ArcGIS Engine中的控件 制图控件,如MapControl.PageLayoutControl,其中MapControl控件主要用于地理数据的 ...

  7. ArcGIS Engine开发之旅02--ArcGIS Engine中的类库

    原文:ArcGIS Engine开发之旅02--ArcGIS Engine中的类库 System类库 System类库是ArcGIS体系结构中最底层的类库.System类库包含给构成ArcGIS的其他 ...

  8. linux内核学习之三:linux中的"32位"与"64位"

    在通用PC领域,不论是windows还是linux界,我们都会经常听到"32位"与"64位"的说法,类似的还有"x86"与"x86 ...

  9. [PHP] PHP服务器接口SAPI中的结构体

    SAPI:在各个服务器抽象层之间遵守着相同的约定,这里我们称之为SAPI接口.例如命令行程序的实现,Apache的mod_php模块实现以及fastcgi的实现等等 1.结构体:使用结构体(Struc ...

随机推荐

  1. UNIX环境高级编程——信号之kill、raise、killpg、alarm、pause、abort、sleep、usleep、nanosleep和setitimer函数

    一.kill, raise, killpg 函数 int kill(pid_t pid, int sig); int raise(int sig); int killpg(int pgrp, int ...

  2. CCDrawNode类的引用

    CCDrawNode Class Reference Inherits from CCNode : CCResponder : NSObject Declared in CCDrawNode.h 总览 ...

  3. STL:list用法详解

    list容器介绍 相对于vector容器的连续线性空间,list是一个双向链表,它有一个重要性质:插入操作和删除操作都不会造成原有的list迭代器失效,每次插入或删除一个元素就配置或释放一个元素空间. ...

  4. driver: Linux设备模型之input子系统详解

    本节从整体上讲解了输入子系统的框架结构.有助于读者从整体上认识linux的输入子系统.在陷入代码分析的过程中,通过本节的知识能够找准方向,明白原理. 本节重点: 输入子系统的框架结构 各层对应内核中的 ...

  5. java程序的加载过程

    昨天笔试阿里有个求java程序加载过程的题目很是复杂,回来研究了好久才有点明白,整理一下.原题代码如下,判断输出: public class StaticTest { public static in ...

  6. java文件的基本操作示例

    一.获得控制台用户输入的信息 public String getInputMessage() throws IOException...{ System.out.println("请输入您的 ...

  7. php 命令空间总结

    本文移到:http://www.phpgay.com/Article/detail/classid/2/id/53.html 1.命名空间的语法: <?php namespace 名称; ?&g ...

  8. 安卓TV开发(三) 移动智能设备之实现主流TV电视盒子焦点可控UI

    前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作体验上有很大的区别,本系列博文主 ...

  9. APP-FND-00676: 弹性域例程 FDFGDC 无法读取为此说明性弹性域指定的默认引用字段

    路径: AR: 设置- 财务系统 - 弹性域- 说明性 -注册 手工增加: RECEIPT_METHOD_ID 路径: AR: 设置- 财务系统 - 弹性域- 说明性 -段 路径:收款 - 收款 点  ...

  10. 【云计算 Hadoop】Hadoop 版本 生态圈 MapReduce模型

    忘的差不多了, 先补概念, 然后开始搭建集群实战 ... . 一 Hadoop版本 和 生态圈 1. Hadoop版本 (1) Apache Hadoop版本介绍 Apache的开源项目开发流程 : ...