一、背景
需求是需要在後臺點擊生成二維碼,然後這個二維碼不上傳到服務器。我們需要把二維碼返回給前臺頁面,並且顯示出來。
二、實現過程
1、生成二維碼
這裏使用的是qrcode這個第三方。網上百度,教程一大堆,這裏我就不細說了.生成二維碼可以參考鏈接
function index($ctx){
require_once APP_PATH. '/classes/phpqrcode/phpqrcode.php';
$link_url="http://www.baidu.com";
$level="L";
$size=6;
ob_start();
$QRcode = new QRcode();
$QRcode->png($link_url,false,$level,$size,2);
logger::info(base64_encode(ob_get_contents()));
$imageString =base64_encode(ob_get_contents());
logger::info($imageString);
ob_end_clean();
if(ob_end_clean()){
logger::info('end clen ');
}
$data=array(
'code'=>2,
'qrcode'=>$imageString
);
header("content-type:application/json; charset=utf-8");
!!!(上面這行代碼必須有,因爲Qrcode::png(),在生成二維碼時,內部更改了response的響應類型爲image/jpeg,因此需要自己手動設置一下響應頭部類型,否則接口無法返回json數據)
return $data;
}
現在要實現的效果是把二維碼路徑通過接口返回給前端。
這裏需要明確,png()方法返回的是二進制的圖片流。所以直接返回是沒用的。如果打印返回值的話,我們會發現,返回值是null。所以這裏,採用ob_start(),利用緩衝區進行一系列的操作。
把二維碼路徑返回給前端。
這裏需要明確,png()方法返回的是二進制的圖片流。所以直接返回是沒用的。如果打印返回值的話,我們會發現,返回值是null。所以這裏,採用ob_start(),利用緩衝區進行一系列的操作
1.第一個參數$text,就是上面代碼裏的URL網址參數,
2.第二個參數$outfile默認爲否,不生成文件,只將二維碼圖片返回,否則需要給出存放生成二維碼圖片的路徑
3.第三個參數$level默認爲L,這個參數可傳遞的值分別是L(QR_ECLEVEL_L,7%),M(QR_ECLEVEL_M,15%),Q(QR_ECLEVEL_Q,25%),H(QR_ECLEVEL_H,30%)。這個參數控制二維碼容錯率,不同的參數表示二維碼可被覆蓋的區域百分比。利用二維維碼的容錯率,我們可以將頭像放置在生成的二維碼圖片任何區域。
4.第四個參數$size,控制生成圖片的大小,默認爲4
5.第五個參數$margin,控制生成二維碼的空白區域大小
6.第六個參數$saveandprint,保存二維碼圖片並顯示出來,$outfile必須傳遞圖片路徑。
第二個參數默認是false,方法返回的是二進制的圖片流。生成在緩衝區的,在頁面輸出的時候會從緩衝區送到瀏覽器。所以在代碼中是使用log輸出是不會記錄在日誌中的,也不需要使用echo進行內容輸出。所以直接使用base64_encode(QRcode::png)是沒有用的。
這裏使用到了ob_start()方法,打開輸出緩衝區,所有的輸出信息不在直接發送到瀏覽器,而是保存在輸出緩衝區裏面。這裏就是把生成的圖片流從緩衝區保存到內存對象上,使用base64_encode變成編碼字符串,通過json返回給頁面。
php緩存區相關的操作函數如下。
一、 相關函數簡介:
1、Flush:刷新緩衝區的內容,輸出。
函數格式:flush()
說明:這個函數經常使用,效率很高。
2、ob_start :打開輸出緩衝區
函數格式:void ob_start(void)
說明:當緩衝區激活時,所有來自PHP程序的非文件頭信息均不會發送,而是保存在內部緩衝區。爲了輸出緩衝區的內容,可以使用ob_end_flush()或flush()輸出緩衝區的內容。
3 、ob_get_contents :返回內部緩衝區的內容。
使用方法:string ob_get_contents(void)
說明:這個函數會返回當前緩衝區中的內容,如果輸出緩衝區沒有激活,則返回 FALSE 。
4、ob_get_length:返回內部緩衝區的長度。
使用方法:int ob_get_length(void)
說明:這個函數會返回當前緩衝區中的長度;和ob_get_contents一樣,如果輸出緩衝區沒有激活。則返回 FALSE。
5、ob_end_flush :發送內部緩衝區的內容到瀏覽器,並且關閉輸出緩衝區。
使用方法:void ob_end_flush(void)
說明:這個函數發送輸出緩衝區的內容(如果有的話)。
6、ob_end_clean:刪除內部緩衝區的內容,並且關閉內部緩衝區
使用方法:void ob_end_clean(void)
說明:這個函數不會輸出內部緩衝區的內容而是把它刪除!
7、ob_implicit_flush:打開或關閉絕對刷新
使用方法:void ob_implicit_flush ([int flag])
說明:使用過Perl的人都知道$|=x的意義,這個字符串可以打開/關閉緩衝區,而ob_implicit_flush函數也和那個一樣,默認爲關閉緩衝區,打開絕對輸出後,每個腳本輸出都直接發送到瀏覽器,不再需要調用 flush()