PHP底层运行原理初探
PHP是一种适用于web开发的动态语言,但从研究PHP实现来讲她就是一个用C语言实现包含大量组件的软件框架。
PHP说简单,但是要精通也不是一件简单的事。我们除了会使用之外,最好要知道它底层的工作原理。那么了解PHP底层实现的目的是什么?
- 动态语言要像用好首先得了解它,因为理解底层才能真正用好上层
- 内存管理、框架模型值得我们借鉴
- 通过扩展开发实现更多更强大的功能,优化我们程序的性能。
PHP是一种适用于web开发的动态语言,但从研究PHP实现来讲她就是一个用C语言实现包含大量组件的软件框架。
PHP说简单,但是要精通也不是一件简单的事。我们除了会使用之外,最好要知道它底层的工作原理。那么了解PHP底层实现的目的是什么?
https://gist.github.com/forthxu/ebddb968059f2b844fa9
https://gist.github.com/forthxu/f42113205494abd54453
#!/bin/bash
#@author forthxu.com
#说明
#找到获取apk信息有两种方式
#一种解压后读取AndroidManifest.xml,解压最好不要通过unzip因为获取的是压缩过的内容,读取不准确,可用apktool反编译解压
#另外一种可通过aapt也就是官方sdk中提供的工具读取信息
#aapt和apktoool工具 https://code.google.com/p/android-apktool
#可能存在的问题 http://www.qiansw.com/centos-apk-apktool.html
#扩展阅读,汉化apk http://bbs.dospy.com/thread-9991523-1-354-1.html
#如果使用unzip解压的方法还可以通过以下方法解析XMl文件
#java可用 java -jar AXMLPrinter2.jar AndroidManifest.xml > AndroidManifest2.xml
#AXMLPrinter2.jar下载 https://code.google.com/p/android4me/
#AXMLPrinter2 php版http://blog.katcin.com/archives/69
#获取apk
if [ ! -s "${1}" ];then
echo "usage:bash ${0} some.apk";
exit;
fi
#获取文件后存储的位置
ex=./ex/;
echo "-----apk信息----";
#apk信息
badging=`aapt d badging $1`;
# echo $badging;
echo "-----apk icon----";
#获取apk icon
icons=`aapt d badging $1 | grep -E "application-icon|application:" | sed -e 's/.*\(res\/\w\{1,\}\-\w\{1,\}\/\w\{1,\}\.png\).*/\1/' | uniq`;
# echo $icons;
for icon in $icons;do
echo $icon;
done
echo "-----解压图标 到 ${ex}----";
#解压图标
unzip -o $1 $icons -d $ex
echo "-----apk name----";
#获取apk name
name=`aapt d badging $1 | grep -E "application:" | sed -e "s/.*label='\(\w*\)'.*/\1/"`;
echo $name;
echo "-----apk 权限----";
#获取apk 权限
permissions=`aapt d permissions $1 | awk -F " " '/uses-permission/ {print $2}'`;
# echo $permissions;
for permission in $permissions;do
echo $permission;
done
echo "-----apk sdkVersion----";
#获取apk sdkVersion
sdkVersion=`aapt d badging $1 | grep -E "sdkVersion:" | sed -e "s/.*:'\(\w\{1,\}\)'.*/\1/"`;
echo $sdkVersion;
echo "-----apk targetSdkVersion----";
#获取apk targetSdkVersion
targetSdkVersion=`aapt d badging $1 | grep -E "targetSdkVersion:" | sed -e "s/.*:'\(\w\{1,\}\)'.*/\1/"`;
echo $targetSdkVersion;
echo "-----apk versionCode----";
#获取apk versionCode
versionCode=`aapt d badging $1 | grep -E "package:" | sed -e "s/.*versionCode='\(\w\{1,\}\)'.*/\1/"`;
echo $versionCode;
echo "-----apk versionName----";
#获取apk versionName
versionName=`aapt d badging $1 | grep -E "package:" | sed -e "s/.*versionName='\(\S\{1,\}\)'.*/\1/"`;
echo $versionName;
echo "-----apk package----";
#获取apk package
package=`aapt d badging $1 | grep -E "package:" | sed -e "s/.*name='\(\S\{1,\}\)'.*/\1/"`;
echo $package;
echo "-----apk supports-screens----";
#获取apk supports-screens
supports=`aapt d badging $1 | grep -E "supports-screens:" | sed -e "s/.*supports-screens:\(.\{1,\}\)/\1/"`;
echo $supports;
echo "-----解压证书 到 ${ex}----";
#解压证书
unzip -o $1 META-INF/CERT.RSA -d $ex
说实话,虽然似乎为之奋斗了十多年,在真正进入软件行业的短短一年之后,我已经对它感到相当的厌倦了。这并不是说这个行业没有前景,而是在这个行业工作,其实很难得到心理上的快乐。
人们说女怕嫁错郎,男怕入错行。我并不认为自己入错了行,我仍然很喜欢设计程序和语言,而且我显然是这个领域的王牌之一。然而我却看到了这个行业里的无限混沌,让我觉得喘不过气来。几十年的垃圾设计堆积在那里,却没有人试图把它们清理掉,权威主义盛行。无论你在哪个公司,哪个地方,只要跟程序员说话,十有八九会谈不来。非常扫兴不说,甚至感觉很伤自尊。
久而久之我发现了,由于程序员工作的性质,他们受到的“熏陶”,形成了一种行业性的心理疾病。这里我就简单的把我所观察到的一些症状总结一下。
fastcgi_param PHP_VALUE "open_basedir=$document_root:/tmp/:/proc/:$document_root/../";
or
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root:/tmp/:/proc/:$document_root/../";
不同的地方是:php_admin_value(php_admin_flag)命令只能用在apache的httpd.conf文件中,而 php_value(php_flag)则是用在.htaccess文件中的,nginx下相同。
因为使用FastCGI,php不是每次都重新启动,所以每个主机sever都需要加入配置,以便每次访问都设置php的open_basedir。
适用 nginx + php5.3以上,php5.2 此方法不生效。
open_basedir=./:/tmp/:/proc/
这种方式的设置需要重启php-fpm后生效
open_basedir=./:/tmp/:/proc/
这种方式不需要重启nginx或php-fpm服务。安全起见应当取消掉.user.ini文件的写权限。
关于.user.ini文件的详细说明:
http://php.net/manual/zh/configuration.file.per-user.php
完全隔离php和系统,如果需要系统功能的自己创建系统环境,路径也要配成相对隔离的环境。
http://www.baidu.com/s?wd=nginx%20chroot
目前最好的是适用第一种方法。
设置open_basedir的同时最好禁止下执行命令的函数,比如:
shell_exec('ls /etc')仍然查看到/etc目录的文件列表
shell_exec('cat /etc/passwd')仍可查看到/etc/passwd文件的内容
建议禁止的函数如下:
disable_functions = pcntl_alarm, pcntl_fork, pcntl_waitpid, pcntl_wait, pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig, pcntl_signal, pcntl_signal_dispatch, pcntl_get_last_error, pcntl_strerror, pcntl_sigprocmask, pcntl_sigwaitinfo, pcntl_sigtimedwait, pcntl_exec, pcntl_getpriority, pcntl_setpriority, eval, popen, passthru, exec, system, shell_exec, proc_open, proc_get_status, chroot, chgrp, chown, ini_alter, ini_restore, dl, pfsockopen, openlog, syslog, readlink, symlink, popepassthru, stream_socket_server, fsocket, chdir
php本身是一个php代码的脚本执行程序,运行方式是指其运行的方法。整理归纳为一下五种方法:
前四种是提供给web服务器来处理php代码文件,其中模块加载的方式其实是最快的的,但FastCGI配合nginx WEB服务是目前的主流,下面主要配合Apache做说明。
多进程环境下,打开同一个文件,进行读写操作过程中,如果其中一个进程删除这个文件,那么,另外正在读写这个文件会发生什么呢?
程序员眼中的用户
戒掉“用户体验”已经很久了,但在微博上看到这个图,突然很有感触,程序员一直像外星物种,去跟客户谈需求还需要跟上一个产品翻译,俗称产品经理。并且不管自我感觉还是用户看来我们确实是这样,不止逻辑思维不一样,而且像理解外星技术一样敬畏我们的技术,但在我看来却是80%的用户是这样使用我们产品!程序员真的需要融入生活,而不是孤单的面对自我。
网络上的代码一般使用substr(md5("x"),0,16)、substr(md5("x"),8,16)、substr(md5("x"),8,-8)这种有损的的方式截取长度(最好用array_unique()剔除重复,即便如此如果多次生成也可能存在重复),md5("x",true)说是长度为16又都没写清楚,这里稍作研究。
本来看MySQL协议是要做一个skynet的lua c库的,今天群里有人实现了,主要是根据openresty/lua-resty-mysql改的,之前工作老停留在协议内容上,不过也好,充分学些了一些MySQL协议。
同时这个项目也值得关注OpenResty。
一次正常的过程如下