I have a really quick question for you:
I read data from an Excel sheet and want to transform it into an assoc array. But sometimes there are no values given in some cells. So if this occurs I want to set the value of the array to 0.
right now I do it like that with the ternary operator and I'm glad I discovered that today:
(isset($excel->sheet[0]['cells'][$row][$value]) ? $excel->sheet[0]['cells'][$row][$value] : 0)
Is there a whay to shorten the repitition in this case? It works but it ain't that pretty :(
Although this is not recommended, I would go the following way (PHP 5.3):
(#$excel->sheet[0]['cells'][$row][$value] ? : 0);
Error suppression operator is a mess, but in this case the only thing you suppress is a well-known notice about undefined variable.
Another option (as stated by Álvaro G. Vicario) could be a simple cast to int (as NULL casts to 0):
(int)#$excel->sheet[0]['cells'][$row][$value];
Another option is making a function to check the existence of such variable – maybe it's a little over-engineering, overkill or just too much –:
function iset($array, $output) {
$args = func_get_args();
$val = $array;
for ($i = 1; $i < count($args) - 1; $i++) {
if (!isset($val[func_get_arg($i)])) {
return func_get_arg(func_num_args() - 1);
}
$val = $val[func_get_arg($i)];
}
return $val;
}
Then use the function like this:
$var = iset($excel->sheet, 0, 'cells', $row, $value, "DEFAULT_VALUE");
Related
Is there in PHP something similar to JavaScript's:
alert(test || 'Hello');
So, when test is undefined or null we'll see Hello, otherwise - we'll see the value of test.
I tried similar syntax in PHP but it doesn't seem to be working right... Also I've got no idea how to google this problem..
thanks
Edit
I should probably add that I wanted to use it inside an array:
$arr = array($one || 'one?', $two || 'two?'); //This is wrong
But indeed, I can use the inline '? :' if statement here as well, thanks.
$arr = array(is_null($one) ? "one?" : $one, is_null($two) ? "two ?" : $two); //OK
you can do echo $test ?: 'hello';
This will echo $test if it is true and 'hello' otherwise.
Note it will throw a notice or strict error if $test is not set but...
This shouldn't be a problem since most servers are set to ignore these errors. Most frameworks have code that triggers these errors.
Edit: This is a classic Ternary Operator, but with the middle part left out. Available since PHP 5.3.
echo $test ? $test : 'hello'; // this is the same
echo $test ?: 'hello'; // as this one
This only checks for the truthiness of the first variable and not if it is undefined, in which case it triggers the E_NOTICE error. For the latter, check the PHP7 answer below (soon hopefully above).
From PHP 7 onwards you can use something called a coalesce operator which does exactly what you want without the E_NOTICE that ?: triggers.
To use it you use ?? which will check if the value on the left is set and not null.
$arr = array($one ?? 'one?', $two ?? 'two?');
See #Yamiko's answer below for a PHP7 solution https://stackoverflow.com/a/29217577/140413
echo (!$test) ? 'hello' : $test;
Or you can be a little more robust and do this
echo isset($test) ? $test : 'hello';
As per the latest version use this for the shorthand
$var = $value ?? "secondvalue";
One-liner. Super readable, works for regular variables, arrays and objects.
// standard variable string
$result = #$var_str ?: "default";
// missing array element
$result = #$var_arr["missing"] ?: "default";
// missing object member
$result = #$var_obj->missing ?: "default";
See it in action: Php Sandbox Demo
I'm very surprised this isn't suggested in the other answers:
echo isset($test) ? $test : 'hello';
From the docs isset($var) will return false if $var doesn't exist or is set to null.
The null coalesce operator from PHP 7 onwards, described by #Yamiko, is a syntax shortcut for the above.
In this case:
echo $test ?? 'hello';
If you want to create an array this way, array_map provides a more concise way to do this (depending on the number of elements in the array):
function defined_map($value, $default) {
return (!isset($value) || is_null($value)) ? $default : $value;
// or return $value ? $default : $value;
}
$values = array($one, $two);
$defaults = array('one', 'two');
$values = array_map('defined_map', $values, $defaults);
Just make sure you know which elements evaluate to false so you can apply the right test.
Since php7.4, you can use the null coalescing assignment, so that you can do
$arr = array($one ??= "one?", $two ??= "two ?");
See the docs here
There may be a better way, but this is the first thing that came to my mind:
echo (!$test) ? "Hello" : $test;
Null is false in PHP, therefore you can use ternary:
alert($test ? $test : 'Hello');
Edit:
This also holds for an empty string, since ternary uses the '===' equality rather than '=='
And empty or null string is false whether using the '===' or '==' operator. I really should test my answers first.
Well, expanding that notation you supplied means you come up with:
if (test) {
alert(test);
} else {
alert('Hello');
}
So it's just a simple if...else construct. In PHP, you can shorten simple if...else constructs as something called a 'ternary expression':
alert($test ? $test : 'Hello');
Obviously there is no equivalent to the JS alert function in PHP, but the construct is the same.
alert((test == null || test == undefined)?'hello':test);
I recently had the very same problem.This is how i solved it:
<?php if (empty($row['test'])) {
echo "Not Provided";}
else {
echo $row['test'];}?></h5></span></span>
</div>
Your value in the database is in variable $test..so if $test row is empty then echo Not Provided
If I have:
$compare = "5<6";
How do I look at the compare variable and return the value true. The input needs to be a string so taking away the " won't help. The string could be very complex so I'm looking for a function already in PHP which can run this, or something that someone has written before which can do this. I've tried the eval() function but that doesn't work, so:
$compare = "5<6";
echo eval($compare);
just errors. Thanks for your help in advance.
Using code evaluation functions are something that should be discouraged, because it may lead to a lot of security problems, but if you want to keep your logic that way, you must evaluate a valid code:
<?php
$compare = "5 > 6";
eval("\$result = $compare;");
var_dump($result);
Your comparing stringmust be used inside the eval function like it would be done in the normal code, not expecting a return value. So what I changed in this sample code is that I used a variable named $result to store the value from the evaluated code.
As you will see when running this code, the $result will be a boolean value (false in this sample, because 5 is not greater than 6, obviously).
Try this:
<?php
$compare = "5<6";
eval('$output = '.$compare.';');
echo $output;
?>
From PHP documentation: http://php.net/manual/en/function.eval.php
Caution The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged.
If you have carefully verified that there is no other option than to
use this construct, pay special attention not to pass any user
provided data into it without properly validating it beforehand.
You can display with echo directly:
<?php
$compare = '5<6';
echo $compare. "\n";
echo eval("return $compare;");
?>
Or You can store result in variable to display later:
<?php
$compare = '5<6';
echo $compare. "\n";
$result = eval("return $compare;");
echo $result;
?>
Be careful ;)
If you wanted to avoid eval it's easy enough to parse comparison expressions. Just split the string on a comparison operator and return the result of the corresponding comparison.
function compare($expr) {
$expr = preg_split('/(>=|<=|<|>|=)/', $expr, -1, PREG_SPLIT_DELIM_CAPTURE);
list($lhs, $op, $rhs) = $expr;
switch ($op) {
case '<': return $lhs < $rhs;
case '<=': return $lhs <= $rhs;
case '>': return $lhs > $rhs;
case '>=': return $lhs >= $rhs;
case '==': return $lhs == $rhs;
}
}
Apparently I missed the bit about "the string could be very complex" when I read the question initially, so this may not be helpful in your case, but I'll leave it here for future reference.
In PHP I find myself writing code like this frequently:
$a = isset($the->very->long->variable[$index])
? $the->very->long->variable[$index]
: null;
Is there a simpler way to do this? Preferably one that doesn't require me to write $the->very->long->variable[$index] twice.
An update, because PHP 7 is now out and is a game-changer on this point ; the previous answers are about PHP 5.
PHP 7 solves this issue. Because you are true at saying that it is frequent to write this in PHP, and that's absolutely not elegant.
In PHP 7 comes the Null Coalesce Operator (RFC), which is a perfect shorthand for the isset ternary condition.
Its goal is to replace this type of condition:
$var = isset($dict['optional']) ? $dict['optional'] : 'fallback';
By that:
$var = $dict['optional'] ?? 'fallback';
Even better, the null coalesce operators are chainable:
$x = null;
# $y = null; (undefined)
$z = 'fallback';
# PHP 7
echo $x ?? $y ?? $z #=> "fallback"
# PHP 5
echo isset($x) ? $x : (isset($y) ? $y : $z)
The null coalesce operator acts exactly like isset() : the subject variable's value is taken if:
The variable is defined (it exists)
The variable is not null
Just a note for PHP beginners: if you use the ternary condition but you know that the subject variable is necessarily defined (but you want a fallback for falsy values), there's the Elvis operator:
$var = $dict['optional'] ?: 'fallback';
With the Elvis operator, if $dict['optional'] is an invalid offset or $dict is undefined, you'll get a E_NOTICE warning (PHP 5 & 7). That's why, in PHP 5, people are using the hideous isset a ? a : b form when they're not sure about the input.
Sadly no, because the RFC has been declined. And because isset is not a function but a language construct you cannot write your own function for this case.
Note: Because this is a language construct and not a function, it cannot be called using variable functions.
If you only assign null instead of the non set variable, you can use:
$a = #$the->very->long->variable[$index];
# makes that instruction throw no errors
Assuming you know that $the->very->long->variable is set, and you're just worried about the array index....
$x = $the->very->long->variable;
$a = isset($x[$index]) ? $x[$index] : null;
Or for a more generic variant that you can use around you code:
function array_valifset($arr,$k, $default=null) {
return isset($arr[$k]) ? $arr[$k] : $default;
}
then call it like this for any array value:
$a = array_valifset($the->very->long->variable,$index);
I stumbled across the same problem and discovered that referencing an array element does not issue a notice or warning but returns null (at least PHP 5.6).
$foo = ['bar' => 1];
var_dump($bar = &$foo['bar']); // int 1
var_dump($baz = &$foo['baz']); // null
Inside an if statement:
if($bar = &$foo['bar']) {
echo $bar;
}
if($baz = &$foo['baz']) {
echo $baz;
}
Before doing something with $error:
$error = NULL;
In some script's saw:
$error = '';
$error = false;
$error = 0;
Which method is 'better' or maybe it depends in which situation i use
it ?
What's your suggestion ?
Depends on your design:
Are you setting it as an Object in case of error? Use NULL.
Are you setting it to true in case of error? Use false.
Are you setting it as a number of some sort in case of error? Use 0.
Are you setting it to a string to describe the error? Use ''.
A better way to indicate errors would be throwing Exceptions though, rather than setting a variable and determine the error according to it.
There is no canonical answer to this question. As long as you use one of these semaphores consistently, you can use anything you want. Because PHP is loosely-typed, all of these values are "falsy" and can be evaluated in a boolean comparison as FALSE.
That said, there is more of a difference between the empty string and the others, so I'd stick with NULLs and FALSEs in this sort of scenario.
1.
$v = NULL;
settype($v, 'string');
settype($v, 'int');
settype($v, 'float');
settype($v, 'bool');
settype($v, 'array');
var_dump($v);
2.
$v = NULL;
var_dump( (string) $v);
var_dump( (int) $v);
var_dump( (float) $v);
var_dump( (bool) $v);
var_dump( (array) $v);
It depends upon the conditions where you need to use the $error. Using a NULL is what I chose mostly as I deal more with MySQL clauses and all!
Take this:
$data = array('one'=>'1','three'=>'3');
Now which is better?
This:
echo #$data['two'];
or this:
function val($data,$key,$default){
if(isset($data[$key])){
return $data[$key];
}
return $default;
}
echo val($data,'two','');
or this:
echo isset($data['two'])?$data['two']:'';
or something else?
avoiding the notice: Notice: Undefined index: two in document on line #num
which one is the most efficient, and which one should I use?
I am wondering that maybe the super-slow error suppressing might be faster than having a dedicated function?
p.s. Lots of answers seem to assume that I am doing this as a form of optimization, this is not true, I am asking the "efficiency" part out of curiosity and the "which should I use" part because I need to use something and I want to know what I should default to.
p.p.s. most efficient and which used will most likely be different
Use whichever you like best. The slowness of your application does not come from this place.
This is common sense answer
"#" symbol will suppress PHP-generated error messages. suppress, notice will occure and error handling function will be called.
isset is part of the language construct, therefore it is much faster.
Use Ternary Operators isset($dat['index']) ? $data['index'] : null, because it looks clean and does not trigger error handling
Coming from java, I would suggest you to use the third option. This way you don't hide a code that doesn't work but you instead provide a default value when there is none.
The first way just hide an error, and the second is just way too long.
Error suppressing with # is know to be really slow. I've read that turning error reporting, doing something and then turning the old reporting level is still faster than just using #.
Regarding other two options - they are equal for me, but just for output, I would use 3rd variant with isset - simply looks nicer and no need to define extra function... If you are using a lot of output - then maybe function would reduce code repeat and would be more useful...
Php has this array_key_exists function that I think is the most correct way to handle what you're doing. As for speed, here is a test program I just made:
//testing #
$t = microtime(TRUE);
$a = array('one' => 1, 'three' => 3);
for ($i = 0; $i < 1000000; $i++)
$b = #$a['two'];
echo (microtime(TRUE) - $t)."\n";
//testing array_key_exists
$t = microtime(TRUE);
$a = array('one' => 1, 'three' => 3);
for ($i = 0; $i < 1000000; $i++)
$b = array_key_exists('two', $a) ? $a['two'] : '';
echo (microtime(TRUE) - $t)."\n";
//testing isset
$t = microtime(TRUE);
$a = array('one' => 1, 'three' => 3);
for ($i = 0; $i < 1000000; $i++)
$b = isset($a['two']) ? $a['two'] : '';
echo (microtime(TRUE) - $t)."\n";
and the results are:
5.9005348682404
9.6285729408264
0.32760310173035
So yeah, isset is noticeably faster.
Time has passed, reflections on the solution
Q. Which should I use by default?
A. Ternary operator.
Q. Which is fastest?
A. Ternary operator.
Q. Which is the most convenient?
A. Custom function.
# error surpressing actually works like this
it switches off error reporting completely for the entire php thread
it does the operation
it switches error reporting back on
which is why it is not recommended
sometimes I use this:
function issetor(&$variable, $or = NULL) {
return $variable === NULL ? $or : $variable;
}
because it is shorter to write:
echo issetor($data['two'],'');
than:
echo isset($data['two'])?$data['two']:'';
Warning: issetor($arr[$k],null); will set the $arr[$k] = null; if $arr[$k] is not already set
Other times I use custom array handling functions, depending on the situation.