In order to include the right file and display an error page if an error occurs, I have the following code (very simplified) :
$page = 'examplePage.php';
$page404 = '404.php';
if (file_exists($page))
{
require($page);
}
else if (file_exists($page404))
{
require($page404);
}
else
{
// Tell the browser to display his default page
}
?>
To summarize :
If I have the file, I include it.
If I don't have the file, i include the error file.
What if the error file does not exist too ?
I would like it to be rendered as the default error page of the browser.
I already achieved this with Internet Explorer by sending an empty content with the HTTP error.
The problem is that the other browsers don't act the same, they all display a blank page.
Is there any way to tell browsers to display their own error page ? (not only 404, but all errors : 304, 500 etc)
Thank you.
Edit : I forgot to tell you that I have the complete control on the headers I send and on the content sent in response.
Edit 2 : here is some code
// possible paths to retrieve the file
$possiblePaths = array(
$urlPath,
D_ROOT.$urlPath,
D_PAGES.$urlPath.'.php',
D_PAGES.$urlPath.'/index.php',
$urlPath.'.php'
);
foreach ($possiblePaths as $possiblePath)
if (file_exists($possiblePath) && !is_dir($possiblePath))
{
if (!is_readable($possiblePath))
{
Response::setCode(403); // calls the header(403)
self::$filePath = self::getErrorPage(403);
}
else
self::$filePath = $possiblePath;
break;
}
if (self::$filePath === null) // no file found => 404
{
Response::setCode(404); // call the header(404)
self::$filePath = self::getErrorPage(404);
}
public static function _getErrorPage($code)
{
if (is_readable(D_ERRORS.$code.'.php')) // D_ERRORS is the error directory, it contains files like 404.php, 403.php etc
return D_ERRORS.$code.'.php';
else
{
/*-------------------------------------------------*/
/* Here i go if the error file is not found either */
/*-------------------------------------------------*/
if ($code >= 400)
Response::$dieResponse = true; // removes all output, only leaves the http header
return null;
}
}
?>
And here is when I print the content :
<?php
if (self::$dieResponse)
{
self::$headers = array(); // no more headers
self::$content = ''; // no more response
}
http_response_code(self::$code); // HTTP code
foreach (self::$headers as $key => $value)
header($key.': '.implode(';', $value)); // sends all headers
echo self::$content;
?>
Edit : here are some screenshots to explain what I want.
This is what i've got in IE :
This is exactly what i want.
Now, in all the other browsers, I've got a blank page. I don't want a blank page.
I want, for example, Chrome to display this :
Default error pages
Web Browsers shows default error pages if content is blank, eg. create a empty PHP file (error.php) and put this:
<?php
$status = http_response_code();
switch ($status) {
case 404:
case 500:
exit;//terminate script execution
break;
...
}
In .htaccess put:
ErrorDocument 400 /error.php
ErrorDocument 500 /error.php
Custom error pages
Using HTTP status
You can use http_response_code() for GET current HTTP status, .htaccess file content:
ErrorDocument 400 /error.php
ErrorDocument 401 /error.php
ErrorDocument 403 /error.php
ErrorDocument 404 /error.php
ErrorDocument 500 /error.php
ErrorDocument 503 /error.php
Page error.php:
<?php
$status = http_response_code();
switch ($status) {
case '400':
echo 'Custom error 400';
break;
case '404':
echo 'Custom error 404';
break;
...
}
Using GET param
ErrorDocument 400 /error.php?status=400
ErrorDocument 401 /error.php?status=401
ErrorDocument 403 /error.php?status=403
ErrorDocument 404 /error.php?status=404
ErrorDocument 500 /error.php?status=500
ErrorDocument 503 /error.php?status=503
Page error.php:
<?php
$status = empty($_GET['status']) ? NULL : $_GET['status'];
switch ($status) {
case '400':
echo 'Custom error 400';
break;
case '404':
echo 'Custom error 404';
break;
...
}
Related: How to enable mod_rewrite for Apache 2.2
If you need to have it display its default 404 page, before any output, do this:
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
See here: http://www.php.net/manual/en/function.header.php
So, for your code, you could modify it to:
$page = 'examplePage.php';
$page404 = '404.php';
if (file_exists($page))
{
require($page);
}
else if (file_exists($page404))
{
require($page404);
}
else
{
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
}
?>
Note the following warning that header stuff has to be done before any other output:
Remember that header() must be called before any actual output is
sent, either by normal HTML tags, blank lines in a file, or from PHP.
It is a very common error to read code with include, or require,
functions, or another file access function, and have spaces or empty
lines that are output before header() is called. The same problem
exists when using a single PHP/HTML file.
I asked similar question before a while ago
Access apache errordocument directive from PHP
Upshot was either redirect the user to a generic 404 page (so the address changes) Header("Location: $uri_404"); or curl your own 404 page and echo it, like so:
Header('Status: 404 Not Found');
$uri_404 = 'http://'
. $_SERVER['HTTP_HOST']
. ($_SERVER['HTTP_PORT'] ? (':' . $_SERVER['HTTP_PORT']) : '')
. '/was-nowhere-to-be-seen';
$curl_req = curl_init($uri);
curl_setopt($curl_req, CURLOPT_MUTE, true);
$body = curl_exec($curl_req);
print $body;
curl_close($curl_req);
Code credit to #RoUS
Maybe you could try:
header('HTTP/1.0 404 Not Found');
Related
Can you please suggest me, how can I set 412 http code in header while coming invalid request from user form with out page termination or break.
Below code I am using in validation function
if(bad request){
header('HTTP/1.1 412 Precondition Failed', true, 412);
}
Note : only header should set the http code and page will return to user form and with error emssage
Validation function
function validateContactData($postData){
$db = &JFactory::getDBO();
$errorMsg = array();
$builder_name = $this->emptyReplace($postData['builder_name']);
if($builder_name == '' ){
header('HTTP/1.1 412 Precondition Failed', true, 412);
$errorMsg['builderNmError'] = "Please Select builder Program. ";
}
return $errorMsg;
}
I have found the solution which I used below function for set the header response without stuck the page .
http_response_code(412);
I have custom 404 page and working fine for pages that does not exist.
But I also want to show 404 page if someone query_string found to be missing/invalid/null from url.
How can I do so?
www.example.com/mypage.php?param1=value1
if(isset($_GET['param1']) && $_GET['param1'] !='')
{
//general code
}
else {
// Here I want to redirect to 404.php
}
also my 404 page is being accessed directly, and I want to prevent it.
I solved this using include, as Marco Mura suggested in his comment.
www.example.com/mypage.php?param1=value1
if(isset($_GET['param1']) && $_GET['param1'] !='')
{
//general code
}
else {
include "404.php";
}
Try to redirect users to 404 page through header() function like this:
www.example.com/mypage.php?param1=value1
if(isset($_GET['param1']) && $_GET['param1'] !='')
{
//general code
}
else {
header('Location: http://www.example.com/404.php');
exit;
}
I have following function in a php file :
function bc_output($vars) {
switch($_GET['a']){
case 'addip':
bc_add_licenses($vars, trim($_GET['current_ip']));
break;
case 'addiprequest':
if(isset($_POST['submitaddip'])) {
display_guidance_text();
bc_add_licenses_request($vars, $_POST);
} else {
display_guidance_text();
bc_get_licenses($vars, '4');
}
break;
default:
display_guidance_text();
bc_get_licenses($vars);
break;
}
}
Now when i go to url such as http://website.com/addon.php?module=b&a=addip it works fine, although for second case i.e http://website.com/addon.php?module=b&a=addiprequest browser throws 403 error..
Can anyone guide me where to proceed from here, i have echoed etc in the function but always 403 error.
Please comment if you need more info.
Ok, am using traditional php, no frameworks, nothing, I am using simple procedural way, now my question is I was searching for a while but am not getting an answer to my question, I am not using .htaccess files as of now, but I really need to understand how 404 error works? I am having a website, where I show post's related to category, say category=php, so I pass this as a get request
$_GET['category'] == 'php';
Now currently what am doing is something like this :
$pocategory = $_GET['category'];
if($pocategory == 'php' || $pocategory == 'javascript') {
//Then show related posts
} else {
header('Location:404.php');
exit;
}
I mean I just want php and javascript as valid request's value, rest I want to redirect to 404 but am not understanding how to do it so I did this way, what if am having more than 50 categories? I cant list them all in this if condition, Inshort how to detect whether the given get request value is invalid or not..
Any help will be much appreciated.
.htaccess is the way to do this.
ErrorDocument 404 index.php?404
that line will tell apache what file to load. The example above calls the main index.php script.
add something like this to the top of your index.php file:
$error_404 = isset($_GET["404"]) ? true : false;
now you can detect if you have a 404 error request. $error_404 will be true, so why not add a simple function:
function error_404($error_404)
{
if($error_404 == true)
{
// do some error stuff here, like set headers, and some text to tell your visitor
}
}
now just call your function:
error_404($error_404);
best to do that immidiatley after the get handler:
error_404($error_404)
$error_404 = isset($_GET["404"]) ? true : false;
or combine the two into one line:
error_404($error_404 = isset($_GET["404"]) ? true : false);
to address the question, add this to the relevant script:
$pocategorys_ar = array("php","javascript");
if (!in_array($pocategory, $pocategorys_ar))
{
error_404(true);
}
Make sure it has access to the error_404() function.
You could put all categories inside an array like this:
$pocategories = array
(
'php',
'javascript'
);
if (in_array($pocategory, $pages))
{
// ...
}
else
{
header('Location:404.php');
}
Another thing you could do is creating a html/php file for every category and do it like so
if (is_file('sites/' . $popcategory . '.php')
{
include('sites/' . $popcategory . '.php');
}
else
{
header('Location:404.php');
}
I'm trying to create a basic REST style API with PHP and I'm having a strange issue. When I visit one of my pages (viewinput.php) through the URL /rest/viewinput.php the page loads fine. When I try through /rest/viewinput I get a "page not found" error.
So, here's the code that determines the type of request and where to send it. This is found on my server.php page
//in server.php
public function serve() {
$uri = $_SERVER['REQUEST_URI'];
$method = $_SERVER['REQUEST_METHOD'];
$paths = explode('/', $this->paths($uri));
array_shift($paths); //
$resource = array_shift($paths);
if ($resource == 'rest') {
$page = array_shift($paths);
if (empty($page)) {
$this->handle_base($method);
} else {
$this->handle_page($method, $page);
}
}
else {
// We only handle resources under 'clients'
header('HTTP/1.1 404 Not Found');
}
}
Since it is a GET method with a determined page name, it will be passed to this function
//in server.php
private function handle_page($method, $page) {
switch($method) {
case 'GET':
if($page == "viewinput"){ //I have both viewinput.php and viewinput just to check both. Only viewinput.php works
$this->display_info();
}
if($page == "viewinput.php"){
$this->display_info();
}
default:
header('HTTP/1.1 405 Method Not Allowed');
header('Allow: GET, PUT, DELETE');
break;
}
}
From here it is then sent to
//in server.php
function display_info(){
$view = new ViewInputs();
$view->view(); //this function is on viewinput.php
}
So, when I visit /rest/viewinput.php the view function displays properly. When I visit /rest/viewinput I get a "broken link" error.
I followed a tutorial online for a REST server Found Here and it works just fine.
The following is in my httpd.conf file
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^/.* rest/server.php
This is my viewinput.php file. I believe that it's working correctly (when page loads, the serve function on server.php should run.
<?
include_once 'server.php';
class ViewInputs{
function view(){
$sql = mysql_query("select * from entry");
?>
<table>
<th>ID</th>
<th>Text</th>
<col width="200">
<col width="150">
<?
while ($result = mysql_fetch_array($sql)){
?>
<tr><td><? echo $result['id']." "; ?></td><td><? echo $result['text']; ?></td></tr>
<?
}
?> </table> <?
}
}
$server = new server();
$server->serve();
?>
From httpd.conf. I may be wrong, but I believe this is how to allow a .htaccess file
DocumentRoot "C:/xampp/htdocs/rest"
<Directory />
Options FollowSymLinks
AllowOverride ALL
Order deny, allow
Deny from none
</Directory>
<Files ".ht*">
Require all ALLOW
</Files>
Your rewrite rule is not written correctly. What is happening is that when you go to rest/viewinput.php that file actually exists so it is able to run. When you go to rest/viewinput that file doesn't exist. You can check your rewrite rule by going to http://martinmelin.se/rewrite-rule-tester/ you will see your rewrite rule is no good.
The point of doing this is so that you don't have a veiwinput.php file, everything should be sent directly to the server.php file. Most likely the rewrite rule you want is something like this:
RewriteRule rest/* rest/server.php
If you want to actually go to viewinput.php there is no point in having a rewrite rule at all, just get rid of it.
If you want rest/viewinput to be treated as rest/viewinput.php then use this:
RewriteRule ^rest/([a-z]+) rest/$1.php