I have the following code working on a WordPress plugin. But there's no WP issue, the matter is:
can I trust @get_headers
to perform most of times?
public function enqueue()
{
$http = is_ssl() ? 'https:' : 'http:';
$url = "$http//netdna.bootstrapcdn.com/font-awesome/3.2.0/css/font-awesome.min.csss";
if( $this->get_http_response_code( $url ) ) {
my_load_external_script();
}
else {
my_load_local_script();
}
}
/**
* Problem with getting header, return false
*
* otherwise return if headers are 200 or not
*
* @param $url string
* @return boolean
*/
private function get_http_response_code( $url )
{
$headers = @get_headers( $url );
if( !$headers )
return false;
return substr( $headers[0], 9, 3 ) === '200';
}
The current requirement for running WordPress is PHP 5.2.4 or greater. As I understand it, there's no 100% guarantee, but for having a plugin running in the wild I'd prefer the less problematic path. I've checked the following Stack Overflow Q&A's, but haven't come to any conclusion:
-
1\$\begingroup\$ Hitting another server on a page request just to check if the CDN is available seems like bad design to me. I would do this check client side in javascript, and if the file is 404 then fallback to an alternate URL. Or make it a configured option of which URL to use. \$\endgroup\$Reactgular– Reactgular2013年11月13日 13:04:40 +00:00Commented Nov 13, 2013 at 13:04
1 Answer 1
In my experience no, using curl
is much better an reliable. I use the following code in one of my projects, this always works (and allows redirects, if you don't want to set CURLOPT_MAXREDIRS
to 0
).
<?php
/**
* Check if the URL is reachable.
*
* @param string $url
* The URL to check.
* @return this
* @throws \LogicException
*/
public function checkReachability($url) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_AUTOREFERER => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_ENCODING => "",
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 1,
CURLOPT_NOBODY => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 5,
// It's very important to let other webmasters know who's probing their servers.
CURLOPT_USERAGENT => "Mozilla/5.0 (compatible; StackOverflow/0.0.1; +https://codereview.stackexchange.com/)",
]);
curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code !== 200) {
throw new LogicException("The URL doesn’t exists (more specifically isn’t reachable).");
}
return $this;
}
?>
Of course you have the problem that you don't always have curl
available, a fallback would be.
<?php
// PHP 5.3+
stream_context_set_default(array("http" => array(
"method" => "HEAD",
"user_agent" => "Mozilla/5.0 (compatible; StackOverflow/0.0.1; +https://codereview.stackexchange.com/)",
)));
set_error_handler(function ($errno, $errstr, $errfile, $errline ) {
throw new LogicException("The URL doesn’t exists (more specifically isn’t reachable).");
});
$headers = get_headers($url);
restore_error_handler();
// String comparisons should be made with ==
if (!isset($headers[0]) || substr($headers[0], 9, 3) != "200") {
throw new LogicException("The URL doesn’t exists (more specifically isn’t reachable).");
}
?>
-
\$\begingroup\$ Kool, I need to wait for new PC until I can test this, thx for the feedback. \$\endgroup\$brasofilo– brasofilo2013年11月13日 11:23:59 +00:00Commented Nov 13, 2013 at 11:23