02/10/2018, 18:06

Lưu nội dung file ảnh vào CSDL và đọc ra từ CSDL

GIỚI THIỆU Một nhu cầu thường gặp khi phát triển các ứng dụng PHP là lưu nội dung file ảnh vào trong CSDL và sau đó đọc nội dung file ảnh đã lưu trong CSDL và hiển thị ra browser. Việc lưu nội dung file nói chung và file ảnh nói riêng vào CSDL... Một nhu cầu thường ...

GIỚI THIỆU Một nhu cầu thường gặp khi phát triển các ứng dụng PHP là lưu nội dung file ảnh vào trong CSDL và sau đó đọc nội dung file ảnh đã lưu trong CSDL và hiển thị ra browser. Việc lưu nội dung file nói chung và file ảnh nói riêng vào CSDL...

Một nhu cầu thường gặp khi phát triển các ứng dụng PHP là lưu nội dung file ảnh vào trong CSDL và sau đó đọc nội dung file ảnh đã lưu trong CSDL và hiển thị ra browser. Việc lưu nội dung file nói chung và file ảnh nói riêng vào CSDL có một số ưu điểm như sau: 

  • Backup/Restore: backup và restore nhiều file nhỏ đôi khi không mấy thuận tiện. Lưu nội dung các file ảnh trong CSDL, bạn chỉ cần backup và restore một file CSDL (thường ở dạng SQL) duy nhất.
  • Đường dẫn trên website: khi lưu file ảnh trên đĩa, nếu cấu trúc thư mục bị thay đổi, bạn có thể phải cập nhật lại đường dẫn ở nhiều chỗ trên website. File ảnh trên đĩa có thể bị xoá mất, hoặc khi bạn backup/restore bị thiếu...Khi lưu file ảnh trong CSDL, bạn có thể giảm thiểu được các rủi ro này.
  • Cấu hình chung của một số host không cho phép bạn lưu file sau khi được upload lên server (qua form upload) trong thư mục (nếu như bạn không cấp quyền write cho everyone, và như vậy thì khá nguy hiểm cho website của bạn). Lưu file trong CSDL là giải pháp khá thích hợp trong hoàn cảnh này.

Không chỉ giới hạn ở file ảnh, chúng ta có thể lưu bất kỳ file nào vào CSDL. Nhưng để đơn giản, trong bài viết này chúng ta sẽ tìm hiểu về cách lưu file ảnh vào CSDL MySQL. Bạn có thể phát triển thêm chương trình mẫu trong bài viết để lưu các định dạng file khác. THIẾT KẾ CSDL
Chúng ta sẽ dùng CSDL MySQL trong bài viết này. Chúng ta cần 1 table để lưu nội dung của file ảnh. Table này có ít nhất 2 cột: 

  • Cột lưu nhận dạng (ID) của file ảnh, để đơn giản ta sẽ sử dụng kiểu dữ liệu AUTO_INCREMENT để làm ID cho các file ảnh lưu trong CSDL. Ta đặt tên cho cột này là imgID.
  • Cột lưu nội dung của file ảnh. Nội dung của file ảnh cũng là 1 chuỗi, nhưng dữ liệu nhị phân. Chúng ta sẽ sử dụng kiểu dữ liệu mediumblob để lưu trữ nội dung của file ảnh (kiểu dữ liệu blob cũng là chuỗi nhị phân, nhưng độ dài tối đa chỉ 65Kb, sẽ không đủ nếu như ta muốn lưu các file ảnh lớn). Ta đặt tên cho cột này là imgData.

Bạn có thể thiết kế thêm một số cột nữa (như ngày tháng file được lưu vào CSDL, tên file...) tuỳ vào yêu cầu cụ thể. Table của chúng ta sẽ có cấu trúc tương tự như sau: 

 

CREATE TABLE tblImage (
    imgID           int             NOT NULL AUTO_INCREMENT,
    imgData         mediumblob      NOT NULL,
    PRIMARY KEY (imgID)
);

LƯU NỘI DUNG FILE ẢNH VÀO CSDL
Ta xem như đã có file ảnh trên server, đoạn chương trình sau sẽ mở file ảnh thông qua tên file, đọc nội dung của file ảnh vào trong 1 biến và lưu vào CSDL (để đơn giản, các đoạn mã kiểm tra lỗi được lược bỏ). 

<?php
//connect vào CSDL MySQL
//host = localhost
//username = root
//password = rỗng
$conn = mysql_connect("localhost", "root", "");
 
//chọn database làm việc
mysql_select_db("test", $conn);
 
//tên file ảnh
$imgFilename = "testimg.jpg";
 
//mở file ảnh để đọc với chế độ đọc binary
$fh = fopen($imgFilename, "rb");
$imgData = fread($fh, filesize($imgFilename));
fclose($fh);
 
//chèn nội dung file ảnh vào table imgData
$sql = "INSERT INTO tblImage (imgData) VALUES('" . mysql_real_escape_string($imgData, $conn) . "')";
mysql_query($sql, $conn);
?>

ĐỌC NỘI DUNG FILE ẢNH TỪ CSDL
Để đọc nội dung của file ảnh từ CSDL, ta cần ID của file ảnh. Đoạn mã sau sẽ minh hoạ điều này: 

<?php
//connect vào CSDL MySQL
//host = localhost
//username = root
//password = rỗng
$conn = mysql_connect("localhost", "root", "");
 
//chọn database làm việc
mysql_select_db("test", $conn);
 
//ID của file ảnh
$imgID = 1;
 
//đọc nội dung file ảnh từ table tblImage
$sql = "SELECT * FROM tblImage WHERE imgID=" . $imgID;
$result = mysql_query($sql, $conn);
if ( mysql_num_rows($result) < 1 ) {
    //không tìm thấy image với ID chỉ định
    //thông báo lỗi nếu cần thiết
} else {
    $row = mysql_fetch_assoc($result);
    $imgData = $row['imgData'];
} //end if
?>

Biến $imgData sẽ chứa nội dung của file ảnh. Bước tiếp theo, ta xuất nội dung của file ảnh ra browser. Quá trình xuất nội dung của file ảnh ra browser tương tự như trong ví dụ Một chương trình download manager đơn giản: 
 <?php
    //...
    $row = mysql_fetch_assoc($result);
    $imgData = $row['imgData'];
    header("Content-type: image/jpeg");
 
    echo $imgData;
    //...
?>

Như bạn cũng đã thấy, lưu file ảnh trong CSDL, đọc dữ liệu ảnh từ CSDL và xuất ra browser thật đơn giản phải không nào? Các bước chính bạn cần lưu ý chỉ là: 

  • Đọc nội dung file vào 1 biến, bạn nhớ phải mở file với chế độ đọc binary.
  • Xử lý các ký tự đặc biệt trước khi lưu vào database (sử dụng hàm mysql_real_escape_string).
  • Trước khi xuất nội dung file ra browser, bạn nhớ dùng hàm header để báo cho browser biết kiểu file mà chương trình của bạn chuẩn bị trả về (tham khảo thêm bài viết Một chương trình download manager đơn giản).

CẢI TIẾN CHƯƠNG TRÌNH
Bạn có thể cải tiến thêm chương trình để lưu bất cứ loại file nào chứ không riêng gì file ảnh. Kết hợp với ví dụ trong bài viết Một chương trình download manager đơn giản, bạn có thể làm 1 chương trình upload file và lưu trong CSDL, đồng thời giấu được đường dẫn không cho download file trực tiếp từ server của bạn.
Bạn có thể cải tiến chương trình như sau: 

  • Đổi tên table tblImage thành tên khác, ví dụ như tblUpload để chứa các file bất kỳ được upload chứ không riêng gì file ảnh.
  • Lưu tên file: tạo thêm 1 cột trong table tblUpload để lưu tên file gốc ban đầu.
  • Lưu kích thước file tạo thêm 1 cột trong table tblUpload để lưu kích thước của file.
  • v.v...

TÀI LIỆU THAM KHẢO

  • PHP Manual: http://www.php.net/manual/en/index.php
    • Các hàm thao tác với CSDL MySQL: http://www.php.net/manual/en/ref.mysql.php
    • Các hàm thao tác với file: http://www.php.net/manual/en/ref.filesystem.php
  • Google: từ khoá MIME types list
    • Các kiểu dữ liệu tương ứng với các kiểu file thông dụng: http://www.webmaster-toolkit.com/mime-types.shtml
    DDTH
Bình luận
0