I'm using getopt to pass variables to my script, but I get the message:
PHP Notice: Undefined index:
Here's my code:
$MyOptions = getopt("c:hp:");
if ($MyOptions['c']) { //line wher error show up!
$MyClub = $MyOptions['c'];
} else {
$MyClub = '53';
}
What did I miss?
The problem is the index c in your $MyOptions array does not exist, you can avoid this in a number of ways, but my preferred option in this case would be to replace the entire if-else statement with;
$MyClub = $MyOptions['c'] ?? '53';
The ?? is the Null Coalescing operator.
The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). It returns its first operand if it exists and is not NULL; otherwise it returns its second operand.
Please be aware this is only available from PHP 7, otherwise you will have to use an isset() to check if the index exists.
Related
I have a PHP error notice:
Undefined index: inventory_amount
$chains[$key] = intval($chain_product['inventory_amount']);
Is it possible to fix it in one line like with ternary function and not with:
if(!empty($chain_product['inventory_amount'])) {
$chains[$key] = intval($chain_product['inventory_amount']);
}
New with PHP. Thanks
Yes, PHP has ternary operator.
Like this:
$variable = ( condition ? true : false );
So in your case it like this:
$chains[$key] = ( !empty($chain_product['inventory_amount']) ? intval($chain_product['inventory_amount']) : 0 );
so if you have inventory_amount empty, it will have 0 assigned as a "fallback".
I have a function within my PHP project which has some specific params..
$user_sequence = $user['user_sequence'];
if ($cached || !$user_sequence) {
return;
}
Notice: Undefined index: user_sequence
I have fixed that with:
if (isset($user['user_sequence'])) {
$user_sequence = $user['user_sequence'];
}
But now my second if() clause get's a warning:
Variable '$user_sequence' is probably undefined
Would setting it to null before if() be the best approach to solve it? Thanks
Spelled out in full, you need to specify what the value should be if $user['user_sequence'] is not set. In your second if statement, you are checking !$user_sequence, so a logical default value would be boolean false:
if (isset($user['user_sequence'])) {
$user_sequence = $user['user_sequence'];
}
else {
$user_sequence = false;
}
Luckily, PHP doesn't make use write out that whole if statement, because we can use the null coalescing operator, and shorten it to this:
$user_sequence = $user['user_sequence'] ?? false;
In other situations, you might want to default to an empty array ($something ?? []) or even just null ($something ?? null).
Notice: Undefined index: extension in /var/www/.. on line 187
//185 - $f_name = $this->filename;
//186 - $path_parts = pathinfo($f_name);
//187 - $file_ext = $path_parts['extension'];
After some googleing I've seen alot of Isset being used. But I'm in doubt, about how to use it, in this case? Is it even going to solve the problem?
Yes, you can use isset in this case. You first check if the key is set before trying to access it. I would use the ternary operator to set a default value if you need to.
$file_ext = isset($path_parts['extension']) ? $path_parts['extension'] : null;
Since php 7.0, You can use null coalescing operator
$file_ext = $path_parts['extension'] ?? null;
https://www.php.net/manual/en/migration70.new-features.php
pathinfo will only return the "extension" index if the path has an extension, otherwise it will not return this index.
A simple check should be used to determine whether the path has an index, such as:
if(!empty($path_parts['extension'])) {
// Extension exists
}
$f_name has no extension, so $path_parts['extension'] is not set.
pathinfo, look Example #2
Is there any way to write the following statement using some kind of safe navigation operator?
echo $data->getMyObject() != null ? $data->getMyObject()->getName() : '';
So that it looks like this:
echo $data->getMyObject()?->getName();
From PHP 8, you are able to use the null safe operator which combined with the null coalescing operator allows you to write code like:
echo $data->getMyObject()?->getName() ?? '';
By using ?-> instead of -> the chain of operators is terminated and the result will be null.
The operators that "look inside an object" are considered part of the chain.
Array access ([])
Property access (->)
Nullsafe property access (?->)
Static property access (::)
Method call (->)
Nullsafe method call (?->)
Static method call (::)
e.g. for the code:
$string = $data?->getObject()->getName() . " after";
if $data is null, that code would be equivalent to:
$string = null . " after";
As the string concatenation operator is not part of the 'chain' and so isn't short-circuited.
Nullsafe operator allows you to chain the calls avoiding checking whether every part of chain is not null (methods or properties of null variables).
PHP 8.0
$city = $user?->getAddress()?->city
Before PHP 8.0
$city = null;
if($user !== null) {
$address = $user->getAddress();
if($address !== null) {
$city = $address->city;
}
}
With null coalescing operator (it doesn't work with methods):
$city = null;
if($user !== null) {
$city = $user->getAddress()->city ?? null;
}
Nullsafe operator suppresses errors:
Warning: Attempt to read property "city" on null in Fatal error:
Uncaught Error: Call to a member function getAddress() on null
However it doesn't work with array keys:
$user['admin']?->getAddress()?->city //Warning: Trying to access array offset on value of type null
$user = [];
$user['admin']?->getAddress()?->city //Warning: Undefined array key "admin"
No there is not.
The absolute best way to deal with this is to design your objects in a way that they always return a known, good, defined value of a specific type.
For situations where this is absolutely not possible, you'll have to do:
$foo = $data->getMyObject();
if ($foo) {
echo $foo->getName();
}
or maybe
echo ($foo = $data->getMyObject()) ? $foo->getName() : null;
What's the equivalent of the following (based in JS style) in PHP:
echo $post['story'] || $post['message'] || $post['name'];
So if story exists then post that; or if message exist post that, etc...
It would be (PHP 5.3+):
echo $post['story'] ?: $post['message'] ?: $post['name'];
And for PHP 7:
echo $post['story'] ?? $post['message'] ?? $post['name'];
There is a one-liner for that, but it's not exactly shorter:
echo current(array_filter(array($post['story'], $post['message'], $post['name'])));
array_filter would return you all non-null entries from the list of alternatives. And current just gets the first entry from the filtered list.
Since both or and || do not return one of their operands that's not possible.
You could write a simple function for it though:
function firstset() {
$args = func_get_args();
foreach($args as $arg) {
if($arg) return $arg;
}
return $args[-1];
}
As of PHP 7, you can use the null coalescing operator:
The null coalescing operator (??) has been added as syntactic sugar
for the common case of needing to use a ternary in conjunction with
isset(). It returns its first operand if it exists and is not NULL;
otherwise it returns its second operand.
// Coalescing can be chained: this will return the first
// defined value out of $_GET['user'], $_POST['user'], and
// 'nobody'.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
Building on Adam's answer, you could use the error control operator to help suppress the errors generated when the variables aren't set.
echo #$post['story'] ?: #$post['message'] ?: #$post['name'];
http://php.net/manual/en/language.operators.errorcontrol.php
You can try it
<?php
echo array_shift(array_values(array_filter($post)));
?>
That syntax would echo 1 if any of these are set and not false, and 0 if not.
Here's a one line way of doing this which works and which can be extended for any number of options:
echo isset($post['story']) ? $post['story'] : isset($post['message']) ? $post['message'] : $post['name'];
... pretty ugly though. Edit: Mario's is better than mine since it respects your chosen arbitrary order like this does, but unlike this, it doesn't keep getting uglier with each new option you add.
Because variety is the spice of life:
echo key(array_intersect(array_flip($post), array('story', 'message', 'name')));