Jump to content

Foreach only runs once [solved]


madsrh

Recommended Posts

Hi. Can anyone tell me why this code only adds one menu item to my wordpress nav? I'm sure this could be done with an array, but I couldn't figure out how.

add_filter( 'wp_list_pages', 'my_menu_link' );add_filter( 'wp_nav_menu_items', 'my_menu_link' ); function my_menu_link($items) {	global $wp_query; $CustomMenuLinks;$CustomMenuLinks["Gmail"] = "www.gmail.com";$CustomMenuLinks["YouTube"] = "www.youtube.com";$CustomMenuLinks["aaaaaaaa"] = "www.sdsaaaaaaaaa.com";$class ='menu-item'; foreach( $CustomMenuLinks as $title=> $url){	$menu_link = '<li class="'.$class.'"><a href="'.$url.'">'.$title.'</a></li>';			$items = $items . $menu_link;return $items;	}}

//MadsRH

Edited by madsrh
Link to comment
Share on other sites

I think, first of all, that you should be initializing the variable as an array:$CustomMenuLinks = array(); I'm a bit surprised that no errors are being shown for trying to treat an undefined variable as an array in the first place.

Link to comment
Share on other sites

You have return statement inside your foreach loop which is causing to break the loop and exiting from the function on first iteration even if there is more element on the array.

Link to comment
Share on other sites

You have return statement inside your foreach loop which is causing to break the loop and exiting from the function on first iteration even if there is more element on the array.
That's right. I hadn't looked carefully, it looks like that return statement was meant to be on the next line. I still recommend initializing the array properly.
Link to comment
Share on other sites

I still recommend initializing the array properly
Yes, I agree on that.@OPwithout initializing $itemsthis
$items = $items . $menu_link;
would throw Notice which should be avoidedYou probably have error reporting in lower level or it is off to show. If you set (Recommended for developing) "error_reporting:E_ALL" and "error_display:on" in php.ini, it would show all the errorsincluding notices.
Link to comment
Share on other sites

Maybe it's just me, but I don't see any undefined variables? $items is defined in the function arguments. And arrays don't need to be initiated as arrays before you can add items without notices. Although, a faster way to append data to an existing string is doing this:

$items .= $menu_link;

Link to comment
Share on other sites

Thanks for all the feedback!!! :Pleased:

I think, first of all, that you should be initializing the variable as an array:$CustomMenuLinks = array();
I'm a newbie with PHP, so I'm just trying to understand how this works. Would an array look like this:
$CustomMenuLinks = array(	  "YouTube" => "www.youtube.com",	  "Gmail" => "www.gmail.com",);

You have return statement inside your foreach loop which is causing to break the loop and exiting from the function on first iteration even if there is more element on the array.
But I can't do it without the Return command. I've tried echo, but it doesn't help me.
Link to comment
Share on other sites

Maybe it's just me, but I don't see any undefined variables? $items is defined in the function arguments. And arrays don't need to be initiated as arrays before you can add items without notices. Although, a faster way to append data to an existing string is doing this:
$items .= $menu_link;

its not defined as anything in the function arguments. $items is how the variable that your passing _into_ the function is seen by the function. if you pass a string to that function, $items will be a string. if you pass a boolean, $items will be a boolean. Edited by thescientist
Link to comment
Share on other sites

Thanks for all the feedback!!! :Pleased: I'm a newbie with PHP, so I'm just trying to understand how this works. Would an array look like this:
$CustomMenuLinks = array(	  "YouTube" => "www.youtube.com",	  "Gmail" => "www.gmail.com",);

But I can't do it without the Return command. I've tried echo, but it doesn't help me.

return after the loop is complete.
Link to comment
Share on other sites

aaaaaaaaahhhhhh of course! That makes sense. It works perfect now!!! Thanks for all the help everyone :good:
in all fairness, Birbal mentioned that in post 3
You have return statement inside your foreach loop which is causing to break the loop and exiting from the function on first iteration even if there is more element on the array.
Link to comment
Share on other sites

its not defined as anything in the function arguments. $items is how the variable that your passing _into_ the function is seen by the function. if you pass a string to that function, $items will be a string. if you pass a boolean, $items will be a boolean.
I'm not sure what your point is. People were saying that $items is undefined, and accessing it would throw error notices. Which is not true. That's all. @OP: By the way, the array you had in your first post is just fine, don't let people confuse you. What you don't need is this:
$CustomMenuLinks;

... this does literally nothing, you can remove that line. And the array you just posted in your last post is fine too. It's fine either way.

Link to comment
Share on other sites

I'm not sure what your point is. People were saying that $items is undefined, and accessing it would throw error notices. Which is not true. That's all.
Where are you seeing my_menu_links being called in the OP's code? I would never assume that an argument has a value without seeing the function actually being called and the value being passed in. What about this my_menu_links($items) { } actually gives it a value? Maybe if the OP did this my_menu_link($items = '') {} but he didn't. so you can only speculate what $items is, and given that, you cant say for certain is is defined. Edited by thescientist
Link to comment
Share on other sites

And arrays don't need to be initiated as arrays before you can add items without notices.
yes it is true it dont need to declare explicitly variable as array, as same with other data types in loosly type language like PHP. No one here is confusing OP. It was certain that the issue was not for variable declaration. its not about it wont work or would throw errors, its about best practice which people should follow.
Link to comment
Share on other sites

Where are you seeing my_menu_links being called in the OP's code? I would never assume that an argument has a value without seeing the function actually being called and the value being passed in. What about this my_menu_links($items) { } actually gives it a value? Maybe if the OP did this my_menu_link($items = '') {} but he didn't. so you can only speculate what $items is, and given that, you cant say for certain is is defined.
Unless you're suggesting to cast all function arguments inside the function, I'm still not sure what your point is. $items is defined in the arguments, so it's always there. I can say for certain that it's defined because the function must be called with at least one argument. Even if you pass an undefined variable to the function, it will exist inside it, because it's defined in the argument. It will throw a notice where you call the function with the undefined variable.Furthermore, PHP will automatically cast the variables if necessary. If your function expects a string, and you're passing boolean TRUE, then PHP will convert it to '1' (without errors and notices).So when I'm doing $items .= $menu_link;, and $items is boolean true, it'll be '1 + whatever $menu_link contains'Same for integers, floats, etc... Except for arrays, but then again you can set the array type hint in your function to prevent errors.
function foo(array $myArray){    // $myArray can only be an array}

Link to comment
Share on other sites

defined is not the same as declared. Defined implies it has a type. (string, int, bool, etc.). And its not casting per se, it is providing a default value for the variable in the event the function is called without a value being passed; it would default to variable of type string with a value of empty string. But if someone passed an array, it would be an array. Either way, as mentioned by Birbal, just because the language allows it, doesn't mean its the best way to do it. I am always in favor of declaring my variables with default values at the beginning of their respective scope, at a minimum to provide clarity and intent to other developers, and of course to myself. And especially if I was writing library/API code, I would type check myself at the top of the method and probably throw an exception myself if someone passed in the wrong type.

Edited by thescientist
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...