What is included in each error level in PHP - php

I'm basically wondering what is included in each error level, as found here in PHP. Example, where does an unset variable or key fall? Or where does a parse fall? I can't seem to find any documentation on the PHP website or general internet regarding this.
Edit: I'm looking for a list of what error causes what error level/type or the other way around.

For each specific case, the manual says what type of error would be thrown. For example, if you look in the variables section, you will see that an unset variable will throw an E_NOTICE error. The same follows for other language constructs, function definitions, extensions and so forth. Simply check the manual.

Related

Cakephp throws an error unless array is devided

So i have an Api call where i get a json array:
When i do the following:
$data = $this->HasOffers->get_full_detail_report()['data']['data'];
$this->set('data',$data);
i get an error saying an internal error has occoured
However if i do:
$data = $this->HasOffers->get_full_detail_report();
$data2 = $data['data']['data'];
$this->set('data',$data2);
everything is working correctly.
Now my question is why is this happening? and how can i fix it?
The syntax you are using in the first example is only available in PHP >= 5.4. See relevant section of PHP manual: http://php.net/manual/en/language.types.array.php#example-88
You can see an example running in different versions of PHP at: http://3v4l.org/XhCKH
Your CakePHP site likely has error reporting turned off so, rather than displaying the syntax error, it is displaying an Internal Error.
I'm guessing you have debug < 2, so the description of the error is not very detailed. However, that behaviour is known to be a PHP < 5.4 issue (post regarding that subject).
To "fix" it, you need to upgrade PHP to 5.4 at least. Or, just use an intermediary variable for those cases, it's not that bad.
This is happening because the array you are referencing in the first example only exists after the function get_full_detail_report() is called. PHP does not like this. PHP wants your array to exists before you reference it. I assume that it attempts to locate any variables within your statement before performing any operations, which would mean it is searching for an array that does not exist until it performs those operations.
If anyone has any more insight into this, I would welcome their revisions / comments.

PHP Error constant for error_get_last function

Is there a constant or env. variable that stores the last error created? The one that is returned via error_get_last?
I don't mean to be sarcastic (well, yes, but only a little), but you do know the PHP manual has a "See also" section, right? Looking at the page for error_get_last(), I found this little gem: The $php_errormsg variable
Of course, that variable has some limitation (i.e. only works in the scope that the error occurred in, and only if track_errors is on).
But actually, why do you want to use a variable. The point of error_get_last() is to give you the last error, so why not use that?

What does #include("filename") mean? What's the difference between that and include "filename"? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Reference - What does this symbol mean in PHP?
I'm making a web application that uses URL queries to access different parts of the application. I was looking for a solution to make an invalid query like index.php?page=dashboarrrd display an error 404 message instead of a PHP error.
After some searching, I found that I could use something like the following to do the job:
if(!#include($fileName)){
#include("pageData/404.php");
}
And that makes sense, but I don't know why that works. I mean, what the heck does the # before the include mean? I totally understand include $filename; but I need an explanation for #include ($fileName)
the code you really need is
$fileName = "pagedata/".basename($_GET['page']).".php";
if(is_readable($fileName)) {
include($fileName);
} else {
include("pagedata/404.php");
}
and # has absolutely nothing to do here
# is one of biggest delusions coming from lack of experience.
Ones who using it do expect only one kind of error, while in fact there can be many more. And to gag ALL possible messages to suppress only one of them is definitely like to throw out the child along with the bath.
There is a fundamental problem that makes such misunderstanding so widespread:
Most PHP users cannot distinguish three sides of error control:
error handling
error reporting
user notification.
Most of time in sake of [3] people mess with (1) and (2). While each of them require separate treatment:
your program should raise no intentional errors. No error should be part of program logic. All errors that ever raised should be only unexpected ones.
if you expect some error, you have to handle it. Not gag with #, but gracefully handle. is_readable() in my code exactly for that.
error reporting is for the programmer and should be always at max. So, error logging should be enabled on a live site and a programmer have to check all errors occurred. And of course he would be interested in such errors, thus # will do only harm here.
User-level error messages should be different from system ones. Your 404.php is a good example of such user-friendly behavior. As for the system error messages, a user shouldn't be able to see them at all. Just turn display_errors off and see - there is no use for the # again!
This is the # Error Control Operator (quoting) :
When prepended to an expression in
PHP, any error messages that might be
generated by that expression will be
ignored.
In normal conditions, if include cannot load the file you've passed as a parameter, it'll emit a warning.
Prepending the # operator to include will prevent that warning from being emited -- and, so, from being displayed / logged.
So, the following portion of code :
include 'does-not-exist.php';
Will get you the following warnings :
Warning: include(does-not-exist.php) [function.include]: failed to open stream: No such file or directory
Warning: include() [function.include]: Failed opening 'does-not-exist.php' for inclusion
While this line :
#include 'does-not-exist.php';
Will get you not warning.
And, as a sidenote, for information : Five reasons why the shut-op operator (#) should be avoided
The # suppresses errors. This is generally discouraged, as when developing you want to see errors.
Errors are easy to suppress when moving to a production environment with the display_errors setting to off. So yea, in most cases, there really is no need for the error to be suppressed.
EDIT
As an extra tidbit to "improve" that, what I used to do when dynamically including a file, is have an array which acts as a "white list" of valid requests. This does not "have" to be an array, just what I chose to do an example with.
$whiteList = array('filename1', 'index', 'home', 'about');
if (in_array($filename, $whiteList)) {
include($filename);
}else {
include('page/404.php');
}
This would do a few things, 1 make you not need the error suppressor. Two, it would make it a bit more securer, as without this, you would need to do a basename call to filter the text to prevent certain type of include injections etc. (Not knowing if you did this already, just extra information).
So yea, you may want analyze / look at other ways to achieve this and above is just one method :)
The use of "#" simply suppresses the error that would normally result from (in this instance) a missing file. Whilst generally its use is a very bad idea, there are some rare exceptions, such as the code snippet you provide above.
For more information, see the Error Control Operators section of the PHP manual.
Additionally, you might find the existing Reference - What does this symbol mean in PHP? question worthy of a quick scan.
The # in php suppresses all error output. For instance, if you had error reporting for warnings, an # in front of a function that generated a warning would not display the warning text.
include is an example of such a construct. If the included file is not found, it will display a warning saying so. The # is not necessary in the code at all, it is just there so that the user will not see warnings.
However, it is better to use apache (or php if you prefer) to change ini for displaying errors on the development site and not displaying them on the production site. That would make the # symbol useless.
A better question is why you need to do this 404 include. Why are you including a file for display? Why not have apache handle 404 redirects on its own? Why wouldn't the file exist in the first place?
# suppresses error messages. The parentheses are optional in include, but whoever wrote that snippet included them.
#include() is the opposite of require(). The first will silently ignore an (optional and missing) include script, while the second will throw an error and halt the script when the (critical) dependency is missing.
In this instance it is only senseful within the if(). The second should preferrably not have an error suppression, as it doesn't mask any seriously security-relevant error message.

Any way to make PHP abort on unset/undefined variables and array indexes and such?

Currently, PHP would trigger (and log if logging is enabled) E_NOTICE 'errors' when accessing undefined variables and array indexes. Is there a way to make it abort on these, so that I know I don't miss any. Frankly, IMO, far too often a script SHOULD abort on such condition anyway, as it will inevitably break something farther down the execution path. In all other cases there is the '#' operator, that's what it is for, right?
I know I can use a custom error handler and abort on any condition. In fact I do use one already, but I do have places where I trigger notices myself (granted, E_USER_NOTICE instead of PHP's own E_NOTICE), and I also always return false letting PHP's own internal handler do its job - logging and aborting on errors, continuing on everything else.
Then there are other cases where PHP produces E_NOTICE without me wanting to abort the script. Basically, there is no way for me to know if a particular E_NOTICE is a result of an unset variable or a totally harmless condition (which notices should be caused by anyway).
Has anyone a neat and non-hackish solution? Some recommended way of doing this?
Cheers.
I'm sure there is no native PHP way to do this.
Extending your already existent error handler to look into the error message (stristr($errmsg, "undefined variable") ...) and die() if necessary is the best (and only) way that comes to mind.
You can user PHP function set_error_handler() to register a custom function that will handles any PHP error. Specify E_NOTICE as the second parameter so that your custom function will only receive E_NOTICE error. Then in that function, simply do 'exit;' if the second parameter which is the error message starts with 'Undefined offset:'.
Rather than try to hack around PHP's error handling, I suggest you enforce some constraints on your script and check your variables with PHP's isset, empty and is_null functions.
I'm not sure what you want. You want to abort on notices, but not every notice? You want to distinguish between the several types of E_NOTICES and abort on some? The only way to do this is to check the message in the error handler and not abort if the message is about undefined variables – which you shouldn't use, by the way.

PHP equivalent of Perl's 'use strict' (to require variables to be initialzied before use)

Python's convention is that variables are created by first assignment, and trying to read their value before one has been assigned raises an exception. PHP by contrast implicitly creates a variable when it is read, with a null value. This means it is easy to do this in PHP:
function mymodule_important_calculation() {
$result = /* ... long and complex calculation ... */;
return $resukt;
}
This function always returns null, and if null is a valid value for the functuion then the bug might go undetected for some time. The Python equivalent would complain that the variable resukt is being used before it is assigned.
So... is there a way to configure PHP to be stricter with variable assignments?
PHP doesn't do much forward checking of things at parse time.
The best you can do is crank up the warning level to report your mistakes, but by the time you get an E_NOTICE, its too late, and its not possible to force E_NOTICES to occur in advance yet.
A lot of people are toting the "error_reporting E_STRICT" flag, but its still retroactive warning, and won't protect you from bad code mistakes like you posted.
This gem turned up on the php-dev mailing-list this week and I think its just the tool you want. Its more a lint-checker, but it adds scope to the current lint checking PHP does.
PHP-Initialized Google Project
There's the hope that with a bit of attention we can get this behaviour implemented in PHP itself. So put your 2-cents on the PHP mailing list / bug system / feature requests and see if we can encourage its integration.
There is no way to make it fail as far as I know, but with E_NOTICE in error_reporting settings you can make it throw a warning (well, a notice :-) But still a string you can search for ).
Check out error reporting, http://php.net/manual/en/function.error-reporting.php
What you want is probably E_STRICT. Just bare in mind that PHP has no namespaces, and error reporting becomes global. Kind of sucks to be you if you use a 3rd party library from developers that did not have error reporting switched on.
I'm pretty sure that it generates an error if the variable wasn't previously declared. If your installation isn't showing such errors, check the error_reporting() level in your php.ini file.
You can try to play with the error reporting level as indicated here: http://us3.php.net/error_reporting but I'm not sure it mention the usage of non initiated variable, even with E_STRICT.
There is something similar : in PHP you can change the error reporting level. It's a best practice to set it to maximum in a dev environnement. To do so :
Add in your PHP.ini:
error_reporting = E_ALL
Or you can just add this at the top of the file your are working on :
error_reporting(E_ALL);
This won't prevent your code from running but the lack of variable assignments will display a very clear error message in your browser.
If you use the "Analyze Code" on files, or your project in Zend Studio it will warn you about any uninitialized variables (this actually helped find a ton of misspelled variables lurking in seldom used portions of the code just waiting to cause very difficult to detect errors). Perhaps someone could add that functionality in the PHP lint function (php -l), which currently only checks for syntax errors.

Categories