Leo Jiang
Leo Jiang

Reputation: 26095

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?

Upvotes: 3

Views: 1679

Answers (7)

mickmackusa
mickmackusa

Reputation: 47903

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

Upvotes: 0

user7675
user7675

Reputation:

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;
}

Upvotes: 0

Agniva
Agniva

Reputation: 1

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.

Upvotes: 0

sissonb
sissonb

Reputation: 3780

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.

Upvotes: 1

AsTeR
AsTeR

Reputation: 7521

As the manual states break is for loop only.

Upvotes: 0

Madara's Ghost
Madara's Ghost

Reputation: 174967

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.

Upvotes: 3

MacMac
MacMac

Reputation: 35321

To "break" out of functions, you can use the return.

function somefunction()
{
    return;

    echo 'This will never get displayed';
}

Upvotes: 1

Related Questions