PHP扩展开发入门PHP-CPP篇(未完待续)

看到此文,是否觉得体内洪荒之力爆发,饥渴难耐想吐槽、情不自禁想捐赠
本文为原创文章,尊重辛勤劳动,可以免费摘要、推荐或聚合,亦可完整转载,但完整转载需要标明原出处,违者必究。

支付宝微  信

在你使用PHP来解决一些事情的时候,可能会考虑亲手开发一个PHP扩展。以下是我能想到的驱使我开发PHP扩展的几点理由:

  1. 扩展PHP的功能在某些非常特殊的使用场景(比如数学,统计和几何等等)。
  2. 相比于用纯PHP代码实现,提高PHP的性能和效率。
  3. 利用自身之前掌握的另一种编程语言(对我来说是C++)来进行快速的开发。

当谈论到选择建立PHP扩展的工具时,我们自然会想到两个不同的方法:

  1. 使用更接近PHP语法的工具,比如Zephir。
  2. 使用更接近C/C++语法的工具,比如下文会提到的PHP-CPP。

个人而言,选择第二种方式更为简单:C/C++是我入门编程的第一门语言,因此我一直觉得使用C/C++写一些更底层的模块更轻松些。PHP-CPP的官方网站也给出了一些为什么这么做的理由。

安装与配置

PHP-CPP发展迅速。在写这篇文章的时候,已经发布了0.9.1版本(两天前发布了0.9.0版本)。据文档描述,“为了迎接下一版本v1.0,此版本被标记为冻结版本(笔者注:feature-freeze https://wiki.openstack.org/wiki/FeatureFreeze)”,所以我们相信,1.0主版本即将到来。

因此建议,至少在这段时间,通过git克隆版本库代码,并通过git pull获取最新的版本。

注:PHP-CPP安装文档表明,暂时仅支持单线程安装(single-threaded PHP installations)。这是由于Zend引擎内部使用了一种非常奇葩的系统来保证线程安全。未来有可能发布支持多线程安全的版本,但是知道即可,目前而言我们还得遵循目前的版本限制。值得一提的是,目前大部分的PHP应用场景都是以“单线程安全”的方式来安装的。

PHP-CPP是由C++11写的。因此,安装在我的Ubuntu 12.04 LTS服务器上的老版本g++不支持它。我们需要将g++编译器更新到版本4.8.x以上。这里有一篇介绍如何升级g++编译器的文章

当然,PHP-CPP编译时也会使用到php.h头文件。通常来说,Ubuntu box中是没有这个文件的,除非装了php-dev工具。我们可以使用下面的命令来安装PHP5相关的开发文件。

sudo apt-get install php5-dev

在升级了g++并安装了必要的头文件后,我们可以使用以下命令来编译和安装PHP-CPP库文件(libphpcpp.so):

make & sudo make install

上述的编译过程很快。在安装之后,libphpcpp.so文件会被拷贝到/usr/lib目录下,同时所有PHP-CPP的头文件会被拷贝到/usr/include和/usr/include/phpcpp文件夹下。

目前为止,已经完成了PHP-CPP库的安装。这些步骤是很简单的,现在我们可以把焦点移到编程上面来了。

在这之前,我们先来讨论下在PHP-CPP中重要的概念和技术。在开始真正的编程之前,建议每个人先通览下PHP-CPP的完整官方文档

扩展项目骨架(空的)文件

PHP-CPP提供了一个扩展项目骨架(skeleton),包含如下三个文件:

  • main.cpp : 主函数文件,包含了一个名为get_module的方法(后文会详细讨论到)\
  • Makefile : 简单的make文件,用于编译扩展
  • yourextension.ini : 仅包含一行,用于加载扩展

Makefile

如果你熟悉*nix开发的话,你也会熟悉这个Makefile文件。我们要对这个文件做一些自定义配置,以满足我们的需求。

  • 更改 NAME = yourextension 为一个更有含义的名字,比如 NAME = skeleton。
  • 根据你系统的配置来修改 INI_DIR = /etc/php5/conf.d。比如对于我的系统来说,应该配置成 INI_DIR = /etc/php5/cli/conf.d。首先,我修改了INI路径配置,让扩展使用PHP的命令行(cli)环境。

下面是我的所有改动。Makefile文件保持原样即可。

yourextension.ini

我重新命名成skeleton.ini,并改了其中一行,如下文:

extension=skeleton.so

main.cpp

在由PHP-CPP提供的空项目文件中,这个文件仅仅包含了一个函数:get_module(),下面是摘要:

/**
 *  tell the compiler that the get_module is a pure C function
 */
extern "C" {

    /**
     *  Function that is called by PHP right after the PHP process
     *  has started, and that returns an address of an internal PHP
     *  strucure with all the details and features of your extension
     *
     *  @return void*   a pointer to an address that is understood by PHP
     */
    PHPCPP_EXPORT void *get_module() 
    {
        // static(!) Php::Extension object that should stay in memory
        // for the entire duration of the process (that's why it's static)
        static Php::Extension extension("yourextension", "1.0");

        // @todo    add your own functions, classes, namespaces to the extension

        // return the extension
        return extension;
    }
}

现在,让我们来修改下面这一行,修改成我们想要创建的扩展名称。

static Php::Extension extension("skeleton", "1.0"); // To be humble, we can change


原文:https://www.sitepoint.com/getting-started-php-extension-development-via-php-cpp/

文章来源:胡旭个人博客 => 【译】PHP扩展开发入门PHP-CPP篇

转载请注明出处,违者必究!


这是一篇原创文章,如果您觉得有价值,可以通过捐赠来支持我的创作~
捐赠者会展示在博客的某个页面,钱将会用在有价值的地方,思考中...


分类: PHP, 技术, 技术分享, 编程 | 标签: , , , , , , | 评论 | Permalink

发表评论

电子邮件地址不会被公开。