#利用开源程序快速开发? 当今的互联网时代,需要的是快速的响应能力和产品能力,而大部分的产品版块和功能,别人也已经设计好,甚至已经开源,所以我们在进行一些产品开发时,不要重复造轮子,利用开源产品进行快速开发,也是一项重要的能力,这也是我们上一节所谈到的借鉴的能力。本节的标题最早叫《学习哪些开源程序》,其实开源程序本身也会过时,笔者从业的这十多年来各种程序起起落落,所以把标题调整成为了《利用开源程序快速开发》,这相对更为符合我们“授人以鱼,不如授人以渔”的精神,更为巧合的是,有一个最近发生的例子,本节就以这个活生生的例子展开描述,希望能对大家了解和使用开源软件有所启发。 2016年4月3日,程序员界大V caoz (曹政是互联网领域知名架构师,4399 CTO)的公众号发了一篇文章《从值乎谈执行力》,谈到了四点,第一点是赞赏知乎的执行力,在短时间开发出了值乎产品。第二点是讨论技术人员的境界,最高的境界是重剑无锋。第三点谈到了一个有关二维码跟踪的创意,第四点谈到了有很多小点子需求,需要合作和执行。笔者当时接收到这篇文章的时候,是晚上11点左右,在火车上,正好比较无聊,看到了第三点有关二维码跟踪的创意,所以用手机的4G做热点,开始尝试做起这个程序来。笔者之前接触过页面上二维码的生成,但并没有特别多的相关开发经验,但是由于有一定的功底,所以并没有认为这非常难的事,认为一个晚上应该能解决这个问题,虽然曹大大说的是两天之内实现原型。 首先描述一下需求,以下需求摘自《从值乎谈执行力》原文:“ > 二维码转换跟踪工具 当你获得一个二维码,或直接一个链接,你可以到这个平台(网页,或者公众号),生成一个新的二维码,这个新的二维码包括了一个跳转页,然后重定向到原始的目标链接,对推广效果来说,就是增加了一次跳转的过程。 而跳转页,其实也就是一个跟踪器,其实什么代码都不用写,就是执行一个跳转操作就可以。然后记录一条日志。 分析程序在后台通过对日志的读取和处理,得到这个广告的点击次数,及点击的用户构成,比如用户点击时间构成,用户地区构成,用户客户端构成,然后当自媒体登录后台的时候,可以看到这个报表。 就是这么一个东西,但是要超级轻简,好用,如果有人能做出来,只要确保你的跳转页是安全的,我是愿意用的。 那么,问题来了,这样一个东西,开发周期和开发成本应该是多少呢?我个人认为,如果只是web版本的简单原型2天足矣。二维码识别和生成的代码,你去搜github都有,google都有共享过高质量代码,调试通了做一个调用页面就可以。后台统计如果不做复杂的话其实非常简单的结构就能完成。而且你的分析程序是异步处理的,基本都不用担心负载问题。甚至这样的分析程序也有很多开源软件可以拿来用。 如果有一些执行力很强,很愿意单枪匹马做一些小工具,小产品的童鞋,可以试试,如果你能在两天内完成这样的东西并发布出去,可以考虑来找我合作,合作方式都可以谈,如果你相信我,我们可以深入合作,我有非常多的产品想法,急缺执行力落地。”。 我把这个链接访问统计需求拆解成了两个功能:一、用户输入一个链接,生成一个带统计功能的链接二维码,别人扫这个二维码,统计系统能监测到链接的访问次数。二、用户上传一个二维码,统计系统分析这个二维码所含的URL,然后生成一个新的带统计功能的链接二维码,别人扫这个二维码,统计系统能监测到链接的访问次数。 在这两个需求中,都需要制作一个记录日志和带跳转功能的程序,比如地址为http://qrcode.app.ucai.cn/index.php?m=Home&c=Index&a=redirect 这个程序,接收一个URL作参数,比如为 http://mp.weixin.qq.com,在程序运行时记录日志,同时跳转到URL参数所在的地址。 在第一个需求中,比如用户提交的URL即是 http://mp.weixin.qq.com,得到的二维码就是http://qrcode.app.ucai.cn/index.php?m=Home&c=Index&a=redirect&url=http://mp.weixin.qq.com 这个链接的二维码。 第二个需求,是用户上传一个二维码,这个二维码可能是别处已生成的二维码,然后分析出二维码地址,比如是http://mp.weixin.qq.com,然后将http://qrcode.app.ucai.cn/index.php?m=Home&c=Index&a=redirect&url=http://mp.weixin.qq.com 生成新的二维码返回给用户。 分析完需求,然后就分析技术实现。第一个需求在提交端,是一个普通URL提交框就可以了,二维码在服务器端生成图片,让用户下载即可。第二个需求涉及到二维码的解析,分析出URL,然后再生成图片,提供给用户下载。 具体实现时,选择了如下基本框架和库。服务器端使用ThinkPHP开发框架,在页面前端使用Bootstrap 开发框架。在服务器端解析和生成二维码,则经过实验,最终选定了https://github.com/rsky/qrcode 和https://github.com/glassechidna/zxing-cpp 前者用于生成二维码,后者用于解析二维码。由于满足原型用即可以,所以无论是解析还是生成二维码,都使用这两个库生成的命令行程序来实现。 比如 zxing程序,可以解析这张图片 ![](https://box.kancloud.cn/2016-04-10_570a4e1c37f64.jpg) 得到地址:http://www.kaistart.com//project/detail/id/2F2A1F549F3B630FE050840AF2423976/from/wccode.html 操作过程如下图: ![](https://box.kancloud.cn/2016-04-10_570a4e1c558c4.png) 而 qrcode中的qr程序,能通过命令 /usr/bin/qr -x3 -v10 -fBMP -o $destbmp $url 得到BMP格式的二维码,要想得到jpg格式,使用convert命令转换即可。 上面这张图,在咱们的统计系统里,可以生成如下这一张新的二维码。 ![](https://box.kancloud.cn/2016-04-10_570a4e1c705da.png) 这个新的二维码,用户扫码了之后,就能得到统计日志。 ![](https://box.kancloud.cn/2016-04-10_570a4e1c8b81b.png) 那么这个程序的难度如何呢?我们只使用了总计100余行代码,还包括 PHP 和 HTML 代码,所以最后在凌晨的 3:15分左右就实现了,前后4个多小时的时间,还是在火车上信号不太稳定的环境之下。大家可以通过 http://qrcode.app.ucai.cn 来体验。 程序代码如下: * 上传页面的代码。 ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="__PUBLIC__/css/bootstrap.min.css"/> <link rel="stylesheet" href="__PUBLIC__/css/bootstrap-theme.min.css"/> <script type="text/javascript" src="__PUBLIC__/js/jquery-1.11.3.min.js"></script> <script type="text/javascript" src="__PUBLIC__/js/bootstrap.min.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> <title>统计二维码转换器</title> </head> <body> <div class="container"> <div class="row"> <form role="form" method="post" enctype="multipart/form-data" action="{:U('Home/Index/upload')}"> <fieldset> <div> <label>链接</label> <input type="text" class="form-control" name="url"/> </div> <div> <label>或者文件</label> <input type="file" class="form-control" name="qrcode"/> </div> <div style="margin-top:20px;"> <input type="submit" class="form-control" name="submit" value="为二维码增加统计链接"/> </div> </fieldset> </form> </div> </div> </body> </html> ``` * PHP程序代码: ``` <?php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function index() { $this->uploader(); } public function uploader() { $this->display("uploader"); } public function genQRCode($url) { $url = "http://".$_SERVER['HTTP_HOST']."/".U('Home/Index/redirect',array('url'=>trim($url))); $destbmp = SITE_PATH . "/data/" . time() . rand(10000000, 99999999) . ".bmp"; $destjpg = str_replace(".bmp",".jpg",$destbmp); $basebmp = basename($destbmp); $basejpg = basename($destjpg); echo '<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> <title>统计二维码转换器</title> </head> <body>'; $cmd = "/usr/bin/qr -x3 -v10 -fBMP -o $destbmp '".$url."'"; system($cmd); if(is_file("/usr/bin/convert")) { $cmd = "/usr/bin/convert $destbmp $destjpg"; system($cmd); echo '<a href="'."/data/$basejpg".'">新的二维码文件(JPG)</a><br />'; echo '<a href="'."/data/$basebmp".'">新的二维码文件(BMP)</a><br />'; } else { echo '<a href="'."/data/$basebmp".'">新的二维码文件</a><br />'; } echo '</body></html>'; } public function upload() { error_reporting(E_ALL); ini_set("display_errors", 1); if(isset($_REQUEST['url']) && $_REQUEST['url']) { $url = $_REQUEST['url']; $this->genQRCode($url); return; } if (empty($_FILES) || empty($_FILES['qrcode']) || empty($_FILES['qrcode']['tmp_name']) ) { $this->error("请上传要增加统计链接的二维码"); exit; } $ext = pathinfo($_FILES['qrcode']['name'])['extension']; $filename = SITE_PATH . "/upload/" . time() . rand(10000000, 99999999) . "." . $ext; move_uploaded_file($_FILES['qrcode']['tmp_name'], $filename); $url = `/usr/bin/zxing $filename`; if (stripos($url, "http") !== false) { $this->genQRCode($url); } else { $this->error("你上传的二维码好像格式不正确,必须是网址二维码哦"); exit(); } } public function redirect() { $url = $_REQUEST['url']; header("Location: $url"); exit; } } ``` 怎么样,非常简单吧!在火车上信号不稳定的情况下,用4个小时实现一个二维码跟踪统计程序,这得益于什么呢?得益于向开源领域借鉴的能力。 从这个例子中,我们可以总结出以下几点: 1、在互联网的产品研发中,快速做出产品与原型,比执行软件工程和把产品打造完美相对更为重要,因为没有上线之前,一切打磨都是凭空的。 2、从开源代码中,我们学习到代码开发的能力和技巧,也要迅速地使用开源软件为我所用,不要重复造轮子。 3、在本例中尽管只是一个小小项目,但是英语、前端开发、后端开发、C项目编译、Nginx配置都得到了应用和发挥。 4、对一个项目的资源整合过程中,需要的是综合的能力,比如本项目中,大部分时间,不是花在写代码,而是花在了在 Github 上搜索合适的项目,并下载编译,评估的环节上,尽管上面轻松地指出了两个库,但是也是从不下五个开源库中选择并确定出来的。 本节不同于前面章节的理论论述,而是从一个实例出发,进行分析,希望能对大家有所启发。