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

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

Related

How to make true/false statements

It's not because I want to know how to do this instead of which one is faster..
How would I make a statement true or false ?
I want this:
if $var = true {
do this
} else{
do this
}
I'm aleady using a foreach but I thought something like this:
if($myvar == 'True'){
echo copy from array
} else {
echo none
}
Normally, if your variable contains a boolean, all you have to do is:
if($myVar)
{
//do stuff
}
else
{
//do something else
}
You can also do this if it's clearer to you:
if($myVar == true)
{
//do stuff
}
else
{
//do something else
}
What's important is not to mistake the comparison operator (==) with the assignment (=) otherwise you'll end up with strange results. This happened in your initial statement in which you also forgot the parenthesis.
As for the "else" statement, it is automatically executed when the condition is false, which in this case would mean $myVar is actually false.

If (x OR y) Performance

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.

PHP if() state keeps evaluating to true even though it isn't

I'm having the toughest time figuring out this problem and I can't seem to find the answer.
Here's what I'm trying to do: I have different nav menus on my website depending on the section. I've already pre-built the different variations and on each page declare $linkbox_array, which is the array of links for my nav menu on that page. On certain pages I display horizontally and on others vertically. When vertical, I need a disclaimer to be added to the bottom of the stacked link boxes.
So my function is trying to say this: if the $linkbox_array is $general_linkboxes and the $bodyClass is "withSidebar", then echo out a disclaimer after array item 2. Otherwise, just echo out the array items.
So this is what I've written (forgive me if it sucks, I'm new to this):
function display_linkboxes($array) {
if ($linkbox_array == $general_linkboxes && $bodyClass = "withSidebar") {
foreach ($array as $linkbox) {
if ($linkbox == $array[2]) {
echo $linkbox;
global $general_disclaimer;
echo $general_disclaimer;
} else {
echo $linkbox;
}
}
} else {
foreach ($array as $linkbox) {
echo $linkbox;
}
}
}
The problem is that it keeps spitting out the $general_disclaimer even when the two conditions aren't true. I tried to deconstruct the function and figure out where I was going wrong and I realized my if statement always evaluates to true even if I put in jibberish. For example:
function display_linkboxes($array) {
if ($linkbox_array == $askjfdalfjk) {
foreach ($array as $linkbox) {
echo $linkbox;
}
}
}
This evaluates to true and displays the links even though $askjfdalfjk doesn't exist. Then I have the opposite problem below. This won't display the links even though the if statement should evaluate to true:
function display_linkboxes($array) {
if ($bodyClass == "withSidebar") {
foreach ($array as $linkbox) {
echo $linkbox;
}
}
}
What in the world am I doing wrong?!?! Any help is greatly appreciated!
In your code:
function display_linkboxes($array) {
if ($linkbox_array == $general_linkboxes && $bodyClass = "withSidebar") {
...
$linkbox_array, $general_linkboxes, and $bodyClass are not in scope for this function, which means they are both equal to each other in that neither of them exists. You need to either pass them as variables to the function (recommended), or change your code to the following:
function display_linkboxes($array) {
global $linkbox_array, $general_linkboxes, $bodyClass;
if ($linkbox_array == $general_linkboxes && $bodyClass == "withSidebar") {
...
I've edited this answer to include the = -> == fix on $bodyClass
Probably you set $linkbox_array outside of your function, then your function doesn't knoew it, unless you ...
function display_linkboxes($array) {
global $linkbox_array; // <------ now the variable exists within the function.
if ($linkbox_array == $askjfdalfjk) {
foreach ($array as $linkbox) {
echo $linkbox;
}
}
}
Same with $bodyClass
Your if conditional just needs a bit of refactoring:
if(($linkbox_array == $general_linkboxes) && ($bodyClass == "withSidebar")) {}
A single '=' is an assignment operation and will always evaluate to true.
A == is the conditional equals operation you were looking for.
Furthermore if you are checking for array equality and order matters to you then you should use the '===' operator which checks not just for the same elements but also the same order
Lastly you have a scoping issue - if your linkbox array is evaluating as equal to a null variable then it hasn't been defined. You can use the print_r() operation to check this. If the array is defined outside the function then you should pass it to the function as a parameter.

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