2015年总结

前6个月在windows服务器上把一整套电商团购特卖系统开发并run起来

后6个月接触了很多

restful API开发模式开发

thinkphp+smarty、lumen、yii等框架下开发

phpUnit单元测试

jenkins自动化集成测试

自动打包发布脚本编写

gerrit git workflow

大用户量、大并发下如何防止商品超卖,如何提高并发量

redis、lua相关开发

vagrant+homestead搭建php开发环境

ELK logstash抓日志、elasticsearch做日志索引、kabana做数据分析

linux常见命令使用tailf 、wc、watch

PHP源码学习计划1

计划:通过3个月时间把php源码学习完毕

今晚我只看了一个库https://github.com/php/php-svn-helpers
这个库只有两个shell脚步文件
作用是我们从github迁出php代码后需要提交到svn时,把git代码库转换为对应的git-svn库

文件内容非常简单

适合初学shell、git命令的同学阅读

========
更新:我又看了一个库https://github.com/php/pecl-file_system-phdfs
这个是pecl库中的php操作hdfs(Hadoop)的扩展
目测功能单一,不会太复杂

采用的是php license 3.0

P3P之殇

P3P:Platform for Privacy Preferences (P3P) (https://www.w3.org/P3P/)
P3P 计划是由服务端告知浏览器一系列多选项问题的答案组成的策略。

P3P规范也包含有用于请求和传输P3P策略的协议.P3P协议所基于的HTTP协议与 Web 浏览器用来与 Web服务器进行通信的 HTTP 协议相同。
不论在何时设置cookie都可以用特定的HTTP报头来传送一个可选的 P3P 简洁策略。

引自:http://www.cnblogs.com/_franky/archive/2011/03/16/1985954.html

大部分查询P3P资料的朋友都是在解决跨域ajax请求和跨域读写cookie两个事的时候偶然知道了这个名词,所以我就不多说了,直接上结论,其他的大家可以参考官方网站以及其他资料。

for IE developers
一些企业应用都是IE only,用P3P解决跨域问题可行,前提是浏览器仅限于IE7~10,做法就是在页面返回的http header中增加一行
P3P:CP=
因为IE对P3P简洁策略的支持,属于搞笑级别的.根本不看内容。(PS:再度引用上文资料)

FOR OTHERS
别看P3P了,兼容性完全不行,项目理念也有安全风险,也未作为正式标准进入http协议内容,甚至我的《松鼠·HTTP权威指南》里一句话都没提过。

对于同网站不同二级域名下解决跨域ajax请求和跨域读写cookie,想要兼容现代浏览器、移动浏览器的朋友,下面是我们整理的一套可行方案
1.设置cookie的domain为一级域名,如.ffan.com,*.ffan.com,ffan.com,此时,浏览器中cookie可以在任一二级三级域名的页面、图片、接口地址中获取到
2.使用jsonp代替json,json仅在同域名,相对路径下可以请求,否则有跨域问题,为此除了jsonp外还可以考虑在json输出前设定response http header 中Access-Control-Allow-Origin: *,不过要注意的是不能设置多次Access-Control-Allow-Origin,否则浏览器仍然不识别。
jsonp的方案所有参数均通过get方式明文传输,Access-Control-Allow-Origin方案需要小心的设置header,但支持get、post两种,可以按需选择。

“image/png” 和 “image/x-png”有哪些区别?

referer: http://stackoverflow.com/questions/2086374/what-is-the-difference-between-image-png-and-image-x-png
前缀 x- 是非标准的 MIME 类型 (例如:未在 IANA注册). 所以可以认为 image/x-png 是 PNG 类型未被标准化之前使用的

6.3. New Content-Transfer-Encodings

Implementors may, if necessary, define private Content-Transfer-Encoding values, but must use an x-token, which is a name prefixed by “X-”, to indicate its non-standard status, e. g., “Content-Transfer-Encoding: x-my-new-encoding”. Additional standardized Content-Transfer-Encoding values must be specified by a standards-track RFC. The requirements such specifications must meet are given in RFC 2048. As such, all content-transfer-encoding namespace except that beginning with “X-” is explicitly reserved to the IETF for future use.

—RFC 2045 — Multipurpose Internet Mail Extensions, Section 6.3
This is also documented in the PNG specification. See FalseVinylShrub’s answer.

根据W3C关于PNG的标准 http://www.w3.org/TR/PNG/#A-Media-type

“image/png” 是PNG格式网络媒体类型的 MIME 类型 [RFC-2045], [RFC-2048].同时也建议支持识别 MIME 类型 “image/x-png”.
所以, 如果你打算上传或是提供一个 PNG 图片, 该用’image/png’. 另外, 处理上传后文件等其他情况应该两种 MIME 类型都支持.

由于IE前些年一直在用”image/x-png”上传,所以造成了一些开发上的困扰。

一行命令解决composer下载问题

一行命令解决composer下载问题: composer config -g repositories.packagist composer https://packagist.phpcomposer.com

===
2016-3-21 更新说明(http://pkg.phpcomposer.com/)
本镜像已经依照 composer 官方的数据源安全策略完全升级并支持 https 协议!请各位同学 按照下面所示的两个方法将 http://packagist.phpcomposer.com 修改为 https://packagist.phpcomposer.com

今天我把chrome的网络设置改成了模拟2G网络

今天我把chrome的网络设置改成了模拟2G网络

今天我把chrome的网络设置改成了模拟2G网络

大家好,我是一个php web开发人员,我今天开发效率很低,因为我的chrome老提示我『正在等待可用的套接字』。

页面打开极其缓慢,这还怎么愉快的写bug,不,debug。直到我忍无可忍,我Google了一下,原来浏览器对一个网址同时最多发起6个请求链接,可以通过chrome://net-internals/#sockets 实时查看,似乎这个设置是硬性设置,无法修改,我陷入了困境。

万万没想到我最后还是解决了这个问题,我发现关了开发者工具打开速度就恢复正常了,然后仔细看了下面板的参数才想起之前把网络设置改成了模拟2G网络

mac下安装php-memcached提示configure: error: memcache support requires ZLIB. Use –with-zlib-dir= to specify prefix where ZLIB解决办法

 

checking for the location of zlib... configure: error: memcache supportrequires ZLIB. Use --with-zlib-dir= to specify prefix where ZLIB 

brew install zlib
brew link --force zlib

默认用brew 安装zlib提示有可能会跟系统的zlib库冲突,没有吧zlib库link到系统目录
重新安装xcode,然并卵

xcode-select --installbrew install php{xx}-memcache

批量从服务器执行命令脚本

#! /bin/bash

machine_list=serverList

lineno=`cat $machine_list |wc -l`;

for((i=1; i<=lineno; i++)) {
line=`sed -n “$i p” $machine_list`;
machine=`echo $line | gawk -F” ” ‘{ print $1 }’`;
path=’/var/log/httpd/logs/lumen.log’;
file=`echo $path`;
echo “INFO: “$file”@”$machine;
ssh $machine “df -h;echo ;echo”;
}
exit 0;

原理就是循环一个ip列表
ssh并执行命令

优化lumen加载速度

通过xdebug+QCachegrind分析lumen一个项目里的某一接口

分析每一个时间较长或者调用次数较多的函数
先看了下route这块用到的是nikic/fast-route 其中按照官方文档介绍,动态路由比静态路由慢,所以项目路由设计时我们添加的都是静态路由,而项目自带一个欢迎页面的动态路由。

优化方案,干掉动态路由,静态路由函数优化:找到
vendor/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php
的addStaticRoute方法
其中为了验证添加的路由是否有效,每一条记录都做了循环校验,这里其实可以在开发环境中启用,线上干掉来提速。
注释代码
/*
if (isset($this->methodToRegexToRoutesMap[$httpMethod])) {

foreach ($this->methodToRegexToRoutesMap[$httpMethod] as $route) {
if ($route->matches($routeStr)) {
throw new BadRouteException(sprintf(
‘Static route “%s” is shadowed by previously defined variable route “%s” for method “%s”‘,
$routeStr, $route->regex, $httpMethod
));
}
}
}

*/

整个请求最重的就是mysql数据库操作了,其中prepare是pdo中做安全验证的必要组件,参考php手册

http://www.php.net/manual/de/pdo.prepare.php

http://stackoverflow.com/questions/1176352/pdo-prepared-inserts-multiple-rows-in-single-query
有说php5.6中array_push 比array_merge快很多

精简mac ox

忽然发现mbp的250GB硬盘只剩下20GB左右了,遂准备清理下硬盘,打开finder看一下几个常用目录右键查看简介,哪个目录的占用空间最大,先把应用程序里暗黑三给删掉了,mac下还是纯粹做开发机用的了,玩放到台机上去玩,应用程序里按文件大小排序,发现Xcode居然是个巨无霸,其他应用普遍在300MB以下,它却占了8GB,右键显示内容,进去后Contents/Developer/Platforms删掉watch、ios虚拟机的目录,反正就算开发我也会在真机上做的,删除,倾倒废纸篓,xcode尺寸直接少了5GB。应用程序最终占用了10~20GB,毕竟常用的软件还是不少。

虚拟机是我的必备装备,把多余的linux和windows虚拟机删掉,80GB 腾出来了….

homebrew缓存路径

由于在终端下载速度太慢,遂考虑先通过地址下载文件后手动放到 缓存目录
$wget https://homebrew.bintray.com/bottles/mysql-5.6.26.yosemite.bottle.tar.gz
$cd /Library/Caches/Homebrew/
$mv ~/mysql-5.6.26.yosemite.bottle.tar.gz ./
$brew install mysql

done!

==> Downloading https://homebrew.bintray.com/bottles/mysql-5.6.26.yosemite.bottle.tar.gz
Already downloaded: /Library/Caches/Homebrew/mysql-5.6.26.yosemite.bottle.tar.gz
==> Pouring mysql-5.6.26.yosemite.bottle.tar.gz
==> /usr/local/Cellar/mysql/5.6.26/bin/mysql_install_db –verbose –user=zouyi –basedir=/usr/local/Cellar/mysql/5.6.26 –
==> Caveats
A “/etc/my.cnf” from another install may interfere with a Homebrew-built
server starting up correctly.

To connect:
mysql -uroot

To have launchd start mysql at login:
ln -sfv /usr/local/opt/mysql/*.plist ~/Library/LaunchAgents
Then to load mysql now:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
Or, if you don’t want/need launchctl, you can just run:
mysql.server start
==> Summary
🍺 /usr/local/Cellar/mysql/5.6.26: 9854 files, 339M

Mac下MySql卸载方法

Mac下MySql卸载方法

mac下mysql的DMG格式安装内有安装文件,却没有卸载文件……很郁闷的事。
网上搜了一下,发现给的方法原来得手动去删。
很多文章记述要删的文件不完整,后来在stackoverflow这里发现了一个遗漏的地方,所以将完整版记述在这里,以供查阅。
先停止所有mysql有关进程。

最后这条很多文章都丢了,切记切记。

 

sudo rm /usr/local/mysql sudo rm -rf /usr/local/mysql*sudo rm -rf /Library/StartupItems/MySQLCOM sudo rm -rf /Library/PreferencePanes/My*vim /etc/hostconfig and removed the line MYSQLCOM=-YES-rm -rf ~/Library/PreferencePanes/My*sudo rm -rf /Library/Receipts/mysql*sudo rm -rf /Library/Receipts/MySQL*sudo rm -rf /var/db/receipts/com.mysql.*

Incompatible implementation of send() in Client / ClientInterface (phpunit)?

Incompatible implementation of send() in Client / ClientInterface (phpunit)?
开发环境 lumen
在phpunit执行测试时报错

PHP Fatal error: Declaration of GuzzleHttp\Client::send() must be compatible with GuzzleHttp\ClientInterface::send(GuzzleHttp\Message\RequestInterface $request) in /Users/michael/Code/contrib/guzzle/src/Client.php on line 26

https://github.com/guzzle/guzzle/issues/1214

找到报错的解决帖

发现自己的项目版本挺新的

于是在autoload加上加载文件的文件名输出

发现加载了global 文件
框架安装的时候是全局安装的
composer update却只更新了本项目
找到global的composer。json文件,把phpunit之外的项目都删掉,global update 解决问题

Console Wars – PHP CLI Libraries 命令行战争 - PHP的终端类库

http://www.sitepoint.com/console-wars-php-cli-libraries/

三大PHP终端类库

每个都zhendui不同用户类型用户喜好提供了不同的方法

  • Symfony console 测试稳定、鲁棒性好、文档丰富、能解决大部分问题 
  • Hoa console 更专业,适合做控制窗口、鼠标、指针等
  • Webmozart console 是最新的库,马上要出稳定版本了,适合那些很快变大的新项目

私有Composer代理服务器 Toran Proxy 安装使用教程(1)

这几年新的php包管理工具Composer火起来了,但是无奈被🔫。。。。

还好我们可以把文件同步到自己的服务器缓存起来,这样xuy组件依赖时就不用再去考虑这个问题了。

安装完toran proxy 安装jiem有个google的网址会卡住,直接暂停页面就出来了,hul这个问题

我们自己用,☑️This instance is for personal use

packagist.org是一个php组件包查询下载的站点,我们选上

缓存选项

考虑到硬盘小,还是lazy模式吧

git settings 等需要时再配置

安装

搭建自己的公开CentOS源

背景:公司的网络实在是有够变态的,有层http代理,没法好好上网,装个linux做实验的时候各种软件下不了,不太懂运维,偶然想到去看局域网里的linux服务器是怎么更新的,果然挖出一个内网的yum源,顺便就想到自己搭建一套http源,从公网里定期同步更新一下,用到的时候就很爽了。

上手:

首先呢,把这个服务器扔到虚拟机里了,远程操作和扩展硬盘会比较容易一些,而且平时挂在那也不会费太多资源。

安装了Centos 6.5

分配两个网卡(一个自动,一个对接局域网)和两块硬盘,其中一个硬盘挂载到/var

找到了国内的高校源 bit、ustc

http://mirror.bit.edu.cn/web/

http://mirrors.ustc.edu.cn/

他们都提供了rsync服务

在linux上安装rsync客户端

我把目录放在/var/www/pub下

依次创建目录层级,只同步我需要的源可以有效减少磁盘占用,不然一个源同步下来我的硬盘就报废了

rsync -avrtH rsync://mirrors.ustc.edu.cn/centos/6/ /var/www/pub/centos/6/
rsync -avrtH rsync://mirrors.ustc.edu.cn/rpmfusion/free/el/ /var/www/pub/rpmfusion/free/el/
rsync -avrtH rsync://mirrors.ustc.edu.cn/rpmfusion/nonfree/el/ /var/www/pub/rpmfusion/nonfree/el/
rsync -avrtH rsync://mirrors.ustc.edu.cn/epel/6Server/x86_64/ /var/www/pub/epel/6Server/x86_64/

同步了几天,同步完成后看了一下虚拟机的硬盘文件还不到100GB,比预想的小很多,分配磁盘时专门划出了200GB呢。

安装apache  yum install -y httpd

关闭selinux  vim /etc/selinux/config selinux=disabled

最后有个软件createrepo可以指定目录生成索引,大家自行百度就知道了

ProtoBuf

http://blog.163.com/jiang_tao_2010/blog/static/12112689020114305013458/

欢迎来到protocol buffer的开发者指南文档,一种语言无关、平台无关、扩展性好的用于通信协议、数据存储的结构化数据串行化方法。

本文档面向希望使用protocol buffer的Java、C++或Python开发者。这个概览介绍了protocol buffer,并告诉你如何开始,你随后可以跟随编程指导( http://code.google.com/apis/protocolbuffers/docs/tutorials.html )深入了解protocol buffer编码方式( http://code.google.com/apis/protocolbuffers/docs/encoding.html )。API参考文档( http://code.google.com/apis/protocolbuffers/docs/reference/overview.html )同样也是提供了这三种编程语言的版本,不够协议语言( http://code.google.com/apis/protocolbuffers/docs/proto.html )和样式( http://code.google.com/apis/protocolbuffers/docs/style.html )指导都是编写 .proto 文件。

windows安装vagrant 以及 laravel homestead[2]

安装 Homestead
由于windows下和linux命令不尽相同
实际上要做的是在你的用户目录下新建一个.homestead目录
然后把Homestead/src/stubs目录的文件全拷贝过去即可
配置文件Homestrad.yaml参考如下

ip: “192.168.10.10”
memory: 2048
cpus: 1
provider: virtualbox

authorize: C:\Users\zy\Homestead\test.key.pub

keys:
– C:\Users\zy\Homestead\test.key

folders:
– map: C:\Users\zy\Homestead\test
to: /home/vagrant/Code

sites:
– map: homestead.app
to: /home/vagrant/Code/Laravel/public

databases:
– homestead

大型网站架构设计学习笔记

最近买了本《大型网站系统与JAVA中间件实践》曾宪杰。
做了这么多年php,为了学习技术,还是只能找java的书籍,不得不说是php开发者的悲哀。
分布式系统基础知识
计算机的五要素CPU、内外存、输入输出设备,分布式系统要逐一对应
线程与进程的执行模式
阿姆达尔定律:多核
互不通信的多线程、共享容器协同的多线程、通过事件协同的多线程、多进程

OSI模型、TCP/IP模型
网络IO实现方式 BIO、NIO、AIO

————————

交易网站基本三部分业务功能:用户、商品、交易
APP server
|
*
APP server + DB server
|
*
APP server * N + DB server
|
*
负载均衡 + APP server *N + DB server +处理session(sitcky、同步、集中存储、cookie based
|
*
数据库读写分离,增加读库
|
*
增加搜索引擎
|
*
增加缓存(页面缓存、数据缓存)
|
*
引入分布式存储系统
|
*
专库专用、数据垂直拆分
|
*
单机数据水平拆分
|
*
应用拆分
按功能拆分
服务化
中间件

替换wordpress 常用公共js库

http://www.bootcdn.cn/

我的wordpress装了七牛云存储的插件,里面可以勾选使用360提供的useso.com的库,其中jquery用的staticfiles.com的cdn,我所处的网络很多网站莫名奇妙被屏蔽,手动更改了插件的内容

这里要赞一下wordpress 在后台可以直接修改代码,太方便了

wordpress gravatar头像不显示的解决方法

function mytheme_get_avatar($avatar) {
$avatar = str_replace(array(“http://www.gravatar.com”,”0.gravatar.com”,”1.gravatar.com”,”2.gravatar.com”),”gravatar.duoshuo.com”,$avatar);
return $avatar;
}
add_filter( “get_avatar”, “mytheme_get_avatar”, 10, 3 );

放到模板函数 functions.php

怎么删除CSS文件开始的  符号

mb_internal_encoding(‘UTF-8’);

通过php – How do I remove  from the beginning of a file? – Stack Overflow.

How do I remove  from the beginning of a file?

在做文件合并的时候发现css文件合并后总是不对,于是首先把换行压缩为空格的代码屏蔽,发现仍有部分样式不对,用w3c css验证工具发现某行样式定义前有乱码,表现为#topNav {}

http://jigsaw.w3.org/css-validator/validator

通过查询发现是utf8文件的bom头在作怪,把源文件的bom头去掉就好了

Linux下GBK->UTF-8文件编码批量转换命令

Linux下GBK->UTF-8文件编码批量转换命令 – a280606790的专栏 – 博客频道 – CSDN.NET.

在工作中,经常会遇到使用操作系统不一样的环境,从而导致在不同环境下的文件编辑的编码是不一样的,Windows默认是GBK编码格式,Linux默认是UTF-8的格式,这样就会出现把GBK编码的文件拷贝到Linux下出现乱码情况,很是让人头疼,下面给大家介绍下GBK->UTF-8文件编码批量转换。

Linux命令-enca 查看文件的编码

Enca语法

Usage: enca [-L LANGUAGE] [OPTION]… [FILE]…
enconv [-L LANGUAGE] [OPTION]… [FILE]…
Detect encoding of text files and convert them if required.
Enca用法

$ enca -L zh_CN file 检查文件的编码
$ enca -L zh_CN -x UTF-8 file 将文件编码转换为”UTF-8″编码
$ enca -L zh_CN -x UTF-8 file1 file2 如果不想覆盖原文件可以这样
除了有检查文件编码的功能以外,”enca”还有一个好处就是如果文件本来就是你要转换的那种编码,它不会报错,还是会print出结果来, 而”iconv”则会报错。这对于脚本编写是比较方便的事情。

转换单个文件的编码

$ enca -L none -x utf-8 index.html
转换多个文件的编码

$ enca -x utf-8 *
Linux文件名编码批量转换–convmv

Convmv语法

$ convmv -f 源编码 -t 新编码 [选项] 文件名
Convmv 常用参数

-r 递归处理子文件夹
–notest 真正进行操作,请注意在默认情况下是不对文件进行真实操作的,而只是试验。
–list 显示所有支持的编码
–unescap 可以做一下转义,比如把%20变成空格
示例

转换一个文件由GBK转换成UTF-8

convmv -f GBK -t UTF-8 –notest utf8 filename
GBK->UTF-8文件编码批量转换脚本

$ find default -type f -exec convmv -f GBK -t UTF-8 –notest utf8 {} -o utf/{} \;
使用iconv 转换

Iconv语法

iconv -f encoding -t encoding inputfile
示例

单个文件转换

$ iconv -f GBK -t UTF-8 file1 -o file2
批量转换

$ find default -type d -exec mkdir -p utf/{} \;
$ find default -type f -exec iconv -f GBK -t UTF-8 {} -o utf/{} \;
这两行命令将default目录下的文件由GBK编码转换为UTF-8编码,目录结构不变,转码后的文件保存在utf/default目录下。

linux 下安装程序为什么需要重新编译?

linux 下安装程序为什么需要重新编译,直接使用可执行文件不行么?
这个疑问一直以来存在我的脑海中。于是今天搜索了一下。
http://www.jb51.net/article/47457.htm
这篇文章告诉我“编译主要是为了能让软件运行更快”的经验竟然不是真的。

软件需要编译安装的真实理由有如下3点:
1.软件在编译期间需要配置
2.软件需要统一安装路径
3.需要最新的版本

但我认为这些理由都不是理由啊。
1.配置模块我可以在使用过程中配置,扩展,调整
2.统一安装路径,在windows下的傻瓜安装向导里主要就是配置路径,但我没看到统一安装路径需要从头编译的道理,实际上安装完了软件我移动到另外的目录里,调整下配置文件,就希望它能继续运行
3.需要新的版本,大家一边宣称开源可以依靠社区的力量,一边却各自为政,全球linuxer重复编译的时间够造好几次人造卫星了。

于是我看到了这样的解释
http://bbs.csdn.net/topics/330116718

这是由于Linux系统的程序相互信赖造成的。比如某个程序依赖于其它一些库,而且版本也有要求,要想直接用,需要在编译时对信赖关系进行调整。./configure就是起这个作用的。

RPM包,DEB包是二进制了,也有依赖,一般情况下,二进制包只对应着特定的发行版。因为,在特定的发行版中,库之间的信赖关系是固定的。比如想把redhat5.2的rpm包安装到fedora上,就不一定成功。

初学者可以使用某个发行版,就不需要自己编译程序了。直接从官网上下载二进制的发行包就行了。有的发行版有在线安装软件的功能,比如redhat和fedora用的yum,unbuntu用的apt-get等

我深深感受到了开源界的恶意,因为商业应用的windows操作系统上开发的软件,虽然老版本的软件在新版本操作系统下不一定兼容,但是通过新出的编译工具打包编译后可以向下兼容,至少看起来是虽然windows有众多版本,但是在任一版本操作系统下的指定版本编译工具打包后的程序是可以在N个版本操作系统中兼容运行的。

当网上的开源卫士宣称全球大部分web服务器跑着linux,而我看到的是周围小公司仍然在使用略贵一些的windows虚拟主机、VPS托管网站时,我更是深有感触。

我们需要行动起来,建立起一个对社会有用的云服务网站,大V们通过网站可以节省重复在本机编译的时间,运维狗通过网站可以快速获取自己需要的可用二进制包,把工作交给云端,我们喝茶去。

一个小网站的开发上线过程是这样的:
开发 -> 更新网站
一个大型线上网站的开发上线过程是这样的:
开发 -> 提交版本库 -> 生成tag -> 线上自动化测试程序 -> 打包生成增量更新 -> 部署

不论大小网站,一个windows服务器上apache新增模块的过程是这样的:
下载指定版本php_mysql.dll -> 放到指定目录 -> 修改apache配置文件 -> 重启服务
不论大小网站,一个linux服务器上apache新增模块的过程是这样的:
下载指定版本php源码 -> phpize编译生成php_mysql.so -> 放到指定目录 -> 修改apache配置文件 -> 重启服务

那么对于不论用多久windows的人,换台机器,重复操作也是很轻松的一件事;
那么对于不论用多久linux的人,换台机器,重复操作也是很花时间的一件事。

半吊子的危险性——误以为PHP5.3以后取消了$GLOBALS超全局变量

今年之前一直在使用php 5.2做开发,很早前就知道5.2升级5.3是个坎,网上还有很多程序升级到5.3有困难。但作为一个半吊子,居然从来没好好看过升级说明,只知道global啥玩意的不支持了,并想当然的理解成了5.3之后再没有全局变量可用了。

http://php.net/manual/zh/migration53.php

今天下点功夫逐一点一下各个升级特性,放到文末供参考

PHP 5.3.x 的大多数改进对现有代码没有影响。需要注意的是有一些不兼容和新功能,在生产环境中切换 PHP 版本需要先行测试代码。

下面说一下我半吊子想当然以为不能用的功能。

register_globals取消了这个开关
不是说取消了部分global

这个开关开的时候$_POST\$_GET\$xxx、cookie、session数组里的值会注册到对应的变量去
另外取消了一些HTTP_VAR_POST这样的变量
全用简写$_POST这种表示
global $variable; 以及$GLOBALS是在任何版本的php中都可用的

以下是测试程序。

实际环境测试运行发现从5.2、5.3、5.4、5.5、5.6各个版本php表现看都是一致的,没有问题。

另外之前想当然的因素之一也是这个文章闹的。
http://www.hack1990.com/cat_2/1273.html

再回顾以下经典的php自动全局变量漏洞
才明白开启register_globals之后才会有这个问题,php5.4及以后这个开关消失,就再不会有这个问题了

——————————————————————

http://www.haidx.com/win-apache-php5-3-x-fastcgi-zend-guard-loader.html
http://www.php.net/manual/zh/appendices.php

【不向下兼容的变化】
给函数传递了不兼容的参数时将返回 NULL,之前是返回FALSE,但有一些例外,比如函数 get_class() 在出现错误时将会返回 FALSE。
realpath() 现在是完全与平台无关的. 结果是非法的相对路径比如 __FILE__ . “/../x” 将不会工作.
数组函数 natsort(), natcasesort(), usort(), uasort(), uksort(), array_flip(), 和 array_unique() 将不再接受对象作为参数, 在将这些函数应用于对象时, 请首先将对象转换为数组.
函数内 include 或者 require 一个文件时,文件内 将不能使用 func_get_arg(), func_get_args() 和 func_num_args() 函数。
最小的 Windows 支持版本是 Windows XP SP3; Windows 98, ME, 2000 和 NT4 将不再被支持.

【被弃用的 INI 指令】
define_syslog_variables
register_globals
register_long_arrays
safe_mode
magic_quotes_gpc
magic_quotes_runtime
magic_quotes_sybase

【被弃用的函数】
call_user_method() (使用 call_user_func() 替代)
call_user_method_array() (使用 call_user_func_array() 替代)
define_syslog_variables()
dl()
ereg() (使用 preg_match() 替代)
ereg_replace() (使用 preg_replace() 替代)
eregi() (使用 preg_match() 配合 ‘i’ 修正符替代)
eregi_replace() (使用 preg_replace() 配合 ‘i’ 修正符替代)
set_magic_quotes_runtime() 以及它的别名函数 magic_quotes_runtime()
session_register() (使用 $_SESSION 超全部变量替代)
session_unregister() (使用 $_SESSION 超全部变量替代)
session_is_registered() (使用 $_SESSION 超全部变量替代)
set_socket_blocking() (使用 stream_set_blocking() 替代)
split() (使用 preg_split() 替代)
spliti() (使用 preg_split() 配合 ‘i’ 修正符替代)
sql_regcase()
mysql_db_query() (使用 mysql_select_db() 和 mysql_query() 替代)
mysql_escape_string() (使用 mysql_real_escape_string() 替代)
废弃以字符串传递区域设置名称. 使用 LC_* 系列常量替代.
mktime() 的 is_dst 参数. 使用新的时区处理函数替代.

【新参数】
PHP 核心:
clearstatcache() – 新增 clear_realpath_cache 和 filename 参数.
copy() – 新增流环境参数 context.
fgetcsv() – 新增 escape 参数.
ini_get_all() – 新增 details 参数.
nl2br() – 新增 is_xhtml 参数.
parse_ini_file() – 新增 scanner_mode 参数.
round() – 新增 mode 参数.
stream_context_create() – 新增 params 参数.
strstr() 和 stristr() – 新增 before_needle 参数.

json:
json_encode() – 新增 options 参数.
json_decode() – 新增 depth 参数.

【新的全局常量】
__DIR__
__NAMESPACE__
E_DEPRECATED
E_USER_DEPRECATED
INI_SCANNER_NORMAL
INI_SCANNER_RAW
PHP_MAXPATHLEN
PHP_WINDOWS_NT_DOMAIN_CONTROLLER
PHP_WINDOWS_NT_SERVER
PHP_WINDOWS_NT_WORKSTATION
PHP_WINDOWS_VERSION_BUILD
PHP_WINDOWS_VERSION_MAJOR
PHP_WINDOWS_VERSION_MINOR
PHP_WINDOWS_VERSION_PLATFORM
PHP_WINDOWS_VERSION_PRODUCTTYPE
PHP_WINDOWS_VERSION_SP_MAJOR
PHP_WINDOWS_VERSION_SP_MINOR
PHP_WINDOWS_VERSION_SUITEMASK

【新类】
日期/时间:
DateInterval
DatePeriod

Phar:
Phar
PharData
PharException
PharFileInfo

【INI 文件处理改变】
移除了 zend_extension_debug and zend_extension_ts. 使用 zend_extension 指令来加载全部 Zend 扩展.
session.use_only_cookies 默认被设置为 “1”(打开).

【其他改变】
如果会话启动失败, session_start() 现在将返回 FALSE.
getimagesize() 现在支持 icon 文件 (.ico).

【禁用global】
$SERVER_xxx、$HTTP_xxx等变量替换成$_SERVER[‘SERVER_xxx’]

记一次openssl生成证书、私钥、公钥

6a2f856e36fc3562ccf765dced56b2b7
之前跟银联对接时,由于我是用PHP做开发的,比较较真,一开始没有用他们提供的工具去做,绕了点弯路。
第一步就是涉及加解密问题,需要用到私钥公钥,实际上用openssl可以很方便的随意生成,不过命令太多,如果你不是用正确的命令可能得到的文件也相去甚远。

openssl genrsa -out rsa_private_key.pem 1024
生成一个私钥文件,这个文件你自己要保存好,他是后面所有东西的基础,他如果没了整套数据都要换。
openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout
生成一个公钥文件,我们知道加密传输就是靠公钥做加密及验证

如果要对方环境可以验签测试,私钥需要多转换一步
openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt
这样这个新产生的私钥可以发给对方使用

怎么用

ServerA用第一步产生的私钥加密数据传给ServerB,ServerB用第二步产生的公钥做验签
同理,ServerB加密后发数据给ServerA时,SeverA可以用B提供的公钥做验签。

博客服务器软件升级

花了点时间将nginx、php、mysql统统升了一遍级。
nginx升级到1.6.2
php升级到5.5.20
mysql升级到5.6.22失败,原因是编译中内存不足,遂改升级到5.5.37.

升级前今天白天请求首页要花7s以上,现在请求首页只要2s多,性能大幅度提升。

记录用支付宝做团购支付的蛋疼经历

145915_82_1310458426_83是有多蛋疼呢?
由于是第一次做,只是大概知道用即时到账支付,用户把钱付到网站运营商就行了。
刚开始做的时候参考了N个团购系统,看起来挺美,没琢磨这块,等到开始测试支付功能的时候,客户说支付不了。
跳转到支付宝总是提示来路不正确,遂要来客户的支付宝账户进入商家服务,一看有三种支付产品,即时到账、双接口、担保交易支付。
客户申请的是双接口,网站程序走的是即时到账接口。于是开始跟客户口水仗说不是即时到账处理不了,然后客户申请即时到账产品没批下来,支付宝不允许团购类网站申请即时到账接口…。
于是把双接口只做了即时到账的接口处理,担保交易的用户要是付了钱也是到支付宝,网站不发货,钱过段时间也能回到用户手里,网站挂个提示得了。
12月底,支付宝停止双接口的申请,再后来支付宝的技术支持论坛访问不了了,然后现在在搞什么商家服务中心改版。
好吧,总之把商品的即时到账付款走通了以后,客户说得考虑批量给用户退款,我说接口没有提供,他们不信,然后我找到支付宝在线技术支持机器人,回复如下:

若买家付款选择的是担保交易,只能登录支付宝帐号,在交易管理里面去操作,退款正常流程是:买家申请退款-等待卖家确认-卖家同意,等待买家退货-等待卖家收货-退款成功。(若已确认收货不允许退款)
若家付款选择的是即时到帐,付款完成之后不允许退款。

网上程序做的都是即时到账接口的退款程序,我摔…..

所以团购类网站只能申请双接口和担保交易支付两种接口来和网站集成,而如果用户用双接口即时到账付款后想要退款,得联系商家再由商家手工确认一遍后手工退款,而担保交易支付更坑,商家得进支付宝账户查账单后点退款….

至此做这个团购支付暂时到了一个门槛了,下一步怎么走,大家用支付宝很习惯,如果换其他的支付方式用户量很小,支付没法进行下去了。

被支付宝绑上了战车又被踢下去是种什么样的感受…

15年,新的起点

一路走来磕磕绊绊,技术一度停滞不前。今天起从头做起。
推荐PHPer在windows下采用phpstudy作为开发环境,最靠谱的功能,一键切换PHP版本,方便研究不同版本php间的差异。
比如今天看namespace是php5.3开始有的,那么在5.2的环境下

我的14年总结

思维乱跑,昨天的稿子丢了后就没回来。重新整理一下吧。

14年给我映像很深的事由那么几件,WordPress升级很频繁就是一件,因为我很懒,这一年的博客数量少的可怜,更别提优质内容了,但每次登陆后台都有几个升级要点击。3.8到4.1四个大分支七个版本。这期间,我的一个WP插件提示我5.2的php他不支持了,为此我把php从5.2一口气升级到php5.5。
年会总是酒不醉人人自醉的,今年年初1月17日的年会是在江南赋举办的。我带着一票20个或实习或转正的学生们从帝都的东七环到帝都的西四环,横跨11环了。
事业刚刚起步,我被抽壮丁了,内部重点项目猛于虎,领导们不爱担责任、不爱出方案,只负责给我们鼓劲,让我们把竞争对手打跑。这一场仗我们打了半年,最后还是打赢了,为何?我们给客户先装上了一套测试程序,配置好了一切,只等他们试用反馈,试用反馈,直到尘埃落定。

————
刚才被搜狗输入法给打断了,他告诉我我已经打了126852字,相当于一本《我的地坛》。我的打字速度不快,38字每分。用到打字的地方不多,我没有登录输入法账户的习惯,这个电脑也是今年5月份后换到手的,除去每月一篇2000字总结外,估计8成打字都是在跟客户撕逼,2成是在写代码注释。这样就符合28定律了,你八成的时间八成是浪费在没啥意义的事上了。

——————
都说今年很忙碌,忙到什么程度呢?1周没回家?no,远远不够。1个月都住酒店,4点半下班去吃海底捞,然后吃到5、6点看日出。又或者code到趴在办公室桌上睡一夜。到底是什么支撑我度过来的呢?

————————
一度人员很足却没事做,一度人员紧缺却招不到人,我感觉我错过了什么,回想起来,当我出现这两个情况的时候,我仍旧坐以待毙,只闷着头赶着项目。明年我要在工作时间把管理的书多看几本。

——————————
今年看着大圣、XX都开始搞前端了,而我则被评为最不可能在前端有所进步的人,只能在无尽的业务中苦苦挣扎了。
是的,今年做的业务太多了,政府、事业单位、学校、部队、房地产公司、广告公司、商务公司、交通、金融每一个领域都有我的身影,我一边给公文套上红头,一边看着时间表绘制燃尽图,一边整理教师的资料,一边看着指纹身份认证,一边捣鼓cas SSO,一边拿pos机刷卡玩,一边遥控摄像头,一边通过支付宝担保交易测试团购。这样的我撕裂了又揉碎了又粘起来了。最后我成了泥。

————————————
你知道我不是个高手,你没想到的是我连个新手都不是。
PHP+mysql可以快速实现很多应用场景,但我们学的用的终归浅显。

今年又接触了几个新东西,nodejs和redis。
前者,我们搞了个大棒的雏形,然后就没有然后了。
后者,我们压了一下,发现windows下果然很慢,存储是顺序的,插入了想再排个序有点难。

LaravelPHP,参与了一把汉化工作,不过人家没屌我。

SeaJS,看明白怎么用require做加载器了,其他的还不会。

这一年技术上的知识积累太少,大概一年都在干活而没想为什么要干,干的是什么,怎么干能更好。

——————————————————
先规划下未来。
我一直有个造轮子的念头,明年我给自己定下一个造轮子计划,查漏补缺,旁征博引,拿来主义,造一套PHP的MVC框架,我对他的期待有三点,1每一次代码改进都通过git版本控制。2每一个可发布版本都具备可简单好用的特性。3在第三个大版本发布后我基本掌握Yaf相当的开发能力。
时间上没有苛求,15年力争完成第一个版本(易用、好改的ORM;简单、好记的mvc路由;完全没难度的模板系统),16年第二个版本(高效的ORM),17年(想不到那么远)

redis初探

redis可以作为代替memcached的缓存方案。
redis的计数器可以做量子增减
redis可以快速存储排行榜等业务数据。

和Memcached类似,但是解决了断电后数据完全丢失的情况
Redis 不适合作为海量数据存储方案. Redis 适合在数据规模较小, 性能要求较高的条件下应用。
参考资料:
http://os.51cto.com/art/201210/361909.htm

git关于文件权限修改引起的冲突及忽略文件权限的办法

http://www.01happy.com/git-ignore-filemode/

项目上用git管理代码,由于开发机器web环境是www用户、文件管理和phpstorm开发工具是用user用户,不同用户间权限问题总是影响效率,干脆全改成777,结果git提交时变成所有文件全部要提交,经查找到如上文章。
在项目目录下
git config core.filemode false

cat .git/config

PDO防注入原理分析以及使用PDO的注意事项

http://zhangxugg-163-com.iteye.com/blog/1835721


setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

$st = $pdo->prepare("select * from info where id =? and name = ?");
$id = 21;
$name = 'zhangsan';

$st->bindParam(1,$id);
$st->bindParam(2,$name);
$st->execute();
$st->fetchAll();
?>

三、使用PDO的注意事项
知道以上几点之后,我们就可以总结使用PDO杜绝SQL注入的几个注意事项:
1. php升级到5.3.6+,生产环境强烈建议升级到php 5.3.9+ php 5.4+,php 5.3.8存在致命的hash碰撞漏洞。

2. 若使用php 5.3.6+, 请在在PDO的DSN中指定charset属性

3. 如果使用了PHP 5.3.6及以前版本,设置PDO::ATTR_EMULATE_PREPARES参数为false(即由MySQL进行变量处理),php 5.3.6以上版本已经处理了这个问题,无论是使用本地模拟prepare还是调用mysql server的prepare均可。在DSN中指定charset是无效的,同时set names 的执行是必不可少的。

4. 如果使用了PHP 5.3.6及以前版本, 因Yii框架默认并未设置ATTR_EMULATE_PREPARES的值,请在数据库配置文件中指定emulatePrepare的值为false。

那么,有个问题,如果在DSN中指定了charset, 是否还需要执行set names 呢?
是的,不能省。set names 其实有两个作用:
A. 告诉mysql server, 客户端(PHP程序)提交给它的编码是什么
B. 告诉mysql server, 客户端需要的结果的编码是什么
也就是说,如果数据表使用gbk字符集,而PHP程序使用UTF-8编码,我们在执行查询前运行set names utf8, 告诉mysql server正确编码即可,无须在程序中编码转换。这样我们以utf-8编码提交查询到mysql server, 得到的结果也会是utf-8编码。省却了程序中的转换编码问题,不要有疑问,这样做不会产生乱码。

那么在DSN中指定charset的作用是什么? 只是告诉PDO, 本地驱动转义时使用指定的字符集(并不是设定mysql server通信字符集),设置mysql server通信字符集,还得使用set names 指令。

如果图片丢失,可以发邮件至zhangxugg@163.com, 索取PDF版本。

我真想不通,一些新的项目,为何不使用PDO而使用传统的mysql_XXX函数库呢?如果正确使用PDO,可以从根本上杜绝SQL注入,我强烈建议各个公司的技术负责人、一线技术研发人员,要对这个问题引起重视,尽可能使用PDO加快项目进度和安全质量。

不要再尝试自己编写SQL注入过滤函数库了(又繁琐而且很容易产生未知的漏洞)。

为什么要抛弃IE7

IE6基本上已经扔进垃圾箱了。
今天看看IE7这个怪物。
在大量的公司内部网络里XP系统几乎是还要再服役5~10年的节奏,所以IE升级到头也只能到IE8,不得不感慨只兼容到IE8想必也是极好的。

到底IE7和IE8差在哪?我得慢慢思考总结下。

1.IE7这个怪物对开发者非常不友好,js报错的行数总是不准,而且还没有开发者工具。

2.js对象里的最后一个逗号
var js_object = {a:1,b:2,c:3,};

过去知道如果对象里最后意外加了一个逗号低版本浏览器是不兼容的,专为此事查了一下,只有IE7及以下的版本IE会报错,IE8及以上、Firefox、Chrome都是OK的。所以如果升级到IE8,所有代码中写js遇到这个逗号再也不用考虑了。

3.IE6、IE7的getElementsByName()和getElementById() bug
一些码畜在IE中调试通过的代码就不再测试其他浏览器兼容性
会有很多表单中直接用getElementById来取值
稍微懂行一些的会改成
实际上在IE7都OK,到了IE8下就跪了
参考网址:http://www.cnblogs.com/peach/archive/2009/01/24/1380606.html

4.

记国际化语言包系统设计及GlotPress安装使用心得

话说没有google就没有这篇文章,连续两天两夜的奋战终于搞妥了i18n语言包翻译的工作环境glotpress。
1.背景
原有的系统由于国际化需要,采用gettext技术对系统中涉及语言的地方都做了处理,方便了使用poEdit直接从源码中提取源文字模板pot的工作。但涉及到其他国语言的翻译仍需要各个语言的翻译根据我们导出的execel逐条翻译。面对一个成型的系统近2W条词条的翻译工作,量还是很大的,而且产品升级后新增词条的翻译如何整合并快速生成语言包文件是一个大问题。
2.技术分析
gettext技术通过设置语言的mapping实现替换的原理并不难以理解,poedit利用正则从代码提取字符也是很简单的逻辑。
GoOgle到gettext工具包中含有msgfmt,msgunfmt分别可以把po文件压成mo文件,把mo文件再解压成po文件。po文件用文本编辑器打开后也很好理解规则,一条原文对应一条翻译,多行的条目首行两个“,后续每行用“”引起来,每条翻译间空一行。
上面两个工具的windows版本官方的release库中也有下载,注意要把tool和runtime的都下载了,而且还得去下iconv的可执行文件,合在一起就木有报错了。
3.系统架构
为了实现更友好的处理,我希望能把现有的语言包全存到数据库中,按需提取且能快速增加,要是能实现自动翻译就更好了。
那么从已知的gettext技术结合php、mysql来处理,思路为利用gettext把已有的mo文件还原成po文件,再用php读取po文件处理后逐条存入数据库,翻译时调用在线的api传入要翻译的原文和原文语言和目标语言,将返回的文字存入相应语言的相应条目内。
按这个思路搞了一晚基本实现了已有的数据存入数据库以及读取。
4.阶段总结
照此开发下去一套系统预计需要几十天建成,劳产率太低,决定暂停。
这时不甘心的我想起来N年前搞bbpress时在一个大神的博客链接的系统内做过在线的插件编辑,那时自己懵懵懂懂,就记得wordpress的官方插件至少都实现了几十个国家的机器语言翻译版本的语言包。(怎么知道是机器翻译的,这个一看就知…)N年前就有的技术,现在应该由成型系统了,于是各种Google,结合记忆确定了这个大神叫做Gautam Gupta,看他github照片居然是阿三哥。他的博客多年后彻底改造了,我找不到原来的系统入口,于是只得上bbpress官方网站找线索,终于在wordpress官网上找到一款将glotpress的开源软件,十来年居然还没有stable的意思…
————————
第一场战役无疾而终….
5.glotpress
既然找到了这个家伙的存在,我满心想着功能强大、易用等名词,但google了一把心凉了半截,这个软件是个小众软件,使用群体并不大,想找篇正儿八经的安装使用文章都没有,继续在国外网站找效果居然一样不明显。不过好在是开源软件,代码量也不大,结构和wordpress也很像,看了看,捣鼓了半天也就搭起来了。

1.使用admin,密码a登录
2.创建项目
3.建立翻译版本
4.导入翻译文件。这个时候如果mo文件速度显然会比po慢,而两种文件导入都很慢,有的时候导入到一半就会报错,这个时候再导入几次应该就能导入完成(导入过的就不再导入了),这里我一上来还犯了一个错,在繁体的语言包里导入了日语的语言包,再导入时好像覆盖不了,就全乱了套,还好数据库就那么几张表很容易看明白,清空重来就是了。
5.这时基本的在线翻译环境建立完毕,如果放到外网给翻译人员开放账号的话就可以轻松实现协同了。
6.怎么实现google的翻译呢?傻眼了,google啊,号称不作恶的google居然把翻译api给在2011年变成收费产品了。
7.替代方案呢?Bing翻译API支持每天2W字符的免费转换。花了一下午把这套方案实现了,悲剧的是这个接口的速度有够慢,而且只能从后台去调用验证接口,根据返回的数据生成api-key再通过soap、http、ajax等三种不同方式实现翻译,依次看msdn最后找到一条较稳定的小道,就是采用ajax方式的v1版本地址,实测速度在glotpress的页面上hack增加自动点击,测试自动翻译数十分钟算了下平均值10s翻译1条。对于本产品5个语言包2W*5=10W的量,需要计算机开着一直做12天。而且结果还全部都是机器语言版本,这个效率实在不敢恭维。
QQ图片20140826223932
8.继续寻求替代方案。

转一个其他人博客对各大api的评价
微软API:利用WCF方式进行翻译,每次翻译英文字数最大为一万两千多个,中文字符的话最多为六七千个,最大200M字符/月的限制,超过限制后要付费。对HTML翻译支持完美,翻译结果也不错,但考虑到免费字符数限制,需做账号轮巡,账号注册的步骤那叫一个繁琐啊……(此方式可做为首选翻译方式,轮巡的翻译功能已实现,有时间了把源码贴上来。 ——qfzhang于2013-05-30更新)
YoudaoAPI:语言支持不够多,只有英文、日文、中文几个之间的互相翻译,且每次请求最多翻译的字符数不能超过200,还有访问频率限制。
GoogleAPI:Google翻译的API,优势明显,翻译结果十分准确,尤其是针对HTML,能够准确跳过HTML标签部分,只翻译文本,但它是付费使用的(v1版为免费版,但接口已关闭),其价格为100万字符/20美金,其价格自然不言而喻。且在使用过程中发现,其标称每次最大翻译字符数不能超过2k,但实际使用时超过1.5k就会报异常。
BaiduAPI:有访问频率限制和长度限制,且翻译结果不理想。

从百度APi的帮助文件看应该还是不错的
http://openapi.baidu.com/wiki/index.php?title=%E5%B8%AE%E5%8A%A9%E6%96%87%E6%A1%A3%E9%A6%96%E9%A1%B5/%E7%99%BE%E5%BA%A6%E7%BF%BB%E8%AF%91/%E7%BF%BB%E8%AF%91API
考虑这两天再试试这个接口,毕竟百度的服务还是很稳定很快速的。
=====

百度API很快,参数很少
缺点却是翻译结果不理想,有些字符串直接翻不动,可能跟访问频率有关

console.log扩展学习

在玩前端时console.log常常会用到,其实这货还有一堆小伙伴,在用不同浏览器的不同调试工具时有不同的方法可以调用。
如下参考chrome和firebug的方法api

https://developers.google.com/chrome-developer-tools/docs/console-api

http://getfirebug.com/wiki/index.php/Console_API