2012-04-08 49 views
6

Tôi đang làm việc trên biểu mẫu tải lên bằng php chỉ cho phép các tệp mp3.là phát hiện loại mime là cách tốt nhất để phát hiện một loại tệp?

khi tải lên xong, tôi phân tích tệp để kiểm tra xem nó có thực sự là mp3 hay không .. bước đầu tiên là phát hiện loại mime là "audio/mpeg", tôi sử dụng thư viện finfo_file() và hoạt động tốt ngoại trừ trong thời gian các bài kiểm tra một số mp3 bị từ chối vì kết quả loại mime của họ là: application/octet-stream

câu hỏi của tôi là: - ứng dụng của tôi có từ chối chắc chắn những mp3 đó không? họ thực sự chơi âm thanh - là có bất kỳ lý do tại sao loại mime này là một mp3? - là việc phát hiện loại mime là cách chắc chắn nhất để biết loại tệp?

Trả lời

0

Nếu bạn muốn một cách cực kỳ mạnh mẽ để phát hiện các loại tệp mà không tin tưởng máy khách cung cấp loại MIME chính xác, hãy sử dụng tiện ích file trên UNIX.

$ file Black\ Sands\ 01\ Prelude.mp3 
Black Sands 01 Prelude.mp3: Audio file with ID3 version 2.2.0, contains: MPEG ADTS, layer III, v1, 320 kbps, 44.1 kHz, Stereo 

$ file homework/math475-hw8.docx 
homework/math475-hw8.docx: Microsoft Word 2007+ 

Trong PHP, bạn có thể sử dụng chức năng exec để gọi.

+0

đây là một tùy chọn mà tôi không nghĩ đến .. và tôi không thể kiểm tra vì tôi đang giành chiến thắng – enkore

+0

Có phiên bản được biên dịch cho win32 [ở đây] (http://gnuwin32.sourceforge.net/packages/ file.htm). –

+0

Lệnh 'file' và hàm' finfo_file' của PHP sử dụng cùng phương thức để xác định loại mime (thường là tham chiếu '/ usr/share/misc/magic'). Nó không được sử dụng sau đó để 'exec file' khi bạn có một chức năng được xây dựng trong. Tuy nhiên, tôi có một trường hợp ở đây, nơi '.mp3' đang được phát hiện dưới dạng' application/octet-stream' bởi cả 'finfo_file' và' file -I', khi tôi mong đợi nó trả về 'audio/mpeg'. Cả hai đều thất bại. Tuy nhiên, tôi nghĩ rằng điều này có thể được giải quyết bằng cách chuyển đường dẫn đến tệp 'magic' được cải thiện làm đối số thứ hai cho' finfo_open'. –

0

Phương pháp phát hiện tệp tốt nhất là sử dụng lược đồ "ma thuật byte" hoặc "số ma thuật", ngoài MIME. Unix file (cũng như finfo_file) thực sự sử dụng "byte ma thuật" để phát hiện tệp này. Vì vậy, trong ngắn hạn: có.

Đừng lo lắng quá nhiều về nội dung tệp của bạn và hơn thế nữa về những gì bạn có thể làm với tệp. Miễn là nó phát, tập tin sẽ không sao.

Nếu bạn thực sự muốn làm nhiều hơn, bạn có thể tự kiểm tra các byte ma thuật. Có a list of them here.

+0

đó là lý do tại sao với getid3() lớp tôi nhận được "audio/mpeg" nhưng với finfo_filei nhận được "application/octet-stream" trên cùng một tệp .. điều này hơi lạ .. nhưng ngay cả khi tệp có thể phát, nếu kết quả với một loại mime khác nhau nó sẽ bị từ chối vì lý do an ninh (trừ khi tôi tìm thấy một cách tốt hơn) .. tôi tự hỏi có bao nhiêu mp3 không có một mime chính xác .. – enkore

+1

@enkore "tôi tự hỏi có bao nhiêu mp3 không phải là một mime chính xác "Kiểu MIME được cung cấp bởi máy khách. Nó không cố hữu trong tập tin mp3. –

2

Trong hầu hết các ứng dụng của tôi khi tải lên là cần thiết, đôi khi tôi giải quyết để xác thực MIME được trình duyệt (ứng dụng khách) truyền qua danh sách các loại MIME được xác định trước. Cách tiếp cận này đưa ra giả định chung rằng nếu có điều gì đó đáng ngờ xảy ra khi trình duyệt không thể truyền đạt loại MIME của một tệp đang được tải lên, có lẽ tôi không muốn bận tâm xử lý nó vào lúc này.

<?php 

$valid_mp3_mimes = array(
    'audio/mpeg', 
    'audio/x-mpeg', 
    'audio/mp3', 
    'audio/x-mp3', 
    'audio/mpeg3', 
    'audio/x-mpeg3', 
    'audio/x-mpeg-3', 
    'audio/mpg', 
    'audio/x-mpg', 
    'audio/x-mpegaudio', 
    'video/mpeg', 
    'video/x-mpeg', 
); 

$uploaded_file_mime = $_FILES['upload_field_name']['type']; 

if(!in_array($uploaded_file_mime, $valid_mp3_mimes)) 
{ 
    die('Upload is not a valid MP3 file.'); 
} 

Bạn có thể hoặc không cảm thấy đây là phương pháp đầy đủ cho mục đích của mình. Hướng dẫn sử dụng PHP tuyên bố rõ ràng rằng thông tin này có sẵn nếu trình duyệt cung cấp thông tin này và kiểu MIME KHÔNG được chọn ở phía máy chủ và do đó không được xem là đã cấp.

Một điều cần lưu ý là tính khả dụng của tài nguyên trên máy chủ cho phép bạn xác thực loại MIME thực của tệp.

Là nhà phát triển PHP, chúng tôi thích tính linh hoạt của việc tạo mã độc lập nền tảng (ví dụ: các ứng dụng web của chúng tôi được xây dựng trên hệ điều hành Windows chạy XAMPP có thể được triển khai sang môi trường lưu trữ Linux với rất ít sửa đổi). Tuy nhiên, khi xác nhận các loại MIME, chúng tôi bắt đầu giới thiệu các phương pháp phụ thuộc nền tảng mà yêu cầu xác minh sự tồn tại của các công cụ này (chẳng hạn như "tệp" hoặc "finfo_file").

Đây có thể là một thực hiện giá trị nghiên cứu (lấy từ kho CodeIgniter GitHub) mà sử dụng những công cụ này và đang ngày càng trở thấu đáo về một ví dụ làm việc như bạn đang đi để có được trong phạm vi PHP:

Loại tệp MIME phát hiện loại MIME (thực tế) của tệp được tải lên, nếu có thể. https://github.com/EllisLab/CodeIgniter/blob/develop/system/libraries/Upload.php#L983


Nguồn

PHP Manual POST phương pháp cập nhật - http://www.php.net/manual/en/features.file-upload.post-method.php

Webmaster Toolkit loại Mime - http://www.webmaster-toolkit.com/mime-types.shtml

FILExt .MP3 File - http://filext.com/file-extension/MP3

Các vấn đề liên quan