If (x OR y) Performance - php

I have a performance related question regarding how PHP evaluates the OR operator in a conditional.
I have a conditional that calls 2 functions, both returning booleans:
The first is a simple, fast function - simpleFunction()
The second is a more intensive function that queries the DB - intensiveFunction()
I could write the conditional like this, so that if the first, simple function returned TRUE, the second more intense function would not be executed:
if ( simpleFunction() ) {
// Do Stuff
} elseif ( intensiveFunction() ) {
// Do the same stuff (redundant code)
}
My question is, when using and OR operator in a PHP conditional, if the first condition (on the left of the operator) is TRUE, will the second function (on the right side of the operator) be executed?
if ( simpleFunction() || intensiveFunction() ) {
//Do Stuff
}
This conditional will be running inside a loop, so I would like to avoid running intensiveFunction() on every iteration.

I believe that once a truthy is found in an or operation, then the statement ends and returns true,
Whereas in an and operation, it runs until it finds a falsey.

Additionally compare this script testing the various logical operators:
<pre>
<?php
function test($bool) {
echo "I was executed\n";
return $bool;
}
echo "<b>||-Operator</b>\n";
if (test(true) || test(true)) {
;
}
echo "<b>|-Operator</b>\n";
if (test(true) | test(true)) {
;
}
echo "<b>or-Operator</b>\n";
if (test(true) or test(true)) {
;
}
echo "<b>&&-Operator</b>\n";
if (test(false) && test(true)) {
;
}
echo "<b>&-Operator</b>\n";
if (test(false) & test(true)) {
;
}
echo "<b>and-Operator</b>\n";
if (test(false) and test(true)) {
;
}
?>
</pre>
Output:
||-Operator
I was executed
|-Operator
I was executed
I was executed
or-Operator
I was executed
&&-Operator
I was executed
&-Operator
I was executed
I was executed
and-Operator
I was executed
Note that | and & always execute the second part even when the output can't be true (&-Operator) anymore or can't become false (|-Operator) anymore.

As Neal pointed out, I should have just tested this:
$hasRun = 'Intesive Function Has NOT Run';
function simpleFunction() {
return TRUE;
}
function intensiveFunction() {
$hasRun = 'Intesive Function Has Run';
return TRUE;
}
if ( simpleFunction() || intensiveFunction() ) {
echo $hasRun;
}
//Result: Intesive Function Has NOT Run function
So yes, once the first condition returns TRUE the conditional exits and the second condition is not evaluated.

Related

php return statement in if statement

Maybe my question is somehow elementary or stupid, however i need to verify this.
I have a php function "functionA" which is repeatedely called in a for loop:
...
for($j=0; $j<$n_samples;$j++) {
if($type=='triband') {
functionA($arg1,$arg2);
}
}
...
and my functionA:
...
functionA($arg1,$arg2) {
$wide_avg_txon = substr($bit_sequence,0,1);
if($wide_avg_txon==0)
{
echo " ---> is OFF...<br />";
}
else
{
echo " ---> is ON...<br />";
// if is ON then skip execution of code inside the function
return;
}
// DO SOME STUFF!
}
...
So simply i do not want to execute the rest of code inside functionA if "$wide_avg_txon==1" and i just want to continue executing the for loop for the next iteration!
Is the above code going to work? What is the difference between: 'return' and 'return false'? Is 'return false' going also to work:
...
if($wide_avg_txon==0)
{
echo " ---> is OFF...<br />";
}
else
{
echo " ---> is ON...<br />";
// if is ON then skip execution of code inside the function
return false;
}
thanks!
Your return will work because you are not interested in the result that is being returned. You just want to continue the for-loop.
If you had a code construction that tested something and you want to know the result of the testing then you could use return false to let the rest of the code know the test failed.
Your functionA will work perfectly, but for readability's sake it may be better to format it this way:
...
function functionA($arg1, $arg2) {
$wide_avg_txon = substr($bit_sequence,0,1);
// if is ON then skip execution of code inside this function
if ($wide_avg_txon != 0) {
echo " ---> is ON...<br />";
return;
}
echo " ---> is OFF...<br />";
// DO SOME STUFF!
}
...
The difference is that you immediately disqualify the "ON" condition that you don't want, and exit the function as quickly as possible. Then the rest of the function is working on whatever it is you want to do, rather that sitting inside of an if statement block.
Function will be stopped after the return statement. You can read more about here:
http://php.net/manual/tr/function.return.php
As as example you can do something like this to test this:
<?php
$_SESSION['a'] = "Naber";
function a(){
return;
unset($_SESSION['a']);
}
a(); // Let see that is session unset?
echo $_SESSION['a'];
?>
Thanks
return false returns false, a boolean. return will return NULL. Neither will execute any subsequent code.
So to expand upon RST's answer, both returns would not satisfy an if condition:
if(functionA($arg1,$arg2))
echo'foo';
else
echo'bar';
bar would be echoed.
Where this might be useful is if you have:
$return=functionA($arg1,$arg2);
if($return===NULL)
echo'Nothing happened';
elseif($return===false)
echo'Something happened and it was false';
else
echo'Something happened and it was true';
NULL is pretty useful.

how to use "class_exists" conditional inside if...elseif

I have a chain of if...elseif...else statements likes so:
if (!empty($video_meta)) {
echo 'foo';
} elseif ( WPCOM_Liveblog::is_liveblog_post() ) {
echo 'bar';
} elseif (has_tag('featured')) {
echo 'foobar';
}
The second elseif statement is reliant on a particular WordPress plugin (liveblog) being activated. In the event that the plugin is not active, the function will throw a fatal error because the class WPCOM_Liveblog doesn't exist.
I tried to use a nested IF statement like this
if (has_post_format('video')) {
echo 'foo';
} elseif (class_exists('WPCOM_Liveblog')) {
if ( WPCOM_Liveblog::is_liveblog_post() ) {
echo'bar';
}
} elseif (has_tag('featured')) {
echo 'foobar';
}
If the second condition is false, it never gets to the final elseif for obvious reasons. The class_exists condition always evaluates to true and the chain of if statements terminate.
I cannot use a simple && conditional, since I'm looking for a deactivated plugin, and the second condition will simply throw a fatal error for an unknown class.
I also cannot change the order of the if...elseif statements. There is a purpose behind the order.
This feels like a simple PHP question, but I'm stumped. Is there anyway I can nest another condition in the elseif? Basically, if the first part of the condition is true, execute the second condition. If both true, return true to the elseif. If the class doesn't exist, then the second conditional check never fires.
In PHP your conditions are executed in order from left to right so you can do the following:
elseif (class_exists('WPCOM_Liveblog') && WPCOM_Liveblog::is_liveblog_post()) {
echo'bar';
}
Proof (via ideone): http://ideone.com/fAN2YK
Or, you could move the test that fails out of the loop:
$plugin_loaded = false;
if ( class_exists('WPCOM_Liveblog') ) {
$plugin_loaded = ( WPCOM_Liveblog::is_liveblog_post() ) ? true : false;
}
if (has_post_format('video')) {
echo 'foo';
} elseif ($plugin_loaded ) {
echo 'bar';
} elseif (has_tag('featured')) {
echo 'foobar';
}

When is it useful to use a PHP function that ends with return;

What are the best usages of functions that end with "return;" and what are the advantages of writing a function that ends this way?
Example:
function MyFunction() {
// (do something)
return;
}
Thank you
You shouldn't, I would always use return null; so that it is an explicit declaration of what is returned (even if it is null). I'm sure this is also in one of the PSR specs as well, but I don't know them well. To confirm that return; === return null;:
function test() {
return;
}
var_dump(test());
// NULL
As to when you would want to return null;..any function that returns something, should always return something. So maybe if you have a function that gathers and returns a value from a DB, and an error occurs:
public function retrieveData()
{
$data = DB::retrieve();
if(!$data) {
return null;
}
return $data;
}
However, a lot of functions that may have errors just return true/false on success or failure so you won't necessarily use this often.
My main point to drive home: if you don't want/need to return anything, don't return anything.
A return; says only "thats the end". Mostly useful in following examples:
function test($string) {
if(empty($string)) {
return; // If the variable is empty, then stop to work!
}
echo $string;
}
A simple example is that you can write a PHP function that spits out formatted HTML:
function printHeader($value)
{
echo "<h1>$value</h1>";
return;
}
However, since you are not returning anything, the return statement is unnecessary and can be left out.
If you are talking about a empty return;, I can think of one example, if you have code that should be executed under a condition, and more code that should be executed if that condition is not met.
function MyFunction() {
if(a < 1) {
// (do something)
return;
}
// If a >= 0 it executes the code above and the code below
// Do something else
}

Nested if statements, any possible way of cleaning?

I have checked a few other questions but they don't really give me the answer I expect..
My code is a like this..
private function handle()
{
if()
{
if(!condition)
{
if(!condition)
{
if(!condition)
{
if(!condition))
{
if(!condition)
{
if(!condition)
{
if(!condition)
{
if(!condition)
{
if(!condition)
{
code
}
return;
}
return;
}
return;
}
return;
}
return;
}
return;
}
return;
}
return;
}
return;
}
}
In my opinion it is readable but messy, sadly I haven't found really a way of making it look 'pretty'. Any ideas?
EDIT: Each return is different.
EDIT2: Gave an answer of my own, thanks everybody!
Conditions can be merged by a && operator..It works form left to right, which means, as soon as the any one starting from left fails, it stops evaluating the condition..
if($a) {
if($b) {
}
}
can be replaced by
if($a && $b) {
}
Use a variable check, or combine the conditions into fewer IF statements.
Variable check like so:
$execute = TRUE;
// Opposite of what you want, e.g. if you want $a only to be TRUE, do $a !== TRUE
if (condition) {
$execute = FALSE;
}
...
// If all the conditions were met, then everything is OK
if($execute === TRUE) {
// code
}else {
// return
}
Edit:
Variable check can be preferably to combining IF statements if you want more control on what returns, e.g. something specific happens if a certain condition fails, which combining conditions can not always allow for.
Like already posted use
if(condition1&&condition2){}
or if this will not work, you can also use function which stops as soon as a condition is true
function some(){
if(!conditon 1){return 0;}
if(condition 2) {return 1;}
}
this provides more power as second if works only if first doesn't satisfy.
You must choose based on your requirements. Sometimes though nested loops are unavoidable.
I thought it out and have found a nice way of doing it, basically I'll make a method for each basic condition, and I'll call them in an if statement with the bitwise AND operator (&), which don't short-circuit.
/**
* nonsql_condition - It means it doesn't check with the database
*
* sql_condition - It means it does check with the database.
*/
if(!$this->nonsql_condition() & !$this->nonsql_condition() & !$this->nonsql_condition() & !$this->nonsql_condition())
{
if(!$this->sql_condition())
{
return error;
}
if(!$this->sql_condition())
{
return error;
}
code;
}
This allows me to use fewer lines of code in my method, plus also not doing unnecessary queries to my database.

Breaking out of multiple functions (short circuiting) in PHP

I want to return multiple nested functions in PHP. It's possible to break out of multiple loops by adding a number after "break". Eg.
while(1)
while(1)
while(1)
break 3;
Can I do a circuit break while calling a sequence of functions?
Not that I know of, it's also not very healthy of a design, as the parent and grandparent functions in question will never know of the break. You should throw an exception and catch it on the parent, which in turn will throw an exception and catch it on the grandparent etc.
To "break" out of functions, you can use the return.
function somefunction()
{
return;
echo 'This will never get displayed';
}
Another solution would be to add a condition to each while.
while(1 && $isTrue)
while(1 && $isTrue)
while(1 && $isTrue)
$isTrue = false;
break;
Although I don't think this is a very clean approach.
As the manual states break is for loop only.
What I do in such cases is that have an exception return value(or object) and do value check on return value at every function return point to make sure that the situation is propagated or handled appropriately, be careful while doing recursions though, you might completely fold up the tree by mistake....btw if it is a simple exit on error kind of situation you can also use exceptions.
It's possible to return a special result from child functions that indicates a specific condition has been met. WordPress uses WP_Error and is_wp_error() for this sort of operation. Any number of nested functions can check to see if a called function returned an error state, and opt to pass that error up the chain rather than continue with processing.
Example:
function outer() {
$result = inner();
// pass failure back to parent
if( is_wp_error($result) ) {
return $result;
}
// other processing
return $final_result;
}
function inner() {
if( some_condition() ) {
// generate an error
return new WP_Error( 'code', 'message' );
}
return $other_result;
}
$result = outer();
// did we get an error?
if( is_wp_error($result) ) {
echo 'Something went wrong.';
} else {
echo $result;
}
Yes, you can very simply construct a "body-less" while() or if() block. Typically, you will see PSR-12 compliant PHP code using {} to bookend the body of the loop/condition block, but the body is not required. Writing a semicolon at the end of the line will be sufficient and your IDE will not complain about bad syntax.
Returning a truthy value from each function will be an adequate indicator that the following function is authorised for execution.
This will provide the "short circuit" functionality that is desired without creating nested control structures or passing variables into different scopes.
I'll demonstrate with a battery of generic functions:
function echo1T() {
echo "1";
return true;
}
function echo2T() {
echo "2";
return true;
}
function echo3T() {
echo "3";
return true;
}
function echo1F() {
echo "1";
return false;
}
function echo2F() {
echo "2";
return false;
}
function echo3F() {
echo "3";
return false;
}
Code: (Demo with more scenarios)
while (echo1T() && echo2F() && echo3T()); // outputs: 12
if (echo1T() && echo2F() && echo3T()); // outputs: 12
$return = echo1T() && echo2F() && echo3T(); // outputs: 12
var_export($return); // outputs false

Categories