display custom 404 error page without redirection in PHP
I created custom 404 error page called error.php, now I want to display the error.php content in user entered url.like this link: http://www.youtube.com/asdfasfsd This is my htaccess code:
ErrorDocument 404 https ://localhost/path/error.php
I want to show the error.php content in same URL without redirect to error.php page if user typed invalid url (for example:https ://localhost/path/nnn.php)
current result:redirecting to error.php expected result:display error.php content in https ://localhost/path/nnn.php
Options +FollowSymlinks RewriteEngine On RewriteCond % !on RewriteRule (.*) https://%% RewriteRule index.html$ index.php [L] RewriteRule service.html$ service.php [L] RewriteRule ^([^/]*)\.html$ about.php?pid=$1 [L] RewriteRule ^cont/([^/]*)\.html$ contact-inner.php?tid=$1 [L] RewriteRule ^contact/([^/]*)/([^/]*)\.html$ contact-page.php?tid=$1&ona=$2 [L] RewriteRule ^about/([^/]*)\.html$ about-inner.php?oid=$1 [L] RewriteRule ^service/([^/]*)/([^/]*)\.html$ service-page.php?oid=$1&ona=$2 [L] ErrorDocument 404 https://localhost/ezhil/path/public_html/error.php order allow,deny allow from all deny from 117.202.102.84 deny from 58.68.25.210 deny from 91.200.13.112 deny from 86.128.130.170 deny from 91.200.13.7 deny from 173.208.206.90
this must be done using .htaccess . if no RewriteRule is met, then execute error.php . The url will stay the same, but the error.php will be executed. no time for me to answer now, lunch break 😛
This question appears to be off-topic because it is about configuring apache, not about programming (in php)
Yes, it is not specific to PHP. But «configuring Apache» is something different to me. Configuring Apache means to me editing /etc/apache2/ (as server administrator), but changing a .htaccess is an edit of the web application. The .htaccess file is a part of a website resp. a web-application (like a CMS), and therefore it does count to web-development in my opinion.
4 Answers 4
Please remove your ErrorDocument rule and replace it with following code :
RewriteCond % !-f RewriteCond % !-d RewriteRule ^(.*)$ error.php [L]
A suggestion by the way: You should put a [L] behind RewriteRule (.*) https://%% , so that no other rule will override the HTTPS-enforcement.
Your .htaccess will then look like this:
Options +FollowSymlinks RewriteEngine On RewriteCond % !on RewriteRule (.*) https://%% [L] RewriteRule index.html$ index.php [L] RewriteRule service.html$ service.php [L] RewriteRule ^([^/]*)\.html$ about.php?pid=$1 [L] RewriteRule ^cont/([^/]*)\.html$ contact-inner.php?tid=$1 [L] RewriteRule ^contact/([^/]*)/([^/]*)\.html$ contact-page.php?tid=$1&ona=$2 [L] RewriteRule ^about/([^/]*)\.html$ about-inner.php?oid=$1 [L] RewriteRule ^service/([^/]*)/([^/]*)\.html$ service-page.php?oid=$1&ona=$2 [L] RewriteCond % !-f RewriteCond % !-d RewriteRule ^(.*)$ error.php [L] order allow,deny allow from all deny from 117.202.102.84 deny from 58.68.25.210 deny from 91.200.13.112 deny from 86.128.130.170 deny from 91.200.13.7 deny from 173.208.206.90
jesus christ or whatever, dont just copy from other questions stackoverflow.com/a/2777272/953684. there are some paths in there (!^subs) from the other question. please pay attention when you answer. you could just link to that answer through a comment.
I had the idea with mod_rewrite before you commented above. Don’t be that angry just because I have overseen that detail.
there is no point which had «first» the idea. the point is you copy and paste something from ANOTHER question, that means its GARBAGE for THIS question. if you can’t understand why this is bad, i can’t help you more. and for the «overseen the detail»: the DETAIL makes the difference. if you dont have time for a detailed answer, just post a link to the other answer for further investigation, or get ready for downvotes for «no research effort».
Stop being that aggresive to new users. I am willing to edit my answers. And leave jesus out of your comments, this offends me.
Modify the line in your .htaccess file. Just use path and filename (Without host)
ErrorDocument 404 /path/error.php
You may need to tweak your existing htaccess a bit for this to work
RewriteEngine On # your existing rules. please note the [L] after each rule RewriteRule ^main$ index.php [L] RewriteRule ^about-us$ aboutus.php [L] RewriteRule ^whatever$ whatever.php [L] # anything else that ends with .php RewriteRule .*\.php$ error.php
as soon a RewriteRule is met, further execution is stopped by [L] . Then if the request ends with .php the error.php will be executed.
Just add code like this in your .htaccess
ErrorDocument 404 ""
ErrorDocument 404 ""
Easy way to test a URL for 404 in PHP?
I’m teaching myself some basic scraping and I’ve found that sometimes the URL’s that I feed into my code return 404, which gums up all the rest of my code. So I need a test at the top of the code to check if the URL returns 404 or not. This would seem like a pretty straightfoward task, but Google’s not giving me any answers. I worry I’m searching for the wrong stuff. One blog recommended I use this:
$valid = @fsockopen($url, 80, $errno, $errstr, 30);
and then test to see if $valid if empty or not. But I think the URL that’s giving me problems has a redirect on it, so $valid is coming up empty for all values. Or perhaps I’m doing something else wrong. I’ve also looked into a «head request» but I’ve yet to find any actual code examples I can play with or try out. Suggestions? And what’s this about curl?
15 Answers 15
If you are using PHP’s curl bindings, you can check the error code using curl_getinfo as such:
$handle = curl_init($url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); /* Get the HTML or whatever is linked in $url. */ $response = curl_exec($handle); /* Check for 404 (file not found). */ $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); if($httpCode == 404) < /* Handle 404 here. */ >curl_close($handle); /* Handle $response here. */
I’m not familiar with cURL yet, so I’m missing a few concepts. What do I do with the $response variable down below? What does it contain?
@bflora, I made a mistake in the code. (Will fix in a second.) You can see the documentation for curl_exec on PHP’s site.
@bflora $response will contain the content of the $url so you can do additional things like checking the content for specific strings or whatever. In your case, you just care about the 404 state, so you probably do not need to worry about $response.
@patrick then you need to specify curl_setopt($handle, CURLOPT_NOBODY, true); before running curl_exec
If your running php5 you can use:
$url = 'http://www.example.com'; print_r(get_headers($url, 1));
Alternatively with php4 a user has contributed the following:
/** This is a modified version of code from "stuart at sixletterwords dot com", at 14-Sep-2005 04:52. This version tries to emulate get_headers() function at PHP4. I think it works fairly well, and is simple. It is not the best emulation available, but it works. Features: - supports (and requires) full URLs. - supports changing of default port in URL. - stops downloading from socket as soon as end-of-headers is detected. Limitations: - only gets the root URL (see line with "GET / HTTP/1.1"). - don't support HTTPS (nor the default HTTPS port). */ if(!function_exists('get_headers')) < function get_headers($url,$format=0) < $url=parse_url($url); $end = "\r\n\r\n"; $fp = fsockopen($url['host'], (empty($url['port'])?80:$url['port']), $errno, $errstr, 30); if ($fp) < $out = "GET / HTTP/1.1\r\n"; $out .= "Host: ".$url['host']."\r\n"; $out .= "Connection: Close\r\n\r\n"; $var = ''; fwrite($fp, $out); while (!feof($fp)) < $var.=fgets($fp, 1280); if(strpos($var,$end)) break; >fclose($fp); $var=preg_replace("/\r\n\r\n.*\$/",'',$var); $var=explode("\r\n",$var); if($format) < foreach($var as $i) < if(preg_match('/^([a-zA-Z -]+): +(.*)$/',$i,$parts)) $v[$parts[1]]=$parts[2]; >return $v; > else return $var; > > >
Both would have a result similar to:
Array ( [0] => HTTP/1.1 200 OK [Date] => Sat, 29 May 2004 12:28:14 GMT [Server] => Apache/1.3.27 (Unix) (Red-Hat/Linux) [Last-Modified] => Wed, 08 Jan 2003 23:11:55 GMT [ETag] => "3f80f-1b6-3e1cb03b" [Accept-Ranges] => bytes [Content-Length] => 438 [Connection] => close [Content-Type] => text/html )
Therefore you could just check to see that the header response was OK eg:
$headers = get_headers($url, 1); if ($headers[0] == 'HTTP/1.1 200 OK') < //valid >if ($headers[0] == 'HTTP/1.1 301 Moved Permanently') < //moved or redirect page >