深入理解PHP之源码目录结构与功能说明

深入理解PHP之源码目录结构与功能说明

说明

本文将详细讲解PHP源码目录结构以及其中各个子目录的作用,帮助读者深入理解PHP的内部结构,从而更好地学习和使用PHP。

源码目录结构

PHP源码目录结构主要分为以下几个部分:

  • build:构建PHP的脚本和辅助工具;
  • ext:PHP的扩展库;
  • main:PHP的主要源代码,包括Zend引擎、内部函数和类库等;
  • sapi:PHP的SAPI接口,用于与Web服务器等程序进行交互;
  • TSRM:线程安全相关代码;
  • Zend:Zend引擎的源代码。

以下是具体的目录结构及其功能:

├── build // 构建PHP的脚本和辅助工具
├── ext // PHP的扩展库
│   ├── bcmath
│   ├── ...
│   └── zip
├── main // PHP的主要源代码
│   ├── output.c // PHP输出相关代码,处理echo、print等输出语句
│   ├── php.h // PHP的主要头文件,定义了一些常量和类型等
│   ├── php.ini-development // PHP开发版本的配置文件
│   ├── php.ini-production // PHP生产版本的配置文件
│   ├── php.ini-production.cli // PHP使用命令行运行时生产版本的配置文件
│   ├── php.ini-recommended // 推荐的PHP配置文件
│   ├── php_stdlib.h // PHP标准库头文件
│   ├── SAPI.h // PHP的SAPI接口头文件
│   ├── sapi_server.h // PHP的Web服务器SAPI接口头文件
│   ├── sapi_cli.h // PHP的命令行SAPI接口头文件
│   ├── zend_API.h // Zend引擎的API接口头文件
│   ├── zend_compile.h // Zend编译相关头文件
│   ├── zend_execute.h // Zend执行相关头文件
│   ├── zend_hash.h // Zend哈希表头文件
│   ├── zend_ini.h // Zend配置文件读取头文件
│   ├── zend_language_parser.h // Zend语言解析器头文件
│   ├── zend_mmap.h // Zend内存映射相关头文件
│   └── zend_operators.h // Zend操作符相关头文件
├── sapi // PHP的SAPI接口,用于与Web服务器等程序进行交互
│   ├── apache2handler // Apache2 SAPI接口相关代码
│   ├── cli // 命令行SAPI接口相关代码
│   ├── fpm // PHP FastCGI进程管理器相关代码
│   ├── litespeed // LiteSpeed SAPI接口相关代码
│   ├── phpdbg // PHP调试器SAPI接口相关代码
│   └── embed // PHP嵌入其他程序的SAPI接口相关代码
├── TSRM // 线程安全相关代码
└── Zend // Zend引擎的源代码
    ├── zend_API.c // Zend引擎的API接口代码
    ├── zend_compile.c // Zend编译相关代码
    ├── zend_execute.c // Zend执行相关代码
    ├── zend_hash.c // Zend哈希表相关代码
    ├── zend_ini.c // Zend配置文件读取相关代码
    ├── zend_language_parser.c // Zend语言解析器相关代码
    ├── zend_list.c // Zend列表相关代码
    ├── zend_mmap.c // Zend内存映射相关代码
    ├── zend_operators.c // Zend操作符相关代码
    └── zend_variables.c // Zend变量相关代码

示例-1: 自定义PHP扩展

通过PHP的扩展库,我们可以为PHP添加自定义的功能。下面是一个简单的示例:自定义一个PHP函数,用于计算斐波那契数列:

  1. 首先在ext目录下创建一个新的目录,命名为fibonacci,并创建config.m4文件:
PHP_ARG_ENABLE(fibonacci, whether to enable Fibonacci function,
[ --enable-fibonacci
   Enable Fibonacci support])

if test $PHP_FIBONACCI != "no"; then
  PHP_SUBST(FIBONACCI_SHARED_LIBADD)
  PHP_NEW_EXTENSION(fibonacci, fibonacci.c, $ext_shared)
fi
  1. 创建fibonacci.c文件,写入以下代码:
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"

PHP_FUNCTION(fibonacci)
{
    long n, i, t1 = 0, t2 = 1, next_term;

    if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &n) == FAILURE) {
        return;
    }

    for (i = 0; i < n; i++) {
        if (i <= 1) {
            next_term = i;
        } else {
            next_term = t1 + t2;
            t1 = t2;
            t2 = next_term;
        }
    }

    RETURN_LONG(next_term);
}

static zend_function_entry fibonacci_functions[] = {
    PHP_FE(fibonacci, NULL)
    {NULL, NULL, NULL}
};

zend_module_entry fibonacci_module_entry = {
    STANDARD_MODULE_HEADER,
    "fibonacci",
    fibonacci_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    "1.0",
    STANDARD_MODULE_PROPERTIES
};

ZEND_GET_MODULE(fibonacci)
  1. 在PHP源码根目录执行以下命令进行编译:
./buildconf
./configure --enable-fibonacci
make
sudo make install
  1. 在PHP中调用该函数:
echo fibonacci(10); // 输出55

示例-2: 自定义PHP SAPI接口

通过PHP的SAPI接口,我们可以自定义PHP与Web服务器等程序的交互方式。下面是一个简单的示例:自定义一个PHP SAPI接口,以HTTP GET方式获取参数并输出Hello, xxx!:

  1. 在sapi目录下创建一个新的目录,命名为custom,并创建Makefile.frag文件:
SAPI =        $(top_builddir)/sapi/custom/php
CC =          gcc
CFLAGS =      -I. -I$(top_srcdir)/Zend -I$(top_srcdir)/main \
              -I$(top_srcdir)/sapi -I$(top_srcdir) \
              $(EXTRA_INCLUDES)
LDFLAGS =     -export-dynamic $(EXTRA_LDFLAGS)
EXTRA_INCLUDES =
EXTRA_LDFLAGS =
OBJS =        custom.o \
              $(top_builddir)/Zend/zend_alloc.o \
              $(top_builddir)/Zend/zend_buildenv.o \
              $(top_builddir)/Zend/zend_builtin_functions.o \
              $(top_builddir)/Zend/zend_execute.o \
              $(top_builddir)/Zend/zend_globals.o \
              $(top_builddir)/Zend/zend_hash.o \
              $(top_builddir)/Zend/zend_indent.o \
              $(top_builddir)/Zend/zend_language_parser.o \
              $(top_builddir)/Zend/zend_list.o \
              $(top_builddir)/Zend/zend_opcode.o \
              $(top_builddir)/Zend/zend_operators.o \
              $(top_builddir)/Zend/zend_ptr_stack.o \
              $(top_builddir)/Zend/zend_stack.o \
              $(top_builddir)/Zend/zend_variables.o \
              $(top_builddir)/main/php_open_temporary_file.o \
              $(top_builddir)/main/php_logos.o

all: $(SAPI)

$(SAPI): $(OBJS)
        $(CC) $(LDFLAGS) -o $@ $(OBJS)

clean:
        rm -f $(SAPI) $(OBJS)
  1. 创建custom.c文件,写入以下代码:
#include "php.h"
#include "SAPI.h"
#include "zend_API.h"

static sapi_module_struct custom_module = {
    "custom",                 // name
    "Custom PHP Module",      // pretty name
    php_uname('s'),           // php.sapi_name
    NULL,                     // startup
    NULL,                     // shutdown
    NULL,                     // activate
    NULL,                     // deactivate
    NULL,                     // message_handler
    NULL,                     // phpinfo
    "1.0",                    // version
    NULL,                     // globals_ctor
    NULL,                     // globals_dtor
    NULL,                     // post_startup
    NULL,                     // child_terminate
    STANDARD_SAPI_MODULE_PROPERTIES
};

static PHP_FUNCTION(hello)
{
    char *name;
    size_t name_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
        return;
    }

    php_printf("Hello, %s!", name);
}

static zend_function_entry custom_functions[] = {
    PHP_FE(hello, NULL)
    {NULL, NULL, NULL}
};

zend_module_entry custom_module_entry = {
    STANDARD_MODULE_HEADER,
    "custom",
    custom_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    "1.0",
    STANDARD_MODULE_PROPERTIES
};

void _custom_module_startup(sapi_module_struct *sapi_module)
{
    sapi_module->php_ini_path_override = NULL;
}

static int custom_module_startup(sapi_module_struct *sapi_module)
{
    _custom_module_startup(sapi_module);
    return zend_startup_module(&custom_module_entry);
}

#ifdef COMPILE_DL_CUSTOM
ZEND_GET_MODULE(custom)
#endif

int main(int argc, char *argv[])
{
    sapi_startup(&custom_module);
    if (php_module_startup(&custom_module, NULL, 0) == FAILURE) {
        return 1;
    }
    php_output_activate(NULL, NULL);
    PHP_EMBED_MAIN_BEGIN();
    php_printf("Content-type: text/html\r\n\r\n");
    zend_execute_scripts(ZEND_REQUIRE, NULL, 1, "hello.php");
    PHP_EMBED_MAIN_END();
    return 0;
}
  1. 在PHP源码根目录执行以下命令进行编译:
cd sapi/custom
make
  1. 在sapi目录创建custom_server.php文件,写入以下代码:
<?php
$request_uri = $_SERVER['REQUEST_URI'];
parse_str(parse_url($request_uri, PHP_URL_QUERY), $params);
$name = $params['name'] ?? 'World';
echo hello($name);
  1. 进入PHP源码目录,执行以下命令启动自定义SAPI服务:
sapi/custom/php -S localhost:8000 -t sapi/custom sapi/custom_server.php
  1. 在浏览器访问http://localhost:8000/?name=PHP,可以看到输出Hello, PHP!。

总结

通过以上两个示例,我们可以了解PHP源码的目录结构和各个子目录的作用,并了解如何利用PHP扩展库和SAPI接口进行自定义开发。同时也可以为读者带来更好的学习和使用PHP的体验。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解PHP之源码目录结构与功能说明 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 基于PHP的登录和注册的功能的实现

    下面是关于基于PHP的登录和注册功能实现的攻略: 一、设计数据库表 首先需要设计基本的用户信息表,可以选择使用MySQL等数据库,例如一个名为user的表,包含以下字段: CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `…

    PHP 2023年5月23日
    00
  • 如何用PHP导出PDF

    我来详细给你描述一下如何用PHP导出PDF的完整攻略。 一、背景介绍 在web开发领域中,PDF是一种非常重要的文档格式,可以方便地打印和查看。而PHP是一种在web开发中被广泛应用的语言,因此如何使用PHP导出PDF文档成为一个非常重要的技能点。下面我将介绍如何使用PHP来生成PDF文档。 二、基本概念 在讲解如何生成PDF文档之前,我们需要了解一些基本概…

    PHP 2023年5月26日
    00
  • PHP 数组遍历方法大全(foreach,list,each)

    PHP 数组遍历方法大全(foreach,list,each) 在 PHP 中,我们需要经常遍历数组数据结构来获取数据或进行其他操作,这时,我们需要使用一些遍历方法来帮助我们处理数组数据。下面,我们将介绍三种 PHP 数组遍历方法:foreach、list、each。 1. foreach foreach 是 PHP 最常用的遍历数组方法之一,也是最方便的方…

    PHP 2023年5月26日
    00
  • php4的session功能评述(一)

    让我对“php4的session功能评述(一)”进行详细讲解。 标题解析 标题:php4的session功能评述(一) 解析:本标题中的“php4”指的是PHP语言的4版本,“session功能”指的是PHP语言中的会话管理功能,“评述”指的是对PHP4版本中的会话管理功能进行评价或者分析,“(一)”表明本文章是系列文章的第一部分。 正文内容 在PHP4版本…

    PHP 2023年5月24日
    00
  • php setcookie(name, value, expires, path, domain, secure) 参数详解

    下面我来详细讲解关于“php setcookie(name, value, expires, path, domain, secure) 参数详解”的攻略。 1. 基本概念 setcookie 是 PHP 中设置 cookie 的函数,主要是用来向客户端保存数据,以便下次服务端可以读取,从而达到记住用户行为或身份的效果。 setcookie 函数的基本语法:…

    PHP 2023年5月26日
    00
  • PHP callback函数使用方法和注意事项

    PHP Callback函数使用方法和注意事项 什么是Callback函数 Callback函数(回调函数),是指在编程语言中,可以将函数作为值传递、存储和使用的一种函数。在PHP中,我们可以将函数作为参数传递到其他函数中执行,也可以在某些事件发生时将函数作为回调函数执行。 Callback函数的使用方法 1. 将函数作为参数传递到其他函数中执行 通过使用P…

    PHP 2023年5月27日
    00
  • PHP中时间处理类Carbon的用法详解

    PHP中时间处理类Carbon的用法详解 Carbon是一款PHP的日期时间处理类库,它拥有足够的灵活性、易用性和可靠性,可以帮助我们简化PHP操作常见时间日期问题的难度。本文将详细介绍Carbon使用方法,包括初始化时间、时间计算、时间格式化和比较等。 安装 在使用Carbon之前,我们需要先安装Carbon库。可以使用composer进行安装,请执行以下…

    PHP 2023年5月26日
    00
  • php实现在多维数组中查找特定value的方法

    要在多维数组中查找特定的值,可以通过递归函数实现。以下是实现该方法的完整攻略: 步骤一:定义递归函数 定义一个递归函数,该函数接受两个参数:要查找的值和要搜索的数组。在函数中,首先判断当前数组是否为多维数组,如果是,则使用递归函数继续搜索。否则,比较当前数组元素的值和要查找的值是否相等,如果相等,则返回该数组元素的键名,否则返回false。 以下是递归函数的…

    PHP 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部