编译 PHP GD 模块

在编译 PHP 使用 –with-gd 选项无法正常将 GD 编译进 PHP,所以我尝试将 GD 编译成一个 PHP 扩展,方法如下:
1. 进入 PHP 源码 ./ext/gd
2. 运行 phpize
3. 进行 ./configure && make && make install
编译完成后修改 PHP 配置文件,设置本扩展的路径。
重启 Apache 问题依旧,查看 Apache 的错误日志,显示该模块无效,猜想可能是没有正确链接 GD 的支持库,看了一下 configure 的选项,意识到 libjpeg 和 libpgn 库没有安装,用 pacman 安装这两个库以后,重新编译 GD 库,问题解决。

在 Gentoo 上安装 Nginx + php

从源码安装 Nginx

./configure --prefix=/usr --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx_error.log --http-log-path=/var/log/nginx_access.log --pid-path=/var/run/nginx.pid --http-client-body-temp-path=/var/tmp/nginx_client_body.tmp --http-proxy-temp-path=/var/tmp/nginx_proxy.tmp  --http-fastcgi-temp-path=/var/tmp/nginx_fastcgi.tmp --with-http_stub_status_module --with-http_ssl_module --with-openssl=/usr/src/openssl

(启用了监控和ssl模块,重新设置文件路径)
make
make install

注意,–with-openssl 指向的是 openssl 的完整源码树。

Nginx 的配置

在 server 段中加入 root 指令,指向网站根目录,然后把 location / 段改为:

location / {
  stub_status on;
  access_log off;
}

这样就能在首页显示状态信息了,在这里用作测试。

从源码安装 PHP 5.2.7

./configure --prefix=/usr --with-config-file-path=/etc/php --with-curl=shared --with-curlwrappers --enable-fastcgi --enable-force-cgi-redirect --with-openssl=shared --with-mysql=shared --with-mysqli=shared --enable-zip=shared --with-xmlrpc=shared --enable-mbstring --enable-pdo=shared --with-pdo-sqlite=shared --with-sqlite=shared --with-gd=shared --with-zlib
make
make install
cp php.ini-dist /etc/php/php.ini

在这种情况下,模块会编译进 PHP 而不是作为模块动态加载,如果想要创建模块需要设置 shared 选项,比如我要把 PDO 作为模块加载:

./configure --enable-pdo=shared --with-pdo-sqlite=shared --with-sqlite=shared

如果是 apache 的话要加上 –with-apxs2 项以创建模块。

设置 FASTCGI

我尝试用 php-cgi 直接创建 FCGI 服务,但无法成功,只好使用 lighttpd 的 spawn-fcgi 程序创建 FCGI 服务(这里偷懒用 emerge 装的 lighttpd):

spawn-fcgi -a 127.0.0.1 -p 9000 -C 5 -f /usr/bin/php-cgi

最后修改 nginx 的配置文件使之调用 php FCGI 服务:

location / {
 index index.php index.htm index.html;
}
location ~ .php$ {
 fastcgi_pass 127.0.0.1:9000;
 fastcgi_index index.php;
 include fastcgi_params;
 fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name;
}

创建一个 phpinfo 页面测试一下吧!

参考

Nginx 编译参数说明
PHP 编译参数说明
Nginx 0.7.x + PHP 5.2.6(FastCGI)搭建胜过Apache十倍的Web服务器(第4版)
Nginx With PHP As FastCGI Howto

在 PHP 中使用 XMLRPC

这几天在研究 Moodle Network 组件,通过这个模块,各个孤立的系统被连接到了一起,实现了单点登录和资源共享(对于 e-learning 有很大的意义),通信协议是 XML-RPC,信息安全不是依赖 SSL 的方案,而是在采用了 XML 签名(不对称加密算法),想法非常好,但实现的不太完整,因为这个模块的原作者离开了在新西兰的公司,整得像个半完成作品。

今天看了一下代码,打算在这上面解决多 Moodle 系统的资源共享问题(包含点对点和 HUB 模式),之前没用过 XMLRPC,所以现在开始学一下,我用的是 PHP 的 XMLRPC 模块(比纯 PHP 实现快了不少)。

首先实现一个 XMLRPC 服务,我封装了一个简单的类:

class xmlrpc_server {
    private $server;
    public function __construct() {
        $this->server = xmlrpc_server_create();
    }
    public function add($name, $func) {
        xmlrpc_server_register_method($this->server, $name, $func);
    }
    public function run() {
        $req = file_get_contents('php://input');
        $response = xmlrpc_server_call_method($this->server, $req, null);
        echo $response;
        xmlrpc_server_destroy($this->server);
    }
}

调用这个类创建一个服务:

header('Content-Type: text/xml');
function func_add($method, $params) {
    return $params[0]+$params[1];
}
$xmlrpc = new xmlrpc_server;
$xmlrpc->add('add', 'func_add');
$xmlrpc->run();

PHP 客户端的调用是通过 HTTP 的 POST 方法,我用的是 cURL 扩展:

require_once('curl.class.php');
class xmlrpc_client {
    public function __construct($url, $autoload = false) {
        $this->connection = null;
        $this->url = $url;
        $this->connection = new curl;
        $this->methods = array();
        if ($autoload) {
            $resp = $this->call('system.listMethods', null);
            $this->methods = $resp;
        }
    }
    public function call($method, $params = null) {
        $post = xmlrpc_encode_request($method, $params);
        return xmlrpc_decode($this->connection->post($this->url, $post));
    }
}
header('Content-Type: text/plain');
$rpc = "http://10.0.0.10/api.php";
$client = new xmlrpc_client($rpc, true);
print_r($client->call('add', array(199,2)));

待续,下一步优化代码并实现 XML 签名技术。

资料:

XML Signature Syntax and Processing
OpenSSH
XML Encryption Syntax and Processing

== TO BE CONTINUED ==