i am trying to get string of cross domain but sometime or some website gives a 403 Forbidden error. So to protect from getting error i am trying to include if statement, if site one get error while getting string then it will move to else part and take string from site two.
Error :
Warning: file_get_contents(https://www.example.com): Failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden
Code :
$siteone = file_get_contents("https://www.example.com");
$sitetwo = file_get_contents("https://www.example.net");
if ($siteone === false) {
$error = error_get_last();
echo $sitetwo;
} else {
echo $siteone;
}
So, here if example.com give 403 error then it automatically ignore example.com and get string from example.net.
I have also tried try and catch but it didn't work. Please help!!
Rather than using file_get_contents or getting caught up writing functions using get_headers etc to verify response code before attempting to capture the contents I'd suggest using cURL. Within your curl request you can inspect the HTTP Response code directly and the added advantage is that you automatically have the content available to you if the request is successful.
$errors = $valid = $content = array();
$break_on_success = false;
$urls=array(
'https://www.bogus.com',
'https://stackoverflow.com/',
'https://developer.mozilla.org',
'https://developer.mozilla.org/en-US/admin',
'https://stackoverflow.com/questions/70518330/if-statement-with-file-get-contents-to-avoid-403-error',
'https://www.gumtree.com/',
'https://httpstat.us/307',
'https://httpstat.us/403',
'https://httpstat.us/401',
'https://www.farcebook.com'
);
foreach( $urls as $url ){
$ch=curl_init( $url );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, true );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 );
curl_setopt( $ch, CURLOPT_CAINFO, $cacert );
curl_setopt( $ch, CURLOPT_CAPATH, $cacert );
$response=curl_exec( $ch );
if( !curl_errno( $ch ) ){
$status=curl_getinfo( $ch, CURLINFO_RESPONSE_CODE );
if( $status==200 ){
$valid[]=$url;
$content[ $url ]=$response;
if( $break_on_success )break;
}else{
$errors[ $status ]=$url;
}
}
$ch=null;
}
printf('<pre>%s</pre>',print_r($valid,true));
printf('<pre>%s</pre>',print_r($errors,true));
This will generate the following output:
Array
(
[0] => https://stackoverflow.com/
[1] => https://developer.mozilla.org
[2] => https://stackoverflow.com/questions/70518330/if-statement-with-file-get-contents-to-avoid-403-error
[3] => https://www.gumtree.com/
[4] => https://httpstat.us/307
[5] => https://www.farcebook.com
)
Array
(
[404] => https://developer.mozilla.org/en-US/admin
[403] => https://httpstat.us/403
[401] => https://httpstat.us/401
)
The urls listed in the first array have been processed and do not return a bogus http status code whereas those in the second can be ignored. If, in the above, you set $break_on_success=true; the code would halt once the first url to return a good response has been found. The HTML content for each url is stored within the $content array and can be subsequently processed.
I mentioned using get_headers to accomplish this goal. Whilst it is possible there are several pitfalls that one might encounter and any code might end up becoming more complicated than is necessary.