#利用开源程序快速开发?
当今的互联网时代,需要的是快速的响应能力和产品能力,而大部分的产品版块和功能,别人也已经设计好,甚至已经开源,所以我们在进行一些产品开发时,不要重复造轮子,利用开源产品进行快速开发,也是一项重要的能力,这也是我们上一节所谈到的借鉴的能力。本节的标题最早叫《学习哪些开源程序》,其实开源程序本身也会过时,笔者从业的这十多年来各种程序起起落落,所以把标题调整成为了《利用开源程序快速开发》,这相对更为符合我们“授人以鱼,不如授人以渔”的精神,更为巧合的是,有一个最近发生的例子,本节就以这个活生生的例子展开描述,希望能对大家了解和使用开源软件有所启发。
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 上搜索合适的项目,并下载编译,评估的环节上,尽管上面轻松地指出了两个库,但是也是从不下五个开源库中选择并确定出来的。
本节不同于前面章节的理论论述,而是从一个实例出发,进行分析,希望能对大家有所启发。