|
因为没有找空间的缘故,所以,需要体验或者测试的朋友可以与我
联系 [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. bool pcpp_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]
# 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 |
|