empty() and alisasing - PHP - php

[Big edit, the question is better in this way]
I would like to find a shortcut (without NOTICE) for this code :
if( !empty( $long_var['with']['useless']['long']['argument'] ) )
$long_var['with']['useless']['long']['argument'] =
Custom::myParsing($long_var['with']['useless']['long']['argument']);
As you can see I've got a long var to process, and I don't want to bring it around... (as it's not an isolate case in my code, I want something "clean")
For now I use this :
if( !empty( $long_var['with']['useless']['long']['argument'] ) ){
$lnArgument = &$long_var['with']['useless']['long']['argument'];
$lnArgument = Custom::myParsing($lnArgument);
}
This could be the best, but it bring back a Error before php5.5 and a Notice after :
if( !empty( $lnArgument = &$long_var['with']['useless']['long']['argument'] ) )
$lnArgument = Custom::myParsing($lnArgument);

What is the use of checking empty in an assignation, even with PHP 5.5? You are assigning something (maybe a NULL, because the expression does not exist and you also got a NOTICE: undefined index) to a variable. You are defining that variable and then checking for empty? Do you know what 'empty' means when checking a variable? First checks if the variable exists and then checks whether that variable equals FALSE. In your case, the variable will always exist (you created it just there). So, you are actually only checking if that variable equals FALSE.
tl;dr:
You can safely replace the empty with a simple assignation, and let the if find if what was assigned equals FALSE or not:
if( $lnArgument = &$long_var['with']['useless']['long']['argument'] )
$lnArgument = Custom::myParsing($lnArgument);
(and you will get Notices, but you already know that)

Related

Why is not possible to decode and unserialize in the same line? (like this example)

Why this is not possible?
$b64_encoded = base64_encode(serialize(array('test')));
if( $b64_decoded = base64_decode($b64_encoded) && $unserialized = unserialize($b64_decoded) )
{
var_dump($unserialized);
}
You can.
What's happened is that PHP sees $b64_decoded as an undefined and unset variable because you've got it tied up in your if statement without correctly parting it.
See this:
if( $b64_decoded = base64_decode($b64_encoded) && $unserialized = unserialize($b64_decoded) )
PHP believes the && has a higher priority over =. Your code effectivly is;
$b64_decoded = (base64_decode($b64_encoded) && $unserialized) = unserialize($b64_decoded)
Which doesn't seem to make any logical sense.
So, we have to tell PHP the priority of the operations and what items are grouped together. We can do this by wrapping our statement with ( )
Such as this:
if( ($b64_decoded = base64_decode($b64_encoded)) && $unserialized = unserialize($b64_decoded) )
^ ^
PHP now understands the priority of the statement as you have specified.

E_NOTICE : type 8 -- Undefined variable

I'm pretty new with PHP and I'm trying to learn all by myself.
I tried to create a simple form with a simple calc to incorporate on my website but I got this E_Notice. And don't know how to echo the result in the html too.
Someone can help?
Link here: PHPfiddle
Your code checks to see if $_POST['valor-finan'] is set -- if it is, it sets the variable $valor_finan. If it IS NOT set, then the variable $valor_finan is never created. Then, your code checks to see if it is empty -- it isn't empty, it doesn't even exist.
Instead, you should set the variable to something no matter what, that way it exists in the code. If you get some $_POST data, use that data, otherwise provide a default value like false.
empty is not the best function to check numeric values. Use is_numeric -- a 0 might be acceptable for your application, but empty will consider 0 to be... empty. Not good for financial calculations.
Also, you are using globals where you don't need to. The global keyword is always bad practice. The switch was unnecessary, too.
Here is your code with the corrections in place:
$valor_finan = (
isset($_POST['valor-finan']) ?
$_POST['valor-finan'] : false
);
$valor_entrada = (
isset($_POST['valor-entrada']) ?
$_POST['valor-entrada'] : false
);
$numero_parcela = (
isset($_POST['numero-parcela']) ?
$_POST['numero-parcela'] : false
);
function calculaFinanciamento ($valor_finan, $valor_entrada, $numero_parcela) {
if(
is_numeric($valor_finan) &&
is_numeric($valor_entrada) &&
is_numeric($numero_parcela)
){
$taxa_percent = 5;
$valor_parcela_bruto = ($valor_finan - $valor_entrada) / $numero_parcela;
$valor_percent = ($taxa_percent / 100) * $valor_parcela_bruto;
$valor_parcela = $valor_parcela_bruto + $valor_percent;
return $valor_parcela;
} else {
return "Por favor preencha os campos, todos são requeridos";
}
}
echo calculaFinanciamento($valor_finan, $valor_entrada, $numero_parcela);
Your variables valor_finan , valor_entrada, numero_parcela have not been set.
Use isset($valor_finan) etc to check if they contain records/have been set or not.

PHP test for empty and/or null and/or unset array

I want to keep this short. I don't know if I have the terminology correct, but I got this example from the Codeigniter handbook Vol.1.
if (count($args) > 1 || is_array($args[0]))
I've run into this problem numerous times. Depending on the datatype different tests are more appropriate. Some tests will just fail in unexpected ways.
How does one determine the most appropriate, and possibly, the most concise test?
Just to be clear I'm looking for the most effective way to test if an object/variable is ready to use, regardless of the datatype, if that's possible.
Also I don't want the solution to apply merely to lists like in the example. It should be widely applicable.
Just use empty
if(!empty($args)){
echo 'Array is set, not empty and not null';
}
use empty() bool empty ( mixed $var )
http://www.php.net/manual/en/function.empty.php
Determine whether a variable is considered to be empty. A variable is considered empty if it does not exist or if its value equals FALSE. empty() does not generate a warning if the variable does not exist.
I've been using the following function for a while.
You can add your own test for all possible variable types.
function is_valid_var($var)
{
if ( isset( $var ) ) {
// string
if ( is_string( $var ) && strlen( $var ) == 0 ) return false;
// array
elseif ( is_array( $var ) && count( $var ) == 0 ) return false;
// unknown
else return true;
}
return false;
}

What is the best way to know is $_GET['example']=="somevalue"?

if((isset($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
OR
if((!empty($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
OR just
if($_GET['example']=='somevalue'){ ... }
I am asking that why I have seen many example where people check first if $_GET['example'] is set and then if $_GET['example']=='somevalue' ( first and second example above ).
I don't understand why not just use the last solution ( if $_GET['example']=='somevalue' then $_GET['example'] is obviously set ).
This question refers to any other variable ( $_POST, $_SERVER, ecc ).
if((isset($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
Is the right one, you want to know that the "variable" exists (or is set) in order to use it. Empty just checks wether it has data of any kind or not.
For example:
<?php
$foo= 0;
if (empty($foo)) { // True because $foo is empty
echo '$foo is either 0, empty, or not set at all';
}
if (isset($foo)) { // True because $foo is set
echo '$foo is set even though it is empty';
}
if (isset($var)) { // FALSE because $var was not declared before
...
}
?>
The differences between isset and empty are subtle but important. They are most relevant when used alone. If you are checking that a variable exists and is a truethy value (e.g. any string that is not all spaces or 0s) you can use either interchangeably.
When to use isset
Use isset when it's important to know if the variable has been defined and is not null:
if (isset($maybeExistsMaybeNull)) {
// variable defined and is not NULL
}
When to use !empty
Use !empty when it's important to know if the variable has be defined and is truthy
if (!empty($mightBeEmpty)) {
// variable defined, and isn't "", " ", 0, "0" etc.
}
!empty is a great shorthand for exists and is something.
When to use array_key_exists
Use array_key_exists when it's important to know if the key exists and the value is of no importance:
if (array_key_exists('something', $array)) {
// $array['something'] exists, could be literally anything including null
}
When not to use isset
If your code looks like this:
if (isset($something) && $something) {
// code is shorter with !empty
}
When not to use !empty
If your code looks like this:
if (!empty($something) && $something === "") {
// you meant isset. this is unreachable.
}
Then you're writing code that can't be executed
Code that throws errors is error prone
Avoid writing code that issues notices/warnings that you are ignoring. For example in the question:
if((isset($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
The first use of example is an undeclared constant. Or is it undeclared - what if you've got define('example', "foo"); somewhere else in the code.
if($_GET['example']=='somevalue'){ ... }
If the url doesn't contain ?example=.. that's going to issue a notice too.
Writing code without displaying errors means you can very easily miss mistakes like the first.
In context: isset and !empty are equivalent
For the example given, these two language constructs act exactly the same.
There is no case where one will act differently than the other, neither will issue a notice if the variable is undefined, and no measurable difference in performance between the two.
As others have said for checking things like $_GET and $_POST you would ideally want to use:
if ( isset($_GET['example']) && $_GET['example'] =='somevalue' ) {
// process data
}
So you always want to firstly make sure that the variable has been set (and not set to null) or in other words exists. Then proceed to check if the variable contains the data that you were expecting. If you try to make reference to a variable which doesn't exist (by not checking isset()) php will give you a notice saying 'undefined variable...etc etc'.
If you wanted to find out if a variable is set but are not concerned too much by what then you could use:
if ( !empty($_GET['example']) ) {
// process data
}
But I would be careful about using empty() on strings in this regard as empty can behave strangely with string data like '0' or ' '.
So I would always do the first one, to a) make sure the variable exists and b) is what you were expecting it to be.
This is something that you'll probably do a lot of and it helps to put together a class/functions which handles this checking for you so you dont have to do it everytime.
function checkValue($key, $value) {
if(array_key_exists($key, $_REQUEST)){
if ($_REQUEST[$key] == $value) {
return true;
} else {
return false;
}
} else {
return false;
}
}
I just use Request as a default instead of switching out (though it is preferable to switch in some cases between POST and GET for security (imo)).
Now you can just call this function anywhere
if (checkValue('Item', 'Tom') === true){} etc
the best is
if((isset($_GET[example]))&&('somevalue'==$_GET['example'])){ ... }
The difference between
'somevalue'==$_GET['example']
AND
$_GET['example']=='somevalue'
If you mistype the == and type = instead, the first notaion will raise an error to notify you.
if((isset($_GET[example]))&&($_GET['example']=='somevalue')){ ... }

Test for NULL value in a variable that may not be set

Considering that:
The isset() construct returns TRUE if a variable is set and not NULL
The is_null() function throws a warning if the variable is not set
Is there a way to test whether a variable exists, no matter it's NULL or not, without using the # operator to suppress the notice?
EDIT
Together with your first replies, I've been thinking about this and I'm getting the conclusion that inspecting get_defined_vars() is the only way to distinguish between a variable set to NULL and an unset variable. PHP seems to make little distinctions:
<?php
$exists_and_is_null = NULL;
// All these are TRUE
#var_dump(is_null($exists_and_is_null));
#var_dump(is_null($does_not_exist));
#var_dump($exists_and_is_null===NULL);
#var_dump($does_not_exist===NULL);
#var_dump(gettype($exists_and_is_null)=='NULL');
#var_dump(gettype($does_not_exist)=='NULL');
?>
$result = array_key_exists('varname', get_defined_vars());
As you already found out, you cannot :
rely on isset, as it return false for a variable that's null.
use $not_exists===null, as it'll raise a notice.
But you could be able to use a combinaison of :
get_defined_vars to get the list of existing variables, including those which are null,
and array_key_exists to find out if an entry exists in that list.
For instance :
$exists_and_null = null;
$exists_and_not_null = 10;
$defined_vars = get_defined_vars();
// true
var_dump(array_key_exists('exists_and_null', $defined_vars)
&& $defined_vars['exists_and_null']===null);
// false
var_dump(array_key_exists('exists_and_not_null', $defined_vars)
&& $defined_vars['exists_and_not_null']===null);
// false
var_dump(array_key_exists('not_exists', $defined_vars)
&& $defined_vars['not_exists']===null);
A couple of notes :
In the first case, the variable exists => there is an entry in the list returned by get_defined_vars, so the second part of the condition is evaluated
and both parts of the condition are true
In the second case, the variable exists too, but is null
which means the first part of the condition is true, but the second one is false,
so the whole expression is false.
In the third case, the variable doesn't exist,
which means the first part of the condition is false,
and the second part of the condition is not evaluated -- which means it doesn't raise a notice.
But note this is probably not that a good idea, if you care about performances : isset is a language construct, and is fast -- while calling get_defined_vars is probably much slower ^^
I would argue here that any code requiring such a comparison would have gotten its semantics wrong; NULL is an unset value in a language that has no straightforward way of distinguishing between the two.
I used a self created function to check this easily, keep in mind it will fire off a PHP warning (I only monitor E_ERROR when I develop).
function isNullOrEmpty( $arg )
{
if ( !is_array( $arg ) )
{
$arg = array( $arg );
}
foreach ( $arg as $key => $value )
{
if( $value == null || trim($value) == "" )
{
return true;
}
}
return false;
}
if (isset($var) && (is_null($var)) {
print "\$var is null";
}
This should do the trick.

Categories