#利用開源程序快速開發?
當今的互聯網時代,需要的是快速的響應能力和產品能力,而大部分的產品版塊和功能,別人也已經設計好,甚至已經開源,所以我們在進行一些產品開發時,不要重復造輪子,利用開源產品進行快速開發,也是一項重要的能力,這也是我們上一節所談到的借鑒的能力。本節的標題最早叫《學習哪些開源程序》,其實開源程序本身也會過時,筆者從業的這十多年來各種程序起起落落,所以把標題調整成為了《利用開源程序快速開發》,這相對更為符合我們“授人以魚,不如授人以漁”的精神,更為巧合的是,有一個最近發生的例子,本節就以這個活生生的例子展開描述,希望能對大家了解和使用開源軟件有所啟發。
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程序,可以解析這張圖片

得到地址:http://www.kaistart.com//project/detail/id/2F2A1F549F3B630FE050840AF2423976/from/wccode.html
操作過程如下圖:

而 qrcode中的qr程序,能通過命令 /usr/bin/qr -x3 -v10 -fBMP -o $destbmp $url 得到BMP格式的二維碼,要想得到jpg格式,使用convert命令轉換即可。
上面這張圖,在咱們的統計系統里,可以生成如下這一張新的二維碼。

這個新的二維碼,用戶掃碼了之后,就能得到統計日志。

那么這個程序的難度如何呢?我們只使用了總計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 上搜索合適的項目,并下載編譯,評估的環節上,盡管上面輕松地指出了兩個庫,但是也是從不下五個開源庫中選擇并確定出來的。
本節不同于前面章節的理論論述,而是從一個實例出發,進行分析,希望能對大家有所啟發。