php if else multiple lines shorthand - php

I would like to conditionally execute two functions:
while($row = mysql_fetch_assoc($result))
(strtolower($message) == $row['question'])
? msg($row['answer']) && update($row['question'])
: '';
but this code is not working.

Shorthand only works for one-line statements. Since your if statement contains two lines, shorthand does not work. Usually while loops are formatted as follows:
while (/* condition */)
{
// code to be executed
}
Your ternary expression is also incorrect; it should be written as follows:
(/* condition */) ? /* if true do this */ : /* if false do this */
In the second part of the ternary statement (?:), you use the conditional operator &&, which compares two boolean expressions. As I understand it, your intention of the use of && is to execute two lines, which is incorrect. Refer to the documentation: PHP Docs (Comparison operators)
You need to write the while loop with braces, because your if statement contains multiple lines of code, as follows:
while($row = mysql_fetch_assoc($result))
{
if (strtolower($message) == $row['question'])
{
msg($row['answer']);
update($row['question']);
}
}

Is there any reason why you need to use the shorthand code to do this?
The following would be rather more readable and also when you (or someone else) comes to update/change/review/debug the code sometime in the future it will be much more obvious what the intended outcomes were.
while($row = mysql_fetch_assoc($result)) {
if (strtolower($message) == $row['question']) {
msg($row['answer']);
update($row['question']);
}
}
Usually the shortnened ?: version is reserved only for the very simplest conditions and actions.

Define a function msg_update() that wraps msg() and update():
function msg_update($row) {
msg($row);
update($row);
}
Then you can do:
while($row = mysql_fetch_assoc($result)) (strtolower($message) == $row['question']) ? msg_update($row['answer']) : '';
This is because a tenary operator takes only simple operations. Hope that works for you.

Related

Second check in or-statement not executed

In my php application i do the following check:
if(($images = $main->get_images($data['id'])) || ($videos = $main->get_videos($data['id']))){
(...)
if($videos){
(...)
}
if($images){
(...)
}
}
This operation sends back an error saying $videos is undefined. My guess is that if the first statement is true, the second wont be checked. Is there any neat way of preforming the second check, even is the first one is true, because in this case if images is true, videos will be evaluated as false
There isn't a way. You'll need to re-write it into something like this...
$images = $main->get_images($data['id']);
$videos = $main->get_videos($data['id']);
if($images || $videos){
(...)
if($videos){
(...)
}
if($images){
(...)
}
}
And just FYI... order of operations means you don't need to enclose the conditions in () brackets. Almost everything gets computed BEFORE the OR operator (including the && operator).
Good luck!
Joey
You can use empty() to see if a variable does not exist or is null e.g.
if(!empty($videos)) {
(...)
}

PHP Shorthand If/Else when using return

There are few nice ways to write shorthands in PHP.
Less common but shortest example:
!isset( $search_order ) && $search_order = 'ASC';
More common but a little longer:
!isset( $search_order ) ? $search_order = 'ASC' : $search_order = NULL;
We can even combine examples above in to an amazing shorthand:
!isset( $_POST['unique_id'] ) && preg_match( '/^[a-zA-Z0-9]{8}$/', $_POST['unique_id'] ) ? $post_unique_id = $_POST['unique_id'] : $post_unique_id = NULL;
But how do we use examples above with functions and return, example:
function filter_gender_request($data) {
preg_match('/(fe)?male/i', $data, $data);
isset($data[0]) && return $data[0]; // It doesn't work here with return
}
At the same time, if I state the following, instead of isset($data[0]) && return $data[0]; then everything works as expected:
if (isset($data[0]) ) {
return $data[0];
}
What am I doing wrong here? If the very first and shortest example works outside of function flawlessly, why then it doesn't work with return?
Is there a possibility to use shorthands with return?
With your current syntax, what do you expect your function to return when $data[0] is not set? Surely you don't expect your function to not return anything, depending upon a condition.
The only alternative I see is the ternary operator, where you return something other than $data[0] when it is not set:
return isset($data[0]) ? $data[0] : null;
For future googlers.
Use php 7 null coalesce (??) operator
return $data[0] ?? null;
Your amazing shortcut is actually rather hideous code. You are abusing the ternary operator, and that code is actually far LESS readable AND less maintainable than if you'd written it out. People expect ternaries to perform a test and return an either/or value. Performing assignment within it is NOT normal behavior.
The problem with your code is you are trying to execute a return statement as part of the ternary expression. The ternary operator generally results in an assignment as in:
$message = is_error() ? get_error() : 'No Errors';
This results in an assignment to $message based on the return value of is_error(). Your code is trying to process a program control statement within the operation. return cannot be assigned to the variable.
For this reason, what the other users have posted are better options for your situation.
oke I don't know what you are doing but this should work:
return ( isset($data[0]) ? $data[0] : false);
Agreeing with what has been answered here, that shorthand is harder to read once you've gone away from it and come back, or worse, another developer in the future.
Imagine yourself with even a small 500 line script file, with 40 lines of shorthand elseif as you use it, would you be ok trying to add or change code?
Especially when the subject or content is not something you're familiar with, it becomes a headache to debug or make additions.
This is much more manageable and doesn't matter what it's about, it's just code:
if ($var == 'unicorns')
{
$this->remove_horn;
}
elseif ($var == 'horse')
{
$this->glue_on_horn;
}
else
{
$this->must_be_a_zebra;
}
just saying

Why is not possible to combine 'continue' keyword in expression?

Why this is not possible to accomplish?
foreach($arr as $k => $v)
{
if($condition) { $obj->myMethod() && continue; }
}
After $obj->myMethod() gets evaluated then the keyword continue is evaluated (executed), resulting in skipping the current iteration.
EDIT: i'm asking this because something like:
if($error) { $log->fatal('Something weird happened.') && continue; }
is single line and self-explanatory.
continue is a statement not an expression.
And never the twain shall meet.
You can't put a statement in an expression. (What would echo false && continue; print?)
Instead, use an if, which can contain statements.
You cannot evaluate continue as a condition. The continue keyword does not work the same way as in other languages. In PHP, depending on context continue and break can be somewhat synonymous, consider this construct:
<?php
switch ($months)
{
// start with vowels
case 'august':
break;
case 'april':
continue; // exactly the same as "break" !!!
default:
return 'OK';
}
throw new StartsWithVowelException('Months with vowels are creepy');
?>
While we are on the topic, the break and continue keywords have a feature in PHP that make them a bit more interesting and powerful than their peers in other languages.
Both can be given a numerical argument when used in a loop that indicates how many loops to continue through or break out of. For example, here is an example that restarts the execution of an outer loop from within an inner one::
<?php
//
// verify that each sub array contains the given value
//
$lowerval = strtolower($value);
foreach ($TwoDArray as $otherArray)
{
foreach ($otherArray as $value)
{
if (strtolower($value) == $lowerval)
{
// we found the value -- this one definitely has it.
continue 2;
}
}
// if we've reached here, then the inner loop doesn't have the
// value. ¡aiiee!
}
?>
Hope this helps you out with these 2 constructs, good-luck.
continue is a statement. In PHP a statement and an expression are two different things, statements cannot be evaluated because they do not by nature return true or false which is a requirement for evaluation in PHP.
In PHP you'd have to do something like:
if(test()) continue;

How to reduce the number of if-else statements in PHP?

I found that there are many if-else statements, especially nested if else statements, these statements make my code less readable. How to reduce the number of if else statements in PHP?
My tips are as follows:
1.Use a switch statement when it is suitable;
2.use exit() statement when it is feasible;
3. Use ternary statement when it is feasible;
Are there other tips that can reduce if else statements, especially nested if-else statements?
Try to use "early return" when possible in order to reduce nesting depth. Try to use boolean expression evaluation.
Example:
function foo($param)
{
$ret = false;
if(userIsLoggedIn()) {
if(is_array($param)) {
if($param['count'] > 0) {
$ret = true;
}
else {
$ret = false;
}
}
}
return $ret;
}
You could rewrite this like:
function foo($param)
{
if(!userIsLoggedIn()) return false;
if(!is_array($param)) return false;
return $param['count'] > 0;
}
Refactor your code into smaller work units. Too much conditional logic is a code-smell and usually indicates that your function needs to be refactored.
There is an official academic method to refactor and simplify a lot of if conditions, called Karnaugh mapping.
It takes in multiple test conditions and attempts to assist in creating simplified if statements that cover all the required cases.
You can learn more about it from wiki here.
Use the ternary operator, refactor your code, write a function or a class which does all the necessary if else statements.
I work on a lot of code thats full of ever evolving business logic and needs to be modified every other day. Two tips that's certainly helped me keep up with the modifications are: avoid all else statements and return/exit as soon as possible. Never get into deep nesting -> create sub routines/functions.
Replacing all else statements with negated if statements makes your code much easier to read top to bottom (the proximity of the condtion and the code block):
# business logic block
if ( $condition ) {
# do something
# code code code
} else {
# code code code
return;
}
# refactored:
if ( ! $contition ) {
# code code code
return;
}
if ( $condition ) {
# code code code
}
Secondly, return/exit as soon as possible. My opinion of course, but I don't see the point in running through any extra conditions/tests when once you've already determined the result of the subroutine, especially when you would like to read the code top to bottom. Removing all ambiguity makes things simpler.
To conclude, I like to avoid using else especially in long lists of BL. Return as soon as you know the result. If the nesting level is more than 2, create sub routines/functions.
polymorphism could get rid of a few as well, allthough harder to implement to reduce if/else in PHP as it is not type safe...
You can reduce the number of if/else codes by using ternary operator or null coalescing operator like this:
Using the ternary operator:
Variable = (Condition) ? (Statement1) : (Statement2);
$age = 20;
print ($age >= 18) ? "Adult" : "Not Adult";
Output:
Adult
By using the null coalescing operator:
// fetch the value of $_GET['user'] and returns 'not passed'
// if username is not passed
$username = $_GET['username'] ?? 'not passed';
print($username);
print("<br/>");
// Equivalent code using ternary operator
$username = isset($_GET['username']) ? $_GET['username'] : 'not passed';
print($username);
print("<br/>");
// Chaining ?? operation
$username = $_GET['username'] ?? $_POST['username'] ?? 'not passed';
print($username);
Output:
not passed
not passed
not passed

PHP: return a part of an if () { }

Let's say I have this code:
if (md5($_POST[$foo['bar']]) == $somemd5) {
doSomethingWith(md5($_POST[$foo['bar']]);
}
I could shorten that down by doing:
$value = md5($_POST[$foo['bar']];
if ($value == $somemd5) {
doSomethingWith($value);
}
But is there any pre-set variable that contains the first or second condition of the current if? Like for instance:
if (md5($_POST[$foo['bar']]) == $somemd5) {
doSomethingWith($if1);
}
May be a unnecessary way of doing it, but I'm just wondering.
No, but since the assignment itself is an expression, you can use the assignment as the conditional expression for the if statement.
if (($value = md5(..)) == $somemd5) { ... }
In general, though, you'll want to avoid embedding assignments into conditional expressions:
The code is denser and therefore harder to read, with more nested parentheses.
Mixing = and == in the same expression is just asking for them to get mixed up.
Since the if is just using the result of an expression, you can't access parts of it.
Just store the results of the functions in a variable, like you wrote in your second snippet.
IMHO your 2nd example (quoting below in case someone edits the question) is just ok. You can obscure the code with some tricks, but for me this is the best. In more complicated cases this advise may not apply.
$value = md5($_POST[foo['bar']];
if ($value) == $somemd5) {
doSomethingWith($value);
}

Categories