سؤال

حسنًا، لدي ملف Index.php الذي عليه معالجة العديد من أنواع الملفات المختلفة.كيف يمكنني تخمين نوع الملف بناءً على ملف REQUEST_URI.

إذا طلبت http://site/image.jpg, ، ويتم إعادة توجيه جميع الطلبات من خلال ملف Index.php، الذي يبدو بهذا الشكل

<?php
   include('/www/site'.$_SERVER['REQUEST_URI']);
?>

كيف يمكنني أن أجعل ذلك يعمل بشكل صحيح؟

هل يجب أن أقوم بالاختبار بناءً على امتداد الملف المطلوب، أم أن هناك طريقة للحصول على نوع الملف؟

هل كانت مفيدة؟

المحلول

إذا كنت متأكدًا من أنك تعمل فقط مع الصور، فيمكنك الاطلاع على الحصول على حجم الصورة () exif_imagetype() دالة PHP، التي تحاول إرجاع نوع الصورة الصامتة.

إذا كنت لا تمانع في التبعيات الخارجية، يمكنك أيضًا التحقق من الخيار الممتاز getID3 المكتبة التي يمكنها تحديد نوع mime للعديد من أنواع الملفات المختلفة.

وأخيرًا، يمكنك الاطلاع على mime_content_type () الوظيفة - ولكن تم إهمالها لـ معلومات الملف امتداد PECL.

نصائح أخرى

تم إهمال mime_content_type()، لذا لن تتمكن من الاعتماد عليه في العمل في المستقبل.يوجد امتداد PECL "fileinfo"، لكنني لم أسمع أشياء جيدة عنه.

إذا كنت تعمل على خادم *nix، فيمكنك القيام بما يلي، والذي كان جيدًا بالنسبة لي:

$file = escapeshellarg( $filename );
$mime = shell_exec("file -bi " . $file);
$filename should probably include the absolute path.
function get_mime($file) {
  if (function_exists("finfo_file")) {
    $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
    $mime = finfo_file($finfo, $file);
    finfo_close($finfo);
    return $mime;
  } else if (function_exists("mime_content_type")) {
    return mime_content_type($file);
  } else if (!stristr(ini_get("disable_functions"), "shell_exec")) {
    // http://stackoverflow.com/a/134930/1593459
    $file = escapeshellarg($file);
    $mime = shell_exec("file -bi " . $file);
    return $mime;
  } else {
    return false;
  }
}

بالنسبة لي، لا شيء من هذا يعمل - mime_content_type تم إهماله، finfo لم يتم تثبيت، و shell_exec غير مسموح.

في الواقع لقد سئمت من عدم وجود معيار طرق استنشاق MIME في PHP.تثبيت معلومات الملف...استخدم الوظائف المهملة...أوه هذه الأعمال، ولكن فقط للصور!لقد سئمت منه، لذلك قمت ببعض البحث ووجدت WHATWG Mimesniffing المواصفات - أعتقد أن هذه لا تزال مجرد مواصفات مسودة.

على أية حال، باستخدام هذه المواصفات، تمكنت من تنفيذ mimesniffer في PHP.الأداء ليس مشكلة.في الواقع، على جهازي المتواضع، تمكنت من فتح آلاف الملفات وشمها قبل انتهاء مهلة PHP.

هنا هو فئة MimeReader.

require_once("MimeReader.php");

$mime = new MimeReader(<YOUR FILE PATH>);
$mime_type_string = $mime->getType();     // "image/jpeg" etc.

إذا كنت تعمل مع الصور فقط وتحتاج إلى نوع mime (على سبيل المثال.بالنسبة للعناوين)، فهذه هي الإجابة الأسرع والأكثر مباشرة:

$file = 'path/to/image.jpg';
$image_mime = image_type_to_mime_type(exif_imagetype($file));

سيتم إخراج نوع mime للصورة الحقيقية حتى إذا قمت بإعادة تسمية ملف الصورة الخاص بك

وفقًا لدليل php، فإن finfo الوظيفة هي أفضل طريقة للقيام بذلك.ومع ذلك، سوف تحتاج إلى تثبيت معلومات الملف امتداد PECL.

إذا لم يكن الامتداد خيارًا، فيمكنك استخدام الامتداد القديم mime_content_type وظيفة.

mime_content_type() يبدو أن هذا هو الطريق الصحيح، على الرغم من التعليقات المذكورة أعلاه التي تقول إنه تم إهماله.إنه ليس - أو على الأقل هذا التجسد mime_content_type() لا يتم إهمالها، وفقا ل http://php.net/manual/en/function.mime-content-type.php.إنه جزء من ملحق FileInfo، لكن وثائق PHP تخبرنا الآن أنه تم تمكينه افتراضيًا اعتبارًا من PHP 5.3.0.

يمكنك استخدام finfo لإنجاز ذلك اعتبارًا من PHP 5.3:

<?php
$info = new finfo(FILEINFO_MIME_TYPE);
echo $info->file('myImage.jpg');
// prints "image/jpeg"

تعتبر علامة FILEINFO_MIME_TYPE اختيارية؛بدونها تحصل على سلسلة مطولة أكثر لبعض الملفات؛(يبدو أن بعض أنواع الصور ستعيد معلومات الحجم وعمق اللون).يؤدي استخدام علامة FILEINFO_MIME إلى إرجاع نوع mime والتشفير إذا كان متاحًا (على سبيل المثال.صورة / بابوا نيو غينيا؛مجموعة الأحرف = ثنائي أو نص/x-php;محارف = لنا-ASCII).يرى هذا الموقع لمزيد من المعلومات.

لم أستخدمه ولكن يوجد امتداد PECL للحصول على نوع mime للملف.الوثائق الرسمية لذلك موجودة في الدليل.

اعتمادًا على أغراضك، يمكن أن يكون امتداد الملف جيدًا، لكنه ليس موثوقًا به بشكل لا يصدق لأنه يمكن تغييره بسهولة.

لقد حصلت على نتائج جيدة جدًا باستخدام وظيفة المستخدم منhttp://php.net/manual/de/function.mime-content-type.php@''جون دوت هوارد في prismmg dot com 26-أكتوبر-2009 03:43''

function get_mime_type($filename, $mimePath = '../etc') { ...

والتي لا تستخدم وظيفة finfo أو exec أو المهملة

يعمل بشكل جيد أيضًا مع الموارد عن بعد!

إذا كنت تتعامل مع الصور فقط، يمكنك استخدام [getimagesize()][1] وظيفة تحتوي على كافة أنواع المعلومات حول الصورة، بما في ذلك النوع.

قد يكون الأسلوب الأكثر عمومية هو استخدام ملحق FileInfo من PECL.يمكن العثور على وثائق PHP لهذا الامتداد على: http://us.php.net/manual/en/ref.fileinfo.php

البعض لديه شكاوى جدية حول هذا التمديد.لذا، إذا واجهت مشكلات خطيرة أو لم تتمكن من تثبيت الامتداد لسبب ما، فقد ترغب في التحقق من الوظيفة المهملة mime_content_type()

إذا كنت تستخدم Linux ولديك الامتداد، فيمكنك ببساطة قراءة نوع MIME من /etc/mime.types عن طريق إنشاء مصفوفة تجزئة.يمكنك بعد ذلك تخزين ذلك في الذاكرة واستدعاء MIME ببساطة عن طريق مفتاح الصفيف :)

/**
 * Helper function to extract all mime types from the default Linux /etc/mime.types
 */
function get_mime_types() {
    $mime_types = array();
    if (
        file_exists('/etc/mime.types') &&
        ($fh = fopen('/etc/mime.types', 'r')) !== false
    ) {
        while (($line = fgets($fh)) !== false) {
            if (!trim($line) || substr($line, 0, 1) === '#') continue;
            $mime_type = preg_split('/\t+/', rtrim($line));
            if (
                is_array($mime_type) &&
                isset($mime_type[0]) && $mime_type[0] &&
                isset($mime_type[1]) && $mime_type[1]
            ) {
                foreach (explode(' ', $mime_type[1]) as $ext) {
                    $mime_types[$ext] = $mime_type[0];
                }
            }
        }
        fclose($fh);
    }
    return $mime_types;
}

يمكن الحصول على التمثيل الصامت لأي ملف على الخادم الخاص بك باستخدام هذا

<?php
function get_mime($file_path){
  $finfo = new finfo(FILEINFO_MIME_TYPE);
  $type  = $finfo->file(file_path);
}

$mime = get_mime('path/to/file.ext');
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top