此文可能比較繁瑣,有更好的方法,但是出于教程目的,這是我的"“最佳實踐”的路線。
今天,我們將討論一個似乎每個人都有些困惑的話題……在MySQL中存儲BLOB圖像,然后使用PHP再次顯示它們。盡管始終建議不要這樣做,但我先展示一些演示代碼,說明如何實現此目標,并討論為什么/為什么不這樣做。然后,討論一些替代方案,以及為什么與直接將圖像直接存儲到數據庫相比。
因此BLOB或“Binary Large Objects”是數據庫中用于存儲原始二進制數據的字段。這些數據可能代表圖片,文件或二進制格式的文本。由于這些類型的對象相當大(甚至可能是千兆字節大小),因此該字段旨在容納大量信息。我們如何在PHP中使用這些字段來插入個人資料圖片?
1、我們必須將圖像讀取為二進制。
2、我們必須準備將其插入數據庫(轉義)。
3、我們使用典型的SQL將其插入數據庫中
對于我們的示例,我們將使用三步過程...
1、設置文檔的內容類型以使其與圖片類型相匹配(對于jpg圖片,圖像/ jpeg)
2、在數據庫中找到圖像并將其拔出
3、顯示它
//圖片由表單提交。打開它進行閱讀(模式“ r”)
$ fp = fopen($ _ FILES ['file_name'] ['tmp_name'],“ r”);
//如果成功,則使用文件大小(以字節為單位)作為長度從文件指針讀取。 如果($ fp){
$ content = fread($ fp,$ _FILES ['file_name'] ['size']);
fclose($ fp);
//在內容中添加斜杠,以便轉義特殊字符。 //如前所述,在這里也可以使用mysql_real_escape_string。你的選擇。 $ content =加號($ content);
//將我們的二進制數據字符串(“內容”)插入到“圖像”列的表“表”中 mysql_query(“插入表(image)值('$ content')”);
}
在這里,我們打開文件進行讀取并將圖像讀取到變量中。對該fread()的調用正在讀取圖像的字節,因此我們為其指定了圖像文件的字節長度。可以使用“ size”鍵從$ _FILES數組中獲得。一旦將其包含在變量中,只需將其插入表中“ BLOB”類型的列中即可。在我們的示例中,“圖像”列是“ BLOB”數據類型。確保您在MySQL中選擇的BLOB也足夠大以容納數據,因為MySQL確實具有不同大小的BLOB數據類型。
//讀取我們要從數據庫中提取的行。
$ result = mysql_query(“從ID = 1的表中選擇圖像”);
//如果成功,則以行的形式獲取該行,并將“ image”列中的數據存儲到變量中。如果($ result){
如果($ row = mysql_fetch_array($ result)){
$ img = $ row [“ image”];
}
}
//將此頁面的內容類型設置為image / jpeg,因為我們要拉出的圖像是jpg圖像。header(“ Content-type:image / jpeg”);
//回顯圖像。回顯“ $ img”;
在這里,我們使用行的ID查找所需的圖像。然后,我們從“圖像”列中提取數據,并將其放入一個變量中,我們將在一秒鐘內回顯該變量。在將頁面的標題設置為image / jpeg的內容類型之后,我們可以從變量中回顯二進制數據。
現在請記住,
在header()調用之前無法打印任何內容。如果這樣做,即使打印一個空格,它也會刷新標題并在您嘗試再次調用header()時導致錯誤。注意:錯誤將與“標題已發送”類似。
此過程與也具有Blob字段的其他數據庫非常相似。這里的想法是,我們要獲取一個二進制對象,將其作為轉義的字符串插入,讀回并以告訴瀏覽器我們正在顯示圖像數據的內容類型進行顯示。
那么為什么我們不應該將圖像存儲到這樣的數據庫中呢?數據庫(尤其是MySQL)非常適合快速查找數據和短數據塊。數據庫通常會獲取這些數據并將其分解為可快速在磁盤上定位的頁面。像BLOB這樣的大字段確實使數據庫膨脹,并且我們平時也會享受到了它的優勢,例如在搜索中使用文件名。但!使用大量二進制數據來膨脹數據庫可能會降低查詢速度,因為然后數據庫被迫(可能)讀取2 GB的BLOB以便進行顯示。所以當然不能這么做。
解決方案:
將大型文件作為二進制文件存儲在數據庫中,保持數據庫的精簡并在數據庫中存儲文件的路徑.
可以將其視為指向對象的指針。如果需要顯示圖像,則可以在數據庫中查找該字段,獲取文件路徑,然后使用該路徑從磁盤上定位圖片以進行顯示。這給您帶來兩個好處:1、將數據庫必須管理的數據保持在最低限度(又稱其占用空間); 2、使用文件路徑,我們可以使用查詢來搜索它,以按文件名查找文件。
那么,為什么要有BLOB字段呢?如果您的圖像很小(例如圖標),則該字段可能是一件好事。我也不建議在數據庫中使用大量圖標,但是可以在不引起過多性能噩夢的情況下使用一小塊二進制數據。但是將數據庫留給文件系統管理簡單的快速數據片段和大文件。