Hướng dẫn
Quảng cáo

Kết hợp Dropzone.js với PHP để tải lên hình ảnh

Bài viết hướng dẫn các bạn các dùng Dropzone.js để tải hình ảnh lên website kết hợp với PHP một cách đơn giản và chi tiết.

Tải tệp lên bằng cách kéo và thả đã trở thành chuẩn mực kể từ năm 2015. Phải thừa nhận rằng không ai thích nhấp vào một vài nút chỉ để tải lên một hình ảnh, sau đó quay lại cùng một trang đó chỉ để tải lên một hình ảnh khác. Chỉ là tốn RẤT NHIỀU công sức.

Đúng vậy, ngày xưa, việc tải tệp lên rất khó khăn. Không chỉ vậy, nếu bạn là nhà phát triển, việc nhập dữ liệu lựa chọn tệp đó RẤT tẻ nhạt.

Rất may, chúng tôi đã tìm ra, không chỉ đẹp hơn mà còn dễ hơn để xử lý việc tải tệp lên… và chúng tôi gọi đó là: Kéo và Thả. 

Có rất nhiều cách để thực hiện tải tệp lên bằng cách kéo và thả. Một là tự tạo bằng JavaScript thuần (Chỉ khi bạn không bị bệnh), hai là sử dụng các thư viện như Modernizr để phát hiện các sự kiện kéo và thả, và ba là sử dụng các plugin như Dropzone.js .

Trong hướng dẫn này, chúng ta sẽ tập trung vào cách sử dụng thư viện JavaScript có tên Dropzone.js để triển khai tải tệp lên bằng cách kéo và thả. Chúng tôi cũng sẽ hướng dẫn bạn cách đảm bảo rằng người dùng chỉ có thể tải hình ảnh lên.

DropzoneJS là gì

Dropzone.js được biết đến là một trong những thư viện JavaScript kéo và thả phổ biến nhất. Tại sao? Vâng, trước hết là MIỄN PHÍ và mã nguồn mở và thứ hai, nó rất dễ sử dụng và áp dụng cho bất kỳ trang web nào.

DropzoneJS giúp các nhà phát triển dễ dàng triển khai các tính năng như vậy chỉ bằng cách thêm một dòng mã duy nhất. Dòng mã duy nhất đó sẽ thực hiện hầu như mọi thứ cho bạn bao gồm cả việc thêm các đầu vào hoặc các thành phần HTML, kiểu, v.v. và điều duy nhất bạn cần làm là đảm bảo rằng tệp sẽ đi đến đâu đó.

Đặc trưng

DropzoneJS cung cấp các tính năng sau:

  • Hỗ trợ kéo và thả
  • Hình ảnh thu nhỏ
  • Hỗ trợ tải lên nhiều tập tin
  • Thanh tiến trình
  • Hoàn toàn tùy biến
  • Đã tối ưu hóa hoàn toàn (13KB)
  • Hỗ trợ hầu hết các trình duyệt

Trình duyệt được hỗ trợ

Hiện tại, DropzoneJS hỗ trợ các trình duyệt sau:

  • Chrome 7+
  • Firefox 4+
  • Trình duyệt IE10+
  • Opera 12+ (nhưng phiên bản 12 dành cho MacOS hiện đang bị vô hiệu hóa do API lỗi)
  • Safari6+

Cách sử dụng DropzoneJS

Điều đầu tiên bạn cần làm để bắt đầu sử dụng DropzoneJS là tải xuống phiên bản mới nhất từ trang GitHub của dự án . Ngay lúc này, phiên bản mới nhất là 6.0.0-beta-2.

Nếu bạn không thể tải xuống các tệp nguồn từ trang GitLab của họ, bạn có thể truy cập trang CDN của họ .

Bằng cách đó, thẻ script của bạn sẽ trông giống như thế này:

Ví dụ

<script src="https://unpkg.com/dropzone@6.0.0-beta.1/dist/dropzone-min.js"></script>


Nếu bạn muốn sử dụng kiểu kéo và thả mặc định, bạn có thể sử dụng tệp CSS sau.

Ví dụ

<link href="https://unpkg.com/dropzone@6.0.0-beta.1/dist/dropzone.css" rel="stylesheet" type="text/css" />


Sử dụng các nguồn trên, bạn sẽ có mã HTML sau.

Ví dụ

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Ví dụ về tải hình ảnh với Dropzone</title>
        <link href="https://unpkg.com/dropzone@6.0.0-beta.1/dist/dropzone.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
        <script src="https://unpkg.com/dropzone@6.0.0-beta.1/dist/dropzone-min.js"></script>
    </body>
</html>

Điều quan trọng cần nhớ là dự án cung cấp hai tệp CSS, tệp basic.css cung cấp kiểu dáng tối giản và dropzone.css tệp mở rộng hơn. Các tệp nguồn mà chúng tôi đang sử dụng ở trên là các phiên bản thu nhỏ của DropzoneJS.

Cách sử dụng cơ bản

Một trong những cách dễ nhất để triển khai dropzone là áp dụng nó vào một phần tử biểu mẫu, mặc dù theo tài liệu chính thức của dropzone , bạn có thể sử dụng bất kỳ phần tử HTML nào như <div>.

Tuy nhiên, nếu bạn là người mới bắt đầu, chúng tôi khuyên bạn nên sử dụng biểu mẫu vì nó chỉ yêu cầu một vài cấu hình để thiết lập.

Bạn có thể khởi tạo nó chỉ bằng cách thêm lớp dropzone và trang hành động nơi bạn muốn gửi dữ liệu POST.

Ví dụ

<form id="dropzone-upload-form" method="POST" action="upload.php" class="dropzone"></form>

Lấy dữ liệu POST từ biểu mẫu Dropzone

Việc lấy dữ liệu từ dropzone không khác gì việc lấy dữ liệu từ Ajax hoặc XMLHTTPRequest.

Tất cả đều thực hiện cùng một công việc. Nhưng với Dropzone, bạn không cần phải tạo hàm Ajax hoặc yêu cầu.

Sau khi bạn áp dụng biểu mẫu trong mã của mình, tất cả những gì bạn cần làm là đảm bảo rằng tệp được tải lên máy chủ của bạn và để làm điều đó, bạn sẽ cần tạo tệp PHP được tham chiếu trong thuộc tính hành động.

Ví dụ, đây sẽ là những gì bên trong tệp upload.php của chúng tôi.

Ví dụ

<?php
if ( !file_exists( 'images/' ) ) {
    mkdir( 'images/', 0777, true);
}
$imagesFolder = '/images/';
if (!empty($_FILES)) {
    $temp = $_FILES['file']['tmp_name'];
    $target = dirname( __FILE__ ) . $imagesFolder;
    $finalFile =  $target . $_FILES['file']['name'];
    move_uploaded_file( $temp, $finalFile );
}
?>


Trước hết, trước khi tải các tệp lên, hãy kiểm tra xem thư mục chúng ta muốn lưu ảnh vào có tồn tại không. Nếu không, hãy tạo thư mục bằng hàm mkdir().

Sau đó, chúng ta kiểm tra xem biến $_FILES có rỗng không. Nếu không, chúng ta gán tên tạm thời của tệp vào một biến mới $temp và tạo một tập hợp các biến khác để tạo tệp cuối cùng mà chúng ta muốn lưu.

Và cuối cùng, chúng ta sử dụng hàm move_uploaded_file() để lưu các tệp.

Với tất cả những điều đó, bạn sẽ có thể lưu tất cả các tệp bạn tải lên.


Sửa đổi tùy chọn cấu hình

Có nhiều cách để cấu hình dropzone.

Cách đầu tiên là truyền đối tượng tùy chọn khởi tạo dropzone.

Cách thứ hai là lưu trữ cấu hình ở đâu đó để Dropzone biết cách thiết lập dropzone khi bạn khởi tạo chúng.

Điều này luôn có thể thực hiện bằng đối tượng Dropzone.options.

Ví dụ

Dropzone.options.myDragAndDropUploader = {
    paramName: "file",
    accept: function(file, done) {
        if (file.name == "weeklyhow.png") {
            done("It is the file.");
        }
        else {
            done("It is not the file");
        }
    }
};


Hãy nhớ rằng the myDragAndDropUploader là id của phần tử của trình tải tệp lên. Nó có thể là một <div> hoặc bất kỳ thứ gì khác ngoài form.

Thiết lập kích thước tệp tối đa

Với Dropzones, theo mặc định, bạn có thể tải lên các tệp có kích thước tệp lên đến 256MB. Đó là giá maxFileSize trị mặc định. Bạn luôn có thể thay đổi giá trị của thuộc tính này bằng cách thêm nó vào đối tượng tùy chọn của bạn như bên dưới.

Ví dụ

Dropzone.options.myDragAndDropUploader = {
    paramName: "file",
    maxFilesize: 1,
    accept: function(file, done) {
        if (file.name == "weeklyhow.png") {
            done("It is the file.");
        }
        else {
            done("It is not the file");
        }
    }
};


Hãy nhớ rằng số nguyên bạn nhập vào thuộc tính maxFilesize chỉ chuyển đổi thành Megabyte. Nếu bạn cần giới hạn kích thước tệp theo kilobyte thì hãy sử dụng số thập phân.

Hạn chế một số loại tệp nhất định

Có hai cách để hạn chế một số loại tệp nhất định.

Một là sử dụng tệp upload.php và tạo điều kiện để kiểm tra xem tệp có phải là hình ảnh hay không.

Hai là sử dụng tham số acceptedFiles để hạn chế loại tệp bạn muốn tải lên.

Giống như những gì chúng tôi đã đề cập trước đó, chúng tôi chỉ muốn tải lên các tệp hình ảnh.

Vì vậy, đối với điều này, chúng tôi có thể chấp nhận các tệp hình ảnh bằng cách sử dụng sau.

Ví dụ

Dropzone.options.myDragAndDropUploader = {
    paramName: "file",
    maxFilesize: 10,
    acceptedFiles: 'image/*',
    accept: function(file, done) {
        if (file.name == "weeklyhow.png") {
            done("It is the file.");
        }
        else {
            done("It is not the file");
        }
    }
};


Ngay khi bạn nhấp vào trình tải tệp lên, bạn sẽ thấy rằng nó chỉ đọc các tệp hình ảnh.
Và nếu bạn thử kéo và thả một loại tệp khác, bạn sẽ thấy kết quả báo lỗi.

Xóa bỏ hình ảnh vừa đăng

Khi bạn đăng tải hình nhưng lại muốn thay bằng một hình khác thì làm thế nào? Sau đây là cách làm của mình:

Cấu hình JS như sau:

Ví dụ

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dropzone with Delete</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.2/min/dropzone.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.2/min/dropzone.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <style>
        .dz-remove {
            cursor: pointer;
        }
    </style>
</head>

<body>
    <form action="/upload" class="dropzone" id="demoupload"></form>
    <input type="hidden" name="featuredimage" value="" id="image">
    <script>
Dropzone.options.demoupload = {
    url: 'upload.php',
    maxFiles: 1,
    acceptedFiles: 'image/*',
    maxFilesize: 1, // Maximum file size in MB
    addRemoveLinks: true,
    success: function (file, response) {
        console.log(response);
        file.fileId = response; // Store fileId on the file object
        document.getElementById('featuredimage').value = response;
    },
    init: function () {
        this.on("error", function (file, message) {
            if (file.size > this.options.maxFilesize * 1024 * 1024) {
                alert("Lỗi rồi nhé!", "Kích cỡ tệp ảnh tối đa là  " + this.options.maxFilesize + "MB", "warning");
                this.removeFile(file);
            } else {
                alert(message);
            }
        });
        this.on("removedfile", function (file) {
                    if (file.fileId) {
                        //alert(file.fileId);
                        $.ajax({
                            type: 'POST',
                            url: 'delete.php', // Server URL to handle deletion
                            data: { fileId: file.fileId },
                            success: function (response) {
                                console.log("File deleted successfully:", response);
                            },
                            error: function (error) {
                                console.error("Error deleting file:", error);
                            }
                        });
                    }
                });
    }
};
    </script>
</body>

</html>

Tệp tin PHP để xóa hình ảnh

Ví dụ

<?php
if (isset($_POST['fileId'])) {
    $fileId = $_POST['fileId'];
    $filePath = "uploads/" . $fileId;

    if (file_exists($filePath)) {
        if (unlink($filePath)) {
            echo json_encode(['success' => true]);
        } else {
            http_response_code(500);
            echo json_encode(['error' => 'Failed to delete file']);
        }
    } else {
        http_response_code(404);
        echo json_encode(['error' => 'File not found']);
    }
}
?>

Xem hình phóng to với Lightbox

Khi tải lên hình ảnh sẽ hiển thị ở chế độ thu nhỏ, bạn muốn xem to thì cần kết hợp với Lightbox. Cách làm như sau:

Sau đây là cách bạn có thể đạt được điều này:

Bước 1: Bao gồm Lightbox CSS và JS

Đảm bảo bạn đã đưa Lightbox CSS và JS vào HTML của mình:

Ví dụ

<head>
    <!-- Other head elements -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.3/dropzone.min.css" rel="stylesheet" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.3/css/lightbox.min.css" rel="stylesheet" />
</head>
<body>
    <!-- Other body elements -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.3/dropzone.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.3/js/lightbox.min.js"></script>
</body>

Bước 2: Sửa đổi cấu hình Dropzone

Cập nhật tập lệnh khởi tạo Dropzone để thêm một nút riêng cho hình ảnh Lightbox:

Ví dụ

Dropzone.options.featureImageDropzone = {
    url: 'upload.php',
    maxFiles: 1,
    acceptedFiles: 'image/*',
    maxFilesize: 1, // Maximum file size in MB
    addRemoveLinks: true,
    init: function() {
        var existingImage = document.getElementById('featureImage').value;
        var dropzone = this;

        if (existingImage) {
            var mockFile = { name: existingImage, size: 12345, url: '/path/to/uploads/' + existingImage };

            // Add the mock file to Dropzone
            dropzone.emit("addedfile", mockFile);
            dropzone.emit("thumbnail", mockFile, mockFile.url);
            dropzone.emit("complete", mockFile);

            // Add a button for the lightbox
            addLightboxButton(mockFile, mockFile.url);

            // Ensure the file is considered added
            dropzone.files.push(mockFile);
        }

        this.on("success", function(file, response) {
            console.log(response);
            document.getElementById('featureImage').value = response.fileName; // Update hidden input with file name

            // Add a button for the lightbox
            addLightboxButton(file, response.fileUrl); // The URL of the uploaded image
        });

        this.on("removedfile", function(file) {
            if (file.name) {
                $.ajax({
                    type: 'POST',
                    url: 'delete-photo.php', // Your server URL to handle deletion
                    data: { fileName: file.name },
                    success: function(response) {
                        console.log("File deleted successfully:", response);
                        document.getElementById('featureImage').value = ''; // Clear hidden input
                    },
                    error: function(error) {
                        console.error("Error deleting file:", error);
                    }
                });
            }
        });

        function addLightboxButton(file, imageUrl) {
            var lightboxButton = document.createElement('button');
            lightboxButton.innerHTML = 'View Larger';
            lightboxButton.className = 'btn btn-lightbox';
            lightboxButton.setAttribute('data-lightbox', 'feature-image');
            lightboxButton.setAttribute('data-title', file.name);
            lightboxButton.setAttribute('href', imageUrl);

            file.previewElement.appendChild(lightboxButton);
        }
    }
};

Giải thích

  1. Thiết lập HTML :

    • Bao gồm Lightbox CSS và JS cho chức năng lightbox.
  2. Khởi tạo Dropzone :

    • Cấu hình Dropzone để xử lý một tệp duy nhất, thêm/xóa liên kết và xử lý các sự kiện thành công và xóa.
    • Khi thành công, tên tệp đã tải lên sẽ được lưu trữ trong đầu vào ẩn và một nút sẽ được tạo cho hộp đèn.
    • Khi xóa, yêu cầu AJAX sẽ xóa tệp khỏi máy chủ và xóa dữ liệu đầu vào ẩn.
    • Khi tải một hình ảnh hiện có hoặc tải lên một hình ảnh mới, một nút riêng biệt sẽ được thêm vào phần tử xem trước Dropzone, cho phép mở hình ảnh ở chế độ xem hộp đèn.

Cách tiếp cận này giữ nguyên màn hình Dropzone ban đầu trong khi thêm một nút mới để xem hình ảnh trong Lightbox.

Ví dụ đầy đủ

Với tất cả thông tin được cung cấp ở trên, bạn sẽ có thể thực hiện các thao tác cơ bản về kéo và thả bằng Dropzone.js.

Và cuối cùng, với tất cả mã nguồn chúng tôi cung cấp ở trên, bạn cũng sẽ có mã sau.

Ví dụ

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>File Upload Example</title>
        <link href="https://unpkg.com/dropzone@6.0.0-beta.1/dist/dropzone.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
        <form id="myDragAndDropUploader" method="POST" action="test.php" class="dropzone"></form>
        <script src="https://unpkg.com/dropzone@6.0.0-beta.1/dist/dropzone-min.js"></script>
    </body>
    <script type="text/javascript">
        Dropzone.options.myDragAndDropUploader = {
            paramName: "file",
            maxFilesize: 10,
            acceptedFiles: 'image/*'
        };
    </script>
</html>


Tệp tải lên bằng PHP

Ví dụ

<?php
if ( !file_exists( 'images/' ) ) {
    mkdir( 'images/', 0777, true);
}
$imagesFolder = '/images/';
if (!empty($_FILES)) {
    $temp = $_FILES['file']['tmp_name'];
    $target = dirname( __FILE__ ) . $imagesFolder;
    $finalFile =  $target . changeString( $_FILES['file']['name'] );
    move_uploaded_file( $temp, $finalFile );
}
?>

Kết luận 

DropzoneJS là một trong những thư viện JavaScript mạnh mẽ nhất để triển khai tải tệp kéo và thả. Trong khóa học này, chúng ta đã học được những điều cơ bản về tất cả những điều đó. Nếu bạn quan tâm đến nhiều hơn, chúng tôi rất muốn cung cấp cho bạn nhưng trong thời gian chờ đợi, chúng tôi hy vọng rằng mọi thứ chúng tôi đề cập ở đây là đủ để bạn bắt đầu.

Bài viết này đã giúp ích cho bạn?

Bài viết mới

Advertisements