How to print custom error when trying to include/require a php file ?
This was my idea:
<?php
try{
include "template/".$_GET['view'].".php";
}
catch (Exception $e){
echo 'some error code';
};
?>
But, still I'm getting default error if required file don't exist.
Decided the comment was worth changing to answer:
Use file_exists() to see if file exists.
If it does, include, else echo your custom error message.
Use file_exists() to check if the file is there before including. That way you can handle the error.
<?php
if(file_exists('asd.php')){
include "asd.php";
}else{
echo "Oh no! The file doesn't exist!";
}
?>
The include errors are not going to be caught by your try/catch, however, I believe that errors inside the included script would be caught correctly. A better solution would be to use the file-exists function, see this post for an example: Optional include in PHP
Once you perform your own verification for the existence for the file you can wrap the executing code in a try catch to ensure errors in that code are caught.
I would not recommend using just file_exist. You don't want your visitor to have access to any file on your file-system so I would recommend a white-list; if the file-name is in the white-list, only then display / include it.
if ((include "template/".$_GET['view'].".php") != 'OK') {
echo "My custom error message";
}
If you want your own error Message you can do it like this:
<?php
$file = "template/".$_GET['view'].".php";
if ( error_reporting() == 0 ){
( #include_once($file) ) OR die("<tt><p><b>ERROR</b> $file file not found!</p>");
}else{
require_once($file);
}
?>
So if there is no error reporting (as most time in productiv enviroment) you can print your own Error Message. If you are in Development Mode (ans error_reporting is on) the you get PHP Error Message!
HINT Never use $_GET Input from user direct for an Include - this is a Black XSS Hole :-D
Related
I have a file called functions.php.
This file consists includes to all the other function files, for example:
include_once("user_functions.php");
include_once("foo_functions.php");
I would like to catch errors where when I screw a code in one of those files, It wouldn't give the error to the entire system.
For example, if there is a parser error in foo_functions.php it will just not include it in functions.php.
Is that possible?
As of PHP 7, most eval/include errors, such as ParseError can be catched:
try {
include_once(__DIR__ . '/test.php');
} catch (\Throwable $e) {
var_dump($e);
}
Parser errors are fatal errors, so you can't catch them. See this question and answer for more details.
What you can do if you can run exec() is call php -l thefilename.php and check the result. See the manual for information on how this works. There are a few problems here, however:
This is extremely dangerous, because you are passing information to the command line. You absolutely must filter any user input very carefully, or you would be giving the user very broad access to your system.
exec() is often disabled, as it should be, because of the extremely high security risks of using it incorrectly.
There's really no good reason to include a file that you haven't already validated for syntax errors. If this is for plugins or something, then I understand your reasoning. If it is code you have control over, however, you should validate before putting it into production.
This code can check if file is exist or not, if file exist than include it.
<?
if(!is_file('user_functions.php')){
//There is no file user_functions.php . You may use file_put_contents('user_functions.php','<? //content ?>');
}else{
//ther is file user_functions.php, so include it.
include 'user_functions.php';
}
?>
And this one help you get syntax errors (PHP 7+ only)
<?
try {
include('user_functions.php');
}catch (ParseError $e) {
echo 'Error: '.$e->getMessage();
//syntax error, unexpected end of file, expecting ',' or ';'
}
?>
so if you use PHP 7+ you may use:
<?
if(!is_file('user_functions.php')){
echo 'Error: file is not exist';
}else{
//check errors
try {
include('user_functions.php');
}catch (ParseError $e) {
echo 'Error: '.$e->getMessage();
//syntax error, unexpected end of file, expecting ',' or ';'
}
}
?>
What if you put
error_reporting(E_ALL);
ini_set("display_errors", 1);
at the beginning of foo_functions.php ?
include() and include_once() return false if they fail. You can use this to check if the included files were successful.
if (!include('user_functions.php'))
echo 'user functions failed to include';
if (!include('foo_functions.php'))
echo 'foo_functions failed to include';
By changing the echos to handle your error logic, you should be able to do what you are asking.
The solution that I am using feels like a band-aid solution, but it will give you control back.
The idea is to use "eval()" to first check for errors. Also, ignore errors with the # in the beginning. Of course you will need to be careful with eval, so don't ever let users feed anything to it.
// first "eval" the file to see if it contains errors
$txt = file_get_contents($template_filename);
// eval starts out in php-mode. get out of it.
$txt = '?' . '>' . $txt;
ob_start();
$evalResult = #eval($txt);
ob_end_clean();
// if there are no errors
if($evalResult !== FALSE) {
require($template_filename);
} else {
error_log(print_r(error_get_last(), TRUE));
}
Please note that I think "file_get_contents + eval" = "require", or very close to it, so you may be able to just skip the require-part.
I am trying to replace the built in php shutdown_function with a custom one.
It works perfectly, however, it still outputs the original error (built in error) above my new error message.
<?php
function shutdown_output() {
$error = error_get_last();
if($error !== NULL) {
echo "ERROR";
exit();
} else {
echo "NO ERROR";
}
}
// Set the error reporting:
register_shutdown_function('shutdown_output');
// test.php does not exist, just here to get a critical error
require_once("test.php");
?>
Any ideas?
As already mentioned in comments, the use of register_shutdown_function is not going to override built-in error handling (the same way that set_error_handler doesn't either).
If you don't want to see the original message, disable the output of them in your php.ini using display_errors = 0. Or on the fly in your script using ini_set('display_errors', 0);.
You know how PHP errors always show up at the very top of the page. Is there a way to suppress that and turn it in to a $var? Then you could place it somewhere in the page.
Yes, you could set your own error handler to intercept and do something with those error besides simply outputting them wherever they occur. But I don't think it's very useful to display PHP errors elegantly on a page. PHP errors are not meant to be pretty, they're not meant to occur at all. If you see one, it should be as jarring as possible and you should fix it as soon as possible. They're meant as a help during development. Trying to pretty them up is spending time on the wrong part of the code.
In production, those errors should be logged to a log file and not visibly output on the page at all.
$php_errormsg holds the previous error, even the suppressed ones.
#fopen('foo.txt', 'w');
echo $php_errormsg; // You can put this anywhere you want the error to display
If you think you'll have more than one error, then you could store these errors in an array.
$errors = array();
for($files as $f) {
#fopen($f, 'w');
$errors[] = $php_errormsg;
}
Then you could print out all your errors:
print_r($errors);
//or
for($errors as $e) {
echo $e;
}
I'm trying to make errors hidden but it seems I'm doing something wrong.
In my hosting configuration display_errors is set to off and I don't have .htaccess file. I tried to write follownng script
<?php
echo ord(ini_get("display_errors")) . " ";
die("error");
?>
And I'm getting following output:
0 error
So, display_errors is set to off, but die() function still shows error on the screen. How to avoid this?
By doing die("error"), you're are commanding the code that it should output the string "error" and stop the code.
You are seeing the "error" message does not mean that there is an error, it is just another string.
die() is a function (commonly used to handle errors), but it is not deactivated when you set display errors off. It will still work and to whatever it is meant to do.
How to avoid this?
Do not use die() to handle errors.
use trigger_error() instead, which will follow the behavior you expected
There is a option to display error to stderr instead of stdout so you won't see them on you webpage, but only in the logs. (Manual)
I found error_log() function. Now I can use
function quit($error)
{
echo "Request failed";
error_log($error);
die();
}
How would I go about checking if and include or a require has an error in it. For example, and include would try to be included, if that page has an error the page isn't included and a message is throw?
Cheers.
You can't catch a parse error in PHP in the same language environment (for obvious reasons).
One approach might be to run php -l your_included_file.php using exec and then check the exit code. The -l (lint) argument checks that your code can be parsed correctly.
You can try using file_exist function, it check whether the file exist or not.
$filename = "/path/to/file.php";
if(file_exists($filename)){
include $filename;
}else{
include "errorpage.php";
}
You can't trap parser errors.
However, if the code executes something that causes an exception to be thrown, you could catch it with a try/catch block.