以前作微信登陸開發時候,發現微信頭像圖片沒有後綴名,傳統的圖片抓取方式不奏效,須要特殊的抓取處理。因此,後來將各類狀況結合起來,封裝成一個類,分享出來。php
建立項目數據庫
做爲演示,咱們在www根目錄建立項目grabimg,建立一個類GrabImage.php和一個index.php。安全
編寫類代碼微信
咱們定義一個和文件名相同的類:GrabImage函數
1測試 2ui |
|
屬性spa
接下來定義幾個須要使用的屬性。
一、首先定義一個須要抓取的圖片地址:$img_url
二、再定義一個$file_name用來存儲文件的名稱,可是不攜帶拓展名,由於可能涉及到拓展名更換,因此這裏拆開定義
三、緊接着就是拓展名$extension
四、而後咱們定義一個$file_dir,該屬性的做用是,遠程圖片抓取到本地後所存儲的目錄,通常相對於PHP入口文件所在的位置做爲起始。可是該路徑通常不保存到數據庫。
五、最後咱們定義一個$save_dir,顧名思義,該路徑是用來直接保存的數據庫的目錄。這裏說明下,咱們不直接存儲文件保存路徑到數據庫,通常是爲了以後若是系統遷移,方便更換路徑作準備。咱們這裏的$save_dir通常爲日期 + 文件名,若是須要使用時候取出,在前方拼上所須要的路徑。
方法
屬性弄完了,接下來咱們正式開始抓取工做。
首先咱們定義一個對外開放的方法getInstances用來獲取一些數據,好比抓取圖片地址,和本地保存路徑。同時將其放入屬性中。
1 2 3 4 5 6 |
|
圖片保存路徑拼接完成,下面咱們要注意一個問題,目錄是否存在。日期在一每天走,可是目錄並不會自動建立。因此,在保存圖片以前,首先須要檢查一下,若是當前目錄不存在咱們須要即時建立。
咱們建立設置目錄方法setDir。屬性咱們設置了private,安全
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
接下來就是抓取核心代碼
第一步,解決一個問題,咱們須要抓取的圖片可能沒有後綴名。按照傳統的抓取方法,先抓取圖片,而後截取後綴名的方案不可行。
咱們必須經過其它方法來得到圖片類型。辦法就是從文件流信息中獲取文件頭信息,從而判斷文件mime信息,就能夠知道文件後綴名。
爲了方便,先定義一個mime和文件拓展名映射。
1 2 3 4 5 6 7 |
|
這樣,當我獲取了類型是image/gif的時候,我就能夠知道是.gif圖片了。
利用php函數get_headers,獲取文件流頭信息。當其值不爲false時候咱們將其賦值給變量$headers
取出Content-Type的值即爲mime的值。
1 2 3 4 |
|
使用上面咱們定義的映射表,咱們能夠很輕鬆的獲取後綴名。
1 |
|
固然上面獲取的$type,可能不存在咱們的映射表中,說明這種類型文件並非咱們想要的,直接拋棄就行了,不用管它。
下面的步驟就和傳統抓取文件同樣。
1 2 3 4 5 6 7 8 |
|
首先獲取本地保圖片存完整路徑$file_path,接下來使用file_get_contents抓取數據,而後使用file_put_contents保存到剛剛的文件路徑。
最後咱們返回一個能夠直接保存到數據庫中的路徑,而不是文件存儲路徑。
該抓取方法完整版是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
最後,爲了簡單,咱們想在其餘地方只要調用其中一個方法就能夠完成抓取。因此,咱們將抓取動做直接放入到getInstances中,在配置完路徑後,直接抓取,因此,在初始化配置方法getInstances裏新增代碼。
1 2 3 4 5 6 7 8 |
|
測試
咱們去剛剛建立的index.php文件內試試。
1 2 3 4 5 6 7 |
|
惹,的確抓取過來了
完整代碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
|