“PHP” 标签页面:

  • php5.2配置使用memcached(附php_memcache.dll官方下载)

    当前PHP都已经到5.4了,但是我还是5.2,没办法,已经从以前的更新强迫症到现在的更新拖延症了。所以说一下PHP5.2的memcached怎么配置使用。

    这里下载最新的pecl包,即使版本不一样,只需要保证是5.2的即可,如pecl-5.2.6-Win32.zip。然后把压缩包里的php_memcache.dll解压缩到PHP安装目录下的ext文件夹中。

    打开php.ini,在extension列表后加上:

    extension=php_memcache.dll

    打开memcached,使用下面脚本测试memcached和PHP联合是否成功:

    <?php
    	$mem = new Memcache;
    	$mem->connect('localhost', 11211) or die ("Could not connect");
    	
    	$mem->set('test', 'testMem');
    
    	echo $mem->get('test');
    	
    ?>

    OK,就是这样。

    2012.06.26 / 1 条评论 / 2,841 次点击 / 分类: 所谓技术

  • PHP与JAVA使用AES128位加密通信

    本来JAVA和JSP之间加密通信好好的,相同的函数,相同的处理,不会有其他大问题。不过有时候就是蛋疼啊,于是就有了PHP与JAVA间使用AES进行加密通信。

    PHP的AES128位由mcrypt模块提供,称为MCRYPT_RIJNDAEL_128。

    JAVA的AES默认就是128位的。

    加密模式有好几种,不同的语言不同的库支持的情况不同。这里选择的是安全且通用的CBC模式。

    至于padding,这是最头疼的问题,因为PHP的padding与Java的padding不一样。如果使用NoPadding,则默认又用不了CBC模式。所以,最好的解决方法是自己padding——在原文末尾加上若干个空格,使原文凑齐16的倍数的长度。当然,原文末尾也可能是空格结束啊,那怎么办?没办法,只有强制原文末尾加上一个换行。这样子,每次解密后,将最右边的换行以及其右边的空格裁剪掉,就得到原文了。

    另外,为了兼容,在加密和解密时,需要将内容转换成16进制的字符数组。这样一来,即使加密/解密的内容不是普通文本,而是二进制数据,也可以轻松传送啦。

    JAVA方面

    初始化代码:

            try {
                cipherEnc = Cipher.getInstance("AES/CBC/NoPadding");
            } catch (NoSuchAlgorithmException ex) {
                ex.printStackTrace();
            } catch (NoSuchPaddingException ex) {
                ex.printStackTrace();
            }
            try {
                cipherDec = Cipher.getInstance("AES/CBC/NoPadding");
            } catch (NoSuchAlgorithmException ex) {
                ex.printStackTrace();
            } catch (NoSuchPaddingException ex) {
                ex.printStackTrace();
            }
    
            key = new SecretKeySpec(keyStr.getBytes(), "AES");
            iv = new IvParameterSpec(ivStr.getBytes());

    加密解密及其核心函数:

        public static String padRight(String s, int n) {
            return String.format("%1$-" + n + "s", s);
        }
    
        public static String padLeft(String s, int n) {
            return String.format("%1$#" + n + "s", s);
        }
        
        public String encrypt(SecretKeySpec enc_key, IvParameterSpec enc_iv, String str){
            byte[] ret = null;
            
            try {
                cipherEnc.init(Cipher.ENCRYPT_MODE, enc_key, enc_iv);
                ret = cipherEnc.doFinal(padRight(str,
                        ((int)Math.ceil(str.length() / 16.0))*16).getBytes());
            } catch (Exception ex) {
                ex.printStackTrace();
                return null;
            }
            
            return byteArray2HexString(ret);
        }
        
        /*
         * str is Hex String
         */
        public String decrypt(SecretKeySpec dec_key, IvParameterSpec dec_iv, String str){
            byte[] ret = null;
            
            try {
                cipherDec.init(Cipher.DECRYPT_MODE, dec_key, dec_iv);
                ret = cipherDec.doFinal(hexString2ByteArray(str));
            } catch (Exception ex) {
                ex.printStackTrace();
                return null;
            }
            
            try {
    			return new String(ret, "UTF-8");
    		} catch (UnsupportedEncodingException e) {
    			return null;
    		}
        }
    
        static final char[] HEX_CHAR_TABLE = {
            '0', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
        };
    
        public static String byteArray2HexString(byte[] b) {
            if (b == null) {
                return null;
            }
            final StringBuilder hex = new StringBuilder(2 * b.length);
            for (final byte by : b) {
                hex.append(HEX_CHAR_TABLE[(by & 0xF0) >> 4]).append(HEX_CHAR_TABLE[(by & 0x0F)]);
            }
            return hex.toString();
        }
        
        public static byte[] hexString2ByteArray(String s) {
            if (s == null) {
                return null;
            }
            byte high, low;
            int len = s.length() / 2;
            byte[] b = new byte[len];
            for(int i=0, k=0; i<len; i++, k+=2)
            {
                high = (byte) (Character.digit(s.charAt(k), 16) & 0x0F);
                low = (byte) (Character.digit(s.charAt(k+1), 16) & 0x0F);
                b[i] = (byte) ((high<<4) | low);
            }
            
            return b;
        }

    PHP方面

    加密解密部分及其核心函数

    	static function encrypt($enc_key, $enc_iv, $data){
    		$pad = str_pad($data, ceil(strlen($data)/16.0)*16, " ");
    		
    		$method = MCRYPT_RIJNDAEL_128;
    		$mode = MCRYPT_MODE_CBC;
    		$td = mcrypt_module_open($method, '', $mode, '');
    		mcrypt_generic_init ( $td , $enc_key , $enc_iv);
    		$encrypt = mcrypt_generic($td, $pad);
    		mcrypt_generic_deinit($td);
    		mcrypt_module_close($td);
    		
    		return bin2hex($encrypt);
    	}
    	
    	static function decrypt($dec_key, $dec_iv, $data){
    		$method = MCRYPT_RIJNDAEL_128;
    		$mode = MCRYPT_MODE_CBC;
    		$td = mcrypt_module_open($method, '', $mode, '');
    		mcrypt_generic_init ( $td , $dec_key , $dec_iv);
    		$decrypt = mdecrypt_generic($td, hex2bin($data));
    		mcrypt_generic_deinit($td);
    		mcrypt_module_close($td);
    	
    		return $decrypt;
    	}
    
    if(!function_exists('hex2bin'))
    {
    	/**
    	 * Converts the hex representation of data to binary
    	 *
    	 * http://www.php.net/manual/en/function.hex2bin.php
    	 *
    	 * @param   string  $str        Hexadecimal representation of data
    	 *
    	 * @return  string              Returns the binary representation of the given data
    	 */
    	function hex2bin($data)
    	{
    		return pack("H*" , $data);
    	}
    }

    就是这样啦。什么?不懂怎么用?那就看看AES的文献,看看Java和PHP的文档再说吧。

    2012.03.08 / 6 条评论 / 4,299 次点击 / 分类: 所谓技术

  • PHP的curl/libcurl连接https/SSL网站

    在PHP中使用libcurl连接https/SSL网站,可以用以下代码测试是否连接畅通:

    <?
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'https://passport.baidu.com/?login');
    curl_setopt($curl, CURLOPT_POST, false);
    $curl_res = curl_exec($curl);
    echo $curl_res;
    if (curl_errno($curl)) {
    	echo 'Error: ' . curl_error($curl);
    }
    curl_close($curl);
    ?>

    如果显示正常,则证明连接畅通。

    如果显示“Error: couldn't connect to host”,则证明出错啦!

    首先,进入phpinfo页面查看libcurl,看看curl字段是否有OpenSSL支持。如果没有,那就自己折腾PHP的安装吧!

    然后,将libeay32.dll和ssleay32.dll拷贝到windows目录、system32目录;或者如果是命令行运行PHP,则拷贝到当前运行目录;或运行Apache运行PHP,则拷贝到当前运行Apache的目录。

    重启Apache或者PHP,再次执行代码查看是否正常。

    2011.12.09 / 2 条评论 / 2,218 次点击 / 分类: 所谓技术

  • Eclipse支持PHP使用Zend Debugger调试

    一、安装Eclipse

    下载地址为http://www.eclipse.org/downloads/

    上面有好多个版本,通过Compare Packages科研看到其中的区别。开发PHP的话,Eclipse IDE for JavaScript Web Developers就行。但我考虑到以后可能要用它来折腾JAVA EE,所以下了Eclipse IDE for Java EE Developers。

    下载下来的是ZIP包,解压即可用。

    二、安装Eclipse for PHP集成开发环境

    参考http://wiki.eclipse.org/PDT/Installation#Installation_Flow

    选择“Help”——“Install New Software...”——Work With下拉菜单处选择对应版本的release,如我的3.7选“Indigo - http://download.eclipse.org/releases/indigo”——展开“Programming Languages”——选择“PHP Development Tools”。

    然后确认条款,等待安装,重启Eclipse即可支持PHP开发。

    三、PHP配置Zend Debugger

    这里,点击“Studio Web Debugger”那个链接,下载ZendDebugger,解压缩,如我解压缩到W:\ZendDebugger文件夹中。

    我是使用PHP5.2,则讲ZendDebugger文件夹中的5.2.x_comp改名为php-5.2.x。

    然后在php.ini的[Zend]段末加上以下内容:

    ; zend_debugger
    zend_extension_manager.debug_server_ts="W:\ZendDebugger"
    ;zend_debugger.allow_hosts=127.0.0.1,192.168.0.0/24
    zend_debugger.expose_remotely=always

    注意,如果是有安装Zend Optimizer的话,要在Zend Optimizer的配置后加入Zend Debugger的配置语句。

    四、联合Eclipse和Zend Debugger

    首先,开启WWW服务器,确认Zend Debugger成功配置。

    然后,开启Eclipse。

    在Eclipse中,选择“Window”——“Preferences”——“PHP”——“PHP executables”。在里面设置php的各项参数。我把SAPI设为“CGI”。

    在Eclipse中,选择“Window”——“Preferences”——“PHP”——“Debug”——“Installed Debuggers”。在里面设置php的各项参数。把Zend Debugger的“Debug Port”设为“10137”,默认的端口为10137,需要与php.ini设置的一致。

    将W:\ZendDebugger中的dummy.php拷贝至Web服务器的根目录中。

    在Eclipse中,选择“Run”——“Debug Configuration...”。在PHP Web Page中右击,选“new”,新建一个server配置,并设置好其中各项内容。点击“Test Debugger”,如果成功了就恭喜恭喜。如果没通过,则按照出错提示修正配置错误。

     

    OK,大功告成。

    2011.11.18 / 3 条评论 / 3,288 次点击 / 分类: 所谓技术

  • PHP查找中文字符的解决方案

    在PHP中查找中文字符,有两种方案。

    1、中文字符是gbk(gb2312)

    有两种解决方法

    第一种:

    将PHP保存为ASCII编码,然后使用strpos查找,如:

    strpos($curl_res, '哈哈')

    第二种:

    将PHP保存为UTF-8无BOM编码,然后转换字符串编码为UTF-8,再查找,如:

    $curl_res = mb_convert_encoding($curl_res, 'utf-8', 'gbk');

    mb_strpos($curl_res, '哈哈');

    2、中文字符是UTF-8

    有两种解决方法

    第一种:

    将PHP保存为UTF-8无BOM编码,然后使用strpos查找,如:

    strpos($curl_res, '哈哈')

    第二种:

    将PHP保存为ASCII编码,然后转换字符串编码为gbk,再查找,如:

    $curl_res = mb_convert_encoding($curl_res, 'gbk', 'utf-8');

    mb_strpos($curl_res, '哈哈');

    应该可以看出一些规律,就是:函数中的中文字符串参数的编码和PHP文件保存格式的编码一致,在使用函数时要考虑到!

    2011.08.13 / 2 条评论 / 5,293 次点击 / 分类: 所谓技术

  • 115网盘外链轻量版(PHP)

    这是PHP的版本,用的是HTTP HEADER的Location转向,并不是做流量转发,真正的数据还是直接有115服务器获得,轻量。

    代码如下,代码中有作者地址,如果失效了就在本博客关注或者直接去作者博客看新版吧:

    <?php
    /*
     * (C) Copyright 2009-2010 115.com All Rights Reserved
     *
     * 115网盘外链php版
     * 空间需要支持allow_url_fopen
     * 外链形式:http://lzq.org.ua/115.php/提取码/xxx
     * 2011.04.10亲测有效
     * 原作者 haowenq  更新:kkbblzq
     *
    */
    $uri = $_SERVER["REQUEST_URI"];
    preg_match("/115.php\/(.+)\//",$uri,$code);//自己修改
    $code = $code[1];
    $opts = array(
    'http'=>array('method'=>"GET",'header'=>"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.3)\r\n")
    );//伪造User-Agent
    $context = stream_context_create($opts);
    $url = "https://uapi.115.com/?ct=upload_api&ac=get_pick_code_info&pickcode=".$code."&version=1172";
    //获得原始下载地址
    $data = file_get_contents($url,false,$context);
    $data = str_replace("\\","",$data);
    preg_match_all("/\"Url\":\"(.*?)\"/", $data, $data);
    $myurl = $data[1][1];//获得下载
    if($myurl){
     header('Content-Type:application/force-download');//强制下载
     header("Location:".$myurl);
     die();
     }
    else echo "提取码不存在或已过期";
    ?>

    $data[1][1]是网通线路,$data[1][0]是电信线路。需要PHP支持allow_url_fopen。

    2011.06.08 / 暂无评论 / 1,627 次点击 / 分类: 所谓技术

  • 用.htaccess设置PHP错误显示

    使用.htaccess可以在某种程度上更改PHP的错误显示的设置,实际上,相当于更改PHP.ini的参数,很是方便。

    将以下相应代码放到对应目录中的.htaccess文件,即可实现相应功能。

    关闭错误显示:

    php_flag display_startup_errors off
    php_flag display_errors off
    php_flag html_errors off
    php_value docref_root 0
    php_value docref_ext 0

    只显示PHP错误:

    php_flag  display_errors        on
    php_flag  display_startup_errors on
    php_value error_reporting        2047

    其中,“2047”为要显示的错误的级别,详细表格如下:

    1 E_ERROR
    2 E_WARNING
    4 E_PARSE
    8 E_NOTICE
    16 E_CORE_ERROR
    32 E_CORE_WARNING
    64 E_COMPILE_ERROR
    128 E_COMPILE_WARNING
    256 E_USER_ERROR
    512 E_USER_WARNING
    1024 E_USER_NOTICE
    2047 E_ALL
    2048 E_STRICT
    4096 E_RECOVERABLE_ERROR 

    要把错误保存到日志文件中,可以这样设置:

    # enable PHP error logging
    php_flag  log_errors on
    php_value error_log  /home/path/public_html/domain/PHP_errors.log

    然后,可以设置不允许访问.log文件:

    # prevent access to PHP error log
    <Files PHP_errors.log>
     Order allow,deny
     Deny from all
     Satisfy All
    </Files>

    设置错误日志的最大体积,以bytes为单位:

    # general directive for setting max error size
    log_errors_max_len integer

    综合上述,.htaccess的PHP错误显示设置汇总:

    # PHP error handling for production servers
    
    # disable display of startup errors
    php_flag display_startup_errors off
    
    # disable display of all other errors
    php_flag display_errors off
    
    # disable html markup of errors
    php_flag html_errors off
    
    # enable logging of errors
    php_flag log_errors on
    
    # disable ignoring of repeat errors
    php_flag ignore_repeated_errors off
    
    # disable ignoring of unique source errors
    php_flag ignore_repeated_source off
    
    # enable logging of php memory leaks
    php_flag report_memleaks on
    
    # preserve most recent error via php_errormsg
    php_flag track_errors on
    
    # disable formatting of error reference links
    php_value docref_root 0
    
    # disable formatting of error reference links
    php_value docref_ext 0
    
    # specify path to php error log
    php_value error_log /home/path/public_html/domain/PHP_errors.log
    
    # specify recording of all php errors
    php_value error_reporting 999999999
    
    # disable max error string length
    php_value log_errors_max_len 0
    
    # protect error log by preventing public access
    <Files /home/path/public_html/domain/PHP_errors.log>
     Order allow,deny
     Deny from all
     Satisfy All
    </Files>

    以下则是适合开发者应用的设置:

    # PHP error handling for development servers
    php_flag display_startup_errors on
    php_flag display_errors on
    php_flag html_errors on
    php_flag log_errors on
    php_flag ignore_repeated_errors off
    php_flag ignore_repeated_source off
    php_flag report_memleaks on
    php_flag track_errors on
    php_value docref_root 0
    php_value docref_ext 0
    php_value error_log /home/path/public_html/domain/PHP_errors.log
    php_value error_reporting 999999999
    php_value log_errors_max_len 0
    
    <Files /home/path/public_html/domain/PHP_errors.log>
     Order allow,deny
     Deny from all
     Satisfy All
    </Files>

    本文大部分内容参考这篇文章:How to Enable PHP Error Logging via htaccess,大家有兴趣的话可以阅读英文原版。

    2010.01.06 / 1 条评论 / 1,360 次点击 / 分类: 所谓技术

  • GHS代理PHP简版

    不知道为什么,我一用HTTP/1.1发送请求,GHS代理就慢得要死。即是改用HTTP/1.0发送请求,如果把服务器端的Header转发给用户,照样慢的要死。不知道是怎么回事,所以只好写出这个只具备一般浏览功能,连POST都不支持,更别说301转向之类的GHS代理的PHP版本。

    采用fsockopen获取数据。

    首先,把绑在GHS的域名绑到某PHP空间,并将实际DNS指向该PHP空间。该空间需要支持.htaccess和URL ReWrite。

    然后,把下面内容保存为index.php,传到根目录:

    <?php
    //header不完整,强制为HTTP 1.0
    $ghslist=
    array(
    "72.14.203.121",
    "72.14.207.121",
    "74.125.43.121",
    "74.125.47.121",
    "74.125.53.121",
    "74.125.77.121",
    "74.125.93.121",
    "74.125.95.121",
    "74.125.113.121",
    "216.239.32.21",
    "216.239.34.21",
    "216.239.36.21",
    "216.239.38.21",
    );
    $ghsnum=rand(0,count($ghslist));
    
    //set_time_limit(600);
    //error_reporting(0); //禁止显示错误
    
    //取得所有http header
    if (!function_exists('getallheaders')) 
    {
        function getallheaders() 
        {
           foreach ($_SERVER as $name => $value) 
           {
               if (substr($name, 0, 5) == 'HTTP_') 
               {
                   $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
               }
           }
           if (isset($_SERVER['PHP_AUTH_DIGEST'])) { 
    		    $headers['AUTHORIZATION'] = $_SERVER['PHP_AUTH_DIGEST']; 
    			} elseif (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) { 
    		    $headers['AUTHORIZATION'] = base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW']); 
    			} 
    			if (isset($_SERVER['CONTENT_LENGTH'])) { 
    		    $headers['CONTENT-LENGTH'] = $_SERVER['CONTENT_LENGTH']; 
    			} 
    			if (isset($_SERVER['CONTENT_TYPE'])) { 
    		    $headers['CONTENT-TYPE'] = $_SERVER['CONTENT_TYPE']; 
    			}
           return $headers;
        }
    }
    
      class   http{   
      
        function   http_fopen($conn_host,$conn_port="80"){   
            $fp=fsockopen($conn_host,$conn_port);   
            if(!$fp){   
                          return   false;   
            }   
            return $fp;
        }   
        //得到查询内容   
        function   http_fget($fp){   
        	//向服务器发送header
        	$fp=$this->sendHeaders($fp);
        	//向客户端发送header
    			while(!feof($fp))
    			{
    				$content=fgets($fp);
    				if(trim($content)=="")
    				{
    					break;
    				}
    				//header($content);
    				//echo $content;
    			}
    			//显示网页内容
    			while(!feof($fp))
    			{
    				echo fgets($fp,128);
    			}
        }   
        /*//设置头部信息
        function setHeaders()
    		{
    			$headers=getallheaders();
    			//传送访客IP信息
    			if (isset($_SERVER['REMOTE_ADDR']))
    			{
    				$headers['X-Real-IP'] = $_SERVER['REMOTE_ADDR']; 
    			}
    			if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
    			{
    				$headers['X-Forwarded-For'] = $_SERVER['HTTP_X_FORWARDED_FOR']; 
    			}
    			else
    			{
    				$headers['X-Forwarded-For'] = $_SERVER['REMOTE_ADDR']; 
    			}
    			return $headers;
    		}*/
    		//发送头部信息
    		function sendHeaders($fp)
    		{
    			//$requestHeader=$this->setHeaders();
    			$theREQUEST_METHOD=isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD']:'GET';
    			$http_host=$_SERVER['HTTP_HOST'];//$requestHeader['Host']="creke.net";//在这里更改http请求时远程主机
    			$theREQUEST='http://'.$http_host.$_SERVER['REQUEST_URI'];//isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI']:'/';//这里设置请求的URI
    			$theSERVER_PROTOCOL='HTTP/1.0';//isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL']:'HTTP/1.1';
    			$firstHeader=$theREQUEST_METHOD." ".$theREQUEST." ".$theSERVER_PROTOCOL."\n";
    			fputs($fp,$firstHeader);
    			fputs($fp,"Host: $http_host\n");
    			fputs($fp,"User-agent: ".$_SERVER[’HTTP_USER_AGENT’]."\n");
    			/*foreach($requestHeader as $name => $value) 
    			{
    				fputs($fp,"$name: $value\n");
    			}*/
    			//发送post内容,这里有问题
    			if(strtolower($theREQUEST_METHOD)=='post')
    			{
    				$line = file_get_contents("php://input");
    				fputs($fp,$line);
    			}
    			fputs($fp,"\n");
    			return $fp;
    		}
    		function http_fclose($fp)
    		{
    			fclose($fp);
    		}
      }   
    
    $thehost="ghs.google.com";//$ghslist[$ghsnum];
    $http=new   http;     
    $fp=$http->http_fopen($thehost);   
    if(!$fp)
    {   
      echo"sorry,con't   connect";   
      exit;   
    }   
    //得到返回的结果   
    $http->http_fget($fp);
    $http->http_fclose($fp);
    exit();
    ?>

    然后,在.htaccess添加如下的ReWrite规则:

    RewriteEngine   on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule     (.*) /index.php [L]

    这样就OK了。

    以后每次访问到这个PHP空间的请求,都会通过fsockopen重新请求到ghs.google.com,这样就达到的GHS代理的目的。最后再提醒一次,本PHP版代理只支持网页浏览,对于POST、301转向等GHS应用暂不支持。

    2009.11.06 / 19 条评论 / 2,115 次点击 / 分类: 所谓技术

  • gzip.php无缓存版

    有缓存那个gzip始终有问题,干脆换成这个无缓存版本。

    本gzip.php默认压缩输出css、js、html、xml等内容。

    Rewrite规则:

    #gzip for non-PHP
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteCond %{REQUEST_FILENAME} ^.*\.(css|js|html|htm|xml|/)$
    RewriteRule ^(.*)$ gzip.php?url=$1 [QSA,L]
    </IfModule>
    #END gzip for non-PHP

    gzip.php文件代码内容:

    <?php
    $allowed = array(
    'css' => 'text/css',
    'js' => 'application/x-javascript',
    'html' => 'text/html',
    'htm' => 'text/html',
    'xml' => 'text/xml',
    );
    $file = isset($_GET['url']) ? $_GET['url'] : null;
    $extension = explode('.', $file);
    $extension = array_pop($extension);
    if(isset($allowed[$extension]))
    {
    $pos = strpos($file, '..');
    if ($pos === false && is_file($file))
    {
    @ob_start ('ob_gzhandler');
    header("Content-type: {$allowed[$extension]}; charset: UTF-8");
    readfile($file);
    } else {
    header('HTTP/1.1 404 Not Found');
    }
    }
    ?>

    2009.11.04 / 4 条评论 / 804 次点击 / 分类: 所谓技术

  • gzip.php改良版

    gzip.php改良版
     
    $key已经确定了某个文件的唯一性,所以把原来的文件名处理换了,并加上$ht_dir。因为$key是来自$_SERVER['QUERY_STRING']的变量,与htaccess位置有关。
    缓存的生成与当前文件目录无关,所以采用$cachedir指定相对网站根目录,存放gz文件的目录。
    相对原版,程序体更改了js的文件类型,更符合规范。更改了$filename和$cache_filename两个变量,并添加了$cur_dir变量设定和$ws_dir变量。同时删除一些改动后已经无用的中间变量。
    如果已经用了php_flag zlib.output_compression on来压缩PHP,那么在放置gzip.php的目录下加上一个.htaccess,里面写上“php_flag zlib.output_compression off”。避免连续压缩两次而出错。
     
    如果更新了CSS文件,记得手动删除对应缓存哦!
    对应Rewrite规则:
    #gzip for css and js
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    #RewriteCond %{HTTP:Accept-encoding} gzip #据说有些防火墙阻挡这个请求,而且大部分都支持Gzip,所以注释掉,不再判断。
    RewriteCond %{REQUEST_FILENAME} ^.*\.(css|js)$
    #RewriteCond %{REQUEST_FILENAME} -f #gzip.php已经有判断文件是否存在,故这里是否判断都没关系,交给gzip.php处理。
    RewriteRule (.*.css$|.*.js$) /wp-content/gzip-cache/gzip.php?$1 [L]
    </IfModule>
    #END gzip for css and js
    这个改良版程序支持针对某子目录的页面的gzip压缩。具体终极完美使用下次再说。
     
    改良gzip.php,支持Win和*nix主机。原版来自:http://www.cbmland.com/post/522/optimized-wordpress-notes-1.html Rewrite参考:这里
    改良gzip.php代码:
    <?php
    //注:本文件需要在其目录下关闭Gzip压缩PHP!
    $cur_dir = 'wp-content/gzip-cache/';//相对网站根目录,本文件的目录
    $cache = false;//Gzip压缩开关
    $cachedir = 'wp-content/gzip-cache/';//相对网站根目录,存放gz文件的目录,确保可写
    $ht_dir = '';//相对网站根目录,使gzip生效的.htaccess文件存放目录
    $ws_dir = dirname(__FILE__);
    $ws_dir = str_replace('\\','/',$ws_dir).'/';
    $ws_dir = str_replace($cur_dir,'',$ws_dir);//计算出网站根目录的绝对路径
    $gzip = strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip');
    $deflate = strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate');
    $encoding = $gzip ? 'gzip' : ($deflate ? 'deflate' : 'none');
     
    if(!isset($_SERVER['QUERY_STRING'])) exit();
     
    $key=array_shift(explode('?', $_SERVER['QUERY_STRING']));
    $key=str_replace('../','',$key);
    $filename=$ws_dir.$ht_dir.$key;//要压缩的文件的绝对路径
     
    $symbol='^';
    $cache_filename=$ws_dir.$cachedir.str_replace('/',$symbol,$key).'.gz';//生成gz文件路径
    $type="Content-type: text/html"; //默认的类型信息
     
    $ext = array_pop(explode('.', $filename));//根据后缀判断文件类型信息
     switch ($ext){
      case 'css':
       $type="Content-type: text/css";
       break;
      case 'js':
       $type="Content-type: application/x-javascript";
       break;
      default:
       exit();
     }
     
    if($cache){
     if(file_exists($cache_filename)){//假如存在gz文件
     
     
      $mtime = filemtime($cache_filename);
      $gmt_mtime = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
     
      if( (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
            array_shift(explode(';', $_SERVER['HTTP_IF_MODIFIED_SINCE'])) ==  $gmt_mtime)
       ){
     
       // 浏览器cache中的文件修改日期是否一致,将返回304
       header ("HTTP/1.1 304 Not Modified");
       header("Expires: ");
       header("Cache-Control: ");
       header("Pragma: ");
       header($type);
       header("Tips: Cache Not Modified (Gzip)");
       header ('Content-Length: 0');
     
     
      }else{
     
       //读取gz文件输出
       $content = file_get_contents($cache_filename);
       header("Last-Modified:" . $gmt_mtime);
       header("Expires: ");
       header("Cache-Control: ");
       header("Pragma: ");
       header($type);
       header("Tips: Normal Respond (Gzip)");
       header("Content-Encoding: gzip");
       echo $content;
      }
     
     
     }else if(file_exists($filename)){//没有对应的gz文件
     
      $mtime = mktime();
      $gmt_mtime = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
     
      $content = file_get_contents($filename);//读取文件
      $content = gzencode($content, 9, $gzip ? FORCE_GZIP : FORCE_DEFLATE);//压缩文件内容
     
      header("Last-Modified:" . $gmt_mtime);
      header("Expires: ");
      header("Cache-Control: ");
      header("Pragma: ");
      header($type);
      header("Tips: Build Gzip File (Gzip)");
      header ("Content-Encoding: " . $encoding);
            header ('Content-Length: ' . strlen($content));
      echo $content;
     
      if ($fp = fopen($cache_filename, 'w')) {//写入gz文件,供下次使用
                    fwrite($fp, $content);
                    fclose($fp);
                }
     
     }else{
      header("HTTP/1.0 404 Not Found");
      echo "<!--404 Not Found-->";
     }
    }else{ //处理不使用Gzip模式下的输出。原理基本同上
     if(file_exists($filename)){
      $mtime = filemtime($filename);
      $gmt_mtime = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
     
      if( (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
      array_shift(explode(';', $_SERVER['HTTP_IF_MODIFIED_SINCE'])) ==  $gmt_mtime)
      ){
     
      header ("HTTP/1.1 304 Not Modified");
      header("Expires: ");
      header("Cache-Control: ");
      header("Pragma: ");
      header($type);
      header("Tips: Cache Not Modified");
      header ('Content-Length: 0');
     
     }else{
     
      header("Last-Modified:" . $gmt_mtime);
      header("Expires: ");
      header("Cache-Control: ");
    &
    nbsp; header("Pragma: ");
      header($type);
      header("Tips: Normal Respond");
      $content = readfile($filename);
      echo $content;
     
      }
     }else{
      header("HTTP/1.0 404 Not Found");
      echo "<!--404 Not Found-->";
     }
    }
     
    ?>

     

    2009.08.20 / 1 条评论 / 1,089 次点击 / 分类: 所谓技术