Linux下C++实现PHP扩展中级应用(二)

这里主要讲述在PHP及Zend框架下怎么使用Zend API和C++语言来实现自己所要的功能以及项目的开发。
此篇文章所运用的环境在Linux 2.4.21-4.ELsmp(Red Hat Linux
3.2.3-20),Apache/2.2.8,gcc version 3.2.3 20030502,PHP 5.2.5 (cli),Zend
Engine v2.2.0下进行。

前言

上次我们说到使用c++写一个完整的php扩展,这里以ext_name模块为例复习一下:

首先仍然修改config.m4文件,由于没有引用外面的模块或者相关库,所以不需要使用PHP_ARG_WITH的方式,使用PHP_ARG_ENABLE方式。找到

  PHP_NEW_EXTENSION(ext_name, ext_name.c, $ext_shared)

修改成

  PHP_REQUIRE_CXX()
PHP_ADD_LIBRARY(stdc++, "", EXTRA_LDFLAGS)
PHP_NEW_EXTENSION(ext_name, ext_name.cpp, $ext_shared)

并将ext_name.c重新命名为ext_name.cpp,接着修改其内容,将

  #include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"

用extern "C"将其用大括号括起来,修改

  ZEND_GET_MODULE(ext_name)

  BEGIN_EXTERN_C()
ZEND_GET_MODULE(ext_name)
END_EXTERN_C()

到此为止,这就是我们第一章内容,第二章比较庞大,这里还是分节来叙述吧。

概述

概述里面主要简单介绍PHP扩展中的一些大致结构和需要注意的事项,做过C扩展PHP的都会知道 PHP_FE是一个宏把这个宏标识的函数,例如:helloworld,这个函数可以直接作用于PHP解释器,比如

  <?php
helloworld();
 ?>

安装ext_name样板后,系统会自动有一个函数confirm_ext_name_compiled,这个函数是可以自行修改的,当然,PHP_FE可以定义多个函数,这些函数都必须在之前进行申明,一般在php_ext_name.h头文件进行申明。

我们还知道,仅仅有头文件和PHP_FE宏来申明这个函数是不行的,这个函数还没有内容,怎么编写这个函数的内容呢?这个在接下来会讲到。

其实,稍微细心的人看了ext_name.cpp就知道,去掉注释后,还有很多的宏命令,比如zend_module_entry、ZEND_GET_MODULE、PHP_MINIT_FUNCTION等等,读者不要着急,下面会一一道来。

关于ext_name.cpp文件中一些变量的命名,通常是PHP模块名(eg:ext_name)前面或者后面有一串字符,比如 le_ext_name、ext_name_functions、这是一种习惯,最好我们在书写的时候遵循这种习惯,这样写出来的代码不仅仅让你自己明 白,让其他的开发人员也能够很快熟悉你的代码。通常一些定义的常量会大写,比如要定义这个模块的名字和版本,可以在头文件中添加:

  #define PHP_EXT_NAME_EXTNAME "ext_name"
#define PHP_EXT_NAME_VERSION "0.1"

然后修改ext_name_module_entry的内容,将"ext_name"和"0.1"分别用PHP_EXT_NAME_EXTNAME和PHP_EXT_NAME_VERSION来替换,这样具有方便且通用。

如果你可能在代码中可能需要用到stl之类的或者c++的一些库,那么你可以在ext_name.cpp文件中添加

  #ifndef __APP_CPP__
#define __APP_CPP__
#include <iostream>
#include <fstream>
#include <string>
/*
#include <sstream>
#include <list>
#include <vector>
#include <map>
#include <hashmap>
#include <set>
#include <bitset>
*/
#endif

PHP 与 Zend API

引用一句经典的原文来说明PHP和Zend API之间的关系

  PHP的核心由两部分组成。最底层是Zend引擎(ZE)。ZE把人类易读的脚本解析成机器可读的符号,
然后在进程空间内执行这些符号。ZE也处理内存管理、变量作用域及调度程序调用。另一部分是PHP内核,
它绑定了SAPI层(Server Application Programming Interface,通常涉及主机环境,如Apache,IIS,CLI,CGI等),
并处理与它的通信。它同时对safe_mode和open_basedir的检测提供一致的控制层,就像流层将fopen()、fread()和
fwrite()等用户空间的函数与文件和网络I/O联系起来一样。

模块信息

模块信息主要体现在ext_name_module_entry结构上,它包含了

1, 标准模块的头

通常用 "STANDARD_MODULE_HEADER" 来填充,它指定了模块的四个成员:

  • 标识整个模块结构大小的 size
  • 值为 ZEND_MODULE_API_NO 常量的 zend_api
  • 标识是否为调试版本(使用 ZEND_DEBUG 进行编译)的 zend_debug
  • 还有一个用来标识是否启用了 ZTS (Zend 线程安全,使用 ZTS 或USING_ZTS 进行编译)的 zts。

2, 模块名称

模块名称这个名字就是使用 phpinfo() 函数后在“Additional Modules”部分所显示的名称。

3, PHP扩展可用到的函数或类

zend函数块的指针

4, 模块启动函数

5, 模块关闭函数

6, 请求启动函数

7, 请求关闭函数

8, 模块信息函数

9, 模块的版本号

10, 其它结构元素

(待续)

Monthly Archives

Pages

Powered by Movable Type 7.7.2

About this Entry

This page contains a single entry by Cnangel published on June 20, 2008 4:02 PM.

RPM简单模板 was the previous entry in this blog.

听复旦黄萱菁教授讲自然语言处理 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.