23 / 06 / 2018 buling

PHP很多时候遇到问题很难定位,比如,微信支付回调的时候 ,明明代码报错了,但很难定位到什么问题导致了错误,这个时候可以用如下代码来定位

define(ROOT_PATH, '/tmp');
//注册结束回调
register_shutdown_function( function(){
    $error = error_get_last();
    if($error){
        file_put_contents(ROOT_PATH.'/some-error.txt', 'error:'.json_encode($error));
    }
} );
//监听错误回调
set_error_handler( function($num, $str, $file, $line, $context = null){
    file_put_contents(ROOT_PATH.'/some-error.txt', 'error:'.$num.';'.$str.';'.$file);
} );
//监听异常回调
set_exception_handler( function(Exception $e){
    file_put_contents(ROOT_PATH.'/some-error.txt', 'error:'.$e->getLine().';'.$e->getMessage().';'.$e->getFile());
} );
//显示所有错误信息
error_reporting( E_ALL );

 早期造个对象,写了个php的rsa帮助类库,先看使用方法

$keys = RsaHelper::new_rsa_key();
//生成完key之后应该记录下key值,这里省略
$privkey = $keys['privkey'];
$pubkey  = $keys['pubkey'];
/* $privkey = '-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKX0cHYmXyHhIx5/
k6GMneVKpUDsqP2PdKFGollWYCbxJUAHPsHsjILGI0ucGnC+VpfKVX6DEagoRBZv
tz+nnpcreVPtNbKMNzhukSY3Mt7Fo1rMaj0pbsaMom1noQjsKJlVgz6akP7RMm4W
zpnMvcDq/9PucfCQP1FGZTbg1hUxAgMBAAECgYBeGam/ROjChC9utrZWby6E+nuT
wd3c0QA4Bp49+/1Pd4NAuBr8yQ2vhXwz/lL7xOHC9ibeMqHLcPGSq0wEGx6P/XWM
0Ldpwu6cWv4qOdHdBDdqrO6mkyBljt4sq1WtTnkLgZ0cCTTeVnnFDmlc9Zr9oT5k
UezOEb55GziRD5XUxQJBANLx3kUjOFRyR1I/wZYHHJkcm8pSgpDe4b1G60orZa9J
nbUTM+cIvmNKzm99m9aIMvgjk/LBydpxV7W5YYDxHrcCQQDJZpcu5OPWNJ3TdrrK
KNa1lfUo5Vb0sCgpTueZdwngBr043XRTyJHqjziX/9Z19UWrE9Gz6U1Klpa7SBYo
O4NXAkEArsKRCahXJ6cRrXOClx/HMpY//0uCPjFYxa32ipkPgjwz+uswycw1px83
jah7ri1iRK99B9ZCu8XBC53MyL16WwJAISu+dsDILb2YyP1jImy7gEjkignL2p0w
4CzYxFPw0m8Jt1XyFOKR9doE7jP69I6jHNw0y7b/Peuzg8EJtTKoHQJBAITAjM7Q
QnIEgYHvw3gaQI8/6992Y0DSMaHt50peI6uJoMV+X9IcjY1eFUSOHV8nb0uI8xQ7
4SbU2yvLPTqUk50=
-----END PRIVATE KEY-----';
$pubkey = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCl9HB2Jl8h4SMef5OhjJ3lSqVA
7Kj9j3ShRqJZVmAm8SVABz7B7IyCxiNLnBpwvlaXylV+gxGoKEQWb7c/p56XK3lT
7TWyjDc4bpEmNzLexaNazGo9KW7GjKJtZ6EI7CiZVYM+mpD+0TJuFs6ZzL3A6v/T
7nHwkD9RRmU24NYVMQIDAQAB
-----END PUBLIC KEY-----'; */
//初始化rsaobject
RsaHelper::init($privkey, $pubkey);
//原文
$data = 'hello';
//私钥加密示例
$encode = RsaHelper::priv_encode($data);
$ret = RsaHelper::pub_decode($encode);
var_dump($ret);
//公钥加密示例
$encode = RsaHelper::pub_encode($data);
$ret = RsaHelper::priv_decode($encode);
var_dump($ret);

      类库源码如下

class RsaHelper{
    private static $_privkey = '';
    private static $_pubkey = '';
    private static $_isbase64 = false;
    /**
     * 初始化key值
     * @param  string  $privkey  私钥
     * @param  string  $pubkey   公钥
     * @param  boolean $isbase64 是否base64编码
     * @return null
     */
    public static function init($privkey, $pubkey, $isbase64=false){
        self::$_privkey = $privkey;
        self::$_pubkey = $pubkey;
        self::$_isbase64 = $isbase64;
    }
    /**
     * 私钥加密
     * @param  string $data 原文
     * @return string       密文
     */
    public static function priv_encode($data){
        $outval = '';
        $res = openssl_pkey_get_private(self::$_privkey);
        openssl_private_encrypt($data, $outval, $res);
        if(self::$_isbase64){
            $outval = base64_encode($outval);
        }
        return $outval;
    }
    /**
     * 公钥解密
     * @param  string $data 密文
     * @return string       原文
     */
    public static function pub_decode($data){
        $outval = '';
        if(self::$_isbase64){
            $data = base64_decode($data);
        }
        $res = openssl_pkey_get_public(self::$_pubkey);
        openssl_public_decrypt($data, $outval, $res);
        return $outval;
    }
    /**
     * 公钥加密
     * @param  string $data 原文
     * @return string       密文
     */
    public static function pub_encode($data){
        $outval = '';
        $res = openssl_pkey_get_public(self::$_pubkey);
        openssl_public_encrypt($data, $outval, $res);
        if(self::$_isbase64){
            $outval = base64_encode($outval);
        }
        return $outval;
    }
    /**
     * 私钥解密
     * @param  string $data 密文
     * @return string       原文
     */
    public static function priv_decode($data){
        $outval = '';
        if(self::$_isbase64){
            $data = base64_decode($data);
        }
        $res = openssl_pkey_get_private(self::$_privkey);
        openssl_private_decrypt($data, $outval, $res);
        return $outval;
    }
    /**
     * 创建一组公钥私钥
     * @return array 公钥私钥数组
     */
    public static function new_rsa_key(){
        $res = openssl_pkey_new();
        openssl_pkey_export($res, $privkey);
        $d= openssl_pkey_get_details($res);
        $pubkey = $d['key'];
        return array(
            'privkey' => $privkey,
            'pubkey'  => $pubkey
        );
    }
}

      妈蛋,win平台下的php protobuf折腾死我了,又改成py了,所以,python版的rsa加密辅助类来了

def new_keys():
    (bob_pub, bob_priv) = rsa.newkeys(1024)
    return {'pubkey':bob_pub.save_pkcs1(), 'privkey':bob_priv.save_pkcs1()}
class RsaHelper:
    def __init__(self, privkey, pubkey):
        self._privkey = privkey.decode('string-escape')
        self._pubkey = pubkey.decode('string-escape')
    def encode_priv(self, data):
        privkey = rsa.PrivateKey.load_pkcs1(self._privkey)
        crypto = rsa.encrypt(data, privkey)
        return crypto
    def decode_pub(self, data):
        pubkey = rsa.PublicKey.load_pkcs1(self._pubkey)
        msg = rsa.decrypt(data, pubkey)
        return msg
    def decode_priv(self, data):
        privkey = rsa.PrivateKey.load_pkcs1(self._privkey)
        msg = rsa.decrypt(data, privkey)
        return msg
    def encode_pub(self, data):
        pubkey = rsa.PublicKey.load_pkcs1(self._pubkey)
        crypto = rsa.encrypt(data, pubkey)
        return crypto
12 / 09 / 2011 buling

      明天要上班了,今天写点日志记录一下。首先,博客换主题了,修正了一下宽度,比较得意的是logo图片和favicon.ico图标。
      上周主要忙于学习写java代码,其实现在学习一门语言很快,因为google太厉害了。然后海涛接了sina app的开发放我们组,他觉得很有意思,我也感觉,只有使用过别人的app才能感觉到app的一般设计模式,sina自身把oauth封装的很好,以至于写一个接口最多不会超过3行代码:1、定义函数,2、参数数组,3、请求返回。
      除此有点点可以提的就是图片写字,需要把大家测试的结构分享给用户,所以我也封了一个类,还算比较好用,先来调用方法:

$bg_img = $_SERVER['Root_Path'].'/html/bg.jpg'; //背景图片
$new_img = $_SERVER['Root_Path'].'/html/new.jpg'; //生成的新图
$img = new SinaApp_Image($bg_img); //实例一个处理对象
$msg_info = array('size'=>12, 'x'=>152, 'y'=>20, 'msg'=>'你中奖了', //文字信息
          'font'=>$_SERVER['Root_Path'].'/inc/SIMSUN.TTC', 'color'=>'#FF0000');
$res = $img->new_img($new_img, array($msg_info)); //生成图片

      命名很人性,应该不会有阅读障碍,就不说明了,如果要写多行字,可以放多个msg_info就可以了。因为sina没有提供获取某应用发出的微博,所以只能依靠话题勉强实现,跟上面提的一样3行代码就不提了。
      这三天没干啥,昨天就折腾了一天主题,到下午的时候,tomato_ma给我介绍了一个网站的活,我发现自己潜意识不想出卖代码,刚开始谈的时候那哥们说,钱多的是,就是不知道往哪儿烧了,结果我提价5k,那哥们承受不起了,最终么有成交,难道在他们眼里代码那么廉价?之前也有一个项目也是,那个提价就更高,sorry,不想太累,不想对未来失去希望。
      最后奉上这个SinaApp_Image类分享给大家(备注一下,文字字体可选)。

/**
 * 图片处理类
 * @author tuyl
 *
 */
class SinaApp_Image{
    public $img_info = array();
    public $img_conf = array();
    public $img_path = '';
    public $err_msg = '';
    /**
     * 构造函数
     * @param string $img_path 背景图片地址
     */
    public function __construct($img_path){
        $this->img_conf = array(1=>'gif', 2=>'jpeg', 3=>'png', 4=>'swf', 5=>'psd',
                  6=>'bmp', 9=>'jpc', 10=>'jp2', 11=>'jpx', 12=>'jb2',
                  13=>'swc', 14=>'iff', 15=>'wbmp', 16=>'xbm');
        $this->img_path = $img_path;
        $this->img_info = @getimagesize($img_path);
    }
    /**
     * 新建一张图片
     * @param strint $new_img 新图片地址
     * @param array $msg_arr 文字数组 $arr = array('size'=>12, 'x'=>152, 'y'=>20, 'msg'=>'msg',
		     'font'=>'inc/SIMSUN.TTC', 'color'=>'#FF0000');
     * @param int $width 新图宽,默认为背景图宽
     * @param int $height 新图高,默认为背景图高
     */
    public function new_img($new_img, $msg_arr=array(), $width=null, $height=null){
        if(!$this->img_info){
            $this->err_msg = '文件['.$this->img_path.']不是一张合法图片';
            return false;
        }
        $width = $width ? $width : $this->img_info[0];
        $height = $height ? $height : $this->img_info[1];
        $nimg=imagecreatetruecolor($width, $height);
        $img_type = $this->img_conf[$this->img_info[2]];
        $cfunc = 'imagecreatefrom'.$img_type;
        if(!function_exists($cfunc)){
            $this->err_msg = '不支持创建['.$this->img_info[2].']类型图片';
            return false;
        }
        $im = $cfunc($this->img_path);
        imagecopy($nimg, $im, 0, 0, 0, 0, $width, $height);
        foreach ($msg_arr as $k=>$v) {
            $cor = str_split(str_replace('#', '', $v['color']), 2);
            $color = imagecolorallocate ($nimg, hexdec('0x'.$cor[0]), hexdec('0x'.$cor[1]), hexdec('0x'.$cor[2]));
            if(isset($v['font'])){ //有字体要求
                imagefttext($nimg, $v['size'], 0, $v['x'], $v['y'], $color, $v['font'], $v['msg']);
            }else{
                imagestring($nimg, $v['size'], $v['x'], $v['y'], $v['msg'], $color);
            }
        }
        $new_fun = 'image'.$img_type;
        $res = $new_fun($nimg, $new_img);
        imagedestroy($im); imagedestroy($nimg);
        return $res;
    }
    public function get_err_msg(){
        return $this->err_msg;
    }
}
12 / 04 / 2011 buling

        虽然现在有点晚了,但还是想写完,今天完成了一个伟大的事情,那就是完完整整的装了一次lamp,N久之前我就开始期望要自己学一次,但原来在业开实在是没时间,这两天稍微有点空闲,刚好来学习一下,星哥给了很多技术支持,特别感谢。
        以前从没装过软件,第一次接触,使用yum,原来这个东西如此之方便。我是安装一个虚拟主机,装的是scientific linux6.0,但因为源不好,安装的时候老卡住,星哥提示要删除缓存文件,再重试,果然:

rm -rf /var/cache/yum/x86_64/6.0/sl/*

       接下来就开始安装软件:很傻瓜的安装:

yum install httpd #安装apache
/sbin/chkconfig httpd on #设置apache服务器httpd服务开机启动
/etc/init.d/httpd start #开启apache
/etc/init.d/httpd status #查看apache状态
yum install mysql #客服端,即连mysql端
yum install mysql-server #服务端
/sbin/chkconfig --add mysqld #把mysql添加到服务清单中
/sbin/chkconfig mysqld on #设置mysql开机启动
/etc/init.d/mysqld start #开启mysql服务 /sbin/service mysqld status
yum install php #
yum install php-mysql #安装php连mysql组件
mysqladmin -u root password '123456' 设置mysql数据库账号
mysql -u root -p
mysql>show databases;
mysql>use test;
mysql>show tables;
mysql> GRANT ALL PRIVILEGES ON my_db.* TO 'user'@'localhost' IDENTIFIED BY 'password';

有的情况可能出现,安装好php后发现运行.php文件显示源代码,修改/etc/httpd/conf/http.conf文件,检查是否有如下配置,没有,添加重启apache即可:

AddType application/x-httpd-php .php

       好了,这就是伟大的amp,安装完了。下面来添加一个www用户,他主要就是放置站点文件的,

useradd www
passwd www

        打开/etc/httpd/conf/httpd.conf文件,在末尾添加如下代码,这里我就不解释,很简单,意会。


    ServerAdmin webmaster@dummy-host.example.com
    DocumentRoot /home/www/html/www.fenchu.com/public_html/
    ServerName fenchu.com
    ServerAlias fenchu.com www.fenchu.com
    ErrorLog logs/dummy-www.fenchu.com-error_log
    CustomLog logs/dummy-www.fenchu.com-access_log common
    Include conf/public/comon.conf
    SetEnv Root_Path /home/www/html/www.fenchu.com/
    SetEnv Base_Url http://www.fenchu.com/


    ServerAdmin webmaster@dummy-host.example.com
    DocumentRoot /home/www/html/bbs.fenchu.com/public_html/
    ServerName bbs.fenchu.com
    ServerAlias bbs.fenchu.com
    ErrorLog logs/dummy-bbs.fenchu.com-error_log
    CustomLog logs/dummy-bbs.fenchu.com-access_log common
    SetEnv Root_Path /home/www/html/bbs.fenchu.com/
    SetEnv Base_Url http://bbs.fenchu.com/

         结果发现一个问题,请求失败,结果星哥出马,指出selinux问题,虽然我现在还没搞懂这是个啥东西,不过知道怎么改,上代码,下来再研究:

#网页不能访问
setenforce 0
vi /etc/selinux/config
SELINUX=disabled
vi /etc/sysconfig/iptables #防火墙
/etc/init.d/iptables stop #关闭防火墙

        大部分问题都解决了,现在说几个小细节,想让用户访问自己目录可以:修改/etc/httpd/conf/httpd.conf 文件中的IfModule mod_userdir.c开启用户目录访问。开启php简写格式需要设置php.ini,short_open_tag = On,记得重启apache。
        最后一个关键问题,因为是虚拟主机,随意只能在我的局域网能访问,外面不可访问,这次又是星哥站了出来:做端口转发,很好,之前写短信网关的时候就是为了好测试,这就驾轻就熟了,把本地的80端口映射到虚拟机的80端口,但是我本地也装了一套amp,因为配置host的时候不能带端口,果断把本地的80端口换成8888端口(修改httpd.conf文件的Listen),然后再putty connection的命令行:-L 80 192.168.203.183:80,192.168.203.183这个ip是虚拟机的ip地址。很好,绑定一下hosts文件:

192.168.0.64 www.500pai.cn #64是我本地ip地址

        效果很好,等这几天把单点登录和短信网关的一些小问题处理一下,就接着来memcache和nginx安装配置。不早了,又该睡觉了。

03 / 03 / 2011 buling

      历时一周的手机竞拍接口正式完成了,刚开始规划的时候感觉不可能,但事实上就是这么快,主要是很多接口都是复制以前的接口就能搞定。一个项目完了总结一下是很有必要的。
      首先这次开发的整个结构沿溪了竞拍web站的风格,遵循统一入口,全面向对象开发。与web站不同的是采用了统一输出,废除了php反射,添加了插件模块,增加调试信息。整个网站结构很清晰。
      index.php?cid=10201&format=xml&charset=gbk; 这个是接口的入口,页面只有两句代码:

include(_BASE_ROOT_.'/config.php');
$index = getInstance();
$index->run();

      在config.php页面中主要是做参数配置和得到一个相应处理类实例

define('VERSION', 'v0.1'); //接口版本
define('DEBUG', 1); //是否开启调试
$GLOBALS['comonArgs'] = array('cid', 'tid'); //通用接受参数
 //通用插件,即所有接口都会调用
$GLOBALS['comonPlugin'] = array('before' => array('refuseSomeUser'), 'after' => array());
//命令调用配置,不同的命令对应不同的处理方法
//可以配置是否验证签名,验证登陆,开启插件等
$GLOBALS['classConfig'] = array(
    '10011' => array('class' => 'User',   'method' => 'login',   'checkSign' => 1,
             'isLogin' => 0, 'args' => array('username', userpwd), 'before' => array());
//传入参数格式检查配置
$GLOBALS['paraConfig'] = array( 'username' => '');
//错误码配置
$GLOBALS['errorConfig'] = array( -200 => '登陆失败');

      最后还有一个最关键的函数,返回相应类的实例。

function getInstance(){
    $classConfig = $GLOBALS['classConfig'];
    $cid = request('cid');
    $classFile = _BASE_ROOT_.'/Interface/'.$classConfig[$cid]['class'].'.php';
    include($classFile);
    $className = 'I_'.$classConfig[$cid]['class'];
    if(class_exists($className)){
        return new $className($classConfig[$cid]);
    }
}

      前端请求页面就这些,来看看类文件吧,当然还有个主干页面Icom.php页面还没上呢,这个是页面通用继承类,是所有类的爸爸,既然是长辈肯定要为子女做很多事情了,比如帮他们登陆,帮他们过滤坏人(注入),帮他们规划(统一输出)

class Icom{
    function __construct($data){
        $this->_conf = $data; //传入配置数据
        $this->_filterArgs(); //过滤get、post、request变量
        $this->_initSystem(); //初始化系统配置
        $this->_checkLogin(); //根据配置是否要求登陆并完成登陆操作
        $this->_checkAuth(); //检查权限,如是否黑名单等。
    }
    function run(){
        $plugin = new I_Plugin($this->_conf, $this->_REQUEST);
        $plugin->runBefore(); //调用前置插件
        $action = $this->_conf['method'];
        $res = $this->$action();
        I_Format::result($res, $this->format, $this->charset, $this->_request('debug'), $this->_debugStr());
        $plugin->runAfter(); //调用结束插件
    }
}

      还有I_Plugin和I_Format类就不多说了,I_Plugin负责找出配置中的所有配置插件,并执行。I_Format类就做统一格式化,一般分json和xml,xml又提供了两种,一种是调用DOMDocument类创建,一种是字符串拼接,当然我们选择了后者,因为性能。
      最想说的是这个插件问题,因为在开发时,发现以前的web竞拍中有大量的判断代码,如内侧资格判断,活动资格判断等等。活动或内侧过期了,那么这里就有一段长长的注释代码,看着人很揪心。所以在开发时加入插件模块,所有的非功能性代码全以插件函数形式加载执行。
      在这次的run函数中没有使用ReflectionClass($this)来反射需要执行的方法,这也是出于性能的因素考虑。不仅代码简单,更重要是更容易理解。
      框架写多了能总结很多,以前写mvc框架的时候接触php反射,所以在web竞拍中就使用上了,当时的模块类中必须有配置代码,现在完全剔除了,给开发者减轻了很多工作量,他们只需要关心功能代码。这次总共14个接口,我自己写了注册、登入、登出、购买拍点、购买拍品、出价6个接口;刘雪飞写了用户相关4个接口;小郭写了竞拍相关4个接口。特别说一下小郭和liuxf之前都没有参加过竞拍开发。特别谢谢,你们的努力大大缩短了开发时间。
      之前做的订制邮件今天下午已经把所有彩种都上了。一下子感觉轻松了很多,本身花不了很多时间,qianqian催的人心咕咕的,现在上完就好了。电信短信网关也上线了,但是response的有点慢,接下来是联通短信网关开发。

03 / 01 / 2011 buling

        一晃就2011年了,好快,三天假真是没什么过的,啥事还没做就没了。1号早上爬起来一看阳光不错,就去爬山,tnn的梧桐山,真是高。前两次都去的是南山,这次终于换了难度高的,之前就听说是深圳最高的山。一路沿溪而上,mq一路失足(听说国家发布说要称妓女为失足妇女),lup也不怎么好,差点把牙个摔没了,shixf还要好点,貌似没的啥问题,估计是去过一次摔出经验了。失误我竟然也掉了一只脚。

        今天在家闲来无事,有点冷就没去公司加班了,索性看了一下上次老大提到的php的spl库。学习了一下,还行,就是php内置的一些类。目前来说没有发现有多高级的地方,不过还是有一些想法,不知道怎么说,等到哪天有用的时候就好了。贴一下代码:

        PHP能调用python程序是不是一件很爽的事情,有很多大型的处理简单用PHP是不能完成,我们就可以通过ice中间件调用python来完成。首先创建一个Slice文件Hello.ice

#ifndef HELLO_ICE
#define HELLO_ICE

module Demo
{

 interface Hello
 {
     ["cpp:const"] idempotent void sayHello(int delay);
     ["cpp:const"] idempotent string returnHello();
     string test(string name);
     void shutdown();
 };

};

#endif

       有了接口文件,开始创建一个python服务端Server.py,代码如下

02 / 08 / 2010 buling

PHP操作Oracle数据库(OCI数据抽象层)
OCI(Oracle 8 Call-Interface)是PHP中内置的数据库抽象层函数。
下面针对连接Oracle数据库操作数据库的常见任务举例说明:
=======================基本查询:无条件查询===================
1、数据库连接:函数:oci_connect()
函数:resource oci_connect ( string username, string password [, string db [, string charset [, int session_mode]]] )
说明:   函数的返回值为资源
           username、password:是Oracle的用户名密码,即方案名及密码
           db:是可选参数,如果使用本地的Oracle实例或者使用tnsnames.ora配置文件中注册的本地服务名,直接提供其名称即可。
           如果此参数留空,则使用本地的ORACLE_SID或者搜索tnsnames.ora文件的注册的默认本地服务名。
           charset:参数是在Oracle9.2以上的版本使用的参数,默认可以留空,使用NLS_LANG 环境变量替代。
           session_mode:用于设定使用特权身份登录(默认禁用),默认有3个选项:OCI_DEFAULT,OCI_SYSOPER 和 OCI_SYSDBA
范例:连接本机注册的本地服务名为hy的Oracle实例,用户名/密码为scott/tiger

    GZIP(GNU-ZIP)是一种压缩技术。经过GZIP压缩后页面大小可以变为原来的30%甚至更小。这样用户浏览的时候就会感觉很爽很愉快!要实现GZIP压缩页面需要浏览器和服务器共同支持,实际上就是服务器压缩,传到浏览器后浏览器解压并解析。浏览器那边不需要我们担心,因为现在绝大多数浏览器都支持解析GZIP过的页面。我们只要把页面在服务器端压缩再输出到浏览器就行了。有点罗嗦,下面说正事。

function ob_gzip($content) // $content 就是要压缩的页面内容,或者说饼干原料
{   
    if( !headers_sent() && // 如果页面头部信息还没有输出
        extension_loaded("zlib") && // 而且zlib扩展已经加载到PHP中
        strstr($_SERVER["HTTP_ACCEPT_ENCODING"],"gzip")) //而且浏览器说它可以接受GZIP的页面
    {
        $content = gzencode($content."
//此页已压缩",9); 为准备压缩的内容贴上“//此页已压缩”的注释标签,然后用zlib提供的gzencode()函数执行级别为9的压缩,这个参数值范围是0-9,0表示无压缩,9表示最大压缩,当然压缩程度越高越费CPU。
        //然后用header()函数给浏览器发送一些头部信息,告诉浏览器这个页面已经用GZIP压缩过了!
        header("Content-Encoding: gzip");
        header("Vary: Accept-Encoding");
        header("Content-Length: ".strlen($content));
    }
    return $content; //返回压缩的内容,或者说把压缩好的饼干送回工作台。
}

06 / 05 / 2010 buling

首页引导文件Index.php文件源码

<?
require(“Config.php”);
require(ABSPATH.”Lib/BaseFun.php”);
require(ABSPATH.”Models/Front.php”);
require(ABSPATH.”Models/Icontroller.php”);
require(ABSPATH.”Models/Template.php”);
$front = FrontController::getInstance();
$front->route();
?>

项目配置文件Config.php源码