I have the following issue. I want to access a property of an object which may or not be there.
Consider this:
$items[] = [
'color' => $row->color
];
But color may or not be set on $row when it's not PHP prints a notice that it is something like this:
Warning: PHP Notice: Undefined property: stdClass::$color
So I want to do this instead:
$items[] = [
'color' => isset($row->color) ? $row->color : null,
];
However that's a lot of code to write each time I want to do this. Perhaps I'll have dozens of similar properties.
So I would like to create a function like:
function checkEmpty($testValue){
if(!isset($atestValue)) {
return $testValue;
} else {
return null;
}
}
and use it
$items[] = [
'color' => checkEmpty($row->color),
];
But this produces the same error as before. I think because I am still trying to access $row->color when I invoke checkEmpty. Why does this produce this error. What is it about isset() function that does not throw this error when $row->color is passed to it -- when the same argument passed to my custom function does throw the error?
You can use the Null coalescing operator
$items[] = [
'color' => $row->color ?? null
];
You can use property_exists build-in function.
property_exists — Checks if the object or class has a property
https://www.php.net/manual/en/function.property-exists.php
so
property_exists($row, 'color')
Note:
As opposed with isset(), property_exists() returns true even if the
property has the value null.
I have an array that has data about an exam, every exam has 1 type only from 4 types in all [iq,math,geo,gen] and I get it this way {{ $exam->type }} I only want to add translate method to the type, so when I write $exam->type->translate() I get the translated word, how the function structure would be and where should I write it, in Exam model or the controller of the page...
translate function:
function translate($word){
return $word == "math"
? "ماث"
: $word == "iq"
? "آيكيو"
: $word == "geo"
? "هندسة"
: $word == "gen"
? "شامل"
: "غير معرّف"
}
Don't nest ternaries like that. It's a mess to read and to resolve since you easily will get the precedence wrong (plus, since PHP 7.4, you need to group nested ternaries with parentheses, or you'll get a deprecation warning, or a fatal error from PHP 8)
If you rather do it manually (instead of using Laravel's translation feature, which probably would be recommended), you can make it easier by using an array:
function translate($word)
{
$words = [
"math" => "ماث",
"iq" => "آيكيو",
"geo" => "هندسة",
"gen" => "شامل",
];
// Check if the word exists in the array and return it
// if it doesn't exist, return the default
return $words[$word] ?? "غير معرّف";
}
Working on a WordPress site and using Advanced Custom Fields. I am looping through an flexible content array and creating an array from the return.
The issue is I need to return differently named images in an array but the images might be null (they can be empty).
This currently works:
"images" => [
"image_one" => ( $l['image_one']['url'] ? $l['image_one']['url'] : NULL ),
/* etc */
]
But this is in a switch statement so I wanted to be able to pass the:
$l['image_one']['url']
To a function and only return the URL if there is one. However I could have a array where $l['image_three']['url'] is not set and not in the array returned so I will always get undefined offset notices.
I can carry on the way I am but its getting repetive and would rather be able to do e.g.:
"image_one" => imageExists($l['image_one']['url'])
But of course I am already calling a key that doesn't exist (possibly). Is there an other methods of tidying up my shorthand if?
Normally I would just do it inline but since you are looking for a function:
function imageExists($arr = null) {
return (empty($arr['url'])) ? null : $arr['url'];
}
imageExists($l['image_one']);
Use isset() on your ternary condition:
function imageExists($image) {
return isset($image['url']) ? $image['url'] : NULL;
}
And invoke with:
imageExists($l['image_one']);
If you're on a version >= PHP 7.0, you can use the null coalescing operator (search here.) For:
function imageExists($image) {
return $image['url'] ?? NULL;
}
Any idea how to check if a key exists and if yes, then get the value of this key from an array in php.
E.g.
I have this array:
$things = array(
'AA' => 'American history',
'AB' => 'American cooking'
);
$key_to_check = 'AB';
Now, I need to check if $key_to_check exists and if it does, get a coresponding value which in this case will be American cooking
if(isset($things[$key_to_check])){
echo $things[$key_to_check];
}
I know this question is very old but for those who will come here It might be useful to know that in php7 you can use Null Coalesce Operator
if ($value = $things[ $key_to_check ] ?? null) {
//Your code here
}
if (array_key_exists($key_to_check, $things)) {
return $things[$key_to_check];
}
isset() will return:
-true if the key exists and the value is != NULL
-false if the key exists and value == NULL
-false if the key does not exist
array_key_exists() will return:
-true if the key exists
-false if the key does not exist
So, if your value may be NULL, the proper way is array_key_exists. If your application doesn't differentiate between NULL and no key, either will work, but array_key_exists always provides more options.
In the following example, no key in the array returns NULL, but so does a value of NULL for a given key. That means it's effectively the same as isset.
The null coalesce operator(??) wasn't added until PHP 7, but this works back to PHP 5, maybe 4:
$value = (array_key_exists($key_to_check, $things) ? $things[$key_to_check] : NULL);
as a function:
function get_from_array($key_to_check, $things)
return (array_key_exists($key_to_check,$things) ? $things[$key_to_check] : NULL);
The simpliest approach is to do this:
if( isset( $things[ $key_to_check ]) ) {
$value = $things[ $key_to_check ];
echo "key {$key_to_check} exists. Value: {$value}";
} else {
echo "no key {$key_to_check} in array";
}
And you get the value usual way:
$value = $things[ $key_to_check ];
Just use isset(), you can use it as follows if you want to use it as an function:
function get_val($key_to_check, $array){
if(isset($array[$key_to_check])) {
return $array[$key_to_check]);
}
}
For Laravel users, you can use this helper out-of-the-box, thanks to the illuminate/support library:
// use Illuminate\Support\Arr;
Arr::get($array, $key, $default_value)
Which is the equivalent of:
array_key_exists($key, $array) ? $array[$key] : $default_value;
This helper supports the dot notation for keys. Ex: "key1.key2.key3", which is the equivalent of doing $array["key1"]["key2"]["key3"].
Outside Laravel (ex. vanilla PHP), you can manually add this library with composer.
I've written a PHP function that can accept 10 parameters, but only 2 are required. Sometimes, I want to define the eighth parameter, but I don't want to type in empty strings for each of the parameters until I reach the eighth.
One idea I had was to pass an abstracted function with an array of parameters which passes it along to the real function.
Is there a better way to set up the function so I can pass in only the parameters I want?
What I have done in this case is pass an array, where the key is the parameter name, and the value is the value.
$optional = array(
"param" => $param1,
"param2" => $param2
);
function func($required, $requiredTwo, $optional) {
if(isset($optional["param2"])) {
doWork();
}
}
Make the function take one parameter: an array. Pass in the actual parameters as values in the array.
Edit: the link in Pekka's comment just about sums it up.
To accomplish what you want, use an array Like Rabbot said (though this can become a pain to document/maintain if used excessively). Or just use the traditional optional args.
//My function with tons of optional params
function my_func($req_a, $req_b, $opt_a = NULL, $opt_b = NULL, $opt_c = NULL)
{
//Do stuff
}
my_func('Hi', 'World', null, null, 'Red');
However, I usually find that when I start writing a function/method with that many arguments - more often than not it is a code smell, and can be re-factored/abstracted into something much cleaner.
//Specialization of my_func - assuming my_func itself cannot be refactored
function my_color_func($reg_a, $reg_b, $opt = 'Red')
{
return my_func($reg_a, $reg_b, null, null, $opt);
}
my_color_func('Hi', 'World');
my_color_func('Hello', 'Universe', 'Green');
You can just set the default value to null.
<?php
function functionName($value, $value2 = null) {
// do stuff
}
In PHP 5.6 and later, argument lists may include the ... token to denote that the function accepts a variable number of arguments. The arguments will be passed into the given variable as an array; for example:
Example Using ... to access variable arguments
<?php
function sum(...$numbers) {
$acc = 0;
foreach ($numbers as $n) {
$acc += $n;
}
return $acc;
}
echo sum(1, 2, 3, 4);
?>
The above example will output:
10
Variable-length argument lists PHP Documentation
NOTE: This is an old answer, for PHP 5.5 and below. PHP 5.6+ supports default arguments
In PHP 5.5 and below, you can achieve this by using one of these 2 methods:
using the func_num_args() and func_get_arg() functions;
using NULL arguments;
How to use
function method_1()
{
$arg1 = (func_num_args() >= 1)? func_get_arg(0): "default_value_for_arg1";
$arg2 = (func_num_args() >= 2)? func_get_arg(1): "default_value_for_arg2";
}
function method_2($arg1 = null, $arg2 = null)
{
$arg1 = $arg1? $arg1: "default_value_for_arg1";
$arg2 = $arg2? $arg2: "default_value_for_arg2";
}
I prefer the second method because it's clean and easy to understand, but sometimes you may need the first method.
Starting with PHP 8 you are able to use named arguments:
function namedParameters($paramOne, $paramTwo, $paramThree = 'test', $paramFour = null)
{
dd($paramOne, $paramTwo, $paramThree, $paramFour);
}
We can now call this function with the required params and only the optinal params, that we want to differ from the default value which we specified in the function.
namedParameters('one', 'two', paramFour: 'four');
Result:
// "one", "two", "test", "four"
I think, you can use objects as params-transportes, too.
$myParam = new stdClass();
$myParam->optParam2 = 'something';
$myParam->optParam8 = 3;
theFunction($myParam);
function theFunction($fparam){
return "I got ".$fparam->optParam8." of ".$fparam->optParam2." received!";
}
Of course, you have to set default values for "optParam8" and "optParam2" in this function, in other case you will get "Notice: Undefined property: stdClass::$optParam2"
If using arrays as function parameters, I like this way to set default values:
function theFunction($fparam){
$default = array(
'opt1' => 'nothing',
'opt2' => 1
);
if(is_array($fparam)){
$fparam = array_merge($default, $fparam);
}else{
$fparam = $default;
}
//now, the default values are overwritten by these passed by $fparam
return "I received ".$fparam['opt1']." and ".$fparam['opt2']."!";
}
If only two values are required to create the object with a valid state, you could simply remove all the other optional arguments and provide setters for them (unless you dont want them to changed at runtime). Then just instantiate the object with the two required arguments and set the others as needed through the setter.
Further reading
Martin Fowler on Constructor vs Setter Injection and
Dependency injection through constructors or property setters?
I know this is an old post, but i was having a problem like the OP and this is what i came up with.
Example of array you could pass. You could re order this if a particular order was required, but for this question this will do what is asked.
$argument_set = array (8 => 'lots', 5 => 'of', 1 => 'data', 2 => 'here');
This is manageable, easy to read and the data extraction points can be added and removed at a moments notice anywhere in coding and still avoid a massive rewrite. I used integer keys to tally with the OP original question but string keys could be used just as easily. In fact for readability I would advise it.
Stick this in an external file for ease
function unknown_number_arguments($argument_set) {
foreach ($argument_set as $key => $value) {
# create a switch with all the cases you need. as you loop the array
# keys only your submitted $keys values will be found with the switch.
switch ($key) {
case 1:
# do stuff with $value
break;
case 2:
# do stuff with $value;
break;
case 3:
# key 3 omitted, this wont execute
break;
case 5:
# do stuff with $value;
break;
case 8:
# do stuff with $value;
break;
default:
# no match from the array, do error logging?
break;
}
}
return;
}
put this at the start if the file.
$argument_set = array();
Just use these to assign the next piece of data use numbering/naming according to where the data is coming from.
$argument_set[1][] = $some_variable;
And finally pass the array
unknown_number_arguments($argument_set);
function yourFunction($var1, $var2, $optional = Null){
... code
}
You can make a regular function and then add your optional variables by giving them a default Null value.
A Null is still a value, if you don't call the function with a value for that variable, it won't be empty so no error.
As of PHP 7.1.0, type declarations can be marked nullable by prefixing the type name with a question mark (?). This signifies that the value can be of the specified type or null
<?php
function name(?string $varname){
echo is_null($varname);
}
name();
name('hey');
?>
for more info: Click here
If you are commonly just passing in the 8th value, you can reorder your parameters so it is first. You only need to specify parameters up until the last one you want to set.
If you are using different values, you have 2 options.
One would be to create a set of wrapper functions that take different parameters and set the defaults on the others. This is useful if you only use a few combinations, but can get very messy quickly.
The other option is to pass an array where the keys are the names of the parameters. You can then just check if there is a value in the array with a key, and if not use the default. But again, this can get messy and add a lot of extra code if you have a lot of parameters.
PHP allows default arguments (link). In your case, you could define all the parameters from 3 to 8 as NULL or as an empty string "" depending on your function code. In this way, you can call the function only using the first two parameters.
For example:
<?php
function yourFunction($arg1, $arg2, $arg3=NULL, $arg4=NULL, $arg5=NULL, $arg6=NULL, $arg7=NULL, $arg8=NULL){
echo $arg1;
echo $arg2;
if(isset($arg3)){echo $arg3;}
# other similar statements for $arg4, ...., $arg5
if(isset($arg8)){echo $arg8;}
}
Just set Null to ignore parameters that you don't want to use and then set the parameter needed according to the position.
function myFunc($p1,$p2,$p3=Null,$p4=Null,$p5=Null,$p6=Null,$p7=Null,$p8=Null){
for ($i=1; $i<9; $i++){
$varName = "p$i";
if (isset($$varName)){
echo $varName." = ".$$varName."<br>\n";
}
}
}
myFunc( "1", "2", Null, Null, Null, Null, Null, "eight" );
func( "1", "2", default, default, default, default, default, "eight" );