博采众长,精于一技。Live for love, work for dream.

Nginx设置PHP的PATH_INFO

默认情况下,Nginx不支持PATH_INFO,但是PHP的路由规则需要用到这个变量。配置这个的时候浪费了不少时间,于是记录一下。

server {
    listen 80;
    server_name demo.com;
    root /path/to/document/root/demo;

    location / {
        index index.html index.php;

        try_files $uri $uri @php_fpm;
    }

    location @php_fpm {
        rewrite ^(.*)$ /index.php$1 last;
    }

    location ~ ^(.+\.php)(.*)$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_split_path_info       ^(.+\.php)(/.+)$;
        fastcgi_param  PATH_INFO          $fastcgi_path_info;
    }

    error_log /var/log/nginx.log;
}

重点在
fastcgi_split_path_info       ^(.+\.php)(/.+)$;
fastcgi_param  PATH_INFO          $fastcgi_path_info;

这两行。

PHP浮点数的精度问题

先看问题:

$f = 0.58;
var_dump(intval($f * 100)); //为啥输出57

我相信有很多的同学有过这样的疑问。

具体原理可阅读“鸟哥”的一篇文章,那里有详细的解说:PHP浮点数的一个常见问题的解答

那么如何避免这种问题呢?
办法有很多,这里列举两个:
1. sprintf

substr(sprintf("%.10f", ($a/ $b)), 0, -7);

2. round (注意会进行四舍五入)

round($a/$b, 3);

或者你有更好的办法,也可以了留言告诉我。

MySQL insert性能优化


对于一些数据量较大的系统,面临的问题除了是查询效率低下,还有一个很重要的问题就是插入时间长。我们就有一个业务系统,每天的数据导入需要4-5个钟。这种费时的操作其实是很有风险的,假设程序出了问题,想重跑操作那是一件痛苦的事情。因此,提高大数据量系统的MySQL insert效率是很有必要的。

经过对MySQL的测试,发现一些可以提高insert效率的方法,供大家参考参考。

1. 一条SQL语句插入多条数据。
常用的插入语句如: INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('0', 'userid_0', 'content_0', 0);
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('1', 'userid_1', 'content_1', 1);

修改成: INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('0', 'userid_0', 'content_0', 0), ('1', 'userid_1', 'content_1', 1);

修改后的插入操作能够提高程序的插入效率。这里第二种SQL执行效率高的主要原因有两个,一是减少SQL语句解析的操作, 只需要解析一次就能进行数据的插入操作,二是SQL语句较短,可以减少网络传输的IO。

这里提供一些测试对比数据,分别是进行单条数据的导入与转化成一条SQL语句进行导入,分别测试1百、1千、1万条数据记录。

记录数单条数据插入多条数据插入
1百0.149s0.011s
1千1.231s0.047s
1万11.678s0.218s

2. 在事务中进行插入处理。
把插入修改成: START TRANSACTION;
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('0', 'userid_0', 'content_0', 0);
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('1', 'userid_1', 'content_1', 1);
...
COMMIT;

使用事务可以提高数据的插入效率,这是因为进行一个INSERT操作时,MySQL内部会建立一个事务,在事务内进行真正插入处理。通过使用事务可以减少数据库执行插入语句时多次“创建事务,提交事务”的消耗,所有插入都在执行后才进行提交操作。

这里也提供了测试对比,分别是不使用事务与使用事务在记录数为1百、1千、1万的情况。

记录数不使用事务使用事务
1百0.149s0.033s
1千1.231s0.115s
1万11.678s1.050s

性能测试:
这里提供了同时使用上面两种方法进行INSERT效率优化的测试。即多条数据合并为同一个SQL,并且在事务中进行插入。
记录数单条数据插入合并数据+事务插入
1万0m15.977s0m0.309s
10万1m52.204s0m2.271s
100万18m31.317s0m23.332s

从测试结果可以看到,insert的效率大概有50倍的提高,这个一个很客观的数字。
注意事项:

1. SQL语句是有长度限制,在进行数据合并在同一SQL中务必不能超过SQL长度限制,通过max_allowed_packe配置可以修改,默认是1M。

2. 事务需要控制大小,事务太大可能会影响执行的效率。MySQL有innodb_log_buffer_size配置项,超过这个值会日志会使用磁盘数据,这时,效率会有所下降。所以比较好的做法是,在事务大小达到配置项数据级前进行事务提交。

原文地址:http://blog.csdn.net/tigernorth/article/details/8094277

nginx实现多重if判断

nginx的配置中不支持if条件的逻辑与/逻辑或运算 ,并且不支持if的嵌套语法,我们可以用变量的方式来实现:
首先是伪代码(即不被nginx支持),写在这里只是为了方便理解:
if ($remote_addr ~ "^(12.34|56.78)" && $http_user_agent ~* "spider") {
    return 403;
}

这是等效的,并真实可用的配置

set $flag 0;
if ($remote_addr ~ "^(12.34|56.78)") {
    set $flag "${flag}1";
}
if ($http_user_agent ~* "spider") {
    set $flag "${flag}2";
}
if ($flag = "012") {
    return 403;
}

[翻译]为什么很多人讨厌PHP ?

几年前我有回复类似的问题,核心理念是,当我们只从一个或少数角度来观看一件事时,往往会忘了另一片风景。

重点是,我们打算用程序语言(PHP)做什么?这会决定我们看的角度,甚至影响了我们的心态。我曾在公开演讲中表示,程序语言对我来说,是个「选择(Option)」,是用来「解决某个问题」。如同我们不会拿榔头敲掉螺丝,而是使用螺丝起子。一旦我们受限于只比较「工具」的局部特性时,我们很容易只看到一个工具的缺点,而忘了它的优点。

今天我在网络上看到Phil Sturgeon在Quora针对此问题的回答,同时也同步在他的博客,分享给大家。

Phil 认为很多人有各种不同的理由「讨厌」PHP,或至少看衰它。其中有一些是有根据的,有些则否。

1. Inconsistent haystack / needle

Phil 举的第一个例子是「不一致的haystack / needle」。

举个PHP 中的两个内置函数:

in_array($needle, $haystack)

strpos($haystack, $needle)

很多人批评函数参数的haystack 及needle 在不同的情况下的顺序不一致,这导致开发者很可能要「硬背」这些API。

Phil指出,其实PHP的函数设计是有规则的。如果haystack处理的是array,则顺序是needle, haystack;反之若是string,则顺序是haystack, needle。

2. PHP is a HTML file, with logic

很多人认为PHP 与HTML 的混用规则是很奇怪的设计。

Phil 指出,PHP 在起初设计上就是预设文件是个HTML,只是中间可以嵌入一些PHP 的逻辑处理。我们也不能否认的是,在当时的那个时代,这个设计使得PHP 使用率得以快速成长。

但也不能否认的是,这个现象在现代看来有些不合味口,所以在未来的PHP 6将会引入新特性来让开发者得以解决这个问题。

3. No standards

在PHP的世界中有太多的Web framework,每个都有着自己的标准,例如很多人会争论使用snake_case还是camelCase。最近这个现象也开始舒解了,因为有PHP-FIG组织制定了相关的遵循标准。

4. Lack of Quality Packages

另外很多人批评PHP 没有够好的模块管理工具。例如我们知道,

Node.js 有NPM

Ruby 有Bundler/Gems

Python 有PIP

Perl 有CPAN

而过去的PHP 只有难用的PEAR。相对好用的PHP 模块管理工具也不是没有,只是过于分散不集中。例如,

CodeIgniter的Sparks

FuelPHP的Cells

Laravel的Bundles

CakePHP的Bakery

ZF2的Modules

Phil认为这个现象将会也会得到舒解。因为除了PHP-FIG组织制定的PSR-0标准外,也有Composer团队推出标准的模块管理计画。

5. Misconception

Phil 指出(编者注: Phil 同时也是Ruby 使用者),很多Ruby 开发者对PHP 的批评认知还停留在PHP 4 的时代。其实PHP 5 已改进非常多,甚至PHP 5.3 是一个大跃进。他认为很多人的评论还停留在7 年前的PHP。

Phil同时也说,有些人说PHP没有内置Web server是个很糟糕的事,但好消息是从PHP 5.4开始就内置built-in web server功能了。

6. You were doing it wrong

Phil 指出,很多人会说「You can mix MySQL, HTML and PHP in the same files. PHP is disgusting!」(编者译: 「你可以把MySQL, HTML 及PHP 同时放在一个文件里面,可见PHP 多么恶心」)。

但Phil 认为这个缺点可以由PHP Web framework 获得解决,同时他也认为如果Ruby 开发者在不使用Sinatra 或Rails 时是怎么解决这个问题的?或者Node.js 开发者不使用Express 或CanJS 时又是怎么解决的?(编者译:Phil 指的应该是「不要拿程序语言(PHP)来和Web framework (Rails 或Express) 来比较」)

7. Elitism

Phil 感慨的指出,现在很多人认为「不使用PHP 的人才酷」(编者注:Phil 言下之意不知是否也指「不要以为使用Rails 或Node.JS 就觉得很潮」?)

除了批评之外,我们该想想,「为什么现在还有那么多人使用PHP ?」。Phil 认为「没意外的话,就是气势(Momentum)」,他说根据统计,证明就是很多人使用PHP,也不否认他仍然使用PHP 的原因就是,相较于Ruby、Python 及Node.JS 而言, PHP 仍然拥有最大的市场。

最后Phil 认为,很多开发者都在追求「完美的语言」,但答案是「世界上没有完美的工具」,因此没有任何人应该「讨厌」任何程序语言。

翻译自:為什麼很多人討厭 PHP ?