2009-03-24 25 views
44

में एक छवि है, एक यूआरएल दिया गया है, मैं यह कैसे निर्धारित कर सकता हूं कि यह एक छवि है या नहीं?यह निर्धारित करने का सबसे अच्छा तरीका है कि कोई URL PHP

यूआरएल के लिए कोई संदर्भ नहीं है - यह सिर्फ एक सादे पाठ फ़ाइल के बीच में है, या शायद अपने आप पर एक स्ट्रिंग है।

मुझे उच्च ओवरहेड नहीं चाहिए (उदा। यूआरएल की सामग्री पढ़ना) क्योंकि इसे किसी पृष्ठ पर कई यूआरएल के लिए बुलाया जा सकता है। इस प्रतिबंध को देखते हुए, यह आवश्यक नहीं है कि सभी छवियों की पहचान की जाए, लेकिन मुझे काफी अच्छा अनुमान चाहिए।

फिलहाल मैं फ़ाइल एक्सटेंशन को देख रहा हूं, लेकिन ऐसा लगता है कि इससे बेहतर तरीका होना चाहिए।

यहाँ मैं वर्तमान में क्या है:

function isImage($url) 
    { 
    $pos = strrpos($url, "."); 
    if ($pos === false) 
     return false; 
    $ext = strtolower(trim(substr($url, $pos))); 
    $imgExts = array(".gif", ".jpg", ".jpeg", ".png", ".tiff", ".tif"); // this is far from complete but that's always going to be the case... 
    if (in_array($ext, $imgExts)) 
     return true; 
    return false; 
    } 

संपादित करें: मामले में यह किसी और यहाँ किसी को भी करने के लिए उपयोगी है अंतिम समारोह एमिल एच के जवाब से तकनीक का उपयोग:

function isImage($url) 
    { 
    $params = array('http' => array(
        'method' => 'HEAD' 
       )); 
    $ctx = stream_context_create($params); 
    $fp = @fopen($url, 'rb', false, $ctx); 
    if (!$fp) 
     return false; // Problem with url 

    $meta = stream_get_meta_data($fp); 
    if ($meta === false) 
    { 
     fclose($fp); 
     return false; // Problem reading data from url 
    } 

    $wrapper_data = $meta["wrapper_data"]; 
    if(is_array($wrapper_data)){ 
     foreach(array_keys($wrapper_data) as $hh){ 
      if (substr($wrapper_data[$hh], 0, 19) == "Content-Type: image") // strlen("Content-Type: image") == 19 
      { 
      fclose($fp); 
      return true; 
      } 
     } 
    } 

    fclose($fp); 
    return false; 
    } 

उत्तर

28

आप HTTP HEAD अनुरोध का उपयोग कर सकते हैं और सामग्री-प्रकार की जांच कर सकते हैं। यह एक अच्छा समझौता हो सकता है। यह PHP Streams का उपयोग करके किया जा सकता है। Wez Furlong में article है जो दिखाता है कि पोस्ट अनुरोध भेजने के लिए इस दृष्टिकोण का उपयोग कैसे करें, लेकिन इसे आसानी से HEAD अनुरोध भेजने के लिए अनुकूलित किया जा सकता है। आप stream_get_meta_data() का उपयोग कर हेडर को http प्रतिक्रिया से पुनर्प्राप्त कर सकते हैं।

बेशक यह वास्तव में 100% नहीं है। कुछ सर्वर गलत शीर्षलेख भेजते हैं। हालांकि यह उन मामलों को संभाल देगा जहां छवियों को एक स्क्रिप्ट के माध्यम से वितरित किया जाता है और सही फ़ाइल एक्सटेंशन उपलब्ध नहीं है। वास्तव में निश्चित होने का एकमात्र तरीका वास्तव में छवि को पुनर्प्राप्त करना है - या तो यह सब, या पहले कुछ बाइट्स, जैसा कि थॉमसट्रटर द्वारा सुझाया गया है।

+0

मैं इसे बुलेट प्रूफ के रूप में वर्णित नहीं करता। ब्राउज़र thomasrutter

+0

हां। मैं सहमत हूँ। मैं भाषा बदल दूंगा। :) मुझे लगता है कि यूआरएल की वास्तविक सामग्री को पुनर्प्राप्त किए बिना यह सबसे अच्छा कर सकता है। –

+0

(डाउनवोट हटा दिया गया) हाँ मुझे लगता है कि यह अब एक सभ्य विकल्प है :) – thomasrutter

13

कुछ अलग दृष्टिकोण हैं।

  • फ़ाइल की शुरुआत में एक जादू संख्या की तलाश करके सामग्री को स्नीफ करें। उदाहरण के लिए, जीआईएफ फ़ाइल के पहले पांच बाइट्स (ascii में) के रूप में GIF87 या GIF89 का उपयोग करता है। दुर्भाग्य से यह आपको नहीं बता सकता है कि छवि में कोई त्रुटि है या यदि छवि में दुर्भावनापूर्ण सामग्री है। यहाँ छवि फ़ाइलों के विभिन्न प्रकार (इन का उपयोग करने के लिए स्वतंत्र महसूस) के लिए कुछ जादू नंबर दिए गए हैं:

     
    "\xff\xd8\xff" => 'image/jpeg', 
    "\x89PNG\x0d\x0a\x1a\x0a" => 'image/png', 
    "II*\x00" => 'image/tiff', 
    "MM\x00*" => 'image/tiff', 
    "\x00\x00\x01\x00" => 'image/ico', 
    "\x00\x00\x02\x00" => 'image/ico', 
    "GIF89a" => 'image/gif', 
    "GIF87a" => 'image/gif', 
    "BM" => 'image/bmp', 
    

    सूँघने इस तरह की सामग्री शायद अपनी आवश्यकताओं के लिए सबसे अच्छा फिट करने के लिए जा रहा है; आपको केवल फ़ाइल के पहले कुछ बाइट्स (हेडर के पीछे) डाउनलोड करना होगा और इसलिए इसे पढ़ना होगा।

  • यह देखने के लिए कि क्या यह त्रुटि के बिना लोड होता है, जीडी लाइब्रेरी का उपयोग कर छवि लोड करें। यह आपको बता सकता है कि छवि वैध है, बिना त्रुटि के या नहीं। दुर्भाग्यवश यह संभवतः आपकी आवश्यकताओं के अनुरूप नहीं है क्योंकि इसे पूरी छवि डाउनलोड करने की आवश्यकता है।

  • यदि आप वास्तव में छवि के लिए HTTP अनुरोध नहीं करना चाहते हैं, तो यह दोनों स्पीफिंग और HTTP शीर्षलेख प्राप्त करने से बाहर निकलता है। हालांकि, आप यह निर्धारित करने का प्रयास कर सकते हैं कि संदर्भ में कुछ छवि है जिसमें यह जुड़ा हुआ है। < आईएमजी तत्व में एक src विशेषता का उपयोग करके जुड़ा हुआ कुछ निश्चित रूप से एक छवि (या एक्सएसएस पर एक प्रयास है, लेकिन यह एक और कहानी है)। यह आपको बताएगा कि छवि के रूप में कुछ इरादा है या नहीं। यह आपको नहीं बताएगा कि छवि वास्तव में उपलब्ध है या वैध है; आपको इसे खोजने के लिए छवि URL के कम से कम पहले छोटे भाग (हेडर या जादू संख्या) को प्राप्त करना होगा।

दुर्भाग्य से, यह संभव है एक फ़ाइल होने के लिए दोनों एक वैध छवि के साथ ही एक ज़िप हानिकारक सामग्री है जो एक हानिकारक साइट से जावा के रूप में क्रियान्वित किया जा सकता है युक्त फ़ाइल - the GIFAR exploit देखते हैं। आप लगभग निश्चित रूप से जीडी जैसी लाइब्रेरी में छवि लोड करके और उस पर कुछ गैर-तुच्छ फ़िल्टर को प्रदर्शित करके इस कमजोरता को रोक सकते हैं, जैसे इसे नरम या तेज करने के लिए इसे एक छोटी राशि (यानी एक रूपांतरण फ़िल्टर का उपयोग करना) और इसे बिना किसी नई फ़ाइल पर सहेजना भर में किसी मेटाडेटा को स्थानांतरित करना।

यह निर्धारित करने की कोशिश कर रहा है कि अकेले इसकी सामग्री-प्रकार द्वारा कोई छवि कुछ अविश्वसनीय है, लगभग फ़ाइल एक्सटेंशन की जांच के रूप में अविश्वसनीय है। < आईएमजी तत्व का उपयोग कर एक छवि लोड करते समय, ब्राउज़र एक जादू स्ट्रिंग के लिए स्नीफ करते हैं।

+0

विस्तृत उत्तर के लिए धन्यवाद, लेकिन एक पृष्ठ प्रदर्शित करने से पहले संभावित रूप से सैकड़ों छवियों को पढ़ने के लिए मेरे आवेदन के लिए शायद बहुत अधिक ओवरहेड होगा। – danio

+0

क्या आपने अपना तीसरा बिंदु बिंदु पढ़ा? सुनिश्चित नहीं है कि आप thomasrutter

+0

आह - बस देखा कि आपको एक टेक्स्ट फ़ाइल से छवि यूआरएल मिल रहे हैं। कुछ प्रकार के हल्के HTTP अनुरोध, जैसे कि मेरा पहला बिंदु बिंदु, शायद आवश्यक होगा। ध्यान दें कि यह HTTP हेड विधि से काफी अधिक ओवरहेड नहीं है। – thomasrutter

11
if(is_array(getimagesize($urlImg))) 
    echo 'Yes it's an image!'; 
+9

getimagesize() पूरी छवि फ़ाइल डाउनलोड करता है। – user191688

3

संपादित करें: लोकप्रिय छवि विस्तार के साथ स्थिर चित्र के लिए।

<?php 
$imgExts = array("gif", "jpg", "jpeg", "png", "tiff", "tif"); 
$url ='path/to/image.png'; 
$urlExt = pathinfo($url, PATHINFO_EXTENSION); 
if (in_array($urlExt, $imgExts)) { 
    echo 'Yes, '.$url.' is an Image'; 
} 

?> 
+0

यह एक छवि है https://contulmeu.moldcell.md/ps/selfcare_uni/crypt/cryptographp.inc.php लेकिन यह यूआरएल आपकी सत्यापन पास नहीं करेगा! तुम गलत हो। – Jekis

+0

जैसा कि जेनेचका बताता है कि यह तकनीक बहुत सीमित है: 1. यह मानती है कि सभी छवि फ़ाइलों में वैध विस्तार हैं; 2. प्रोग्राम प्रारूपों के बाद लेखक के बारे में सोचा नहीं गया है/लेखक के प्रारूपों के लिए इसका कोई समर्थन नहीं है – danio

1

हम छवि प्रकार की जांच करने के लिए exif_imagetype का उपयोग कर सकते हैं, इसलिए यह किसी अन्य सामग्री प्रकार की अनुमति नहीं है। यह छवियों को केवल अनुमति देता है और हम उन्हें कुछ छवि प्रकारों तक सीमित कर सकते हैं, नमूना कोड के बाद दिखाएं कि जीआईएफ छवि प्रकार को कैसे अनुमति दें।

if (exif_imagetype('image.gif') != IMAGETYPE_GIF) { 
    echo 'The picture is not a gif'; 
} 

आप छवि प्रकार निम्न का उपयोग कर सकते हैं,

IMAGETYPE_GIF 
IMAGETYPE_JPEG 
IMAGETYPE_PNG 
IMAGETYPE_SWF 
IMAGETYPE_PSD 
IMAGETYPE_BMP 
IMAGETYPE_TIFF_II (intel byte order) 
IMAGETYPE_TIFF_MM (motorola byte order) 
IMAGETYPE_JPC 
IMAGETYPE_JP2 
IMAGETYPE_JPX 
IMAGETYPE_JB2 
IMAGETYPE_SWC 
IMAGETYPE_IFF 
IMAGETYPE_WBMP 
IMAGETYPE_XBM 
IMAGETYPE_ICO 

अधिक जानकारी के: link

+1

सच है, लेकिन 'exif_imagetype' यूआरएल के साथ काम नहीं करता है। – fredrikekelund

7

एमिल एच के जवाब के अलावा:

एक यूआरएल की सामग्री प्रकार की जाँच करने के get_headers() का उपयोग करना getimagesize()

के साथ पूरी फ़ाइल को डाउनलोड किए बिना
$url_headers=get_headers($url, 1); 

    if(isset($url_headers['Content-Type'])){ 

     $type=strtolower($url_headers['Content-Type']); 

     $valid_image_type=array(); 
     $valid_image_type['image/png']=''; 
     $valid_image_type['image/jpg']=''; 
     $valid_image_type['image/jpeg']=''; 
     $valid_image_type['image/jpe']=''; 
     $valid_image_type['image/gif']=''; 
     $valid_image_type['image/tif']=''; 
     $valid_image_type['image/tiff']=''; 
     $valid_image_type['image/svg']=''; 
     $valid_image_type['image/ico']=''; 
     $valid_image_type['image/icon']=''; 
     $valid_image_type['image/x-icon']=''; 

     if(isset($valid_image_type[$type])){ 

      //do something 

     } 
    } 
+1

'$ url_headers ['सामग्री-प्रकार'] 'बहुत अच्छी तरह से एक सरणी हो सकता है, और' $ type' असाइन करने से पहले जांच की जानी चाहिए। साथ ही, सरणी को पढ़ने के क्रम को ट्रैक रखने के लिए सावधानी बरतें (अगर केवल अंतिम सामग्री-प्रकार में रुचि रखते हैं, सभी रीडायरेक्ट के बाद, तो आप सरणी में अंतिम आइटम चाहते हैं) – Birrel

2

कुछ दिए गए उत्तर के समान लेकिन थोड़ा अलग तर्क के साथ।

$headers = @get_headers($url, 1); // @ to suppress errors. Remove when debugging. 
if (isset($headers['Content-Type'])) { 
    if (strpos($headers['Content-Type'], 'image/') === FALSE) { 
    // Not a regular image (including a 404). 
    } 
    else { 
    // It's an image! 
    } 
} 
else { 
    // No 'Content-Type' returned. 
} 

@error control operator है।

नोट हम हालत में "सख्त" ऑपरेटर === FALSE इस्तेमाल किया क्योंकि strpos($headers['Content-Type'], 'image/') हमारे उपयोग के मामले में 0 वापसी करता है तो सुई भूसे के ढेर में पाया जाता है। == का उपयोग करके टाइप कास्टिंग के साथ गलती से FALSE के रूप में व्याख्या की जाएगी।

0

टूटी हुई है या नहीं मिला छवियों लिंक
के लिए तेजी से समाधान मैं तुम्हें अनुशंसा करते हैं कि getimagesize (उपयोग न करें) क्योंकि यह 1 डाउनलोड छवि तो यह छवियों आकार की जांच होगी + अगर यह नहीं होगा छवि तो यह फेंक होगा अपवाद तो नीचे दिए गए कोड का उपयोग

if(checkRemoteFile($imgurl)) 
{ 
//found url, its mean 
echo "this is image"; 
} 

function checkRemoteFile($url) 
{ 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL,$url); 
    // don't download content 
    curl_setopt($ch, CURLOPT_NOBODY, 1); 
    curl_setopt($ch, CURLOPT_FAILONERROR, 1); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    if(curl_exec($ch)!==FALSE) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

नोट: इस मौजूदा कोड को आपकी सहायता करने टूटी हुई या नहीं मिला यूआरएल छवि को पहचानने के लिए यह आप छवि प्रकार या हेडर की पहचान करने में मदद नहीं करेगा

संबंधित मुद्दे

 संबंधित मुद्दे