Réponses:
Ici:
$file = 'http://www.domain.com/somefile.jpg';
$file_headers = @get_headers($file);
if(!$file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found') {
$exists = false;
}
else {
$exists = true;
}
À partir d' ici et juste en dessous du post ci -dessus, il existe une solution curl :
function url_exists($url) {
if (!$fp = curl_init($url)) return false;
return true;
}
$file_headers[0]
page d'erreur différente . par exemple, youtube.com. sa page d'erreur ayant cette valeur comme HTTP/1.0 404 Not Found
(la différence est 1,0 et 1,1). que faire alors?
strpos($headers[0], '404 Not Found')
pourrait faire l'affaire
strpos($headers[0], '404')
c'est mieux!
Lorsque vous déterminez si une URL existe depuis php, il y a quelques points à prendre en compte:
Gardez à l'esprit que quelle que soit la méthode que vous utilisez, il faut du temps pour attendre une réponse.
Tout le code peut (et le fera probablement) s'arrêter jusqu'à ce que vous connaissiez le résultat ou que les requêtes aient expiré.
Par exemple: le code ci-dessous peut mettre LONGTEMPS à afficher la page si les URL sont invalides ou inaccessibles:
<?php
$urls = getUrls(); // some function getting say 10 or more external links
foreach($urls as $k=>$url){
// this could potentially take 0-30 seconds each
// (more or less depending on connection, target site, timeout settings...)
if( ! isValidUrl($url) ){
unset($urls[$k]);
}
}
echo "yay all done! now show my site";
foreach($urls as $url){
echo "<a href=\"{$url}\">{$url}</a><br/>";
}
Les fonctions ci-dessous pourraient être utiles, vous souhaiterez probablement les modifier en fonction de vos besoins:
function isValidUrl($url){
// first do some quick sanity checks:
if(!$url || !is_string($url)){
return false;
}
// quick check url is roughly a valid http request: ( http://blah/... )
if( ! preg_match('/^http(s)?:\/\/[a-z0-9-]+(\.[a-z0-9-]+)*(:[0-9]+)?(\/.*)?$/i', $url) ){
return false;
}
// the next bit could be slow:
if(getHttpResponseCode_using_curl($url) != 200){
// if(getHttpResponseCode_using_getheaders($url) != 200){ // use this one if you cant use curl
return false;
}
// all good!
return true;
}
function getHttpResponseCode_using_curl($url, $followredirects = true){
// returns int responsecode, or false (if url does not exist or connection timeout occurs)
// NOTE: could potentially take up to 0-30 seconds , blocking further code execution (more or less depending on connection, target site, and local timeout settings))
// if $followredirects == false: return the FIRST known httpcode (ignore redirects)
// if $followredirects == true : return the LAST known httpcode (when redirected)
if(! $url || ! is_string($url)){
return false;
}
$ch = @curl_init($url);
if($ch === false){
return false;
}
@curl_setopt($ch, CURLOPT_HEADER ,true); // we want headers
@curl_setopt($ch, CURLOPT_NOBODY ,true); // dont need body
@curl_setopt($ch, CURLOPT_RETURNTRANSFER ,true); // catch output (do NOT print!)
if($followredirects){
@curl_setopt($ch, CURLOPT_FOLLOWLOCATION ,true);
@curl_setopt($ch, CURLOPT_MAXREDIRS ,10); // fairly random number, but could prevent unwanted endless redirects with followlocation=true
}else{
@curl_setopt($ch, CURLOPT_FOLLOWLOCATION ,false);
}
// @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,5); // fairly random number (seconds)... but could prevent waiting forever to get a result
// @curl_setopt($ch, CURLOPT_TIMEOUT ,6); // fairly random number (seconds)... but could prevent waiting forever to get a result
// @curl_setopt($ch, CURLOPT_USERAGENT ,"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1"); // pretend we're a regular browser
@curl_exec($ch);
if(@curl_errno($ch)){ // should be 0
@curl_close($ch);
return false;
}
$code = @curl_getinfo($ch, CURLINFO_HTTP_CODE); // note: php.net documentation shows this returns a string, but really it returns an int
@curl_close($ch);
return $code;
}
function getHttpResponseCode_using_getheaders($url, $followredirects = true){
// returns string responsecode, or false if no responsecode found in headers (or url does not exist)
// NOTE: could potentially take up to 0-30 seconds , blocking further code execution (more or less depending on connection, target site, and local timeout settings))
// if $followredirects == false: return the FIRST known httpcode (ignore redirects)
// if $followredirects == true : return the LAST known httpcode (when redirected)
if(! $url || ! is_string($url)){
return false;
}
$headers = @get_headers($url);
if($headers && is_array($headers)){
if($followredirects){
// we want the the last errorcode, reverse array so we start at the end:
$headers = array_reverse($headers);
}
foreach($headers as $hline){
// search for things like "HTTP/1.1 200 OK" , "HTTP/1.0 200 OK" , "HTTP/1.1 301 PERMANENTLY MOVED" , "HTTP/1.1 400 Not Found" , etc.
// note that the exact syntax/version/output differs, so there is some string magic involved here
if(preg_match('/^HTTP\/\S+\s+([1-9][0-9][0-9])\s+.*/', $hline, $matches) ){// "HTTP/*** ### ***"
$code = $matches[1];
return $code;
}
}
// no HTTP/xxx found in headers:
return false;
}
// no headers :
return false;
}
return $code
pour if($code == 200){return true;} return false;
trier uniquement les succès
$headers = @get_headers($this->_value);
if(strpos($headers[0],'200')===false)return false;
donc chaque fois que vous contactez un site Web et obtenez autre chose que 200 ok, cela fonctionnera
return strpos(@get_headers($url)[0],'200') === false ? false : true
. Cela pourrait être utile.
vous ne pouvez pas utiliser curl sur certains serveurs vous pouvez utiliser ce code
<?php
$url = 'http://www.example.com';
$array = get_headers($url);
$string = $array[0];
if(strpos($string,"200"))
{
echo 'url exists';
}
else
{
echo 'url does not exist';
}
?>
$url = 'http://google.com';
$not_url = 'stp://google.com';
if (@file_get_contents($url)): echo "Found '$url'!";
else: echo "Can't find '$url'.";
endif;
if (@file_get_contents($not_url)): echo "Found '$not_url!";
else: echo "Can't find '$not_url'.";
endif;
// Found 'http://google.com'!Can't find 'stp://google.com'.
J'utilise cette fonction:
/**
* @param $url
* @param array $options
* @return string
* @throws Exception
*/
function checkURL($url, array $options = array()) {
if (empty($url)) {
throw new Exception('URL is empty');
}
// list of HTTP status codes
$httpStatusCodes = array(
100 => 'Continue',
101 => 'Switching Protocols',
102 => 'Processing',
200 => 'OK',
201 => 'Created',
202 => 'Accepted',
203 => 'Non-Authoritative Information',
204 => 'No Content',
205 => 'Reset Content',
206 => 'Partial Content',
207 => 'Multi-Status',
208 => 'Already Reported',
226 => 'IM Used',
300 => 'Multiple Choices',
301 => 'Moved Permanently',
302 => 'Found',
303 => 'See Other',
304 => 'Not Modified',
305 => 'Use Proxy',
306 => 'Switch Proxy',
307 => 'Temporary Redirect',
308 => 'Permanent Redirect',
400 => 'Bad Request',
401 => 'Unauthorized',
402 => 'Payment Required',
403 => 'Forbidden',
404 => 'Not Found',
405 => 'Method Not Allowed',
406 => 'Not Acceptable',
407 => 'Proxy Authentication Required',
408 => 'Request Timeout',
409 => 'Conflict',
410 => 'Gone',
411 => 'Length Required',
412 => 'Precondition Failed',
413 => 'Payload Too Large',
414 => 'Request-URI Too Long',
415 => 'Unsupported Media Type',
416 => 'Requested Range Not Satisfiable',
417 => 'Expectation Failed',
418 => 'I\'m a teapot',
422 => 'Unprocessable Entity',
423 => 'Locked',
424 => 'Failed Dependency',
425 => 'Unordered Collection',
426 => 'Upgrade Required',
428 => 'Precondition Required',
429 => 'Too Many Requests',
431 => 'Request Header Fields Too Large',
449 => 'Retry With',
450 => 'Blocked by Windows Parental Controls',
500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
503 => 'Service Unavailable',
504 => 'Gateway Timeout',
505 => 'HTTP Version Not Supported',
506 => 'Variant Also Negotiates',
507 => 'Insufficient Storage',
508 => 'Loop Detected',
509 => 'Bandwidth Limit Exceeded',
510 => 'Not Extended',
511 => 'Network Authentication Required',
599 => 'Network Connect Timeout Error'
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if (isset($options['timeout'])) {
$timeout = (int) $options['timeout'];
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
}
curl_exec($ch);
$returnedStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if (array_key_exists($returnedStatusCode, $httpStatusCodes)) {
return "URL: '{$url}' - Error code: {$returnedStatusCode} - Definition: {$httpStatusCodes[$returnedStatusCode]}";
} else {
return "'{$url}' does not exist";
}
}
La solution get_headers () de karim79 n'a pas fonctionné pour moi car j'ai obtenu des résultats fous avec Pinterest.
get_headers(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Array
(
[url] => https://www.pinterest.com/jonathan_parl/
[exists] =>
)
get_headers(): Failed to enable crypto
Array
(
[url] => https://www.pinterest.com/jonathan_parl/
[exists] =>
)
get_headers(https://www.pinterest.com/jonathan_parl/): failed to open stream: operation failed
Array
(
[url] => https://www.pinterest.com/jonathan_parl/
[exists] =>
)
Quoi qu'il en soit, ce développeur démontre que cURL est bien plus rapide que get_headers ():
http://php.net/manual/fr/function.get-headers.php#104723
Étant donné que de nombreuses personnes ont demandé que karim79 répare sa solution cURL, voici la solution que j'ai construite aujourd'hui.
/**
* Send an HTTP request to a the $url and check the header posted back.
*
* @param $url String url to which we must send the request.
* @param $failCodeList Int array list of code for which the page is considered invalid.
*
* @return Boolean
*/
public static function isUrlExists($url, array $failCodeList = array(404)){
$exists = false;
if(!StringManager::stringStartWith($url, "http") and !StringManager::stringStartWith($url, "ftp")){
$url = "https://" . $url;
}
if (preg_match(RegularExpression::URL, $url)){
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($handle, CURLOPT_HEADER, true);
curl_setopt($handle, CURLOPT_NOBODY, true);
curl_setopt($handle, CURLOPT_USERAGENT, true);
$headers = curl_exec($handle);
curl_close($handle);
if (empty($failCodeList) or !is_array($failCodeList)){
$failCodeList = array(404);
}
if (!empty($headers)){
$exists = true;
$headers = explode(PHP_EOL, $headers);
foreach($failCodeList as $code){
if (is_numeric($code) and strpos($headers[0], strval($code)) !== false){
$exists = false;
break;
}
}
}
}
return $exists;
}
Laissez-moi vous expliquer les options de curl:
CURLOPT_RETURNTRANSFER : renvoie une chaîne au lieu d'afficher la page appelante à l'écran.
CURLOPT_SSL_VERIFYPEER : cUrl ne récupérera pas le certificat
CURLOPT_HEADER : inclure l'en-tête dans la chaîne
CURLOPT_NOBODY : ne pas inclure le corps dans la chaîne
CURLOPT_USERAGENT : certains sites en ont besoin pour fonctionner correctement (par exemple: https://plus.google.com )
Note supplémentaire : Dans cette fonction, j'utilise l'expression régulière de Diego Perini pour valider l'URL avant d'envoyer la requête:
const URL = "%^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@|\d{1,3}(?:\.\d{1,3}){3}|(?:(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)(?:\.(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)*(?:\.[a-z\x{00a1}-\x{ffff}]{2,6}))(?::\d+)?(?:[^\s]*)?$%iu"; //@copyright Diego Perini
Note complémentaire 2 : j'explose la chaîne d'en-tête et les en-têtes utilisateur [0] pour être sûr de ne valider que le code retour et le message (exemple: 200, 404, 405, etc.)
Note supplémentaire 3 : Parfois, valider uniquement le code 404 ne suffit pas (voir le test unitaire), il existe donc un paramètre facultatif $ failCodeList pour fournir toute la liste de codes à rejeter.
Et, bien sûr, voici le test unitaire (y compris tout le réseau social populaire) pour légitimer mon codage:
public function testIsUrlExists(){
//invalid
$this->assertFalse(ToolManager::isUrlExists("woot"));
$this->assertFalse(ToolManager::isUrlExists("https://www.facebook.com/jonathan.parentlevesque4545646456"));
$this->assertFalse(ToolManager::isUrlExists("https://plus.google.com/+JonathanParentL%C3%A9vesque890800"));
$this->assertFalse(ToolManager::isUrlExists("https://instagram.com/mariloubiz1232132/", array(404, 405)));
$this->assertFalse(ToolManager::isUrlExists("https://www.pinterest.com/jonathan_parl1231/"));
$this->assertFalse(ToolManager::isUrlExists("https://regex101.com/546465465456"));
$this->assertFalse(ToolManager::isUrlExists("https://twitter.com/arcadefire4566546"));
$this->assertFalse(ToolManager::isUrlExists("https://vimeo.com/**($%?%$", array(400, 405)));
$this->assertFalse(ToolManager::isUrlExists("https://www.youtube.com/user/Darkjo666456456456"));
//valid
$this->assertTrue(ToolManager::isUrlExists("www.google.ca"));
$this->assertTrue(ToolManager::isUrlExists("https://www.facebook.com/jonathan.parentlevesque"));
$this->assertTrue(ToolManager::isUrlExists("https://plus.google.com/+JonathanParentL%C3%A9vesque"));
$this->assertTrue(ToolManager::isUrlExists("https://instagram.com/mariloubiz/"));
$this->assertTrue(ToolManager::isUrlExists("https://www.facebook.com/jonathan.parentlevesque"));
$this->assertTrue(ToolManager::isUrlExists("https://www.pinterest.com/"));
$this->assertTrue(ToolManager::isUrlExists("https://regex101.com"));
$this->assertTrue(ToolManager::isUrlExists("https://twitter.com/arcadefire"));
$this->assertTrue(ToolManager::isUrlExists("https://vimeo.com/"));
$this->assertTrue(ToolManager::isUrlExists("https://www.youtube.com/user/Darkjo666"));
}
Grand succès à tous,
Jonathan Parent-Lévesque de Montréal
assez vite:
function http_response($url){
$resURL = curl_init();
curl_setopt($resURL, CURLOPT_URL, $url);
curl_setopt($resURL, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($resURL, CURLOPT_HEADERFUNCTION, 'curlHeaderCallback');
curl_setopt($resURL, CURLOPT_FAILONERROR, 1);
curl_exec ($resURL);
$intReturnCode = curl_getinfo($resURL, CURLINFO_HTTP_CODE);
curl_close ($resURL);
if ($intReturnCode != 200 && $intReturnCode != 302 && $intReturnCode != 304) { return 0; } else return 1;
}
echo 'google:';
echo http_response('http://www.google.com');
echo '/ ogogle:';
echo http_response('http://www.ogogle.com');
Toutes les solutions ci-dessus + sucre supplémentaire. (Solution AIO ultime)
/**
* Check that given URL is valid and exists.
* @param string $url URL to check
* @return bool TRUE when valid | FALSE anyway
*/
function urlExists ( $url ) {
// Remove all illegal characters from a url
$url = filter_var($url, FILTER_SANITIZE_URL);
// Validate URI
if (filter_var($url, FILTER_VALIDATE_URL) === FALSE
// check only for http/https schemes.
|| !in_array(strtolower(parse_url($url, PHP_URL_SCHEME)), ['http','https'], true )
) {
return false;
}
// Check that URL exists
$file_headers = @get_headers($url);
return !(!$file_headers || $file_headers[0] === 'HTTP/1.1 404 Not Found');
}
Exemple:
var_dump ( urlExists('http://stackoverflow.com/') );
// Output: true;
pour vérifier si l'URL est en ligne ou hors ligne ---
function get_http_response_code($theURL) {
$headers = @get_headers($theURL);
return substr($headers[0], 9, 3);
}
function url_exists($url) {
$headers = @get_headers($url);
return (strpos($headers[0],'200')===false)? false:true;
}
Voici une solution qui ne lit que le premier octet du code source ... renvoyant false si le file_get_contents échoue ... Cela fonctionnera également pour les fichiers distants comme les images.
function urlExists($url)
{
if (@file_get_contents($url,false,NULL,0,1))
{
return true;
}
return false;
}
la manière simple est de boucler (et plus rapide aussi)
<?php
$mylinks="http://site.com/page.html";
$handlerr = curl_init($mylinks);
curl_setopt($handlerr, CURLOPT_RETURNTRANSFER, TRUE);
$resp = curl_exec($handlerr);
$ht = curl_getinfo($handlerr, CURLINFO_HTTP_CODE);
if ($ht == '404')
{ echo 'OK';}
else { echo 'NO';}
?>
Une autre façon de vérifier si une URL est valide ou non peut être:
<?php
if (isValidURL("http://www.gimepix.com")) {
echo "URL is valid...";
} else {
echo "URL is not valid...";
}
function isValidURL($url) {
$file_headers = @get_headers($url);
if (strpos($file_headers[0], "200 OK") > 0) {
return true;
} else {
return false;
}
}
?>
get_headers () retourne un tableau avec les en-têtes envoyés par le serveur en réponse à une requête HTTP.
$image_path = 'https://your-domain.com/assets/img/image.jpg';
$file_headers = @get_headers($image_path);
//Prints the response out in an array
//print_r($file_headers);
if($file_headers[0] == 'HTTP/1.1 404 Not Found'){
echo 'Failed because path does not exist.</br>';
}else{
echo 'It works. Your good to go!</br>';
}
cURL peut renvoyer du code HTTP Je ne pense pas que tout ce code supplémentaire soit nécessaire?
function urlExists($url=NULL)
{
if($url == NULL) return false;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if($httpcode>=200 && $httpcode<300){
return true;
} else {
return false;
}
}
Une chose à prendre en compte lorsque vous vérifiez l'en-tête d'un 404 est le cas où un site ne génère pas immédiatement un 404.
De nombreux sites vérifient si une page existe ou non dans la source PHP / ASP (et cetera) et vous redirigent vers une page 404. Dans ces cas, l'en-tête est essentiellement étendu par l'en-tête du 404 qui est généré. Dans ces cas, l'erreur 404 n'est pas dans la première ligne de l'en-tête, mais dans la dixième.
$array = get_headers($url);
$string = $array[0];
print_r($string) // would generate:
Array (
[0] => HTTP/1.0 301 Moved Permanently
[1] => Date: Fri, 09 Nov 2018 16:12:29 GMT
[2] => Server: Apache/2.4.34 (FreeBSD) LibreSSL/2.7.4 PHP/7.0.31
[3] => X-Powered-By: PHP/7.0.31
[4] => Set-Cookie: landing=%2Freed-diffuser-fig-pudding-50; path=/; HttpOnly
[5] => Location: /reed-diffuser-fig-pudding-50/
[6] => Content-Length: 0
[7] => Connection: close
[8] => Content-Type: text/html; charset=utf-8
[9] => HTTP/1.0 404 Not Found
[10] => Date: Fri, 09 Nov 2018 16:12:29 GMT
[11] => Server: Apache/2.4.34 (FreeBSD) LibreSSL/2.7.4 PHP/7.0.31
[12] => X-Powered-By: PHP/7.0.31
[13] => Set-Cookie: landing=%2Freed-diffuser-fig-pudding-50%2F; path=/; HttpOnly
[14] => Connection: close
[15] => Content-Type: text/html; charset=utf-8
)
J'exécute des tests pour voir si les liens sur mon site sont valides - m'alerte lorsque des tiers modifient leurs liens. J'avais un problème avec un site qui avait un certificat mal configuré qui signifiait que les get_headers de php ne fonctionnaient pas.
Donc, j'ai lu que curl était plus rapide et j'ai décidé de l'essayer. puis j'ai eu un problème avec linkedin qui m'a donné une erreur 999, qui s'est avérée être un problème d'agent utilisateur.
Je m'en fichais si le certificat n'était pas valide pour ce test, et je m'en fichais si la réponse était une redirection.
Ensuite, j'ai pensé utiliser get_headers de toute façon si curl échouait ...
Essayez....
/**
* returns true/false if the $url is present.
*
* @param string $url assumes this is a valid url.
*
* @return bool
*/
private function url_exists (string $url): bool
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_NOBODY, TRUE); // this does a head request to make it faster.
curl_setopt($ch, CURLOPT_HEADER, TRUE); // just the headers
curl_setopt($ch, CURLOPT_SSL_VERIFYSTATUS, FALSE); // turn off that pesky ssl stuff - some sys admins can't get it right.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
// set a real user agent to stop linkedin getting upset.
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36');
curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (($http_code >= HTTP_OK && $http_code < HTTP_BAD_REQUEST) || $http_code === 999)
{
curl_close($ch);
return TRUE;
}
$error = curl_error($ch); // used for debugging.
curl_close($ch);
// just try the get_headers - it might work!
stream_context_set_default(array('http' => array('method' => 'HEAD')));
$file_headers = @get_headers($url);
if ($file_headers)
{
$response_code = substr($file_headers[0], 9, 3);
return $response_code >= 200 && $response_code < 400;
}
return FALSE;
}
sorte d'un vieux fil, mais .. je fais ceci:
$file = 'http://www.google.com';
$file_headers = @get_headers($file);
if ($file_headers) {
$exists = true;
} else {
$exists = false;
}