PHP自动化发布工具:Deployer

项目迭代的过程中, 不断把新开发的功能发布到不同的系统环境是一件家常便饭的工作. 传统的做法一般是: 登录到某台服务器上; 更新代码; 更新依赖(composer up); 重启一些服务(比如队列什么的)... 随着项目逐渐长大, 服务器的数量会越来越多, 每次发布新功能都需要亲自登录到20台服务器上, 一遍又一遍的做着重复的操作,还得确保每一次操作都正确且没有疏漏, 对于程序员来说, 这样的事情是不可想象的。重复的工作,就交给代码去完成吧! Deployer 是一款用PHP开发的自动化发布工具。又要发布新版本了? 你所要做的仅仅是在命令行中输入一行命令,执行预先写好的脚本,之后所有的工作deployer会帮你完成。甚至,你还可以把它和版本控制工具的Hook结合起来,例如,当master分支收到新的提交后,deployer自动从版本控制中拉去新的代码,并在指定服务器上完成后续的发布工作,自动化发布实现了! 如果你是一名PHP程序员那就太棒了, 因为deployer的部署脚本也是用PHP来写的。deployer的原理其实很简单,添加服务器配置,通过ssh方式以秘钥或者密码登录到远程服务器并执行脚本。服务器配置文件大概是这样: prod: host: domain.com user: www identity_file: ~ stage: production deploy_path:…

如何正确使用composer

composer 是一款优秀的PHP依赖管理工具,正如pip之于python、gem之于ruby、gem之于node。无论任何一门语言,在现代软件开发实践中,依赖管理对于开发者而言都是必不可少的一个部分。敏捷开发强调不要重复造轮子,而依赖管理工具则提供了一种最容易的方式帮助我们方便的获取到别人造好的漂亮轮子,并且完美的安插到我们的项目之中。理想总是好的,但当理想落地成为现实的时候,一切又变得不那么美好,尤其是当它准备落在中国的土地上。 因为众所周知的原因,composer在国内并不好用,虽然在PHP社区里也有一些为国内开发者提供的镜像网站,然而经过尝试,这些镜像的表现也不尽人意,常常出现502等让开发者们叫苦不迭。简单分析一下,composer更新缓慢主要在两个地方,一是从packgist获取依赖包的下载地址时常常会卡死(也就是: Loading composer repositories with package information 这一步); 二是从github下载文件时,有时会因为网络请求超时而中断 自建镜像 Satis是composer官方提供的一个搭建私有镜像的工具, clone satis 到自己的服务器以后, 在配置文件中申明需要的依赖, 如: { "repositories": [ { "type": "composer"…

还在随手修改数据表?!试试DB Migrations吧

在项目迭代的过程中,数据库结构常常需要跟随业务需求的变化做出调整,尤其在迭代的初期阶段,加一个字段减一个字段的需求更是家常便饭。在小型团队中,往往是负责开发功能模块的程序员在完成本地开发环境数据库的变更后,直接到生产环境中更新数据库结构。 这样的工作方式虽然看起来很轻松,但却可能给你的团队带来不小的麻烦。 首先,是团队成员之间数据库环境的同步问题。为了使团队中的其他开发者及时了解数据库环境的变化,你不得不在每一次修改数据表结构后,都告知整个团队你对当前数据库所做的变更,并确保所有人正确更新了他们开发环境中的数据库。 另外,变更数据库的程序员还需要同时对可能存在几个环境负责,如测试环境,项目展示环境(UAT)等都需要一一进行更新,靠人手动去维护成本高,速度慢,并且容易出错。在持续交付已经逐渐成为软件开发标准流程的今天,再继续这样的做法实在不够敏捷的。 不过幸运的是,现在我们已经有了成熟的方案来应对这样的麻烦。既然我们可以通过版本控制的方式让代码同步变得更加轻松,那为什么我们不用同样的方式来管理数据库的变更呢?这就是 Database Migrations。下面我将以Doctrine Migrations为例,来说明我们应当如何解决这样的问题。 安装 composer require doctrine/migrations Doctrine Migrations 提供了两种调用方式供你选择。一个是注册命令行工具, 另外,你也可以选择直接使用 Doctrine Migrations可执行文件(.Phar)…

优雅的PHP微型框架: Silex

Silex是我最喜欢的PHP开发框架之一(不,我现在更喜欢Laravel系列了)。其优点在于他既能够允许你不浪费时间构建任何项目结构,仅用3行代码启动一个超轻量级的应用,同时也支持你以十分优雅的方式,将各种优秀的第三方组件以极低的成本加入到Silex中,使之能胜任企业级应用的开发。 Silex与Symfony、Twig、Pimple等著名PHP开源项目一样也是SensioLabs家族中的一员,Silex建立在Symfony生态圈的基础之上,你可以很方便地将Symfony的各种组件安插在Silex上,这也是我在Slim(另一款优秀的PHP微型框架)和Silex中最终选择后者的主要原因。基本上,你可以把Silex当作一个迷你版的Symfony。Silex的学习成本非常低,只用花半个小时通读一遍Silex官方文档你就能大概了解Silex的基本使用方法。微型框架的重点就在于要够简单,和Slim一样,用Silex你也可以在3行代码之内启动你的应用,下面是一个 Hello World 的例子: 在Silex的设计中,各种第三方库可以以Service Provider的方式被组织起来,为Silex提供更强大的功能支持,也能便于开发者更轻易的将这些Provider复用在新的项目上。Silex中已经为一些优秀的第三方库定义好了现成的Provider,例如:Doctrine,Twig,Symfony Security 等,要使用它们,你要做的只是将这些现成的Provider(在)注册到应用中即可。 另外,Silex内置的Pimple也为框架的依赖注入提供了方便的实现方案。 喜欢TDD吗?没问题!Silex同样为测试提供了非常友好的支持。在PHPUnit和Symfony Web…

PHP持续集成实践: PHPCI

持续集成(Continuous Integration)作为一种成熟的软件开发实践已经被广大程序员所熟知,Github上大量的开源项目也都纷纷加上Travis-CI来为自己的项目保驾护航。相信很多程序员都有过这样的经历:在与团队协作开发项目时,大部分时间大家都在各自的分支编写不同功能模块的代码,直到下一版本发布前,大家才开始开始着手将自己负责的模块合并到主分支中,这时你往往会发现,要将代码合并到主分支中甚至已经不再是一件简单的事了。自己一段时间前写的代码已经变得有点陌生,合并代码过程中一些小改动也许会在不经意间破坏整个项目,面对突然出现的大量陌生代码(其他程序员提交分支),产品上线的deadline却已经近在咫尺,原本简单的工作现在成了整个团队噩梦。 以上只是一个假想的片段,但这样的场景却又是如此似曾相识,持续集成思想的诞生正是为了解决类似这样的问题。Martin Fowler告诉我,在敏捷的团队,我们是这样工作:在完成手头的工作(并确保新鲜的代码都有测试覆盖时),在本地执行并通过构建(至少是测试)。将主分支的代码合并到本地分支,再次执行构建确保一切OK。将代码提交到主分支版本库,等待CI系统从版本库中检出代码,并再次构建项目。此时你只需要泡一杯咖啡,静静等待CI完成构建,如果构建通过,则证明你提交的代码没有任何问题,至此,一次集成工作已经顺利完成。 持续集成鼓励程序员们在保证构建通过的前提下,尽可能频繁地将手头的代码集成到主分支中。将代码集成作为一项最普通的日常工作,好处显而易见,团队所有的dev都能在最快时间内获得项目最新的修改,而主分支项目随时都可以上线发布。生活变得不再艰难。 PHPCI是一款专门面向PHP项目开发的持续集成工具。尽管还算不上完美,部分插件还有一些小Bug,…

PHP图像识别 php-tesseract

在做一些网络爬虫工具的时候,经常需要把图片信息转化成文本数据(比如电商网站相互之间比价,而价格往往是图片格式)。网上关于PHP图像识别的文章不少,不过质量都不怎么样,好的工具包更是寥寥无几。好不容易找到一个优秀的PHP图片识别扩展,和大家分享一下。 首先安装依赖程序: sudo apt-get install python-distutils-extra tesseract-ocr tesseract-ocr-eng libtesseract-dev libleptonica-dev php5-dev swig libcv-dev build-essential subversion 编译安装 php-tesseract: svn checkout http://php-tesseract.googlecode.com/svn/trunk/ php-tesseract cd php-tesseract ./configure --prefix=/usr make sudo make install make test 这里有一个官方提供的例子: wget http://php-tesseract.googlecode.…

PHP socket 编程: select同步非阻塞多路复用模式

听了凌总培训的socket之后,认识到socket编程虽然平时应用的不多(特别是PHP的socket编程,基本上没什么应用),但确实是非常重要的一块知识,我等泥腿子程序员务必要好好学习,千万不可舍本逐末、急功近利,捡了芝麻丢西瓜$_$。。。 因为在socket编程方面没什么基础,所以只是简单的看了一下PHP的socket,加深对socket的认识。PHP socket是基于BSD的socket接口实现的,所以如果想更深入的学习可以直接研究一下UNIX编程,这里不再赘述。 php作为一个效率一般的单线程语言,用来做socket服务器确实有点勉强,不过php还是提供了各种相关函数,使其可以完整地实现socket编程的各项功能。 // Create a new socket $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $server['host'] = '127.0.0.1'; $server['port'] = '2013'; socket_bind($socket,$server['host'],$server['port']); socket_…

Symfony PHP Framework

Symfony是一个很优秀的PHP开发框架,其大量参考了 J2EE 的架构模式(和Spring十分类似),非常适合大型项目的开发.什么,你了解J2EE?那么恭喜你,你已经成功了一半! 优势: 强大的命令行脚手架工具(也有GUI工具),协助你快速完成大量的初期项目搭建工作. Java bean式的依赖注入管理,向高耦合说再见. 完全自定义的路由管理,支持配置文件或者注释配置的方式. 完全模块化的设计,如果你愿意,框架的各个部分都可以换成你喜欢的库. 模板文件对布局,继承有良好的支持,据说用起来相当不错. 非常齐全的手册,Cookbook 等 统统都是免费的 ... 有兴趣? 那么现在就开始吧: Symfony Get Started…

PHP的测试驱动开发

Whenever you are tempted to type something into a print statement or a debugger expression, write it as a test instead. --Martin Fowler 正确的测试代码可以很大程度的保证生产代码的可靠性,TDD规范要求开发者在编写生产代码之前先为其接口编写测试。这样可以保证在产品需求不变的前提下稳步推进开发进程,避免潜在BUG,同时也不必担心在改代码的过程中影响该代码其他的调用者。有测试代码为你保驾护航那么就请大胆的重构吧,TDD保证你的代码整天干爽。从此,我们终于告别坑爹的队员,告别客户的夺命连环call,程序员们可以睡个好觉了。所以还有什么理由向这样可爱的开发方式说不呢,现在就开始吧。 PHP最知名的测试框架PHPUnit完整的复制了JUnit3的实现方式,如果你了解JUnit,那基本可以直接上手了. 代码顺利通过测试了,不过当测试代码越来越多以后,要挨个执行测试还是比较麻烦的,别担心,phpunit提供了测试套件帮助你完美解决这个问题。以下是一个简单测试套件的例子: /** * 我的测试套件 */ class suite extends PHPUnit2_…

PHP编写简单HTTP代理程序

工作室寒假作业:写了一个简单的HTTP代理程序,以加深了对HTTP协议的理解。 基本原理: 用户通过浏览器向代理的客户端程序发送请求,客户端把请求组织成数据发送给代理服务器的服务端,服务端根据客户端发来的数据,还原用户的请求,再将数据返回给客户端,最后呈现给用户。 配置客户端程序Apache虚拟主机(VirtualHost)监听某一端口,并开启rewrite,将浏览器的所有请求都重定向到客户端程序的入口。 RewriteEngine on RewriteRule ^(.*)$ index.php 客户端从$_SERVER中获取用户请求的header信息,并组织数据发送给服务端程序。 /** * 把请求发送到代理服务器 */ function run(){ //组织数据 $data = $this->buildData(); //生成一个 curl 句柄 $curl = $this->buildCurl($data) ; //把请求数据发送给服务端 $content = curl_exec($curl); //设置header header ("Content-type: ".curl_…