Category: php

  • MediaWiki的维护脚本

    MediaWiki的 maintenance 目录下存放着维护脚本,记录一下。 createAndPromote.php 用于创建或者修改已经存在的用户。参数如下 php createAndPromote.php [–bureaucrat] [–sysop] [–bot] [–custom-groups=<group1>,<group2>] [–force] username [password] 示例 php createAndPromote.php –bureaucrat –sysop –custom-groups=developer WikiSysop mypassword

  • 配置windows上的git commit时的默认编辑器

    在Win下使用github的Git Shell,每次commit时都会弹出记事本,使用不是太爽,想换成vim才顺手。操作步骤如下 安装gvim 将gvim的目录加入Path环境变量中,在 我的电脑 – 属性 - 高级 - 环境变量中修改 配置git git config –global core.editor gvim 重启Git Shell即可生效!

  • 用git部署php站点

    在小站点上,直接用git来部署php代码相当方便,你的远程站点以及本地版本库都有一个版本控制,追踪问题或者回滚是很轻松的事情。下面介绍用git部署时的设置步骤 在远程服务器的设置 假定你需要部署的代码在/var/www/yoursite cd /var/www/yoursite git init . git config receive.denyCurrentBranch ignore git config –bool receive.denyNonFastForwards false cd .git/hooks wget https://gist.githubusercontent.com/volca/9482044/raw/344a590af350b997db3819fa21426dfe8bc140f4/post-update chmod +x post-update 在本地git库中新增配置 [remote “prod”] url = your-ssh-username@your-host:/var/www/yoursite/ 这样就算设置完成了。 如果你想把本地的代码推送到远程服务器,下面简单的步骤就可以做到 git pull git push prod 注意事项 如果远程服务器上git的配置目录.git暴露在外部可访问的位置,请在web服务器上设置这个目录不可见。

  • git svn实战

    我之前写了几个wordpress插件,比如inline-javascript, code-prettify。这些插件都托管在wordpress.org提供的svn服务器上,但是我实在太喜欢在git下活动了,因此动了点心思,想把插件代码传到github上,开发完之后利用git-svn传到wordpress的svn服务上。 照着这个思路,捋起袖子就开干了。 用git-svn抓取插件代码 wordpress的插件svn库大且缓慢,如果直接用git-svn去clone代码,一定会慢死,所以我按照以前的笔记,用git从大型svn快速clone代码。 以code-prettify插件为例,首先需要读取这个插件创建时的版本号 svn log http://svn.wp-plugins.org/code-prettify|tail -4|head -1 得到了如下信息,获得一个版本号 318479 r318479 | plugin-master | 2010-12-03 20:12:29 +0800 (五, 03 12 2010) | 1 line 开始clone代码 git svn clone -s –prefix=svn/ -r318479:HEAD http://svn.wp-plugins.org/code-prettify 设置git仓库 首先把代码传了一份到github: https://github.com/volca/code-prettify 然后操作本地git仓库 git branch -m svn git remote add origin git@github.com:volca/code-prettify.git git checkout master 本地svn分支对应svn的远程仓库,本地master分支对应github的远程仓库 Happy time 现在可以按照平常的习惯在git下更改代码,然后用git […]

  • 防止伪造跨站请求的小招式

    伪造跨站请求介绍 伪造跨站请求比较难以防范,而且危害巨大,攻击者可以通过这种方式恶作剧,发spam信息,删除数据等等。这种攻击常见的表现形式有: 伪造链接,引诱用户点击,或是让用户在不知情的情况下访问 伪造表单,引诱用户提交。表单可以是隐藏的,用图片或链接的形式伪装。 比较常见而且也很廉价的防范手段是在所有可能涉及用户写操作的表单中加入一个随机且变换频繁的字符串,然后在处理表单的时候对这个字符串进行检查。这个随机字符串如果和当前用户身份相关联的话,那么攻击者伪造请求会比较麻烦。 yahoo对付伪造跨站请求的办法是在表单里加入一个叫.crumb的随机串;而facebook也有类似的解决办法,它的表单里常常会有post_form_id和fb_dtsg。 随机串代码实现 咱们按照这个思路,山寨一个crumb的实现,代码如下:

  • php的filter扩展小技巧

    做为一个合格的web开发人员,一定会牢记一个原则——永远不能相信用户输入的数据,行走江湖,安全第一是很重要的。用户通过表单或url传过来的数据,一定要仔细检查过了,才往后台数据库里存进去。在一个成熟的开发团队里,贯彻这个原则不成问题;但是如果在一个新人老手混搭的小team里,很容易就忽视了这个问题,那么各种安全漏洞比如跨站攻击,sql注入等等真是防不胜防。 实际上,用php 5自带的filter扩展能够较好的解决这个问题。我在从前的blog里记录了filter扩展的常规用法——直接利用filter来校验数据,这样有不少额外的代码量,所以我得介绍一个比较偷懒的办法——自动对所有输入变量进行过滤,这只需要对php.ini增加一行配置,然后重启apache或fastcgi让php配置生效。 filter.default=”special_chars” 开启了这项配置后,会自动使用filter_input方法对$_GET, $_POST, $_COOKIE, $_REQUEST以及$_SERVER变量进行过滤转义。配置中special_chars是常量FILTER_SANITIZE_SPECIAL_CHARS的缩写,它能自动转义大部分危险字符例如: '"<>。而php手册对它的解释是: HTML-escape ‘”& and characters with ASCII value less than 32, optionally strip or encode other special characters. 在这个情况下,新人们写出这样的代码我也不会太担心: $foo = $_GET[‘foo’]; echo $foo; 在部分场合,我们可能还是需要未转义的变量,比如某个ajax接受的参数是一段json串,用这段代码即可获得原始数据: $foo = filter_input (INPUT_GET, ‘foo’, FILTER_UNSAFE_RAW); fitler扩展与yahoo使用的yiv如出一辙,印象里似乎就是yahoo对yiv做了些修改贡献给php社区,但是暂时没找到出处。

  • 关于“facebook的memcached实战”小记

    上周挤到QCon的会场里,听了两场 —— Facebook的Memcached实战,以及Twitter 的可伸缩性数据架构。当时对facebook超大规模使用memcached印象很深刻,只可惜到现在也没见到这个的ppt。平时用php比较多,因此听闻同样使着php的facebook讲memcached,有些小小的感触,记录下来。 更高效的序列化函数 php有两个memcache扩展,默认都是使用php自带的序列化函数serialize来存储数组或对象。但是serialize最为人诟病的就是速度慢,序列化之后占用空间大。由于facebook已经在memcached里保存了200T字节的数据,因此序列化函数即便作出的百分之一的优化对它来说都是个不小的收益。他们发粪涂墙在thrift的binary协议基础上搞出了一个fb_serialize,据称这个序列化方法能快上3倍,快倒算了,还能节省30%空间, 200T字节的数据能节省出30%,简直就是传说中的银弹啊,这让php官方的开发人员们情何以堪? facebook目前已经开源了thrift,其中自带了一个thrift协议的php扩展,但是这些代码里没有找到传说中的fb_serialize,我倒是从最近他们放出来hiphop-php里找到了这部分代码,哪位大侠去扒拉扒拉弄出来做成php扩展造福广大群众? 作为备选方案,我推荐igbinary,这也是一个binary的序列化方法。在上次的测试结果中,它甚至能节约50%的存储空间,速度也是稳超php原生的序列化方法,搞不好facebook换了这个序列化方法能省下更多的内存来? 节约每个item的存储空间有什么好处?我个人认为一个是省钱,另外一个就是能够带来速度上的提升。我们平常碰到稍大一点的item都得用gzip压的妥妥贴贴的才送到memcached里,网络传输的开销小了,这是实实在在的性能提升。何乐而不为? mcproxy mcproxy = memcached + proxy。facebook的机房遍布各洲,利用mcproxy来进行跨机房的同步或分发,全球制霸,指着太阳就能等到那天了。一般的互联网企业还真用不上这玩意,规模还没上去的时候,这些乱七八糟的只会拖后腿。facebook还没开源mcproxy,但是我找到两个替代品: memagent is a simple but useful proxy program for memcached servers. moxi = memcached + integrated proxy 从项目描述来看,moxi最接近facebook介绍的mcproxy,成熟度也比较高。 数据的一致性 Marc Kwiatkowski在会场上用大篇幅的ppt和大量的动画来阐述这个问题,他们用了很多额外的手段来解决在跨机房情况下因为延时问题造成的脏数据。这一段看着挺晕,但是我们联想到facebook用到的多级cache技术: 本地全局变量 + apc + memcache,不难理解这样做颇有些道理,这相当于用memcache实现了一个版本控制系统。 我还是很晕这段ppt。

  • 关于改善xhprof使用情况的设想

    自从去年将xhprof用在生产环境以来,对生产环境的程序调试,性能优化都带来很多便利。但是在使用过程中,还是有一些细节需要改善。 问题 xhprof的profile日志直接以文件形式保存在生产服务器上,需要定时清理,或者收集起来移动到查看日志的工具机上。 由于xhprof生成的profile是一个大数组,所以保存到文件时使用了标准的php serialize,日志文件偏大,一个不留神就容易占用很多服务器磁盘空间。 查看日志列表时,一个个点开查看比较费劲。 针对这几个问题,我有一些小小的设想。 日志存放 部署一个中央日志服务器,采用facebook的scribe来收集日志。生产环境的服务器产生的xhprof日志,都写入到scribe的客户端,由客户端自动同步到中央日志服务器的scribe上,不占用本地的存储空间。在代码上的改动也比较小,只要基于iXHProfRuns接口实现一个XhprofRuns类,调整save_run方法的存储方式即可。 更换序列化方法 xhprof默认是将profile信息用php原生的序列化方法处理后进行保存,而我在前两天比较过igbinary vs serialize vs json_encode的性能和占用字节数,这个测试里igbinary在各方面都有一定优势,尤其是占用存储空间会大幅度减小,所以我只要更换序列化方法为igbinary_serialize即可获得改善。 优化列表展示 我已经厌倦挨个查看profile日志的大图,费时费力还没有针对性。所以我现在的做法是,在profile日志的列表中将前1000个日志的总体执行时间直接输出到列表中,并且将执行时间过长的日志用红色粗体标识。做了这个小小的改动之后,当我想要去视察一下运行情况时,就把日志列表中那些红通通的链接点开看看就行了,真正的省时省力。 如何从xhprof日志文件中获取执行时间?简单的代码如下 /** * 由xhprof日志获得执行时间 * * @param string $log xhprof日志的文件路径 * @return int 执行时间 */ function getSpentTime($log) { $profile = unserialize(file_get_contents($log)); return $profile[‘main()’][‘wt’] / 1000; }

  • igbinary vs serialize vs json_encode

    最近看到memcached扩展支持额外的序列化方式 — igbinary,这是一个未收录到pecl的php扩展,它提供的两个主要方法: igbinary_serialize igbinary_unserialize 据称可以用它来代替php自带的序列化函数serialize,性能更好,而且占用的字节数也更少。下面我就 igbinary ,serialize ,json_encode三者的性能做了一个简单的测试。 测试 以一个包含1000000个元素的数组做为原始数据,分别以json, serialize, igbinary进行序列化和反向操作。 <?php ini_set(‘memory_limit’, ‘512m’); $array = array_fill(0, 1000000, rand(1, 9999)); $start = microtime(true); $export = json_encode($array); $end = microtime(true); $duration = $end – $start; print(‘JSON Encode: ‘ . $duration . PHP_EOL); $start = microtime(true); $import = json_decode($export); $end = microtime(true); $duration = $end […]

  • memcache连接慢又一例

    继上次解决memcache连接慢问题以来,好长一段时间没在这个问题上翻过跟头。这一次我又在生产环境观察到php和memcache的连接时间经常会在50ms以上。 作为一个cache,占用了这么长的执行时间,天理何在? 实际的运行环境如下: apache + mod_php php-memcache扩展版本为2.2.5 memcache的并发连接数在400左右,相当少 这次memcache扩展用的是最新的稳定版,无可挑剔。所以刚开始我认为是网络环境的问题,于是直接采用telnet工具直连memcache进行测试,发现速度飞快!一点便秘感都没有!所以把目光仍然放回到memcache扩展上来,集中对比较慢的addServer方法各项参数进行排查。 Memcache::addServer方法 bool Memcache::addServer ( string $host [, int $port = 11211 [, bool $persistent [, int $weight [, int $timeout [, int $retry_interval [, bool $status [, callback $failure_callback [, int $timeoutms ]]]]]]]] ) 比对结果表明,$weight参数对memcache的连接时间有显著的影响,$weight的默认值为1,一旦设置为别的数值,连接时间便会由毫秒级变成50ms左右,立竿见影。 鉴于php-memcache扩展一贯恶劣的表现,俺不得不痛下决心迁移到新的memcached扩展上。memcached扩展基于libmemcached开发,而且提供了丰富的接口方法,应该是更好的选择。