威尼斯手机平台登陆-官方网站登录

威尼斯手机平台登陆为您带来世界三大博彩公司最新相关资讯,威尼斯官方网站登录充分考虑到不同地域网民的不同需求,威尼斯手机平台登陆良好的用户界面,人性化的操作,实用的功能设计使其广泛受到欢迎,推动实体出版、影视、动漫、游戏等相关文化产业的发展。

您的位置:威尼斯手机平台登陆 > 最新文章 > 为公平起见我已经更新了 PHP 和 Rust 的版本,Zend目录里面包含了PHP的Zend

为公平起见我已经更新了 PHP 和 Rust 的版本,Zend目录里面包含了PHP的Zend

发布时间:2020-03-04 19:15编辑:最新文章浏览(158)

    更新: 初稿刚发布还没几个小时我意识到我的 PHP 基准测试是错的。为公平起见我已经更新了 PHP 和 Rust 的版本。你可以在 GitHub 仓库里看到変更(链接在底部)。

    第一步. 生成需要调用的so文件

    本文实例讲述了PHP7扩展开发教程之Hello World实现方法。分享给大家供大家参考,具体如下:

    去年十月,我和 Etsy 的同事有过一个关于如何为像PHP样的解释性语言写拓展的讨论,Ruby或Python目前的状况应该会比PHP容易。我们谈到了写一个成功创建扩展的障碍是它们通常需要用C来写,但是如果你不擅长C这门语言的话很难有那个信心。

    1.  首先做一个简单的so文件:

    一、下载PHP源代码

    从那时起我便萌生了用Rust写一个的想法,过去的几天一直在尝试。今天上午我终于让它运行了。

    /** * hello.c

    要开发PHP扩展,需要先下载PHP的源代码,一方面是因为我们的扩展一般会用到PHP自身定义的函数和宏,另一方面我们可以利用官方提供的工具减少工作量。

    C或PHP中的Rust

    我的基本出发点就是写一些可以编译的Rust代码到一个库里面,并写为它一些C的头文件,在C中为被调用的PHP做一个拓展。虽然并不是很简单,但是很有趣。

    * To compile, use following commands:

    我下载了PHP-7.0.2,地址是:

    Rust FFI(foreign function interface)

    我所做的第一件事情就是摆弄Rust与C连接的Rust的外部函数接口。我曾用简单的方法(hello_from_rust)写过一个灵活的库,伴有单一的声明(a pointer to a C char, otherwise known as a string),如下是输入后输出的“Hello from Rust”。

    // hello_from_rust.rs
    #![crate_type = "staticlib"]
    
    #![feature(libc)]
    extern crate libc;
    use std::ffi::CStr;
    
    #[no_mangle]
    pub extern "C" fn hello_from_rust(name: *const libc::c_char) {
        let buf_name = unsafe { CStr::from_ptr(name).to_bytes() };
        let str_name = String::from_utf8(buf_name.to_vec()).unwrap();
        let c_name   = format!("Hello from Rust, {}", str_name);
        println!("{}", c_name);
    }
    

    我从C(或其它!)中调用的Rust库拆分它。这有一个接下来会怎样的很好的解释。

    编译它会得到.a的一个文件,libhello_from_rust.a。这是一个静态的库,包含它自己所有的依赖关系,而且我们在编译一个C程序的时候链接它,这让我们能做后续的事情。注意:在我们编译后会得到如下输出:

    note: link against the following native artifacts when linking against this static library
    note: the order and any duplication can be significant on some platforms, and so may need to be preserved
    note: library: Systemnote: library: pthread
    note: library: c
    note: library: m
    

    这就是Rust编译器在我们不使用这个依赖的时候所告诉我们需要链接什么。

     *   gcc -O -c -fPIC -o hello.o hello.c

    解压源码压缩包, tar xzf php-7.0.2.tar.gz,我们现在只需要关注Zend和ext这两个目录。

    从C中调用Rust

    既然我们有了一个库,不得不做两件事来保证它从C中可调用。首先,我们需要为它创建一个C的头文件,hello_from_rust.h。然后在我们编译的时候链接到它。

    下面是头文件:

    // hello_from_rust.h
    #ifndef __HELLO
    #define __HELLO
    
    void hello_from_rust(const char *name);
    
    #endif
    

    这是一个相当基础的头文件,仅仅为了一个简单的函数提供签名/定义。接着我们需要写一个C程序并使用它。

    // hello.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "hello_from_rust.h"
    
    int main(int argc, char *argv[]) {
        hello_from_rust("Jared!");
    }
    

    我们通过运行一下代码来编译它:

    gcc -Wall -o hello_c hello.c -L /Users/jmcfarland/code/rust/php-hello-rust -lhello_from_rust -lSystem -lpthread -lc -lm
    

    注意在末尾的-lSystem -lpthread -lc -lm告诉gcc不要链接那些“本地的古董”,为了当编译我们的Rust库时Rust编译器可以提供出来。

    经运行下面的代码我们可以得到一个二进制的文件:

    $ ./hello_c
    Hello from Rust, Jared!
    

    漂亮!我们刚才从C中调用了Rust库。现在我们需要理解Rust库是如何进入一个PHP扩展的。

    从 php 中调用 c

    该部分花了我一些时间来弄明白,在这个世界上,该文档在 php 扩展中并不是最好的。最好的部分是来自绑定一个脚本 ext_skel 的 php 源(大多数代表“扩展骨架”)即生成大多数你需要的样板代码。为了让代码运行,我十分努力地学习 php 文档,“扩展骨骼”。

    你可以通过下载来开始,和未配额的 php 源,把代码写进 php 目录并且运行:

    $ cd ext/
    $ ./ext_skel –extname=hello_from_rust

    这将生成需要创建 php 扩展的基本骨架。现在,移动你处处想局部地保持你的扩展的文件夹。并且移动你的

    .rust 源

    .rust库

    .c header

    进入同一个目录。因此,现在你应该看看像这样的一个目录:

    .
    ├── CREDITS
    ├── EXPERIMENTAL
    ├── config.m4
    ├── config.w32
    ├── hello_from_rust.c
    ├── hello_from_rust.h
    ├── hello_from_rust.php
    ├── hello_from_rust.rs
    ├── libhello_from_rust.a
    ├── php_hello_from_rust.h
    └── tests
    └── 001.phpt

    一个目录,11个文件

    你可以在 php docs 在上面看到关于这些文件很好的描述。建立一个扩展的文件。我们将通过编辑 config.m4 来开始吧。

    不解释,下面就是我的成果:

    PHP_ARG_WITH(hello_from_rust, for hello_from_rust support,
    [  --with-hello_from_rust             Include hello_from_rust support])
    
    if test "$PHP_HELLO_FROM_RUST" != "no"; then
      PHP_SUBST(HELLO_FROM_RUST_SHARED_LIBADD)
    
      PHP_ADD_LIBRARY_WITH_PATH(hello_from_rust, ., HELLO_FROM_RUST_SHARED_LIBADD)
    
      PHP_NEW_EXTENSION(hello_from_rust, hello_from_rust.c, $ext_shared)
    fi
    

    正如我所理解的那样,这些是基本的宏命令。但是有关这些宏命令的文档是相当糟糕的(比如:google”PHP_ADD_LIBRARY_WITH_PATH”并没有出现PHP团队所写的结果)。我偶然这个PHP_ADD_LIBRARY_PATH宏命令在有些人所谈论的在一个PHP拓展里链接一个静态库的先前的线程里。在评论中其它的推荐使用的宏命令是在我运行ext_skel后产生的。

    既然我们进行了配置设置,我们需要从PHP脚本中实际地调用库。为此我们得修改自动生成的文件,hello_from_rust.c。首先我们添加hello_from_rust.h头文件到包含命令中。然后我们要修改confirm_hello_from_rust_compiled的定义方法。

    #include "hello_from_rust.h"
    
    // a bunch of comments and code removed...
    
    PHP_FUNCTION(confirm_hello_from_rust_compiled)
    {
        char *arg = NULL;
        int arg_len, len;
        char *strg;
    
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
            return;
        }
    
        hello_from_rust("Jared (from PHP!!)!");
    
        len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "hello_from_rust", arg);
        RETURN_STRINGL(strg, len, 0);
    }
    

    注意:我添加了hello_from_rust(“Jared (fromPHP!!)!”);。

    现在,我们可以试着建立我们的扩展:

    $ phpize
    $ ./configure
    $ sudo make install

    就是它,生成我们的元配置,运行生成的配置命令,然后安装该扩展。安装时,我必须亲自使用sudo,因为我的用户并不拥有安装目录的 php 扩展。

    现在,我们可以运行它啦!

    $ php hello_from_rust.php
    Functions available in the test extension:
    confirm_hello_from_rust_compiled

    Hello from Rust, Jared (from PHP!!)!
    Congratulations! You have successfully modified ext/hello_from_rust/config.m4. Module hello_from_rust is now compiled into PHP.
    Segmentation fault: 11

    还不错,php 已进入我们的 c 扩展,看到我们的应用方法列表并且调用。接着,c 扩展已进入我们的 rust 库,开始打印我们的字符串。那很有趣!但是……那段错误的结局发生了什么?

     

    正如我所提到的,这里是使用了 Rust 相关的 println! 宏,但是我没有对它做进一步的调试。如果我们从我们的 Rust 库中删除并返回一个 char* 替代,段错误就会消失。

    这里是 Rust 的代码:

    #![crate_type = "staticlib"]
    
    #![feature(libc)]
    extern crate libc;
    use std::ffi::{CStr, CString};
    
    #[no_mangle]
    pub extern "C" fn hello_from_rust(name: *const libc::c_char) -> *const libc::c_char {
        let buf_name = unsafe { CStr::from_ptr(name).to_bytes() };
        let str_name = String::from_utf8(buf_name.to_vec()).unwrap();
        let c_name   = format!("Hello from Rust, {}", str_name);
    
        CString::new(c_name).unwrap().as_ptr()
    }
    

    并变更 C 头文件:

    #ifndef __HELLO
    #define __HELLO
    
    const char * hello_from_rust(const char *name);
    
    #endif
    

    还要变更 C 扩展文件:

    PHP_FUNCTION(confirm_hello_from_rust_compiled)
    {
        char *arg = NULL;
        int arg_len, len;
        char *strg;
    
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
            return;
        }
    
        char *str;
        str = hello_from_rust("Jared (from PHP!!)!");
        printf("%s/n", str);
    
        len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "hello_from_rust", arg);
        RETURN_STRINGL(strg, len, 0);
    }
    

      *   gcc -shared -o libhello.so hello.o

    Zend目录里面包含了PHP的Zend Engine源代码,有些函数和宏的定义我们需要在这里面简单地看一下。

    无用的微基准

    那么为什么你还要这样做?我还真的没有在现实世界里使用过这个。但是我真的认为斐波那契序列算法就是一个好的例子来说明一个PHP拓展如何很基本。通常是直截了当(在Ruby中):

    def fib(at) do
        if (at == 1 || at == 0)
            return at
        else
            return fib(at - 1) + fib(at - 2)
        end
    end
    

    而且可以通过不使用递归来改善这不好的性能:

    def fib(at) do
        if (at == 1 || at == 0)
            return at
        elsif (val = @cache[at]).present?
            return val  
        end
    
        total  = 1
        parent = 1
        gp     = 1
    
        (1..at).each do |i|
            total  = parent + gp
            gp     = parent
            parent = total
        end
    
        return total
    end
    

    那么我们围绕它来写两个例子,一个在PHP中,一个在Rust中。看看哪个更快。下面是PHP版:

    def fib(at) do
        if (at == 1 || at == 0)
            return at
        elsif (val = @cache[at]).present?
            return val  
        end
    
        total  = 1
        parent = 1
        gp     = 1
    
        (1..at).each do |i|
            total  = parent + gp
            gp     = parent
            parent = total
        end
    
        return total
    end
    

    这是它的运行结果:

    $ time php php_fib.php
    
    real    0m2.046s
    user    0m1.823s
    sys 0m0.207s
    

    现在我们来做Rust版。下面是库资源:

    #![crate_type = "staticlib"]
    
    fn fib(at: usize) -> usize {
        if at == 0 {
            return 0;
        } else if at == 1 {
            return 1;
        }
    
        let mut total  = 1;
        let mut parent = 1;
        let mut gp     = 0;
        for _ in 1 .. at {
            total  = parent + gp;
            gp     = parent;
            parent = total;
        }
    
        return total;
    }
    
    #[no_mangle]
    pub extern "C" fn rust_fib(at: usize) -> usize {
        fib(at)
    }
    

    注意,我编译的库rustc – O rust_lib.rs使编译器优化(因为我们是这里的标准)。这里是C扩展源(相关摘录):

    PHP_FUNCTION(confirm_rust_fib_compiled)
    {
        long number;
    
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &number) == FAILURE) {
            return;
        }
    
        RETURN_LONG(rust_fib(number));
    }
    

    运行PHP脚本:

    <?php
    $br = (php_sapi_name() == "cli")? "":"<br>";
    
    if(!extension_loaded('rust_fib')) {
        dl('rust_fib.' . PHP_SHLIB_SUFFIX);
    }
    
    for ($i = 0; $i < 100000; $i ++) {
        confirm_rust_fib_compiled(92);
    }
    ?>
    

    这就是它的运行结果:

    $ time php rust_fib.php
    
    real    0m0.586s
    user    0m0.342s
    sys 0m0.221s
    

    你可以看见它比前者快了三倍!完美的Rust微基准!

    */

    ext目录里面包含了PHP原生的扩展,以及我们开发自己的扩展时可以利用的工具,Linux下使用ext_skel,Windows下使用ext_skel_win32.php

    总结

    这里几乎没有得出什么结论。我不确定在Rust上写一个PHP的扩展是一个好的想法,但是花费一些时间去研究Rust,PHP和C,这是一个很好的方式。

    如果你希望查看所有代码或者查看更改记录,可以访问GitHub Repo。

    int hello_add(int a, int b)

    二、使用ext_skel工具

    {

    我们可以在ext目录下看到所有的PHP原生扩展,其中包括了熟悉的curl,json,mbstring,simplexml,sockets等扩展,还有很多没有用过甚至没有听说过的扩展,不用在意这些,我们先打开我们最熟悉的curl来看看,有config.m4配置文件,有php_curl.h,curl_file.c等源代码,还有一些中间文件,最后还有一个tests目录,里面放的curl扩展的单元测试。重点关注config.m4,php_curl.h,curl_file.c即可,最简单的场景下这三个文件就是一个扩展的全部组成部分了。

        return a + b;

    打开随便看一下,不算太复杂,但是自己写一个类似的还是挺头疼的,这时就需要用到我前面提到的ext_skel工具了。这个工具也在ext目录下,我们执行一下,./ext_skel --help,可以看到若干参数,我们用到的只有--extname=module,这里填上自己开发的扩展名称。想深入了解各个参数的作用可以看这里:

    }

    ./ext_skel --extname=hello
    

    然后将它编译成.so文件并放到系统中:

    ext目录下多了一个hello目录,我们后续的工作都在这个目录下面,工具已经为我们自动生成了一些文件。

    $ gcc -O -c -fPIC -o hello.o hello.c                      // -fPIC:是指生成的动态库与位置无关

    config.m4配置文件

    $ gcc -shared -o libhello.so hello.o                     // -shared:是指明生成动态链接库

    开发PHP扩展,在写C代码之前,要先配置一下这里。我们打开可以看到详细的注释说明,dnl是注释语法。

    $ su        // 切换成超级用户,此时,需要输入密码。

    如果你的扩展用到了外部依赖,就配置--with-hello选项,否则配置--enable-hello选项,删除这下面3行的del注释

    # cp libhello.so /usr/local/lib      // 把生成的链接库放到指定的地址

    PHP_ARG_ENABLE(hello, whether to enable hello support,Make sure that the comment is aligned:[ --enable-hello Enable hello support])
    

    # echo /usr/local/lib > /etc/ld.so.conf.d/local.conf       //  把库地址写入到配置文件中

    PHP_ARG_WITH和PHP_ARG_ENABLE这两个宏用来配置configure选项,一个配置需要外部依赖的,另一个配置不需要外部依赖的

    # /sbin/ldconfig                // 用此命令,使刚才写的配置文件生效

    配置好的内容,在后面执行configure --help时可以看到。

    1. 写段小程序来验证其正确性:

    php_hello.h头文件

    /**

    类似于C语音的头文件,包含了一些自定义的结构和函数声明,在这个demo中暂时不需要改动

     * hellotest.c

    hello.c代码文件

     * To compile, use following commands:

    真正的逻辑代码都在这个文件中,后面会详细介绍。

    *   gcc -o hellotest -lhello hellotest.c

    三、编写代码

    */

    好了,到这一步我们终于要开始写代码了,打开hello.c文件。

    #include

    整个扩展的入口是zend_module_entry这个结构,具体的定义可以在Zend目录下的zend_modules.h文件中看到,一共有十几个属性,快速跳过,我们暂时只需要"hello world"。

    int main()

    zend_module_entry hello_module_entry = { STANDARD_MODULE_HEADER, "hello", hello_functions, PHP_MINIT, PHP_MSHUTDOWN, PHP_RINIT, /* Replace with NULL if there's nothing to do at request start */ PHP_RSHUTDOWN, /* Replace with NULL if there's nothing to do at request end */ PHP_MINFO, PHP_HELLO_VERSION, STANDARD_MODULE_PROPERTIES};
    

    {

    STANDARD_MODULE_HEADER帮我们实现了前面6个属性

        int a = 3, b = 4;

    "hello"是扩展的名字

        printf("%d + %d = %d", a, b, hello_add(a,b));

    hello_functions是扩展包含的全部方法的集合

        return 0;

    后面5个宏分别代表5个扩展特定方法

    }

    PHP_HELLO_VERSION是扩展的版本号,定义在头文件中

    编译并执行:

    STANDARD_MODULE_PROPERTIES帮我们实现了剩下的属性

    $ gcc -o hellotest -lhello hellotest.c                // 编译测试文件,生成测试程序

    暂时都不需要修改,知道这是一个入口就行。顺着这个入口,我们继续看怎么给扩展添加方法,在hello_functions[]方法数组中已经有了一个示例方法confirm_hello_compiled,我们参考它写我们的方法hello_world

    $ ./hellotest           // 运行测试程序

    const zend_function_entry hello_functions[] = { PHP_FE(confirm_hello_compiled, NULL) /* For testing, remove later. */ PHP_FE PHP_FE_END /* Must be the last line in hello_functions[] */};
    

    第二步. 制作PHP模块(外部模块)

    先在扩展的方法数组中添加上hello_world,然后再定义hello_world。找到confirm_hello_compiled方法定义的地方,在它下面依葫芦画瓢,php_printf是Zend Engine中的printf方法。

    请确保你已安装 PHP及APACHE服务器。

    PHP_FUNCTION{ php_printf; RETURN_TRUE;}
    

    $ cd php-5.2.3/ext

    四、编译安装

    1. 然后通过下面的命令用ext_skel脚本建立一个名为 hello 的模块:

    最后就是编译安装我们的扩展了,安装过PHP扩展的同学不用看,没有经验的可以参考一下。

    $ ./ext_skel --extname=hello

    ./configuremakemake install
    

    2. 执行该命令之后它会提示你应当用什么命令来编译模块,可惜那是将模块集成到php内部的编译方法。

    现在PHP的扩展目录中已经有了hello.so这个文件,在php.ini中添加上扩展的配置

    如果要编译成可动态加载的 php_hello.so,方法要更为简单。

    extension = hello.so
    

    $ cd hello

    五、测试

     首先编辑 config.m4 文件,去掉第16行和第18行的注释(注释符号为 dnl 。)

    写一个test.php方法,执行脚本就可以看到"Hello World!"

    16:  PHP_ARG_ENABLE(hello, whether to enable hello support,

    更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP扩展开发教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》、《PHP网络编程技巧总结》及《php常见数据库操作技巧汇总》希望本文所述对大家PHP程序设计有所帮助。
    

    17:  dnl Make sure that the comment is aligned:

    18:  [  --enable-hello           Enable hello support])

    1. 然后执行 phpize 程序,生成configure脚本:

    $ phpize

     该程序在ubuntu的php5-dev包中

    1. 打开 php_hello.h,在 PHP_FUNCTION(confirm_hello_compiled); 之下加入函数声明:

    PHP_FUNCTION(confirm_hello_compiled);   /* For testing, remove later. */

    PHP_FUNCTION(hello_add);

    1. 打开 hello.c,在 PHP_FE(confirm_hello_compiled, NULL) 下方加入以下内容。

    zend_function_entry hello_functions[] = {

        PHP_FE(confirm_hello_compiled,  NULL)       /* For testing, remove later. */

        PHP_FE(hello_add,   NULL)       /* For testing, remove later. */

        {NULL, NULL, NULL}  /* Must be the last line in hello_functions[] */};

        然后在 hello.c 的最末尾书写hello_add函数的内容: 

    PHP_FUNCTION(hello_add)

    {

        long int a, b;

        long int result;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &a, &b) == FAILURE) {

            return;

        }

        result = hello_add(a, b);

        RETURN_LONG(result);}保存退出,编译并安装:

    1. $ ./configure

    $ make LDFLAGS=-lhello

    $ sudo make install

    Installing shared extensions:     /usr/lib/php5/20060613+lfs/$ su# cp modules/hello.so/usr/lib/php/modules

    luther@gliethttp:~$ sudo vim /etc/php5/apache2/php.ini;

    enable_dl = Off;允许dl()动态加载so扩展功能enable_dl = On

    luther@gliethttp:~$ sudo service apache2 reload    然后在 /var/www/html 下建立一个 hello.php 文件,内容如下:

    <?php

        dl("hello.so");

        echo hello_add(3, 4);

    ?>

    然后在浏览器中打开hello.php文件,如果显示7,则说明函数调用成功了。

    第三步. 制作PHP模块(内部模块)

    另外可以在apache重启的时候让我们的so库直接动态编译进php5,就像linux的insmod hello.ko模块一样,不用dl加载也不用重新编译php,就可以直接使用so的函数了,步骤如下:

    luther@gliethttp:~$ sudo vim /etc/php5/apache2/php.ini
    enable_dl = Off
    extension=hello.so
    luther@gliethttp:~$ sudo service apache2 restart

    不能reload而必须restart apache,这样so就像insmod hello.ko一样被融到了php5内核,然后代码就可以忽略掉dl("hello.so");了,

    [注意,这种方式只适合hello.so库内所有功能代码已经全部调试ok,如果还处在调试期间,那么需要采用上面的dl强制加载的方式]

    代码如下:

    <?php

        echo hello_add(3, 4);

    ?>,

         但是该功能不太适合调试,因为每次修改hello.so中代码的话,都需要让service apacherestart重启才能让php5内核再次加载新的hello.so扩展.可以这样定义hello.so的实现,这样每次执行.php网页,都会在/var/www/下建立一个文件夹,所以php扩展实现了

    一,搭建php环境
    下载php 5.2.6 源码 并解压
    编译安装,搭建php环境
    二,创建扩展项目
    进入源码目录
    cd php5.2.6/ext/
    ./ext_skel --extname=my_ext
    创建名字为my_ext的项目,最终会生成my_ext.so
    三,更改配置和程序
    $ vi ext/my_ext/config.m4
    根据你自己的选择将
    dnl PHP_ARG_WITH(my_ext, for my_ext support,
    dnl Make sure that the comment is aligned:
    dnl [ --with-my_ext Include my_ext support])
    修改成
    PHP_ARG_WITH(my_ext, for my_ext support,
    Make sure that the comment is aligned:
    [ --with-my_ext Include my_ext support])
    或者将
    dnl PHP_ARG_ENABLE(my_ext, whether to enable my_ext support,
    dnl Make sure that the comment is aligned:
    dnl [ --enable-my_ext Enable my_ext support])
    修改成
    PHP_ARG_ENABLE(my_ext, whether to enable my_ext support,
    Make sure that the comment is aligned:
    [ --enable-my_ext Enable my_ext support])
    $ vi ext/my_ext/php_my_ext.h

    PHP_FUNCTION(confirm_my_ext_compiled); /* For testing, remove later. */
    更改为
    PHP_FUNCTION(say_hello);
    $ vi ext/my_ext/my_ext.c

    zend_function_entry php5cpp_functions[] = {
    PHP_FE(confirm_my_ext_compiled, NULL) /* For testing, remove later. */
    {NULL, NULL, NULL} /* Must be the last line in php5cpp_functions[] */
    };
    更改为
    zend_function_entry php5cpp_functions[] = {
    PHP_FE(say_hello, NULL)
    {NULL, NULL, NULL} /* Must be the last line in php5cpp_functions[] */
    };
    在最后添加:
    PHP_FUNCTION(say_hello)
    {
    zend_printf("hello worldn");
    }
    四,编译
    $ cd my_ext
    $ /usr/local/php/bin/phpize
    ps: 如果出现:Cannot find autoconf.……的错误信息,则需要安装 autoconf (安装过程略)
    $ ./configure --with-php-config=/usr/local/php/bin/php-config
    $ make
    这时会编译出 my_ext/modules/my_ext.so
    五,配置php.ini
    将my_ext.so放入/usr/local/php/ext/目录
    $ vi php.ini

    修改添加如下:
    extension_dir = '/usr/local/php/ext/'
    extension=my_ext.so
    六,测试
    $ vi test.php
    <?php
    say_hello();
    ?>
    $ /usr/local/php/bin/php test.php
    hello world.
    则大功告成

    下面我来讲讲如何作一个php的扩展
    首先要有一个搭建好的php环境
    我把php的安装在了/usr/local/php当然也通过
    php的一个配置php.ini的路径但是要注意了
    用这种方法安装的php扩展不能实现
    我们在php安装以后的/usr/local/php/bin目录
    找到这个文件phpize稍后我们将用到他
    他就是个shell脚本你可以用vi phpize来查看他的内容
    但是你要注意了这个脚本不是在哪里都可以应用的
    [root@ns root]# phpize
    Cannot find config.m4.
    Make sure that you run '/usr/local/bin/phpize' in the top level source directory of the module

    [root@ns root]# phpize
    Cannot find config.m4.
    Make sure that you run '/usr/local/bin/phpize' in the top level source directory of the module
    你会看到这两种结果实际上你查看了这个脚本
    很轻松的就会发现是怎么来处理的
    你的模扩展的时候最好
    放在/usr/local/src/php-4.3.5/ext下
    来执行他你在这里也可以这样/usr/local/php/bin/phpize来执行也可以
    phpize来执行

    我们在/usr/local/src/php-4.3.5/ext下找到这个工具
    来建立一个php扩展的一个框架
    [root@ns ext]#cd /usr/local/src/php-4.3.5/ext/
    [root@ns ext]# ./ext_skel --extname=jinzhesheng_module
    Creating directory jinzhesheng_module
    Creating basic files: config.m4 .cvsignore jinzhesheng_module.cphp_jinzhesheng_module.h CREDITS EXPERIMENTAL tests/001.phptjinzhesheng_module.php [done].

    To use your new extension, you will have to execute the following steps:

    1.  $ cd ..
    2.  $ vi ext/jinzhesheng_module/config.m4
    3.  $ ./buildconf
    4.  $ ./configure --[with|enable]-jinzhesheng_module
    5.  $ make
    6.  $ ./php -f ext/jinzhesheng_module/jinzhesheng_module.php
    7.  $ vi ext/jinzhesheng_module/jinzhesheng_module.c
    8.  $ make
    执行了这个步骤以后你会看到这样的结果
    Repeat steps 3-6 until you are satisfied with ext/jinzhesheng_module/config.m4 and
    step 6 confirms that your module is compiled into PHP. Then, start writing
    code and repeat the last two steps as often as necessary.
    这样以后我们会在这个目录下生成一个目录叫jinzhesheng_module
    进入这里面我们看看
    [root@ns ext]# cd jinzhesheng_module/
    [root@ns jinzhesheng_module]# ls
    config.m4  EXPERIMENTAL          jinzhesheng_module.php    tests
    CREDITS    jinzhesheng_module.c  php_jinzhesheng_module.h

    然后我们要修改文件顺序是
    configue.m4
    jinzhesheng_module.c
    php_jinzhesheng_module.h

    使用文本编辑器打开config.m4文件,文件内容大致如下:

    dnl $Id$d

    dnl config.m4 for extension my_module

    dnl don't forget to callPHP_EXTENSION(my_module)

    dnl Comments in this file start with the string 'dnl'.

    dnl Remove where necessary. This file will not work

    dnl without editing.

    dnl If your extension references something external, use with:

    dnl PHP_ARG_WITH(my_module, for my_module support,

    dnl Make sure that the comment is aligned:

    dnl [  --with-my_module             Include my_module support])

    dnl Otherwise use enable:

    dnl PHP_ARG_ENABLE(my_module, whether to enable my_module support,

    dnl Make sure that the comment is aligned:

    dnl [  --enable-my_module           Enable my_module support])

    if test "$PHP_MY_MODULE" != "no"; then

      dnl If you will not be testing anything external, like existence of

      dnl headers, libraries or functions in them, just uncomment the

      dnl following line and you are ready to go.

      dnl Write more examples of tests here...

      PHP_EXTENSION(my_module, $ext_shared)

    Fi

    根据你自己的选择将

    dnl PHP_ARG_WITH(my_module, for my_module support,

    dnl Make sure that the comment is aligned:

    dnl [  --with-my_module             Include my_module support])

    修改成

    PHP_ARG_WITH(my_module, for my_module support,

    Make sure that the comment is aligned:

    [  --with-my_module             Include my_module support])

    或者将

    dnl PHP_ARG_ENABLE(my_module, whether to enable my_module support,

    dnl Make sure that the comment is aligned:

    dnl [  --enable-my_module           Enable my_module support])

    修改成

    PHP_ARG_ENABLE(my_module, whether to enable my_module support,

    Make sure that the comment is aligned:

    [  --enable-my_module           Enable my_module support])
    我这里用了后者
    然后保存退出
    然后在编辑
    Vi my_module.c
    将文件其中的下列代码进行修改

    /* Every user visible function must have an entry in my_module_functions[].

    */

    function_entry my_威尼斯正规官网,module_functions[] = {

            PHP_FE(say_hello,       NULL)  /* ?添加着一行代码 */

            PHP_FE(confirm_my_module_compiled,      NULL) /* For testing, remove later. */

            {NULL, NULL, NULL}      /* Must be the last line in my_module_functions[] */

    };

    在文件的最后添加下列代码

    PHP_FUNCTION(say_hello)

    {

            zend_printf("hello worldn");

    }

    保存文件退出

    然后我们就可以在这个目录下使用上面的命令了
    /usr/local/php/bin/phpize
    执行以后会看到下面的
    [root@ns jinzhesheng_module]# /usr/local/php/bin/phpize
    Configuring for:
    PHP Api Version:         20020918
    Zend Module Api No:      20020429
    Zend Extension Api No:   20050606
    [root@ns jinzhesheng_module]#
    然后执行./configure --enable-jinzhesheng_module --with-apxs=/usr/local/apache/bin/apxs --with-php-config=/usr/local/php/bin/php-config
    我们在安装以后的php的bin目录下的可以找到这个文件的
    php-config 和phpize
    这一步骤一定要注意你的apache的apxs放在哪里了
    然后执行make
    你会看到出现错误了你重新定义了函数我们前面的
    这个你在回头改一下这个文件把原来的函数删除掉在生成的文件里面会有同样的函数
    你在加入你的代码
    就可以通过了
    这个时候会在当前的目录下生成一个目录叫modules他的下面就放着你要的
    jinzhesheng_module.so文件
    cp modules/jinzhesheng_module.so /usr/local/php/ext/
    这里需要你先设置你的php的扩展目录的在
    在php.ini里面
    通过extension_dir
    最后一不是你在php.ini文件中打开这个扩展
    extension=jinzhesheng_module.so
    然后
    重新起动apache
    用phpinfo来察看一下ok了

    本文由威尼斯手机平台登陆发布于最新文章,转载请注明出处:为公平起见我已经更新了 PHP 和 Rust 的版本,Zend目录里面包含了PHP的Zend

    关键词: