black_key 发表于 2005-12-25 13:59:42

Pcpp-0.0.1 Release!

因为没有找空间的缘故,所以,需要体验或者测试的朋友可以与我
联系 [email protected]

希望参与开发的朋友,也请与我联系,因为目前仅我本人在开发,所以,
如果有更多朋友加入进来的话,我将开通 官方网站与 CVS . 谢谢!


README


立项初衷:

由于当时公司的项目需要,我第一次接触 PHP 是在 1 年多前,当初php5-beta1的时候,
兴致勃勃地用还没成熟的PHP5开发了第一套自己的php程序,她叫 HHManager , 是一个
MVC 的 php 实现, 在里面,我"竭尽全力" 地使用 php5 的所有新特性,为 HHManager
加入了类操作系统的 signal, event等特性,但最终我发觉,随着系统的逐渐庞大,执行效率成为了很
大的瓶颈,而且由于php语言本身的局限,有许许多多的功能,想法没法很好的实现。之后
HHManager 就从此搁置了。曾经一度,我认为php是没有任何潜力的脚本语言,也许是由于
上述的一些原因,许多人在构建web应用的时候都倾向于 Java 或者 .Net, 无可否认 .Net
和Java都是很优秀的平台,但是我还是想拥有一个足够简单,足够快速,足够廉价的web构建
系统,我想到了扩展 Zend engine, 我做了很多尝试,写了一些扩展,最终我还是觉得,扩
展的编写实在是太~~~~~~~~麻烦了。为了和PHP脚本语言的融合,zend 作了许多的工作,这些
工作都需要扩展编写者去完成,例如处理脚本调用扩展函数传递过来的参数,及扩展函数返回
给脚本的返回值等,在我对zend失去信心的时候,我想起了HHManager,我可不可以沿用
HHManager 的模式去建立一个扩展,然后在这个扩展的平台下再产生一个模块系统呢? 于是。。
Pcpp 就诞生了。


Pcpp 的含义:

名字有点怪异,其实我当时没有想好怎么取名, 想着 扩展 是用 C++ 编写,用于 PHP 中。干脆
就叫 Pcpp 算了 :)

Pcpp 的处理流程:

封装:

1。处理PHP脚本传递过来的扩展函数调用参数
我叫 PHP 调用叫做一个 Action

2。处理 Pcpp 下的模块的返回结果,并最终以 php 本身的数据类型返回给 PHP。

调用:

当接收到一个 PHP 的调用请求。 Pcpp 会根据这个Action,去寻找已经加载的,合适
的Pcpp模块去处理这个 Action ,Pcpp 有自己的数据类型,模块处理完 Action ,会
返回 Pcpp 的数据类型,然后 Pcpp 会进行数据类型的转换,并返回给 PHP。这一切
对于 PHP 脚本来说是透明的。

Pcpp 能带来什么?

当 ZE(Zend engine) 被 Apache 加载的时候, 所有扩展模块都被加载进内存,并随着ZE的
生存而常驻内存。
当 Pcpp 扩展模块被 ZE 加载之后, Pcpp 立即扫描 Pcpp.ModRoot(php.ini里设置) 指令
里设置的路径,并加载所有Pcpp模块,此后,所有 Pcpp 模块都与 Pcpp 一起,常驻内存。

最重要一点, Pcpp 接管了 PHP 与 模块之间的通讯过程, 这意味着模块编写者不需要了解
ZE(ZE 的API开发文档基本很少,晕~) , Pcpp 定义了一个模块接口,任何模块编写者,只要
实现了这个接口(从接口类继承), 就可以用 C++ 去编写自己的模块。并放到 Pcpp 的模块
目录中。

因为所有Pcpp模块都是常驻内存的,这样可以假设: 模块的调用都是高效的。
所以,许多应用,例如前台UI模版引擎,国际化,配置文件访问,以及许多要求高效的计算处理场合,
都可以用模块去完成。

另外,由于模块使用 C++ 编写而成,所以模块本身是通过编译的,可以把商业逻辑封装在模块
中而不必担心代码泄露,还起了降低成本的作用,你不需要为购买昂贵的 php 编码器(如果你惯用
Zend 的 decoder 的话)而费神了。


如何调用 Pcpp?

Pcpp 目前定义了数个基本的方法:

1. mixed pcpp_process(string modName [, string direct, string params]);
   这是主要的办法,PHP 脚本通过该方法发送一个 Action
   
   modName        :        指定调用的模块名(区分大小写)
   direct        :        指定传递给模块的指令(可选),一个模块可能定义多个指令去区别不同的调用
                                例如: pcpp_process("Users", "GetName") 指示模块取得用户名,而
                                           pcpp_process("Users", "GetPassword") 则指示模块取得用户密码.
   params        :   传递给模块的指令参数(可选),模块可以定义指令参数,例如:
                                pcpp_process("Localization", "GetValue", "Key:password;Area:zh_CN")
                                params 的格式是 “参数名:参数值;参数名:参数值”的形式
                               
   返回值        :        返回值根据模块的返回值而不同,目前 Pcpp 定义了 long, string, bool, null,
                                double 返回值, 日后打算增加 array, 及一个重要的: 类似 .Net ADODB 里的
                                DataSet 类型
                               
2. long pcpp_count()
        已加载的模块数量
       
3. string[] pcpp_mod_list()
        列出已加载的模块名
       
4. string[] pcpp_direct_list(string modName)
        列出一个模块支持的指令
       
5. boolpcpp_is_loaded(string modName)
        指示一个模块是否已经加载




Pcpp 的编译安装:

〉依赖:


在 redhat fc3 + php5.0.4/php4.3.4 + glibc 2.3.3 下编译通过


Pcpp 依赖 php 源码包。以及我的另外两个包,libhcpp, libcpi

1. 安装 libhcpp:
下载 libhcpp-0.0.1.tar.gz, 解压
# ./configure --prefix=/usr/local/libhcpp
# make
# make install

2. 安装 libcpi(libcpi倚赖libhcpp):
下载 libcpi-0.0.1.tar.gz, 解压
# ./configure --prefix=/usr/local/libcpi --with-libhcpp=/usr/local/libhcpp
# make
# make install

最后:
# vi /etc/ld.so.conf
# 添加两行 "/usr/local/libhcpp/lib" 及 "/usr/local/libcpi/lib" 后":qw"保存退出
# ldconfig


安装 Pcpp 扩展模块

下载 Pcpp-x.x.x.tar.gz

# tar zxvf Pcpp-x.x.x.tar.gz
# cd Pcpp-x.x.x
# ./configure --prefix=/usr/local/pcpp --with-zend=<zend source code path> --with-libhcpp=<libhcpp path> --with-libcpi=<libcpi path>
# make
# make install
# ln -s /usr/local/pcpp/lib/libpcpp.so /usr/local/php/ext/pcpp.so(这里假设php.ini里设置的extension_dir = /usr/local/php/ext,你可以响应更改)
# mkdir /usr/local/pcpp/mod (建立Pcpp模块目录, 可以随便更改)
# vi php.ini (加入
#                                extension = Pcpp.so
#                               
#                                Pcpp.ModRoot = /usr/local/pcpp/mod
#                        )
# 重启 apache ,你现在应该可以看到 phpinfo() 里输出有 Pcpp 的信息了。



Pcpp module how to

/// Core.cpp ///

#include <string>

/// 模块需要的头文件
#include "libcpi/include/Mod.h"

using namespace std;
using namespace HaoSoft::CPI;

/// 所有模块必须从 HaoSoft::CPI::ModBase 继承
class Core : public ModBase {

public:

        Core() {
        }

    /// 可选实现,实现无指令调用
        TResult Process() throw() {
        }

    /// 可选实现,实现php里指令调用 pcpp_process(modName, direct)
        TResult Process(const string& direct) throw() {
        }

        /// 可选实现,实现php里指令+参数调用 pcpp_process(modName, direct, params)
        TResult Process(const string& direct, ParamCollection* params) throw() {
        }

        /// 可选实现,返回模块支持的指令列表
        HaoSoft::CPI::TStringArray DirectList() const throw() {
        }
       
    /// 必须实现, 纯虚成员,返回模块名。该成员返回值被用来与扩展函数 pcpp_process() 等有模块名参数的调用匹配
        string Name() const throw() {
                return ("Core");
        }

};

/// 必须定义, Core 为类名,区分大小写
__MOD(Core)

/// Core.cpp ///

编译模块: #g++ -fPIC -shared -lcpi -o /usr/local/pcpp/mod/Core.so Core.cpp ,重启 apache 即可生效使用

TODO list:

0。取消 模块里的 HaoSoft 这个命名空间前缀。
1。增加 Array       数据类型 ,使模块能返回数组
2。增加 DataSet 数据类型 ,使模块能返回数据库表数据。
3。增加 模块访问控制 的支持,例如 ACL (访问控制列表)
4。增加 模块间相互调用的支持


最后:

   如果朋友们喜欢 Pcpp 的话, 欢迎加入 Pcpp 的开发工作中来

我希望 Pcpp 能成为构建大型商业 web 服务的重要基石。如果你在使用

Pcpp 的过程中构建了许多可重用的模块, 希望你能将他贡献出来给开源

社区。 我的目标只有一个,让 Pcpp 更强大!

                                                
                                                 黄浩
                                                 e-mail: [email protected]
                                                                                               2005.12.23
页: [1]
查看完整版本: Pcpp-0.0.1 Release!