Please consider code below
<?php
$a = '';
echo empty($a) ? '' : substr($a, 0, 1); // Prints: ''
echo substr($a, 0, 1); // Prints: ''
Which "echo" is better? In first one always $a will be checked and substr will run normally and in second one, substr checks $a internally and may trigger some notice errors.
The first one is better.
You always need to prevent errors / warnings / notices.
Although I wouldn't even use the one-liner just for readability.
The input string must be one character or longer. So it is better to check before.
Please check : http://php.net/manual/en/function.substr.php
The most important part is that you differ between input and output variables:
$input['a'] = '';
$output['a'] = empty($input['a']) ? '' : substr($input['a'], 0, 1);
echo $output['a'];
How you write the validation is your business, it should deal with all edge cases and should not trigger any errors/warnings.
Edit: If you're concerned to reduce the number of function calls, the following snippet does not make use of any functions, only one language constructs:
$a = empty($a[0])?'':$a[0];
echo $a;
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
What's different between isset($string) and #$string in PHP ?
This works both ways, so what's the difference?
if(isset($string))
....
if(#$string)
....
isset is true if the given variable exists and is not null.
#$var is true if the value of $var is true in a loose comparison.*
!== null and == true matches different values.
In the case of #$var, if $var does not exist, an error will be generated internally and raised and its output suppressed through #. This is a much more expensive operation, and it may trigger custom defined error handlers on the way. Do not ever use it if there's an alternative.
* A non-existent variable's value is substituted by null, which equals false.
Using isset($str) is not the same as #$str.
isset($str) is true if $str is set and is not null.
#$str is true if $str is truthy.
Consider the following example:
$str = "0";
if (isset($str)) {
// This gets printed because $str is set
echo "Str is set" . PHP_EOL;
}
if (#$str) {
// This is NOT printed because $str is falsy
echo "Str is truthy" . PHP_EOL;
}
It should also be noted that #, in addition to being a bad habit, incurs a significant performance penalty.
Function isset() check variable and return true if variable exists. Sign # ignore error. Give almost the same values. Next code maybe show it:
if(isset($string))
print 1; // no print
if(#$string)
print 2; // no print
$string = false;
if(isset($string))
print 3; // print 3
if(#$string)
print 4; // no print
Simple stuff,
This works without any problems:
$openMonday = rtrim(chunk_split($result['opening_hours']['periods'][1]['open']['time'], 2, ':'), ':');
$business->openingTimes['monday'] = isset($openMonday) ? $result['opening_hours']['periods'][1]['open']['time'] : '';
But I don't want to write two lines for this because then I would have to do it also for all the other opening hours.
Why can't I just write
$business->openingTimes['monday'] = isset(rtrim(chunk_split($result['opening_hours']['periods'][1]['open']['time'], 2, ':'), ':')) ? $result['opening_hours']['periods'][1]['open']['time'] : '';
I'm always getting the error that it's expecting a variable. How can I use methods in the isset with ternary operator?
The problem here is that isset() is not a real function but a language construct, which requires its arguments to be variables, or it issues a syntax error.
See also the manual entry: http://php.net/manual/en/function.isset.php
Anyway, as also #deceze said, you probably do not want to use isset() here, since it is used to check if a variable exists.
In this case, you could use empty(), so instead of writing
$openMonday = rtrim(chunk_split($result['opening_hours']['periods'][1]['open']['time'], 2, ':'), ':');
$business->openingTimes['monday'] = isset($openMonday) ? $result['opening_hours']['periods'][1]['open']['time'] : '';
you could do
$openMonday = rtrim(chunk_split($result['opening_hours']['periods'][1]['open']['time'], 2, ':'), ':');
$business->openingTimes['monday'] = !empty($openMonday) ? $result['opening_hours']['periods'][1]['open']['time'] : '';
And you should not worry to make it a one-liner at any cost! Create a function instead, and then call it when needed... But if you really still want to do it inline, then you could do
$business->openingTimes['monday'] = !empty(rtrim(chunk_split($result['opening_hours']['periods'][1]['open']['time'], 2, ':'), ':')) ? $result['opening_hours']['periods'][1]['open']['time'] : '';
just remember that the above requires at least PHP 5.5!
And finally, the row above could just be written as
$business->openingTimes['monday'] = !rtrim(chunk_split($result['opening_hours']['periods'][1]['open']['time'], 2, ':'), ':') ? $result['opening_hours']['periods'][1]['open']['time'] : '';
without any need for isset() nor empty()
You don't need isset here! isset is used to safely test whether... well... a variable exists. You know your variable exists, because you're declaring it on the line before. If you want to mush it into one line, you're not even using a variable, you're directly working with the value. You just want to compare the value to false, which you can do inline easily.
Just get rid of isset. And read The Definitive Guide To PHP's isset And empty.
SOLUTION
$business->openingTimes['monday'] = isset($result['opening_hours']['periods'][1]['open']['time']) ? rtrim(chunk_split($result['opening_hours']['periods'][1]['open']['time'], 2, ':'), ':') : '';
To explain what I did. I asked if the variable is set, and if so it uses the method chunk_split otherwise the string will be empty.
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");
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.