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

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.

Related

What do you call this implicit loop syntax in PHP?

Scratching my head looking at this render function:
public function render($layout, $echo=false)
{
if ($this->_escape)
{
foreach ($this as $n => &$v)
{
if (0) {
} elseif (is_array($v) or is_object($v)) {
$this->htmlspecialchars_recursive($v);
} elseif (is_scalar($v)) {$v=htmlspecialchars($v,ENT_QUOTES,null,false);}
}
}
if ($echo) { $this->insert($layout); return true;
} else { ob_start(); $this->insert($layout); return ob_get_clean(); }
}
I understand that the ampersand means that we're modifying the contents of the collection (associative array in this case?) that we're iterating over, but what's up with this if (0) business?
There's some sort of implicit iteration stuff going on here, what's this called in PHP?
It's called "this refactor is incomplete".
It appears that there was originally 3 if cases used, and the first one became no longer valid. Instead of just removing it, the author changed it to if(0), which will always evaluate to false.
The correct way would be to modify it to this
if (is_array($v) or is_object($v)) {
$this->htmlspecialchars_recursive($v);
}
elseif (is_scalar($v)) {
$v=htmlspecialchars($v,ENT_QUOTES,null,false);
}
The ampersand in the foreach is the reference symbol. $this is an object, and $n will be the property names and $v will be the property value. Without the & you get a copy of the property value. With the & you get a reference to the property, ie: you are changing the actual property value.

How to skip lines in php

I'm struggling in finding a way to correctly do this logic.
If (this thing is null)
Skip it
Else
Don't skip it
I tried with if/else and while loops but each one will crash the program. I test something like this:
(inside a foreach)
if($value->getThing() == NULL) {
//HOW TO SKIP???
//I try to 'set' this thing
$value->setThing(0); //BUT IT Doesn't work because it's an associated object...
} else {
$value->getThing();
}
And tried this:
(inside foreach)
while ($value->getThing() != NULL) {
$value->getThing();
//Do Calculation...
}
Both just crash when it gets to the thing thats null. I know why but I can't figure out how to skip the null thing.
and if you can't tell, I'm a newbie. But I'm learning.
EDIT: The thing is null in the db.
Try this code :
foreach($values as $value){
if(!is_null($value->getThing())){
#do calculation
}
}
For "skipping" an entry you can use "continue".
foreach($array as $key => $value){
if($value['foo'] == null){
continue;
}
//Do the calculation
}
..or perhaps:
foreach($array as $key => $value){
if(is_null($value['foo'])){
//Null value treatment
continue;
}
//Do the calculation
}
What you are actually looking for is the NOT IS Operator as I like to call it.
foreach ($things as $thing) {
if (!is_null($thing)) {
// Do the stuff that you wanna do
}
}
The above dummy code teaches that you do not have to use an else. It also shows the is_null() function which checks if something is actually NULL. Furthermore it shows the ! operator that can also be translated to NOT IS.
What !is_null() actually says is: "If the return value of this function, variable and so on is not NULL..."
Good luck.
Try this:
$names = file('name.txt');
// To check the number of lines
echo count($names).'<br>';
foreach($names as $name) {
echo $name.'<br>';
}

PHP - how to use a 'break;' in a ternary operator

I have the following function. It compares one value to each value in an array.
function catExists($id) {
$cats = getCats();
foreach ($cats as $cat) {
if ($cat['id'] == $id) {
return true;break;
} else {
return false;
}
}
}
I'm trying to shorten the whole thing by using ternary operators.
function catExists($id) {
foreach (getCats() as $cat) return ($cat['id'] == $id) ? true : false;
}
The problem I have is that I can't use break; when the condition turns to true. i.e The returned value will keep reverting back to false unless the true condition is at the end of the array.
Is their a way that this can be achieved on a single line?
Thanks
That's not what ternary operators are meant to do. Keep it simple (KISS). You don't need the break statement at all since return ends the function execution and returns the program control back to the main program.
I'd write it this way:
function catExists($id) {
foreach (getCats() as $cat) {
if ($cat['id'] == $id)
return true;
}
return false; // 'return true' never happened, so return false
}
If you really want to make it one line, you could use array_column() in conjunction with array_search() like so:
function catExists($id) {
return array_search($id, array_column(getCats(), 'id')) !== FALSE;
}

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.

Combine three "complex" PHP conditions in one perfect php snippet

I'm stuck in Drupal Panels / PHP Access plugins.
At least, now I found the three conditions to create my final snippet. the purpose of it is to return TRUE; if "condition1 is TRUE" OR "condition2 is TRUE" OR "condition3 is TRUE". I found a lot of similar questions, but the last condition force me to post here to find the right way to do this.
Condition 1:
// At least $view1->result has result.
$view1 = views_get_view('sp_onglet_videos');
$view1->set_display('views-tab-embed_1');
$output1 = $view1->preview();
if ($view1->result) {
return TRUE;
}
Condition 2 (same thing):
// At least $view2->result has result.
$view2 = views_get_view('sp_onglet_audio');
$view2->set_display('views-tab-default');
$output2 = $view2->preview();
if ($view2->result) {
return TRUE;
}
Condition 3 is more complex:
// Checks for content in the field field_txt_videos.
if (isset($contexts['argument_nid_1']->data-> field_txt_videos)) {
$field = $contexts['argument_nid_1']->data-> field_txt_videos;
if (is_null($field)) {
return FALSE;
}
if (is_array($field)) {
foreach ($field as $key => $val) {
if (is_array($val)) {
$field[$key] = array_filter($val);
}
}
$field = array_filter($field);
return count($field);
}
if (is_string($field) && trim($field) == '') {
return FALSE;
}
if ($field) {
return TRUE;
}
return FALSE;
}
I would like to have something clean (and functional) like this:
if ($view1->result && $view2->result && $field) {
return TRUE;
}
But it's to tricky for my php knowledge. Need a little help !
You want to save the result of the 3rd condition (into a variable) and use this result to run your final condition/query. But you can query the 3rd condition if it is a function.
It is better to properly space your code and use plenty of newlines.
However, PHP does have some pretty cool tricks to do assignment inside conditional statements.
if(($view1 = views_get_view('sp_onglet_videos')) AND $view1->set_display('views-tab-embed_1') AND ($output1 = $view1->preview()) AND $view1->result) return TRUE;
However, as you can see this code is a mess - don't do it unless your assignment is really small. Take this simple security check at the top of a PHP file:
<?php defined('BASE_PATH') OR die('Not Allowed');

Categories