I have a basic if-then-else statement to catch an "exception" but I can not do much in case the exception happens so I would like to exit my script at this point with a fatal error. How can I do this?
The code is:
if(ksort($hFileList)) $fileList = array_values($hFileList);
else ???
That is: I am duing all I can to ensure my $hFileList is there and looks as it should, but in case something unexpected happens, I would like to produce a standard php fatal error.
Shall I simply get rid of the if and let it "crash" instead?
just put a call to phps trigger_error method:
if( true === $errorCase ) {
trigger_error( $yourErrorMessage, E_ERROR );
}
that'll stop your script with a fatal error.
see php documentation also:
http://php.net/manual/de/function.trigger-error.php
You can also you die() function like:
if(ksort($hFileList))
{
$fileList = array_values($hFileList);
}
else
{
die("Error Occurred");
}
You could actually use trigger_error(..) if you do not want any exception-catching mechanisms.
You might like a more readable construct:
ksort($hFileList) or trigger_error("IT FAILED!",E_ERROR);
$fileList = array_values($hFileList);
Use good old exit() function maybe?
Related
Well, I have run into a bit of a pickle here. I am needing to check some PHP for syntax errors. I noticed this bit that needs to run from the commandline:
php -l somefile.php
However, is there a way to run this from within a PHP file itself? I've been looking and have think that I can use parse_str function somehow to accomplish this by entering it into a $_GET, but can't quite understand how this works.
Someone else told me to use token_get_all() php function to determine this.
But I can't figure out how to do this with any approach? Can anyone here give me some sample code to get started perhaps?? I don't think using eval() is the way to go, although I had an eval($code) working, but don't think I should run the script if there are PHP syntax errors.
Any help on this is greatly appreciated, as always!
You could simply do shell_exec() like this:
$output = shell_exec('php -l /path/to/filename.php');
This gives you the output of the command line operation in the string $output.
It is safer to check the return status of php -l
$fileName = '/path/to/file.php';
exec("php -l {$fileName}", $output, $return);
if ($return === 0) {
// Correct syntax
} else {
// Syntax errors
}
See this fiddle to see it in action
I use token_get_all for this. I have some PHP code in the db. Before saving, I do
function is_valid_php_code_or_throw( $code ) {
$old = ini_set('display_errors', 1);
try {
token_get_all("<?php\n$code", TOKEN_PARSE);
}
catch ( Throwable $ex ) {
$error = $ex->getMessage();
$line = $ex->getLine() - 1;
throw new InvalidInputException("PARSE ERROR on line $line:\n\n$error");
}
finally {
ini_set('display_errors', $old);
}
}
Works like a charm. Syntax only. No missing variables, type incompayibility etc.
InvalidInputException is my own. You can make it anything, or return a bool, or handle the exception yourself.
I'm not sure if display_errors is necessary. It was at some point.
I would do it like this:
$php_file = 'The path to your file';
if(substr(`php -l $php_file`, 0, 16) == 'No syntax errors') {
// Correct syntax
} else {
// Error
}
php_check_syntax should do the trick. If you're running PHP >= 5.05, see the first comment in the comments section for the implementation.
You can use exec to check for syntax errors.
$tempFile = path/of/file
$syntaxParseError = strpos(exec('php -l '.$tempFile), 'No syntax errors detected') === false;`
Unfortunately, this will not give you the line number or tell you anything about the error. For that you will either need to install static analyzer on your server Is there a static code analyzer [like Lint] for PHP files? or write your own parser.
NB. token_get_all() will not determine anything on its own, but it useful function for making a parser.
Why use the shell at all?
function syntax_is_valid($code)
{
try
{
#eval($code);
}
catch (ParseError $e)
{
return false;
}
return true;
}
Alternatively use $e->getMessage() for more info.
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.
Well, I have run into a bit of a pickle here. I am needing to check some PHP for syntax errors. I noticed this bit that needs to run from the commandline:
php -l somefile.php
However, is there a way to run this from within a PHP file itself? I've been looking and have think that I can use parse_str function somehow to accomplish this by entering it into a $_GET, but can't quite understand how this works.
Someone else told me to use token_get_all() php function to determine this.
But I can't figure out how to do this with any approach? Can anyone here give me some sample code to get started perhaps?? I don't think using eval() is the way to go, although I had an eval($code) working, but don't think I should run the script if there are PHP syntax errors.
Any help on this is greatly appreciated, as always!
You could simply do shell_exec() like this:
$output = shell_exec('php -l /path/to/filename.php');
This gives you the output of the command line operation in the string $output.
It is safer to check the return status of php -l
$fileName = '/path/to/file.php';
exec("php -l {$fileName}", $output, $return);
if ($return === 0) {
// Correct syntax
} else {
// Syntax errors
}
See this fiddle to see it in action
I use token_get_all for this. I have some PHP code in the db. Before saving, I do
function is_valid_php_code_or_throw( $code ) {
$old = ini_set('display_errors', 1);
try {
token_get_all("<?php\n$code", TOKEN_PARSE);
}
catch ( Throwable $ex ) {
$error = $ex->getMessage();
$line = $ex->getLine() - 1;
throw new InvalidInputException("PARSE ERROR on line $line:\n\n$error");
}
finally {
ini_set('display_errors', $old);
}
}
Works like a charm. Syntax only. No missing variables, type incompayibility etc.
InvalidInputException is my own. You can make it anything, or return a bool, or handle the exception yourself.
I'm not sure if display_errors is necessary. It was at some point.
I would do it like this:
$php_file = 'The path to your file';
if(substr(`php -l $php_file`, 0, 16) == 'No syntax errors') {
// Correct syntax
} else {
// Error
}
php_check_syntax should do the trick. If you're running PHP >= 5.05, see the first comment in the comments section for the implementation.
You can use exec to check for syntax errors.
$tempFile = path/of/file
$syntaxParseError = strpos(exec('php -l '.$tempFile), 'No syntax errors detected') === false;`
Unfortunately, this will not give you the line number or tell you anything about the error. For that you will either need to install static analyzer on your server Is there a static code analyzer [like Lint] for PHP files? or write your own parser.
NB. token_get_all() will not determine anything on its own, but it useful function for making a parser.
Why use the shell at all?
function syntax_is_valid($code)
{
try
{
#eval($code);
}
catch (ParseError $e)
{
return false;
}
return true;
}
Alternatively use $e->getMessage() for more info.
Why am I getting this error?
Warning: file_get_contents(http://www.example.com) [function.file-get-contents]: failed to open stream: HTTP request failed! in C:\xampp\htdocs\test.php on line 22
Fatal error: Maximum execution time of 30 seconds exceeded in C:\xampp\htdocs\test.php on line 22
Here is the code:
try {
$sgs = file_get_contents("http://www.example.com");
}
catch (Exception $e) {
echo '123';
}
echo '467';
Aren't try\catch supposed to continue the excecution of the code? Or maybe there is some different way to do it?
try... catch is more for null object exceptions and manually thrown exceptions. It really isn't the same paradigm as you might see in Java. Warnings are almost deceptive in the fact that they will specifically ignore try...catch blocks.
To suppress a warning, prefix the method call (or array access) with an #.
$a = array();
$b = #$a[ 1 ]; // array key does not exist, but there is no error.
$foo = #file_get_contents( "http://somewhere.com" );
if( FALSE === $foo ){
// you may want to read on === there;s a lot to cover here.
// read has failed.
}
Oh, and it is best to view Fatal Exceptions are also completely uncatchable. Some of them can be caught in some circumstances, but really, you want to fix fatal errors, you don't want to handle them.
catch cannot catch a fatal error.
Just search for timeout in the manual for file_get_contents, there are several solutions listed there, here is one:
$ctx = stream_context_create(array(
'http' => array(
'timeout' => 1
)
)
);
file_get_contents("http://example.com/", 0, $ctx);
try..catch will only catch exceptions. A fatal error is not an exception.
If PHP exceeds its maximum execution time, there's nothing you can do. PHP simply stops dead. It's the same if PHP runs out of memory: Nothing you can do to fix it after it's happened.
In other words, exceptions are errors you can potentially recover from. Fatal errors are, well, fatal and unrecoverable.
In PHP a fatal error will halt execution of the script. There are ways to do something when you run into them, but the idea of a fatal error is that it should not be caught.
Here are some good details: http://pc-technic.blogspot.com/2010/10/php-filegetcontents-exception-handling.html
Basically change your code to do the following:
try {
#$sgs = file_get_contents("http://www.example.com");
if ($sgs == FALSE)
{
// throw the exception or just deal with it
}
} catch (Exception $e) {
echo '123';
}
echo '467';
Note the use of the '#' symbol. This tells PHP to ignore errors raised by that particular piece of code. Exception handling in PHP is very different than java/c# due to the "after the fact" nature of it.
Fatal errors in PHP are not caught. Error handling and Exception handling are two different things. However if you are hell bent on handling fatal errors as exception, you will need to set up your own error handler and direct all errors to it, make your error handler throw exceptions and you can then catch them.
file_get_contents doesn't throw exception (and thus errors and warnings it throws aren't catchable). You are getting PHP warning and then fatal error, which explains you why the script doesn't continue - it exceeded limit for loading scripts set in php.ini.
I have a page that will basically be used to concatenate a bunch of xml files, it will act as glue that binds them together. There's a small chance the xml files that are being combined might not be well formed because the user will have access.
I'm trying to basically rewrite a live file if there are no warnings / errors thrown in a specific set of code.
So far I have:
try {
$first = simplexml_load_file( 'file.xml' );
} catch ( Exception $e ) {
$write = false;
}
if ( !$write ) {
// write to live file.
}
This obviously catches error exceptions, but sometimes function invocations can return warnings and not errors per se, what can I use to catch errors, basically only write if no warnings and errors have been thrown in the try block?
Example of a warning being thrown:
Warning: simplexml_load_file() parser error : Start tag expected, '<'
Just look for other "symptoms" of a failed read. From the simplexml_load_file manual entry:
Return Values
Returns an object of class SimpleXMLElement with properties containing the data held within the XML document. On errors, it will return FALSE.
So, use it like this:
$first = simplexml_load_file( 'file.xml' );
if ($first == false) {
echo "File couldn't be loaded";
exit(); // abort normal program execution, redirect or what have you
}
// continue as normal
Almost all functions return some sort of false in case of an error. You shouldn't use manual "error parsing" except for very special cases. This isn't one of them.
A few things come to mind for this situation. if you will always have warnings enabled (not a great idea for a production server) you can always use the output buffering functions to check if there was any text sent out
ob_start();
... //code
$str = ob_get_contents();
if (! empty($string))
{
// a warning was thrown.
}
The better way is to define an error handler for warnings and do whatever you want with them:
set_error_handler("my_warning_handler", E_WARNING);
function my_warning_handler($errno, $errstr) {
// do something
}
Set an error handler, and raise exceptions from there. Then catch them as usual.