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

yizhihongxing

深入理解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 Trait基类use trait,本类不use

    一 回顾trait使用 https://blog.csdn.net/bushuwei/article/details/103514174发现之前本人说明很模糊,自己居然不知道为什么其实这里的$c,就是class B再次回顾逻辑 二 分析 self和static区别说的没毛病 Trait基类use trait,本类不use。那么如果用的new self,则你n…

    PHP 2023年4月17日
    00
  • PHP互换两个变量值的方法(不用第三变量)

    当需要交换两个变量的值时,通常都需要借助第三个变量来保存一个变量的值,再进行交换。但是,PHP 提供了更加简单的方法,而且不需要使用第三个变量。这种方法就是通过使用位运算符 ^ 来实现变量值的交换。 下面是使用位运算符 ^ 来交换变量值的方法: $a = 10; $b = 20; $a ^= $b; $b ^= $a; $a ^= $b; echo $a .…

    PHP 2023年5月26日
    00
  • 深入php中var_dump方法的使用详解

    深入PHP中var_dump方法的使用详解 什么是var_dump方法? var_dump是PHP中一种用于调试的方法,它能够将一个变量或表达式的结构信息以及值打印出来,是PHP程序调试中必不可少的工具。 var_dump的基本用法 var_dump方法接收一个或多个参数,每个参数都可以是一个任意类型的PHP变量(包括整数、浮点数、字符串、数组、对象、资源、…

    PHP 2023年5月26日
    00
  • 探讨PHP使用eAccelerator的API开发详解

    探讨PHP使用eAccelerator的API开发详解 什么是eAccelerator? eAccelerator 是一个开源的 PHP 加速器,它通过优化 PHP 脚本进行加速,提高对 PHP 的性能和可扩展性。eAccelerator 对 PHP 的加速主要是通过以下两个方面来实现的: 字节码缓存:将 PHP 脚本编译成可以供服务器直接解释执行的字节码,…

    PHP 2023年5月27日
    00
  • PHP导出EXCEL快速开发指南–PHPEXCEL的使用详解

    PHP导出EXCEL快速开发指南–PHPEXCEL的使用详解 简介 PHP作为一种非常流行的Web开发语言,其在数据处理方面有着出色的表现。PHPEXCEL是PHP中一款非常强大的导出Excel工具,它支持导出各种格式的Excel表格,并且提供了丰富的样式和数据处理功能。 本文将介绍PHPEXCEL的使用方法,并提供两个示例来说明如何在PHP中使用PHPE…

    PHP 2023年5月26日
    00
  • 微信小程序加载更多 点击查看更多

    微信小程序加载更多功能可以通过调用小程序提供的API实现。在实现过程中主要分为两个部分,第一部分是在wxml文件中添加“加载更多”组件,第二部分是在js文件中监听“加载更多”组件的点击事件,实现数据的动态加载。 下面是具体的实现步骤: 第一步:在wxml文件中添加“加载更多”组件 <!–展示数据的列表部分–> <scroll-view …

    PHP 2023年5月23日
    00
  • PHP微商城开源代码实例

    下面我将详细介绍“PHP微商城开源代码实例”的完整攻略。 一、背景介绍 “PHP微商城开源代码实例”是一种基于PHP语言的微信公众号商城系统,它可以帮助用户快速搭建自己的微商城,并且提供了完整的后台管理功能。系统代码全部开源,可以自由定制和修改。 二、系统安装与配置 1. 环境要求 首先,我们需要在部署环境上,确保系统运行的正常。本系统需要以下环境: PHP…

    PHP 2023年5月24日
    00
  • PHP去掉从word直接粘贴过来的没有用格式的函数

    要去掉从Word直接粘贴过来的没有用格式的内容,可以采用以下步骤: 使用strip_tags()函数去除HTML和PHP标记,只保留纯文本。 示例1: // 原文本内容 $text = ‘<p>这是一段从Word直接粘贴过来的内容。</p><p>没有任何格式</p>’; // 去除HTML和PHP标记,只保留文…

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