Nginx 试用 HTTPS

一、#openssl req -new -nodes -keyout server.key -out server.csr

二、用 server.csr 去申请 SSL 证书(免费的SSL证书服务商http://www.startssl.com)

三、将SSL证书服务商提供的密文保存至 server.crt

四、将 server.key 和 server.crt 文件上传至 nginx/conf 目录

五、配置 nginx 配置文件

a)强制从 HTTP 跳转至 HTTPS

    server {
        listen       80;
        server_name  ssl.nt00.com;
        rewrite ^/(.*)$ https://ssl.nt00.com/$1;
    }

b)配置 HTTPS

    server {
        listen       443;
        server_name  ssl.nt00.com;
        root   /www/ssl.nt00.com;

        ssl                  on;
        ssl_certificate      server.crt;
        ssl_certificate_key  server.key;

        ssl_session_timeout  5m;

        ssl_protocols  SSLv2 SSLv3 TLSv1;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers   on;

        location / {
            index  index.html index.php;
        }
        location ~ \.php($|/) {
            fastcgi_pass            unix:/tmp/php-fpm.socket;
            fastcgi_split_path_info ^(.+\.php)(.*)$;
            include                 fastcgi.conf;
        }
    }

PHP不能使用 header 进行 301 跳转

看到一个段PHP代码做跳转的时候是输出的 javascript 而没有使用 header(‘Location: xxx’) ,于是将其改为了 header(‘Location: xxx’)。

结果不能正常跳转,显示空白,监控 http 请求发现,即使在我设置完 header 完之后直接 exit 的情况下,服务器端仍然输出了 3bit 的字符。

于是开始找是哪输出的这 3bit ,从入口的 index.php 直到设置 header 的地方都没有任何输出。。。

最后只能用 exit 从 index.php 入口处一句一句代码的中断调试,追踪到引入 config 文件的时候发现这 3bit 的输出是从 config 文件中输出的。

打开 config 通读代码却没有发现任何输出语句,百思不得其解。。。

后来突然想到会不会是字符编码的问题,因为PHP会将文件的 bom 信息输出,PHP在有内容输出后又不能设置 header ,因此导致 header 函数无效?

查看该文件编码 utf8格式 ,印象中3年前搭建项目的时候应该全站源码都是 utf8无bom 格式。于是修改文件编码格式,问题解决。

这种莫名其妙的Bug其实只要开发的同学细心点就能避免的。

1年前一个同学遇到这个问题的时候问过我,因为我已离职,没有全面的检查代码就没有能解决。

没想到今年回来后,这个问题还是由我来解决了。。。

nginx + image_filter_module + lua 处理图片(缩放、翻转)

        location ~ ^/([^_]+)_(\d+)x(\d+)\.(jpg|jpeg|png|gif)$ {
                set $true_uri /$1.$4;
                set $width $2;
                set $height $3;
                access_by_lua '
                    ngx.req.set_uri(ngx.var.true_uri)
                ';
                #image_filter test;
                image_filter resize $width $height;
                #image_filter rotate 90;
                #image_filter crop 100 100;
        }

演示地址: http://yii.nt00.com/upload/1/532c1704b9306_200x200.png

 

PHP序列化方式对比

< ?php
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ . DIRECTORY_SEPARATOR . 'Classes');
include 'PHPExcel.php';

$file = __DIR__ . DIRECTORY_SEPARATOR . 'data.xlsx';//约5万行记录
$bm = memory_get_usage(true)/1024/1024;
$objPHPExcel = PHPExcel_IOFactory::load($file);
$em = memory_get_usage(true)/1024/1024;
echo sprintf("%.9f\r\n", $em-$bm);

echo "serialize ...\r\n";
/* 超出内存限制
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'data.db', serialize($objPHPExcel));
*/

/* 不能序列化 PHPExcel 对象?
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'data.db', json_encode($objPHPExcel));
*/

/* 超出内存限制 It's like JSON. but fast and small.
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'data.db', msgpack_pack($objPHPExcel));
*/

/* It's ok. Very fast. */
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'data.db', igbinary_serialize($objPHPExcel));
echo "done.";

比 define 和 apc_define_constants 效率更高的定义常量的方式:hidef

浏览器禁用 cookie 时使用 http header etag 保存会话信息

/* 禁用cookie和session时,使用 ETag 保存会话信息
$session = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? unserialize(base64_decode($_SERVER['HTTP_IF_NONE_MATCH'])) : array('counter'=>0);
$session['counter']++;
header('ETag: '.base64_encode(serialize($session)));
echo $session['counter'];
*/

// 客户端禁用cookie时,使用 ETag 保存 session_id
ini_set('session.use_cookies', 0);
if(isset($_SERVER['HTTP_IF_NONE_MATCH'])){
	$session_id = $_SERVER['HTTP_IF_NONE_MATCH'];
	session_id($session_id);
	session_start();
}else{
	session_start();
	$session_id = session_id();
}

if(phpversion() >= 5.3){
	header_remove('Cache-Control');
}else{
	header('Cache-Control:');
}

header('ETag: '.$session_id);
$_SESSION['counter'] = isset($_SESSION['counter']) ? $_SESSION['counter']+1 : 1;
echo $_SESSION['counter'];

求两个日期区间段的交集

$t1 = strtotime('2013-07-01 00:00:00');
$t2 = strtotime('2013-07-10 23:59:59');
$s  = strtotime('2013-07-05 00:00:00');
$e  = strtotime('2013-07-15 23:59:59');

$xs = date( 'Y-m-d H:i:s', $t1 > $s ? $t1 : $s );
$xe = date( 'Y-m-d H:i:s', $t2 < $e ? $t2 : $e );
if( ($s >= $t1 && $s < = $t2) || ($t1 >= $s && $t1 < = $e) ){
	echo $xs, ' ', $xe, "\r\n";
}

$xs = $t1 > $s ? $t1 : $s ;
$xe = $t2 < $e ? $t2 : $e ;
if($xs <= $xe){
	echo date('Y-m-d H:i:s', $xs), ' ', date('Y-m-d H:i:s', $xe), "\r\n";
}

php 不依赖第三方服务与 java 后台服务通信

服务端 java 监听端口

package com.st.xk;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class XKServer {

	private static boolean isDo = true;

	public static void main(String[] args) {
		try {
			ServerSocket ss = new ServerSocket(8090, 10, InetAddress.getByName("172.16.2.8"));
			while (isDo) {
				Socket s = ss.accept();
				new WorkerThread(s).start();
			}
			ss.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		Runtime.getRuntime().addShutdownHook(new Thread(){
			public void run(){
				isDo = false;
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
	}

}
package com.st.xk;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class WorkerThread extends Thread {

	private Socket socket;

	public WorkerThread(Socket socket) {
		this.socket = socket;
	}

	public void run() {
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
			
			StringBuilder sb = new StringBuilder();
			String str;
			while((str = reader.readLine()) != null){
				sb.append(str);
			}
			socket.shutdownInput();
			
			writer.write(sb.toString());
			writer.flush();
			socket.shutdownOutput();
			
			reader.close();
			writer.close();
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

客户端 php 利用 socket 连接向 java 程序发送消息

< ?php
function testSocket($i){
	$str = '{id:'.$i.',time:'.time().'}';
	$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
	socket_connect($socket, '172.16.2.8', 8090);
	socket_write($socket, $str, strlen($str));
	socket_shutdown($socket, 1);
	while($rStr = socket_read($socket, 4096)){
		echo $rStr;
	}
	echo "\n";
	socket_close($socket);
}
?>