If I try to use a variable which doesnt even exist in PHP, I dont get any errors or notices. In the example below the return value is "null". I'd like to see some form of notification if that happens so that I can find bugs in my code more easily.
echo $doesNotExist -> something; //returns null
The error reporting in my php.ini is the following
error_reporting = E_ALL
What do I have to do to see notifications when accessing varibles that don't exist?
To clarifiy this:
I know that I can check if a variable exists by using isset(). That's not what I want though. I want to get a notification in case I accidentaly try to use a variable that does not exists. For example if I misspell the name of a variable.
display_errors = On is in my php.ini
As well as error_reporting, you may need to turn on display_errors, which should be off in production environments.
Production environments can use log_errors instead, which outputs the errors to the file named in the error_log directive.
I generally use thw following;
if(isset($var) && !empty($var)) {
//Do something with $var
} else {
//Define $var
}
As said in a previous answer you also need to turn error reporting on in the php.ini
what you do is perfectly valid in PHP. It just creates and instantiates that variable at runtime, and doesn't throw an error like other languages.
even isset would not work too well. Say you set an object variable with a wrong name. If you do isset on that name, it will be true. If you do isset on the correct name, it will be false.
Example:
class test{
public $name1;
}
$test = new test;
$test->name2 = 'wrong';
var_dump($test);
prints: object(test)#1 (2) { ["name1"]=> NULL ["name2"]=> string(5) "wrong" }
Related
I am trying to encapsulate isset() and empty() in a function.
It worked fine on my home development sever (apache 2.4.3, PHP 5.2.17 under WinXP). When I ported it to my university Linux machine running Fedora, I got a notice about undefined index.
I checked my php.ini on my home computer, and error reporting is set to all. I put error_reporting(E_ALL); in my PHP script to try duplicate the error. It didn't happen.
Question 1: Why am I not getting the notice on my home development computer?
Here is my function:
<?php
function there($s) {
if (! isset($s)) {
return false;
}
if (empty($s)) {
return false;
}
return true;
}
?>
Here I test if a session variable exists:
if (! there($_SESSION['u'])) {
$_SESSION['u'] = new User();
}
I switched my function so that I test empty() before I test isset() thinking this will avoid getting the notice. I haven't had a chance yet to test this at school.
Question 2: Does empty() in general avoid giving a notice if the variable is undefined, or not set?
Question 3: Can I use my there() function to do this, or will I get the notice just by passing the undefined or unset parameter?
isset and empty are not functions, they are language constructs. As such, they can get away with such things as reading the literal variable name instead of trying to access the value. Any function you define can't do that.
With that in mind, there is no need to test for both. empty is a superset of isset, so you only really need to check for empty.
Your function is almost equivalent to !empty:
if (empty($_SESSION['u'])) {
$_SESSION['u'] = new User();
}
The only difference is: your wrapper function will complain if it's passed a variable that doesn't exist - whereas, as a language construct empty will not (and neither will isset).
Your sub-questions
Why am I not getting the notice on my home development computer?
Probably because you've got error reporting turned off.
Does empty() in general avoid giving a notice if the variable is undefined, or not set?
Yes.
Can I use my there() function to do this, or will I get the notice just by passing the undefined or unset parameter?
You will get notices about undefined variables.
As a way of proving #Kolink 's fine reply really, something which I had not realised ...
echo '<form action="" method=POST>
<input type=text value="" name="string" />
<input type=text value=0 name="int" />
<input type=submit />
</form>';
if( empty($_POST['string'] ) ){
var_dump( $_POST['string']) ;
}
if( empty($_POST['int'] ) ){
var_dump( $_POST['int']) ;
}
if( empty($_POST['something'] ) ){
echo 'something was not set, but you cannot var_dump it without a warning';
}
I realize this is an old thread, and it already has an accepted answer. So, I will not answer the questions again here. But for completeness sake and in the hope that it may help others I am sharing something I use.
Take a look at the following code:
<?php
echo var_dump($_SESSION['something']);
This will give you:
PHP Notice: Undefined variable: _SESSION in - on line 2
NULL
But if you do this:
<?php
echo var_dump(mycheck($_SESSION['something']));
function mycheck( &$var ){ // Note the & so we are passing by reference
return $var;
}
You will get:
NULL
This is because internally the $var variable will get created the instant the function is called. But since the $_SESSION['something'] does not exist, the $var is getting set to null which is then returned. Voila, notice gone. But be aware that the variable $_SESSION['something'] has now been created internally, even though isset($_SESSION['something']) will still return false because isset determines 'if a variable is set and is not NULL'.
PHP manual for isset: http://php.net/manual/en/function.isset.php
I know it's not a good practice to hide the warnings using #copy, but what other alternatives are there?
Is there any way you can make sure copy would work or not ?
Use is_readable() and is_writable() to check the status of the source and target before attempting the copy().
Really, you should not be displaying errors to the browser. Turn off display_errors in php.ini.
Then you can test if it succeeded by its boolean return value, without needing to worry about the warnings on screen.
if (!copy('srcfile', 'destfile')) {
// something failed.
}
If you use '#' before a function you'll not the warning or the notice returned but you'll keep the result (boolean, string...).
Try this :
if (!#copy('srcfile', 'destfile')) {
// something failed.
}
I'm using wamp to develop a php application. My problem is that everytime I call a variable that sometimes happens to not have a value, I get an error that says it's an undefined index. Is there a way to change the error reporting to not display this error? I have to use isset to determine if it's set or not before I output the variable, but I don't want to have to do this. There are areas of my application that make this method inefficient.
If you don't want to change error_reporting level you should check, is variable exists, before using it. You may use
if(isset($var))
for it. You may add some function, to not write it always. Example:
function getPost($name,$default=null){
return isset($_POST[$name])?$_POST[$name]:$default;
}
Usage:
getPost('id');
getPost('name','Not Logged In');
You can just turn off the mechanism in php.ini.
This thread would help you.
http://www.wampserver.com/phorum/read.php?2,70609,70700
But it generally its better to take care of undefined variables as they might save you some run time trouble.
Update:
In php.ini change
error_reporting = E_ALL to error_reporting = E_ALL & ~E_NOTICE
There are multiple ways to get around this:
error_reporting(0) Use this at the top of your script
set display_errors = Off in php.ini
Use '#' before the statement that generates an error
But unless you are writing something trivial you absolutely must use array_key_exists or if(!empty($arrayName['key'])) for everything sent by the user.
Try this:
if(!isset($var)) $var="";
PHP.ini files reside in both :
bin\php\php5.x
and
bin\apache\apache2.x\bin
be sure to make the changes in the apache folder version.
Also setting :
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On
leaves errors from being displayed on the client, but still allows them to be logged in the error log.
I'm already set its debugging option to true,but when there's error in smarty template(i.e. there is no corresponding plugin for a specific smarty_modifier),nothing is output for information.
UPDATE
For anyone that wants to have a try,this is the most simple template I can think of :
{$var|nosuch_modifier}
1- First, you can check if error_reporting is on. this is usually done in php.ini but you can place these statements on top of your php source.
ini_set('display_errors', 1);
ini_set('error_reporting', E_ALL);
and make sure it is not disabled elsewhere.
2- smarty may report errors as throwing an exception. You can define a global exception handler to catch them, here is an example;
try {
// place your code here
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
Update upon comments:
The only reason I can think of is that you've set compile_check to false.
$tpl->compile_check = false;
In this case, Smarty will show the latest compiled source, whatever you do to the tpl file. So, did you check and set compile_check to true?
$tpl->compile_check = true;
Try
ini_set('display_errors', true);
error_reporting(E_ALL);
in the PHP code.
Smarty error reporting can be set manually.
$smarty->error_reporting = E_ALL ^ E_NOTICE;
Some comments from the Smarty.class.php
error muting is done because some people implemented custom
error_handlers using http://php.net/set_error_handler and for some
reason did not understand the following paragraph:
It is important to remember that the standard PHP error handler is
completely bypassed for the error types specified by error_types
unless the callback function returns FALSE. error_reporting() settings
will have no effect and your error handler will be called regardless -
however you are still able to read the current value of
error_reporting and act appropriately. Of particular note is that this
value will be 0 if the statement that caused the error was prepended
by the # error-control operator.
Smarty deliberately uses #filemtime() over file_exists() and
filemtime() in some places. Reasons include
- #filemtime() is almost twice as fast as using an additional file_exists()
- between file_exists() and filemtime() a possible race condition is opened, which does not exist using the simple #filemtime() approach.
I made a function like this (no need to write the whole function here) :
public function selectNode($from, $attributes = null, $childs = null)
and, of course, if I call it this way :
$node->selectNode();
The argument $from isn't initialized and then you got a warning error.
I know you can suppress the error doing #$node->selectNode(); or something like that thanks to #.
But, I want to handle it myself. How can I do that if that's possible?
The only way I found is to initialize it like this public function selectNode($from = null, $attributes = null, $childs = null) but that doesn't make it clear ($from is not an option as the others).
(And, of course, this function, here, is just an example. It could be extended to other functions)
How come you can miss a required parameter? It is not a file or an outside variable! You will get this error just by trying to call this script. It is like parse error. What to handle here?
It's development phase error. It just needs to be corrected, not handled.
Anyway, you are doing it wrong.
Never add intentional errors to your code.
Language's error reporting mechanism is for handling unexpected errors, not intentional ones.
If you expect an error here - handle it yourself. Don't make PHP to raise error
So, make it $from = null,, yes. And then handle this null whatever you want.
Surely if the $from parameter is not required you should assign it a default variable so it's optional and then do checking based on this.
It would probably be most elegant to just check if $from isset in the code before you reference it and supply it with null as default in the parameters, isset will return false from a null value.
I guess you've got display_errors set to on in php.ini and now these warnings are popping up on your screen and you don't want to see them popping up anymore? If that's the case, then change your php.ini :
display_errors = Off
log_errors = On
error_log = /path/to/php-error.log
Errors will then be logged to the file you specified in error_log, and won't show up on your screen anymore.
You could use a try-catch block handling the error yourself.
try {
$node->selectNode();
}
catch (Exception $e){
echo $e; // do whatever you like here with error info $e, if you leave the parenthesis empty here nothing is done and the error message is suppressed
}
Are you looking for the following (or one of its variants)?
<?php error_reporting(0); ?>