I have a situation where I have a function that does some database retrieval and either returns a value or an error. I'd like to have a single statement that calls the function and depending on result either assigns the returned value or a default value.
Using the tenary operator I could do something like this:
$val=(getVal($param)!='error' ? getVal($param) : "default");
but I don't want to have to call getVal twice because it excutes database queries and is expensive on performance.
I could also do it in two statements, but if possible I just want one. Appreciate any help.
Try this
$val=(($result=getVal($param))!='error' ? $result : "default");
There are only two ways I am aware of (maybe there is more).
Either you first assign function result to a variable and then use if:
$res = getVal($param);
$val = ($res != 'error' ? $res : "default");
Note: This is possibly the best option both for readability and performance.
Or you modify function from this:
function getVal($param) {
...
return $something;
}
to this:
function getVal ($param, &$result) {
...
$result = $something;
return $something;
}
And use it:
$val = (getVal($param,$res) != 'error' ? $res : "default");
But this looks fishy to me
Related
So, I am writing a function that receives two arguments, and before I do anything with these variables, I want to check if they are not null.
if (!is_null($foo) && !is_null($bar)) {
/* do something */
}
The problem is that I think we are repeating code, and in some cases when the variable name is a little bit bigger, it becomes painful to write every time.
So, there is a way to shorten this code?
You can use isset which returns FALSE if variable is null. You can set there a lot of variables so code will be shorter:
if (isset($foo, $bar))
You can write your own function to check this:
function is_any_null() {
$params = func_get_args();
foreach($params as $param) {
if (is_null($param))
return true;
}
return false;
}
Now you can use it like this:
if (!is_any_null($foo, $bar)) {
/* do something */
}
is_null() checks a variable to determine if the value is NULL. It can be used in an if statement. It depends on what you would like to do in that if statement. For example, if you would like to do an echo, you can make it a bit shorter using the `elvis``operator:
echo (is_null($foo) && is_null($bar)) ?: 'The values are not null';
Or you could make it a one liner by leaving the { and } out of your code and putting everything on one line.
if (!is_null($foo) && !is_null($bar)) die("NULLLLL");
I have an interesting situation. I am using a form that is included on multiple pages (for simplicity and to reduce duplication) and this form in some areas is populated with values from a DB. However, not all of these values will always be present. For instance, I could be doing something to the effect of:
<?php echo set_value('first_name', $first_name); ?>
and this would work fine where the values exist, but $user is not always set, since they may be typing their name in for the first time. Yes you can do isset($first_name) && $first_name inside an if statement (shorthand or regular)
I am trying to write a helper function to check if a variable isset and if it's not null. I would ideally like to do something like varIsset('first_name'), where first_name is an actual variable name $first_name and the function would take in the string, turn it into the intended variable $first_name and check if it's set and not null. If it passes the requirements, then return that variables value (in this case 'test'). If it doesn't pass the requirements, meaining it's not set or is null, then the function would return '{blank}'.
I am using CodeIgniter if that helps, will be switching to Laravel in the somewhat near future. Any help is appreciated. Here is what I've put together so far, but to no avail.
function varIsset($var = '')
{
foreach (get_defined_vars() as $val) {
if ($val == $var) {
if (isset($val) && $val) {
echo $val;
}
break;
}
}
die;
}
Here is an example usage:
<?php
if (varIsset('user_id') == 100) {
// do something
}
?>
I would use arrays and check for array keys myself (or initialize all my variables...), but for your function you could use something like:
function varIsset($var)
{
global $$var;
return isset($$var) && !empty($$var);
}
Check out the manual on variable variables. You need to use global $$var; to get around the scope problem, so it's a bit of a nasty solution. See a working example here.
Edit: If you need the value returned, you could do something like:
function valueVar($var)
{
global $$var;
return (isset($$var) && !empty($$var)) ? $$var : NULL;
}
But to be honest, using variables like that when they might or might not exist seems a bit wrong to me.
It would be a better approach to introduce a context in which you want to search, e.g.:
function varIsset($name, array $context)
{
return !empty($context[$name]);
}
The context is then populated with your database results before rendering takes place. Btw, empty() has a small caveat with the string value "0"; in those cases it might be a better approach to use this logic:
return isset($context[$name]) && strlen($name);
Try:
<?php
function varIsset($string){
global $$string;
return empty($$string) ? 0 : 1;
}
$what = 'good';
echo 'what:'.varIsset('what').'; now:'.varIsset('now');
?>
I am looking for an optimized way to do something like this:
Check if what am I receiving from a function:
Is set
Is an array
If so, I would like to directly assign it to a variable.
For that propose, I would do something like:
Let's suppose that I'm calling a function that returns me an array (or not).
<?php
$data_table = isset(Api::get($url)) && is_array(Api::get($url)) ? (array)Api::get($url) : array();
?>
However, doing something like this would require three calls to the function:
The first, to check in an if statement if it is really returning something
The second to check if the return is an array
The thing to assign the return to $data_table variable
I've thought about doing the following, but I'm not sure how it could work like this:
<?php
$data_table = isset($result = Api::get($url)) && is_array($result) ? (array)$result : array();
?>
Please let me know your thoughts.
Thanks.
You can use empty(). From the manual:
No warning is generated if the variable does not exist. That means empty() is essentially the concise equivalent to !isset($var) || $var == false.
It doesn't quite check for whether it's an array, rather whether the variable (of many types) is empty, but it's a shorter way than what you're doing. I think if you want to check for an array and for isset, that's what you'll have to do - no way around it.
<?php
$data_table = !empty($result) ? $result : array();
?>
This is a minor thing, but it's been bugging me for a while. I've wracked my brain for a way to write statements like this without any repetition of code. For example:
echo isset($array[0])? $array[0]: 'not set';
$var = empty($other_var)? '$other_var not set': $other_var;
Is there some sort of test-and-return (for the former) or test-and-set (for the latter) operator I don't know about? This may seem like a minor point, but the duplication seems unnecessary and can lead to very long lines that can complicate maintenance. Consider:
$another_var = array_key_exists($array[Utility::FindIndex($username)][Constants::App_CRITERION], $haystack[NthDimension('my dimensional indicator')])? $array[Utility::FindIndex($username)][Constants::App_CRITERION], $haystack[NthDimension('my dimensional indicator')]: 'not set';
Yes, yes, the above line is totally contrived but it's not unthinkable that something like this could occur. It just seems strange to me that there isn't a way to test something and assign it's value (if true) without repetition without repetition.
It won't handle the isset () case, which is a main use case for this pattern, but PHP 5.3 does have a short form for the ternary operator.
$new_val = $if_true ? $if_true : $if_false;
can be shortened to
$new_val = $if_true ?: $if_false;
I couldn't find it in the docs, strangely, but here's a question about it: What is ?: in PHP 5.3?
I think in PHP 6 there was a function planned called issetor or something similar. But I can't remember the name. And PHP 6 is dead either way.
So, write it yourself:
function issetor(&$var, $default) {
return isset($var) ? $var : $default;
}
echo issetor($_GET['me'], 'you');
If you want to make it even more abstract, look at this:
function isor(&$var, $default, $condition) {
if (!is_callable($condition)) {
throw new InvalidArgumentExpression('condition not callable!');
}
return $condition($var) ? $var : $default;
}
// this is equivalent to issetor($_GET['me'], 'you');
echo isor($_GET['me'], 'you', function(&$var) { return isset($var); });
// but you may use a more complicated thing here, too:
echo isor($_GET['me'], 'you', function($var) use($allowed) { return in_array($var, $allowed); });
// this is equivalent to:
echo in_array($_GET['me'], $allowed) ? $_GET['me'] : 'you';
// now the "normal" version is still shorter. But using isor allows you to store often used $condition closures in variables. For example, if you want to check if several values are in an array, you could write:
$isAllowed = function ($var) use ($allowed) {
return in_array($var, $allowed);
};
$a = isor($a, 'default', $inAllowed);
$b = isor($b, 'default', $inAllowed);
$c = isor($c, 'default', $inAllowed);
$d = isor($d, 'default', $inAllowed);
If you want to pass additional variables to your condition function without always useing closures you may add another argument. (Note I didn't use an argument array and call_user_func_array, because you may not pass per reference using it, but obviously you may extend the code so it does so.)
function isor(&$var, $default, $condition, $addArgument = null) {
if (!is_callable($condition)) {
throw new InvalidArgumentExpression('condition not callable!');
}
return $condition($var, $addArgument) ? $var : $default;
}
// the above in_array condition:
echo isor($a, 'default', 'in_array', $allowed);
I'm using a template engine that inserts code in my site where I want it.
I wrote a function to test for something which is quite easy:
myfunction() { return '($this->data["a"]["b"] ? true : false)'; }
The problem is, $this->data is private, and I can't access it everywhere, so I have to use getData(); which causes my problem.
$this->getData()['a']['b']
does not work, and assigning the value first doesn't either because it will be used directly in an if() block.
Any ideas?
Since PHP 5.4 it's possible to do exactly that:
getSomeArray()[2]
Reference: https://secure.php.net/manual/en/language.types.array.php#example-62
On PHP 5.3 or earlier, you'll need to use a temporary variable.
You cannot use something like this :
$this->getData()['a']['b']
ie, array-access syntax is not possible directly on a function-call.
Youy have to use some temporary variable, like this :
$tmp = $this->getData();
$tmp['a']['b'] // use $tmp, now
In your case, this probably means using something like this :
function myfunction() {
$tmp = $this->getData();
return ($tmp['a']['b'] ? true : false);
}
You have to :
first, call your getData() method, and store its return value in a temporary varibale
then, use that temporary variable for your test
You don't have much choice about that, actually...
Ok... apparently there really isn't a better way, so I'm going to answer myself with a not so beautiful solution:
I created the function:
arrayGet($array, $index) { return $array[$index]; }
And used it like this:
myfunction() { return '(arrayGet(arrayGet($this, "a"), "b") ? true : false)' }
This is not pretty but works.
$this->data is always accessible, if it is protected. $object->data is not accessible from everywhere, so if you're returning $this in your code, and it is evaluated as such, it should be ok.
Btw, there is a bug in your code: The quotes need to be escaped.
myfunction() { return '($this->data[\'a\'][\'b\'] ? true : false)'; }
It is possible from PHP version 5.4.
If you don't want a temporary variable for that and your PHP version is less, than 5.4, than you still can use a few built in functions to get the first or the last element:
$x = 'first?last';
$first = array_shift(explode('?', $x));
$last = end(explode('?', $x));
$last2 = array_pop(explode('?', $x));
Edit:
!!! Please note, that in later versions( 5.4+ ) PHP will throw a notice, because end only expects variables as parameter.