Strange behavior of isset - php

isset() in php 5.3 seems to be behaving unexpectedly. I have a class called DB details that encapsulates a bunch of string properties with getters and setters.
$dbdetails->getDatabasename() evaluates to a string ("mydb")
This throws a 500 error:
if(!isset($dbdetails->getDatabasename())){
//do something
}
This works fine
$databasename = $dbdetails->getDatabasename();
if(!isset($databasename)){
//do something
}
I wasn't able to see any log output because apache sent back a 500 even though the error ini param is set (sic) to On. I know this is something to do with the isset call for sure.
Any idea what could be wrong, or did I find a PHP bug?

The isset function checks whether a variable is set. Checking against $databasename is valid, because it is a variable that can be set or not. Checking against a function is invalid, because it simply isn't a variable.
You probably want to use is_null( $value ) when checking the immediate result of a function.
An example from the comments on the the is_null documentation:
<?php
function test( ) { return null; }
var_dump( is_null( test( ) ) ); // displays "true"
var_dump( isset( test( ) ) ); // parse error, because "test()" is not a variable
?>
PHP: is_null
PHP: isset

That's how isset() works. Same as empty(). They can only work with a variable, not an expression. From the documentation:
isset() only works with variables as passing anything else will result in a parse error. For checking if constants are set use the defined() function.
Therefore, isset(function_call()) is invalid syntax.

Related

Why can't I assign a variable inside of isset? - php

Recently, I've attempted to be tricky and assign a variable inside of an isset function. I tried to do it like so
if(isset($accountid =$_POST['Recipient']))
{
// my code here ...
}
However, when I do this I receive the error
syntax error, unexpected '=', expecting ',' or ')'
Here is the documentation for isset if you want to reference it in your answer.
bool isset ( mixed $var [, mixed $... ] )
This isn't the hugest deal - but I'd be interested to know why I can't do something along those lines!
isset is a language construct and not a true function. It is mentioned in the docs:
Warning
isset() only works with variables as passing anything else will result
in a parse error. For checking if constants are set use the defined()
function.
You are trying to pass a statement, this might be the reason. Here is a note I found in php.net manual for isset().
http://php.net/manual/en/function.isset.php
isset() only works with variables as passing anything else will result in a parse error.
You're putting an operation that doesn't return a pointer to a variable in a function that expects one.

Correct way to use !is_null()

There is an example in PHP Object-Oriented Solutions that seems to be flawed, if I understand is_null properly.
The sample code in the book is as follows:
if (!is_null($required) && !is_array($required)) {
throw new Exception('The names of required fields must be an array, even if only one field is required.');
}
This code is supposed to test that a var $required is not NULL and is an array. To my understanding, is_null() returns TRUE if the variable is not set or is NULL. So, does it make sense to negate is_null() in that example if you're trying to throw an exception when the variable is not set, NULL, or is not an array? The only way an exception is thrown is if (true && true) is satisfied.
FROM: http://www.php.net/manual/en/language.types.null.php
A variable is considered to be null if:
it has been assigned the constant NULL.
it has not been set to any value yet.
it has been unset().
<?php
if(is_null($obj)){
echo 'is null';
}
While $obj is considered NULL because it hasn't been registered yet, it will still throw a Notice: undefined ...
The correct use for your if statement should first check to see if the variable exists then check to see if it is an array.
if (!isset($required) || !is_array($required)) {}
-or-
if (empty($required) || !is_array($required)) {}
The nice thing about is_array() is the fact that if $required IS NULL then it's not an array and will pass the if clause.
isset() and empty() will both ensure that the variable exists. Failure to pass either of these methods will quit the if statement and no errors will be returned.
I appreciate all the feedback, but somehow I think part of my question was not addressed. The fact that the variable is being tested with a Logical AND, means that both statements must be TRUE for the Exception in the if clause to run.
But, I don't think the use of !is_null($required) is correct. The sample code from the book was testing for a variable to contain an array with one to many values. Even if it has one value, the $required variable (for other reasons) still must be declared as an array with a single value. So, if $required hold's a value of (int) 5, an Exception should be thrown. If the $required variable is not declared/instantiated, an Exception should be thrown. If the $required variable holds NULL, an Exception should be thrown. Here is where the logic of this sample code fails. Using the online php command line that #Calimero posted, this logic fails when $required is set to NULL.
Instead of using !is_null($required) , is_null($required) without the negation should have been used since is_null returns TRUE if the value of $required is indeed NULL. So, if you negate is_null() when the $required value happens to be NULL, that part of the logical AND operation becomes FALSE, therefore the Exception never gets run at all because the logical AND operation requires both statements to be TRUE for the logic to jump into the curly braces. Which is precisely what the if clause was supposed to catch in the first place. The sample code was supposed to catch the $required variable not being set and not being of an array type.
And as I mentioned in a comment, isset() probably wasn't used because isset will return TRUE even if the $required variable is an empty string, a string with a space, an empty array, etc.
Someone please confirm I'm not talking stupid. LOL.
Take a look at this: (http://3v4l.org/QpVXq)
**Is_null**
The is_null is php construct language and can be used to test whether a variable is set to null.
$myVariable = null;
is_null($myVariable); // this returns true,because it is set to null
$myVariable = 10;
is_null($myVariable); // this returns false, cuz it is assigned to value
If the variable does not exist is_null will also return true,
but with an error notice as it is not supposed
to be used with uninitialized variables.
//returns true and also notice with (undefined variable notice)
is_null($myNewVariable);// true (undefined variable notice)
If the code is part of a function, it could be that the function allows for null values, but if the value is passed and it's not an array, then an exception must be thrown. If the code is not part of a function, it may be just demonstrating how to detect if a value is an array only if it isn't null, thus allowing null values.

Are isset() and !== null equivalent?

Since isset appears to be a function (http://php.net/manual/en/function.isset.php), there might be some overhead for calling it. So I wonder if using !== null instead of isset would produce faster code while, most importantly, keeping the code's behavior exactly the same?
From PHP Manual:
isset — Determine if a variable is set and is not NULL
isset Returns TRUE if var exists and has value other than NULL, FALSE otherwise.
http://php.net/manual/en/function.isset.php
The function call overhead is so small you probably don't need to worry about it.
Read this post: Why are PHP function calls *so* expensive?
Note that isset is not a function (it has a special opcode for it), so it's faster.
What about $foo = NULL, a variable can be set, and also be null
isset is not a function, It is a Language construct in PHP, It is much faster.
isset determines if a variable is set and is not NULL.
as above isset is to check if a variable is set and is not NULL. To make sure I usually use it as
if( isset( $var ) === TRUE )
{
// Do what you want
}
This doesn't throw any unnecessary notices in PHP

isset or !empty for $_GET[var]

i recently had to do a "test" for a job, and i got feed back saying that this statement was incorrect:
$images = $flickr->get_images(5, !empty($_GET['pg']) ? $_GET['pg'] : 1);
The "supposed" error was generated via the ternary operator on the first time the page was loaded, as there was no "?pg=1" (or whatever) passed via the query string.
The feed back said i should have used isset instead. I have looked at various posts both here (question 1960509) and blogs, but cannot find any definitive answer.
Is this really an error? How can i replicate this issue? do i need to put on E_STRICT or something in my php.ini file? Or might this be due to an older version of php?
Note: please don't tell me about how i should validate things.. i know this... it was a test to just see if i could use the flickr api calls.
This is perfectly fine. empty is not an actual function, it's a language construct. It does not issue a warning if a variable is not set (in that case the variable is considered empty, thus the 'function' returns TRUE just as you want), and additionally it checks for empty or zero values.
You could see empty as a normal isset check with an additional loose comparison to FALSE:
empty($var) === (!isset($var) || $var == FALSE)
$images = $flickr->get_images(5, (isset($_GET['pg']&&($_GET['pg']))) ? $_GET['pg'] : 1);
without isset you'll get error so combine them
I'd use
$images = $flickr->get_images(5, array_key_exists('pg', $_GET) ? $_GET['pg'] : 1);
Combine with !empty($_GET['pg']) if needed (i.e. array_key_exists('pg', $_GET) && !empty($_GET['pg'])), but array_key_exists is the intended function for this job.
I think in a situation like this isset is the correct function to use as it is checking the existence of the array element rather than checking if the value of the element has been set. As Martin notes, the best thing to do here is combine them as this will only check the value if the element exists, meaning that the error will not occur on the first page load.
Also, I think this will only give a warning if E_NOTICE is on (or perhaps E_WARNING as well)
The reason you would get an error is because the empty function is designed to check the value of an existing variable, whearas isset() is designed to tell you whether a variable has been instantiated, however because empty() is a language construct technically it doesn't throw an error or create a warning so most people don't see the difference.
From the docs:
empty() is the opposite of (boolean) var, except that no warning is generated when the variable is not set.
isset — Determine if a variable is set and is not NULL. So "isset" is the correct function to use for checking for value is set or not.
More details :http://php.net/manual/en/function.isset.php

PHP isset($_SESSION[$var]) Not working at all

In my project, I have a wrapper class for $_SESSION, so session variables can be accessed by $session->var. I was trying to check if session variables were set or not using isset:
if (!isset($this->session->idUser)) {
...
}
but isset is not returning anything. So in my wrapper class I wrote the following function to test what was going on.
public function isItSet($var)
{
die(isset($_SESSION["id"]));
}
this results in an empty page. I tried:
public function isItSet($var)
{
die(is_null(isset($_SESSION["id"])));
}
still an empty page. Then I tried:
public function isItSet($var)
{
die(isset($_SESSION));
}
This returns 1.
Can anyone tell me why trying to check if a session variable is set returns nothing?
To support isset() you need to overload the function in your wrapper.
So, in your wrapper, add:
public function __isset($var){
return isset($_SESSION[$var]);
}
To use it, you just have to do:
isset($this->session->myVar);
If it is still not working, do:
var_dump($_SESSION)
This will dump the whole $_SESSION array and show you whether the variable you are checking for actually exists.
In my opinion, issue is related to testing and not with PHP session.
The MAIN REASON behind why session variable isset returns nothing is use of
die()
function which is equivalent to exit() according to PHP manual itself.
http://in1.php.net/die
So, use var_dump() instead.
isset returns an empty page because your variable does not exist in session, so isset return false, however, echo false return ''.
It was already written in the commentary to hakre
You can test this like that:
echo "false : " . false . "\n";
echo "true : " . true . "\n";
=>
false :
true : 1
So, for your test, do a var_dump($_SESSION) and you will see if it is normal that isset($_SESSION['id']) returns false.
You can also test: die("false : " . (false == isset($_SESSION['id'])));
Your results are basically correct.
The boolean values being pass to each function just confused you i think.
Heres a clear explainations what happens to each of your statement.
LETS GET IT ONE BY ONE
// declaring this array as a set of session being passed as sample.
$string = array('name'=>'kaii');
echo die(isset($string['id'])); // figure 1
// step
// isset($string) returns a value of false because of unexistent of an array with the name of id.
// die(false) returns nothing because of the value being passed by isset is false.
// result would be definitely empty
echo die(is_null(isset($string['id']))); // figure 2
// step
// isset($string) returns a value of false because of unexistent of an array with the name of id.
// is_null(false) returns a value of false because it only accepts NULL as its parameter value to return true.
// die(false) returns nothing because of the value being passed by is_null is false.
// result would be definitely empty
echo die(isset($string)); //figure 3
// step
// isset($string) returns a value of true because of a $string variable is set and exist.
// die(true) returns a value of 1 because of the value being passed is true which is equivalent to 1 .
// result would be definitely return a value of 1.
note: In general your statement is correct just a few justification is needed to support it.
Additional:
print_r(),var_dump()
use it to check your session if it has a name that youre trying to
declared.
A brief explanation:
isset()
returns a boolean value of true or false
is_null()
accepts only a NULL parameter value to return a boolean value of
true else it goes false.
die()
returns a value of 1 for true and empty value for false.
Reasons:
A boolean TRUE value is converted to the string "1". Boolean
FALSE is converted to ""
The isset function: Returns TRUE if var exists and has value other than NULL, FALSE otherwise.
if the session variable is set gives TRUE if the session variable unset it gives FALSE.
Example:
$_SESSION['views']=1; session variable is setted. => gives TRUE
unset($_SESSION['views']); session variable is not setted.
=> after this if(isset($_SESSION[$var])) it gives FALSE
There are two options: the session variable is setted or not.
isset() only works with variables as passing anything else will result in a parse error. For checking if constants are set use the defined() function.
For More Information about isset click here
A couple of things you could try:
Add this to your codebase: http://philsturgeon.co.uk/blog/2010/09/power-dump-php-applications. It's much better than var_dump and you can clearly see true or false for boolean values. It's saved me much grief.
Second, die() doesn't always give me what I expected, so it's better to echo something and then die() right after.
As #doydoy44 mentioned, false outputs a blank, so you might be getting a blank page for good reason. Again, the link above will solve this problem and make things clearer.
Your original code above has idUser as the variable being checked, all your other examples use id. I assume you know that, but I thought I'd mention it just in case.
Finally, I'd cross-check that the session wrapper was working as I'd expected, e.g.
if (!isset($this->session->idUser)) {
dump($_SESSION);
dump($this->session);
}
I'd obviously expect to get the same content back from both of them.
Hope that helps somewhat.
By the looks of it, it seems that there is no "ID" key on the session array.
This was verified on your comment to F21's answer ("undefined index error").
What you can do is define/initialize an "ID" key on the session array with value as null or empty string "" after your session has started. Then populate it with your value later on with your codes.
This is to make sure that when you use isset($_SESSION["ID"], the result can either be true or false rather than an undefined index error.
Session variables are a bit magic. Less magic than historically, but still it's unsurprising that unusual things are observed.
It would make sense to run the tests in the question in three states: once with the session variable set, and twice without the session variable set - once with a different session variable set and once with no session variables set.
Adapting F21's answer, to support isset() you need to overload the function in your wrapper. Whilst doing that you may as well create an isset that functions as you expect.
Something along the lines of the following will solve both the 'false is invisible' and an issue with removing session values.
public function __isset($var){
if (isset($_SESSION[$var]) && $_SESSION[$var]."">"") {
return true;
} else {
return false;
}
}

Categories