translate

发布 : 2019-03-15 浏览 :

Extension Writing Part I: Introduction to PHP and Zend

Introduction

如果你正在读这个教程,你可能对写一个PHP扩展有一些兴趣。如果没有兴趣…当你读完这个教程的时候,你或许会发现一个你不知道存在的兴趣!

本教程假设您基本熟悉PHP语句和PHP解释器使用的语言:C。

让我们首先确定为什么要编写PHP扩展。

  1. 有一些特定于库或操作系统的调用不能直接从PHP中进行,这是因为该语言固有的抽象程度。
  2. 您想让PHP本身以某种不寻常的方式运行。
  3. 您已经编写了一些PHP代码,但是您知道它可以更快、更小,并且在运行时消耗更少的内存。
  4. 您有一个特别聪明的代码想要出售,重要的是,您出售它的一方能够执行它,但不能查看源代码。

这些都是完全合理的理由,但是为了创建扩展,您需要首先理解什么是扩展。

What’s an Extension?

如果你使用过PHP,那么你已经使用过扩展。除了少数例外,PHP语言的中的每个用户空间函数被分组到一个或另一个扩展中。其中许多函数都是标准扩展的一部分–总共超过400个。PHP源代码包附带了大概86个扩展,平均每个扩展有大约30个函
数。算一下,大概有2500个函数。好像这还不够,PECL存储库提供了超过100个额外的扩展,甚至更多的扩展可以在Internet的其他地方找到。

“所有这些函数都存在于扩展中,还剩下什么?“我听见你问。“它们是什么东西的延伸?”PHP的‘核心’是什么?”

PHP的核心由两个单独的部分组成。在最低层,您可以找到Zend引擎(ZE)。ZE处理将人可读的脚本解析为机器可读的令牌,然后在进程空间中执行这些令牌。ZE还负责内存管理,变量的范围,以及调度函数调用。另外一部分是PHP核心。PHP处理
与SAPI层的通信和绑定(服务器应用程序编程接口,也通常用于指主机环境–Apache,IIS,CLI,CGI等)。它还为safe_modeopen_basedir检查提供了统一的控制层,以及流层,流层将文件和网络I/O与fopen()fread()
fwrite()等用户空间函数关联起来。

Lifecycles

当给定的SAPI启动时,例如,响应/usr/local/apache/bin/apachectl start,PHP首先初始化它的核心子系统。在这个启动例程的末尾,它加载每个扩展的代码并调用它们的模块初始化例程(MINIT)。这使每个扩展都有机会初始化内部
变量、分配资源、注册资源处理程序并将其函数注册到ZE中,这样,如果脚本调用其中一个函数,ZE就知道要执行哪些代码。接下来,PHP等待SAPI层请求要处理的页面。在CGI或CLI SAPIs的情况下,这是立即发生的,而且只有一次。对于
Apache、IIS或其他功能齐全的web服务器SAPIs,它是在远程用户请求页面时发生的,并且重复任意次数,可能是并发的。无论请求是如何传入的,PHP都首先要求ZE为运行脚本设置一个环境,然后调用每个扩展的请求初始化(RINIT)函数。
RINIT为扩展提供了设置特定环境变量、分配特定资源或执行其他任务(如审计)的机会。运行中的RINIT函数的一个主要例子是在会话扩展中,如果会话。启用auto_start选项后,RINIT将自动触发userspace session_start()函数,并预先填充$_SESSION变量。

本文作者 : Xuebin Zhang
原文链接 : https://capping.github.io/2019/03/15/translate/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
留下足迹