यह देखने के लिए कि कोई दूरस्थ फ़ाइल PHP का उपयोग करके मौजूद है, कैसे देख सकता है?


86

सबसे अच्छा मुझे मिल सकता है, एक if fclose fopenप्रकार की चीज, पृष्ठ लोड को वास्तव में धीरे-धीरे करता है।

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


मुझे लगता है कि आप CURL का उपयोग कर सकते हैं और इसके रिटर्न कोड की जांच कर सकते हैं। लेकिन अगर यह गति है जो एक समस्या है, तो बस इसे ऑफ़लाइन और कैश करें।
मिशैल टाटेरियोनिज़िक

हां, लेकिन मैं अभी भी एक ऑफ़लाइन स्क्रिप्ट (क्रोन से रन) का उपयोग करने की सिफारिश करूंगा, जो वेबसाइटों की सूची को पार्स करता है, जांचता है कि क्या उन्हें फेवीकोन्स और कैश मिला है जो कि फ्रंटएंड के लिए डेटा है। यदि आप क्रोन का उपयोग नहीं कर सकते / कर सकते हैं, तो कम से कम हर नए URL की जाँच के लिए परिणाम कैश करें।
मिशैल टाटेरोनिकोइज़

3
ब्राउज़र में एक प्लेसहोल्डर छवि के साथ एक टूटी हुई छवि को बदलने के लिए, कृपया क्लाइंट के साइड-सॉल्यूशन पर विचार करें, onerrorजैसे कि jQuery का उपयोग करके समाधान

जवाबों:


135

आप CURLOPT_NOBODY के माध्यम से HTTP HEAD विधि का उपयोग करने के लिए कर्ल को निर्देश दे सकते हैं।

ज्यादा या कम

$ch = curl_init("http://www.example.com/favicon.ico");

curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// $retcode >= 400 -> not found, $retcode = 200, found.
curl_close($ch);

वैसे भी, आप केवल HTTP हस्तांतरण की लागत को बचाते हैं, टीसीपी कनेक्शन की स्थापना और समापन को नहीं। और फ़ेविकॉन्स छोटे होने के कारण, आपको बहुत सुधार नहीं दिखाई दे सकता है।

परिणाम को स्थानीय रूप से कैशिंग करना एक अच्छा विचार है यदि यह बहुत धीमा हो जाता है। HEAD फ़ाइल के समय की जाँच करता है, और इसे हेडर में देता है। आप ब्राउज़रों की तरह कर सकते हैं और आइकन का CURLINFO_FILETIME प्राप्त कर सकते हैं। अपने कैश में आप URL => [फ़ेविकॉन, टाइमस्टैम्प] स्टोर कर सकते हैं। फिर आप टाइमस्टैम्प की तुलना कर सकते हैं और फ़ेविकॉन को फिर से लोड कर सकते हैं।


6
बस एक नोट: retcodeसभी 400 कोड पर त्रुटियां इसलिए सत्यापन >=सिर्फ इतना नहीं होगा>
जस्टिन बुल

4
यदि आप उपयोगकर्ता एजेंट स्ट्रिंग प्रदान नहीं करते हैं तो कुछ साइटें ब्लॉक हो जाती हैं, इसलिए मैं CURLOPT_NOBODY: davidwalsh.name/set-user-agent-php-curl-spoof
rlorenzo

6
@ 3x रीकोड एक त्रुटि नहीं है, लेकिन एक पुनर्निर्देशन है। जिन्हें या तो मैन्युअल रूप से नियंत्रित किया जाना चाहिए या CURLOPT_FOLLOWLOCATION का उपयोग करना चाहिए।
रेमन पोका

6
कर्ल_सेटॉप ($ ch, CURLOPT_SSL_VERIFYPEER, गलत) का उपयोग करें; HTTPS के साथ URL की शुरुआत के लिए समान कोड काम करता है यह सुनिश्चित करने के लिए!
कृष्ण गोपाल

61

जैसा कि Pies का कहना है कि आप CURL का उपयोग कर सकते हैं। आप केवल हेडर देने के लिए cURL प्राप्त कर सकते हैं, न कि शरीर, जो इसे और तेज़ बना सकता है। एक बुरा डोमेन हमेशा कुछ समय ले सकता है क्योंकि आप समय-आउट के अनुरोध का इंतजार कर रहे होंगे; आप शायद CURL का उपयोग करके टाइमआउट लंबाई बदल सकते हैं।

यहाँ उदाहरण है:

function remoteFileExists($url) {
    $curl = curl_init($url);

    //don't fetch the actual page, you only want to check the connection is ok
    curl_setopt($curl, CURLOPT_NOBODY, true);

    //do request
    $result = curl_exec($curl);

    $ret = false;

    //if request did not fail
    if ($result !== false) {
        //if request was ok, check response code
        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);  

        if ($statusCode == 200) {
            $ret = true;   
        }
    }

    curl_close($curl);

    return $ret;
}

$exists = remoteFileExists('http://stackoverflow.com/favicon.ico');
if ($exists) {
    echo 'file exists';
} else {
    echo 'file does not exist';   
}

3
RemoteFileExists (' stackoverflow.com/' ) यह भी सही लौटेगा, लेकिन यह सिर्फ एक कड़ी है। यह फ़ंक्शन चेक नहीं कर रहा है लिंक सामग्री प्रकार फ़ाइल है।
डोनाटास नेवीडॉन्किस

36

CoolGoose का समाधान अच्छा है लेकिन यह बड़ी फ़ाइलों के लिए तेज़ है (क्योंकि यह केवल 1 बाइट पढ़ने की कोशिश करता है):

if (false === file_get_contents("http://example.com/path/to/image",0,null,0,1)) {
    $image = $default_image;
}

+1। क्या CURL के खिलाफ इस समाधान के लिए कमियां हैं?
एड्रियानो वरोली पियाज़ा

1
आप बस उपयोग कर सकते हैं fopen- यदि अनुरोध रिटर्न कोड 404 है, तो फ़ॉपन गलत है।
s3v3n

यह वास्तव में धीमा है और मेरे लिए काम नहीं किया (जिसका अर्थ है कि यह अभी भी एक टूटी हुई छवि प्रदर्शित करता है यदि फ़ाइल पथ सही नहीं था)
हेल्मुट

जब भी कोई चित्र या फ़ाइल मौजूद नहीं होती है, तो यह दृष्टिकोण काम नहीं करता है। ऐसा तब होता है जब कोई साइट mod_rewrite या किसी प्रकार के अन्य "नियमों" का उपयोग करती है, कैसे अनुरोधों को संभाला जाना चाहिए।
एरिक Epnjak

28

यह आपके मूल प्रश्न का उत्तर नहीं है, लेकिन आप जो करने की कोशिश कर रहे हैं, उसे करने का एक बेहतर तरीका है:

वास्तव में साइट के फ़ेविकॉन को सीधे प्राप्त करने की कोशिश करने के बजाय (जो कि एक शाही दर्द है, यह /favicon.png, /favicon.ico, /favicon.gif, या यहां तक ​​कि /path/to/favicon.png हो सकता है), Google का उपयोग करें:

<img src="http://www.google.com/s2/favicons?domain=[domain]">

किया हुआ।


4
वाक्य विन्यास थोड़ा भ्रम पैदा करता है। तो यहाँ एक उदाहरण: <img src = " google.com/s2/favicons?domain=stackoverflow.com ">
हबीब परवाद

19

सबसे अधिक मतदान के जवाब का एक पूरा कार्य:

function remote_file_exists($url)
{
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_NOBODY, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); # handles 301/2 redirects
    curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if( $httpCode == 200 ){return true;}
}

आप इसे इस तरह से उपयोग कर सकते हैं:

if(remote_file_exists($url))
{
    //file exists, do something
}

ओह! मैं पिछले कुछ दिनों से दूर हूं, लेकिन महीने की शुरुआत लगभग 24/7 थी। मुझे जानकारी देने के लिए धन्यवाद!
पेड्रो लोबिटो

यह काम नहीं करता है यदि सर्वर किसी HTTP कोड (या cUrl doesnt इसे पकड़ता है) का जवाब नहीं देता है। जो मुझे काफी बार याद आ रहा है। उदाहरण के लिए। छवियों के मामले में।
वेक्सी

क्या होगा यदि url दूसरे URL या https संस्करण पर पुनर्निर्देशित हो? उस स्थिति में यह कर्ल कोड काम नहीं कर पाएगा। सबसे अच्छा तरीका है हेडर की जानकारी प्राप्त करना और केस-असंवेदनशील स्ट्रिंग "200 ओके" की खोज करना।
इंफोकोनिक

@Infoconic आप जोड़ सकते हैं curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);। मैंने 302पुनर्निर्देशन को संभालने के लिए उत्तर अपडेट किया है।
पेड्रो लोबिटो

18

यदि आप छवियों के साथ काम कर रहे हैं, तो getimagesize का उपयोग करें। File_exists के विपरीत, यह अंतर्निहित फ़ंक्शन दूरस्थ फ़ाइलों का समर्थन करता है। यह एक सरणी लौटाएगा जिसमें छवि जानकारी (चौड़ाई, ऊंचाई, टाइप..एटीसी) होगी। आपको बस इतना करना है कि सरणी (चौड़ाई) में पहले तत्व की जांच करें। सरणी की सामग्री को आउटपुट करने के लिए print_r का उपयोग करें

$imageArray = getimagesize("http://www.example.com/image.jpg");
if($imageArray[0])
{
    echo "it's an image and here is the image's info<br>";
    print_r($imageArray);
}
else
{
    echo "invalid image";
}

दूरस्थ संसाधन उपलब्ध नहीं होने पर 404 चेतावनी में परिणाम। कुछ समय के लिए, मैंने इसके @सामने उपयोग करके त्रुटि को दबाकर संभाल लिया getimagesize, लेकिन इस हैक के लिए दोषी महसूस कर रहा हूं ।

मेरे मामले में यह सबसे अच्छा तरीका था, क्योंकि जब भी कोई छवि / फ़ाइल मौजूद नहीं होती है, तो मैं पुनर्निर्देशित हो जाता हूं। मैं दूसरा कहता हूं कि @ के साथ दमनकारी त्रुटियां नहीं हैं, लेकिन इस मामले में यह आवश्यक था।
एरिक Epnjak

मैं पता लगा कि हम भी इस्तेमाल कर सकते हैं exif_imagetype, और यह बहुत तेजी से है stackoverflow.com/a/38295345/1250044
yckart

7

यह HTTP स्थिति कोड (404 = नहीं मिला) प्राप्त करके किया जा सकता है जो file_get_contentsडॉक्स संदर्भ विकल्पों के उपयोग के साथ संभव है । निम्न कोड खाते को पुनर्निर्देशित करता है और अंतिम गंतव्य का स्थिति कोड लौटाएगा ( डेमो ):

$url = 'http://example.com/';
$code = FALSE;

$options['http'] = array(
    'method' => "HEAD",
    'ignore_errors' => 1
);

$body = file_get_contents($url, NULL, stream_context_create($options));

foreach($http_response_header as $header)
    sscanf($header, 'HTTP/%*d.%*d %d', $code);

echo "Status code: $code";

यदि आप पुनर्निर्देश का पालन नहीं करना चाहते हैं, तो आप इसे ( डेमो ) समान कर सकते हैं :

$url = 'http://example.com/';
$code = FALSE;

$options['http'] = array(
    'method' => "HEAD",
    'ignore_errors' => 1,
    'max_redirects' => 0
);

$body = file_get_contents($url, NULL, stream_context_create($options));

sscanf($http_response_header[0], 'HTTP/%*d.%*d %d', $code);

echo "Status code: $code";

उपयोग किए गए कुछ फ़ंक्शंस, विकल्पों और चरों को एक ब्लॉग पोस्ट पर अधिक विस्तार के साथ समझाया गया है जो मैंने लिखा है: पहले PHP स्ट्रीम के साथ HEAD




PHP के अधिक $http_response_headerदेखने के लिए php.net/manual/en/reserved.variables.httpresponseheader.php देखें ।
बिग मैकलेरज्यूज

1
दूसरे संस्करण ने मेरे लिए काम किया और डिफ़ॉल्ट file_get_contents कॉल की तुलना में (कोई कस्टम स्ट्रीम_कंटेक्स्ट) यह 50% तेजी से नहीं था, अर्थात अनुरोध के लिए 3,4s से 1,7s तक।
एरिक npnjak

@ Erik iserpnjak: यदि "कोई रिवाज नहीं" stream_context है, तो यह डिफ़ॉल्ट है। आप डिफ़ॉल्ट संदर्भ से विकल्प प्राप्त कर सकते हैं और देख सकते हैं कि वे आपके कस्टम संदर्भ से कैसे भिन्न होते हैं। यह आपको कुछ जानकारी देनी चाहिए कि समय अलग क्यों है। - php.net/stream-context-get-default और php.net/stream-context-get-options
hakre

6
if (false === file_get_contents("http://example.com/path/to/image")) {
    $image = $default_image;
}

कार्य करना चाहिए ;)


समारोह से पहले जोड़ने @
Tebe

6

यदि सुरक्षा कारणों से allow_url_fopen सेटिंग को सेट किया गया है तो URL की इनबिल्ट फ़ंक्शंस URL की जाँच के लिए काम नहीं कर सकती हैं । कर्ल एक बेहतर विकल्प है क्योंकि बाद में हमें अपना कोड बदलने की आवश्यकता नहीं होगी। नीचे एक मान्य URL सत्यापित करने के लिए उपयोग किया गया कोड है:

$url = str_replace(' ', '%20', $url);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);  
curl_close($ch);
if($httpcode>=200 && $httpcode<300){  return true; } else { return false; } 

कृपया CURLOPT_SSL_VERIFYPEER विकल्प पर ध्यान दें, जो HTTPS के साथ URL की शुरुआत को सत्यापित करता है।


6

छवियों के अस्तित्व की जांच करने के लिए , इसे exif_imagetypeअधिक पसंद किया जाना चाहिए getimagesize, क्योंकि यह बहुत तेज है।

को दबाने के लिए E_NOTICE, बस त्रुटि नियंत्रण ऑपरेटर को रोकें ( @)।

if (@exif_imagetype($filename)) {
  // Image exist
}

एक बोनस के रूप में, लौटाए गए मान के साथ ( IMAGETYPE_XXX) से exif_imagetypeहम image_type_to_mime_type/ के साथ माइम-प्रकार या फ़ाइल-एक्सटेंशन भी प्राप्त कर सकते हैं image_type_to_extension


4

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


1
+1 यदि आप उनके फ़ेविकॉन (favicon.ico, favicon.gif, favicon.png) के लिए कई स्थानों की जाँच नहीं कर रहे हैं, तो यह सबसे अच्छा समाधान प्रतीत होता है
गैलन

3
function remote_file_exists($url){
   return(bool)preg_match('~HTTP/1\.\d\s+200\s+OK~', @current(get_headers($url)));
}  
$ff = "http://www.emeditor.com/pub/emed32_11.0.5.exe";
    if(remote_file_exists($ff)){
        echo "file exist!";
    }
    else{
        echo "file not exist!!!";
    }

3

आप निम्नलिखित का उपयोग कर सकते हैं:

$file = 'http://mysite.co.za/images/favicon.ico';
$file_exists = (@fopen($file, "r")) ? true : false;

URL पर कोई छवि मौजूद है या नहीं, यह जांचने की कोशिश करते समय मेरे लिए काम किया


2

आप उपयोग कर सकते हैं :

$url=getimagesize(“http://www.flickr.com/photos/27505599@N07/2564389539/”);

if(!is_array($url))
{
   $default_image =”…/directoryFolder/junal.jpg”;
}

2

अगर PHP में कोई दूरस्थ फ़ाइल मौजूद है, तो यह जाँचने के लिए यह मेरे लिए काम करता है:

$url = 'https://cdn.sstatic.net/Sites/stackoverflow/img/favicon.ico';
    $header_response = get_headers($url, 1);

    if ( strpos( $header_response[0], "404" ) !== false ) {
        echo 'File does NOT exist';
        } else {
        echo 'File exists';
        }

1

आपको HEAD अनुरोध जारी करना चाहिए, एक नहीं प्राप्त करना चाहिए, क्योंकि आपको URI सामग्री की बिल्कुल भी आवश्यकता नहीं है। जैसा कि पिज़ ने ऊपर कहा था, आपको स्थिति कोड (200-299 श्रेणियों में, और आप वैकल्पिक रूप से 3xx पुनर्निर्देश का पालन कर सकते हैं) के लिए जाँच करनी चाहिए।

उत्तर प्रश्न में बहुत सारे कोड उदाहरण हैं जो सहायक हो सकते हैं: PHP / कर्ल: HEAD अनुरोध कुछ साइटों पर एक लंबा समय लेता है


1

एक और भी अधिक परिष्कृत विकल्प है। आप एक JQuery चाल का उपयोग करके सभी क्लाइंट-साइड की जाँच कर सकते हैं।

$('a[href^="http://"]').filter(function(){
     return this.hostname && this.hostname !== location.hostname;
}).each(function() {
    var link = jQuery(this);
    var faviconURL =
      link.attr('href').replace(/^(http:\/\/[^\/]+).*$/, '$1')+'/favicon.ico';
    var faviconIMG = jQuery('<img src="favicon.png" alt="" />')['appendTo'](link);
    var extImg = new Image();
    extImg.src = faviconURL;
    if (extImg.complete)
      faviconIMG.attr('src', faviconURL);
    else
      extImg.onload = function() { faviconIMG.attr('src', faviconURL); };
});

से http://snipplr.com/view/18782/add-a-favicon-near-external-links-with-jquery/ (मूल ब्लॉग वर्तमान में नीचे है)


1

यहाँ सभी उत्तर जो get_headers () का उपयोग करते हैं, एक GET अनुरोध कर रहे हैं। यह सिर्फ एक HEAD अनुरोध करने के लिए बहुत तेज़ / सस्ता है।

यह सुनिश्चित करने के लिए कि गेट_हेडर्स () आपको इसे जोड़ना चाहिए एक GET के बजाय एक HEAD अनुरोध करता है:

stream_context_set_default(
    array(
        'http' => array(
            'method' => 'HEAD'
        )
    )
);

इसलिए यह जाँचने के लिए कि क्या कोई फ़ाइल मौजूद है, आपका कोड कुछ इस तरह दिखाई देगा:

stream_context_set_default(
    array(
        'http' => array(
            'method' => 'HEAD'
        )
    )
);
$headers = get_headers('http://website.com/dir/file.jpg', 1);
$file_found = stristr($headers[0], '200');

$ file_found या तो गलत या सही लौटेगी, जाहिर है।


0

पता नहीं कि यह कोई तेज़ है जब फ़ाइल दूरस्थ रूप से मौजूद नहीं है, is_file () है , लेकिन आप इसे शॉट दे सकते हैं।

$favIcon = 'default FavIcon';
if(is_file($remotePath)) {
   $favIcon = file_get_contents($remotePath);
}

डॉक्स से: "PHP 5.0.0 के रूप में, इस फ़ंक्शन का उपयोग कुछ URL रैपर के साथ भी किया जा सकता है। समर्थित प्रोटोकॉल और रैपर्स के संदर्भ में निर्धारित करें कि कौन से रैपर कार्यक्षमता के स्टेट () परिवार का समर्थन करते हैं।"
पैट्रिकअकेर्स्ट्रैंड

क्या आपका मतलब है कि अगर आप एक स्ट्रीम रैपर रजिस्टर करते हैं तो यह काम कर सकता है? एक कार्य उदाहरण दिखाने के लिए अपने प्रश्न को संपादित करें और मैं अपना डाउनवोट हटा दूंगा (और यदि मैं कर सकता हूं तो आपको अपवोट कर सकता हूं)। लेकिन फिलहाल, मैंने एक दूरस्थ फ़ाइल के साथ php cli से is_file का परीक्षण किया, और गलत मिला।
greg0ire

काम का कोई उदाहरण नहीं:var_dump(is_file('http://cdn.sstatic.net/stackoverflow/img/sprites.png')); bool(false)
greg0ire

0

यदि फ़ाइल को बाहरी रूप से होस्ट नहीं किया गया है, तो आप दूरस्थ URL को अपने वेबसर्वर पर निरपेक्ष पथ में अनुवाद कर सकते हैं। इस तरह आपको CURL या file_get_contents इत्यादि को कॉल करने की आवश्यकता नहीं है।

function remoteFileExists($url) {

    $root = realpath($_SERVER["DOCUMENT_ROOT"]);
    $urlParts = parse_url( $url );

    if ( !isset( $urlParts['path'] ) )
        return false;

    if ( is_file( $root . $urlParts['path'] ) )
        return true;
    else
        return false;

}

remoteFileExists( 'https://www.yourdomain.com/path/to/remote/image.png' );

नोट: आपका वेबसर्वर इस फ़ंक्शन का उपयोग करने के लिए DOCUMENT_ROOT को पॉप्युलेट करना चाहिए


0

यदि आप सिम्फनी फ्रेमवर्क का उपयोग कर रहे हैं, तो इसका उपयोग करने का एक बहुत सरल तरीका भी है HttpClientInterface:

private function remoteFileExists(string $url, HttpClientInterface $client): bool {
    $response = $client->request(
        'GET',
        $url //e.g. http://example.com/file.txt
    );

    return $response->getStatusCode() == 200;
}

HttpClient के लिए डॉक्स भी बहुत अच्छे हैं और शायद यह देखने लायक है कि क्या आपको अधिक विशिष्ट दृष्टिकोण की आवश्यकता है: https://symfony.com/doc/current/http_client.html


-1

आप फाइल सिस्टम का उपयोग कर सकते हैं: Symfony \ Component \ Filesystem \ Filesystem का उपयोग करें; Symfony \ Component \ Filesystem \ Exception \ IOExceptionInterface का उपयोग करें;

और $ फ़ाइल की जाँच करें = नया फ़ाइल सिस्टम (); अगर ($ fileSystem-> मौजूद है ('path_to_file') == true) {...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.