Jump to content


Photo

Filtering an array is breaking my site

arrayunset in_array wordpress

  • Please log in to reply
20 replies to this topic

#1 aikorei

aikorei

    Member

  • Members
  • PipPip
  • 29 posts
  • LocationSeattle, WA

Posted 12 February 2013 - 03:20 PM

I'm new to the site here, so I hope this is the right place for this post. It's also from a Wordpress site, but since Wordpress isn't the issue (and my [lack of] programming knowledge is), I figured this wouldn't fit on the Wordpress forums very well.

So here's my problem. I downloaded a plugin which I'm trying to modify, and it's breaking my site (internal server error), which always makes for a fun day. Here's the piece I'm inserting:

// ---START--- Add Buddypress 'Friends' filter.
$wpdb->show_errors();
$k_user_id = $current_user->ID;
$k_friends1 = $wpdb->get_col( "SELECT initiator_user_id FROM $wpdb->prefix . 'bp_friends' WHERE friends_user_id = $k_user_id AND is_confirmed = 1" );
$k_friends2 = $wpdb->get_col( "SELECT friends_user_id FROM $wpdb->prefix . 'bp_friends' WHERE initiator_user_id = $k_user_id AND is_confirmed = 1" );
$k_friends = array($k_friends1, $k_friends2);

foreach($workers as $x) {
if(!in_array($x, $k_friends, TRUE) {
unset($workers[$x]);
}
}
$wpdb->hide_errors();

The plugin has already defined the $workers variable, but I'd like to modify that variable by removing any values not contained in either of the two SQL queries. To provide more context, this plugin is an appointments plugin that I'm trying to integrate with Buddypress so that users can schedule appointments with each other, but only if they're friends.

I know just enough php to get myself in trouble, so I'm sure there's something that's very obvious to everyone else, but I'm not seeing it...and it's very likely to do with me not understanding exactly how the functions are actually working.

Any help would be very much appreciated.

Thanks!

#2 Jessica

Jessica

    This is not my name.

  • Gurus
  • 8,982 posts
  • LocationDallas, TX
  • Age:26

Posted 12 February 2013 - 03:22 PM

In the future you need to post the error you get as well as your code.

if(!in_array($x, $k_friends, TRUE) {
- You're missing a closing parenthesis.


Also in SQL you shouldn't put quotes around column names. 'bp_friends' makes it a string, and causes an error.

ALSO - Your're doing 2 queries when you have absolutely no need to. All of this logic could be done in one query.

Edited by Jessica, 12 February 2013 - 03:23 PM.

My goal in replying to posts is to help you become a better programmer, including learning how to debug your own code and research problems. For that reason, rather than posting the solution, I reply with tips and hints on how to find the solution yourself. See below for useful links when you get stuck.

How to Get Good Help: How to Ask Questions | Don't be a help vampire
Debugging Your Code: Debugging your SQL | What does a php function do? | What does a term mean? | Don't see any errors?
Things You Should Do: Normalize Your Data | use print_r() or var_dump()
Lulz: "Functions should not have side effects." - trq

Please take a look at my new PHP/Web Dev blog: The Web Mason - Thanks!!

#3 aikorei

aikorei

    Member

  • Members
  • PipPip
  • 29 posts
  • LocationSeattle, WA

Posted 12 February 2013 - 03:29 PM

Thanks, Jessica, for the extremely prompt reply. I totally missed the closing ).

As for the quotes around column names, the bp_friends is actually the table name. My understanding is that it needs to be a string to append it to Wordpress's table prefix (which in this case is not wp_ as is the case in most WP installs).

And honestly, I don't know enough about SQL to put both of those queries into one...not even sure where to start on that.

More generally, is my logic on the right track for what I'm attempting to do though?

Edit: The error was just a 500 internal server error.

Edited by aikorei, 12 February 2013 - 03:31 PM.


#4 Jessica

Jessica

    This is not my name.

  • Gurus
  • 8,982 posts
  • LocationDallas, TX
  • Age:26

Posted 12 February 2013 - 03:37 PM

If you don't see PHP errors, you need to enable error_reporting, set to E_ALL.

Table names should not be strings either. If you're having trouble appending them do it outside of the SQL in a separate string, but this should work:
$sql = "SELECT initiator_user_id FROM {$wpdb->prefix}bp_friends WHERE friends_user_id = $k_user_id AND is_confirmed = 1";
$k_friends1 = $wpdb->get_col($sql);

If I understand what you're trying to do, this should do it.

$sql = "SELECT IF((initiator_user_id = $k_user_id), friends_user_id, initiator_user_id) AS friend_id
FROM {$wpdb->prefix}bp_friends 
WHERE 
(friends_user_id = $k_user_id 
OR initiator_user_id = $k_user_id)
AND is_confirmed = 1";

Will get you one array of everyone who is a friend to $k_user_id.


For the final part "removing any values not contained in either of the two SQL queries" array_intersect should work.

Edited by Jessica, 12 February 2013 - 03:39 PM.

My goal in replying to posts is to help you become a better programmer, including learning how to debug your own code and research problems. For that reason, rather than posting the solution, I reply with tips and hints on how to find the solution yourself. See below for useful links when you get stuck.

How to Get Good Help: How to Ask Questions | Don't be a help vampire
Debugging Your Code: Debugging your SQL | What does a php function do? | What does a term mean? | Don't see any errors?
Things You Should Do: Normalize Your Data | use print_r() or var_dump()
Lulz: "Functions should not have side effects." - trq

Please take a look at my new PHP/Web Dev blog: The Web Mason - Thanks!!

#5 aikorei

aikorei

    Member

  • Members
  • PipPip
  • 29 posts
  • LocationSeattle, WA

Posted 12 February 2013 - 05:07 PM

Thanks so much for the responses, Jessica. I've verified that the SQL values are returning correctly, so thanks very much for the help there.

Now the last remaining piece I'm having is in actually removing the values that I don't want there. When I used array_intersect(), I didn't see any difference in the page output. I used

$k_workers = array_intersect($workers, $k_friends);

and updated subsequent variables to use this new variable, but there was no noticeable change in page output.

And just because I'm (apparently) stubborn I went back to my original foreach statement:

  foreach($workers as $x) {
   if(!in_array($x, $k_friends, TRUE)) {
    unset($workers[$x]);
   }
  }

I have a message printed immediately before and after this message to display the contents of the arrays I'm looking at to see what's actually happening here. When I load the page, the first echo() is printed, but then the page stops and nothing is displayed in the body content...I also don't see the echo() immediately after this. =) I think it's fairly safe to assume something in my foreach statement isn't working right.

And the array_intersect() function looks so straightforward it should be easy to see what the problem is...but I didn't see any problem.

#6 Barand

Barand

    Sen . ( ile || sei )

  • Gurus
  • 13,885 posts
  • LocationCheshire, UK

Posted 12 February 2013 - 05:14 PM

shouldn't it be array_diff()?

$k_workers = array_diff($workers, $k_friends);

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts
|baaSelect| generate js and php code for dynamic linked dropdowns

 


#7 aikorei

aikorei

    Member

  • Members
  • PipPip
  • 29 posts
  • LocationSeattle, WA

Posted 12 February 2013 - 05:21 PM

I dunno, I started learning php 2 weeks ago. =)

After referring to the manual though, I'm not sure array_dif() is what I want. Doesn't this function only return values from the first array that aren't in the second array? I actually want to only return values that are in the second array, which seems to be the array_intersect() function...unless I'm completely misunderstanding something.

Edit: I should probably explain what I do want more clearly. The $workers function comes with the plugin, and is used to generate a dropdown menu. I want to filter this array to only populate IDs that are also the user's "friends" (this comes from the SQL queries above). So if they're in $k_friends, then it's OK to leave them in $workers...otherwise, I'd like them to come out.

Edited by aikorei, 12 February 2013 - 05:23 PM.


#8 Barand

Barand

    Sen . ( ile || sei )

  • Gurus
  • 13,885 posts
  • LocationCheshire, UK

Posted 12 February 2013 - 05:49 PM

You're right. I read it wrongly.

perhaps if you give an example or two

$workers = array(1,2,3);
$friends = array(2,4)

$required = ???

Edited by Barand, 12 February 2013 - 05:52 PM.

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts
|baaSelect| generate js and php code for dynamic linked dropdowns

 


#9 Jessica

Jessica

    This is not my name.

  • Gurus
  • 8,982 posts
  • LocationDallas, TX
  • Age:26

Posted 12 February 2013 - 05:51 PM

In array intersect I think you want to switch the order of your arguments.
My goal in replying to posts is to help you become a better programmer, including learning how to debug your own code and research problems. For that reason, rather than posting the solution, I reply with tips and hints on how to find the solution yourself. See below for useful links when you get stuck.

How to Get Good Help: How to Ask Questions | Don't be a help vampire
Debugging Your Code: Debugging your SQL | What does a php function do? | What does a term mean? | Don't see any errors?
Things You Should Do: Normalize Your Data | use print_r() or var_dump()
Lulz: "Functions should not have side effects." - trq

Please take a look at my new PHP/Web Dev blog: The Web Mason - Thanks!!

#10 Jessica

Jessica

    This is not my name.

  • Gurus
  • 8,982 posts
  • LocationDallas, TX
  • Age:26

Posted 12 February 2013 - 05:53 PM

And if that isn't it then do a print_r on the 3 arrays
My goal in replying to posts is to help you become a better programmer, including learning how to debug your own code and research problems. For that reason, rather than posting the solution, I reply with tips and hints on how to find the solution yourself. See below for useful links when you get stuck.

How to Get Good Help: How to Ask Questions | Don't be a help vampire
Debugging Your Code: Debugging your SQL | What does a php function do? | What does a term mean? | Don't see any errors?
Things You Should Do: Normalize Your Data | use print_r() or var_dump()
Lulz: "Functions should not have side effects." - trq

Please take a look at my new PHP/Web Dev blog: The Web Mason - Thanks!!

#11 aikorei

aikorei

    Member

  • Members
  • PipPip
  • 29 posts
  • LocationSeattle, WA

Posted 12 February 2013 - 06:32 PM

OK, I'm obviously doing something wrong here. What I have total is:

// ---START--- Add Buddypress 'Friends' filter.
$wpdb->show_errors();
error_reporting(E_ALL);
$k_user_id = $current_user->ID;
$k_table = $wpdb->prefix . 'bp_friends';
$k_friends1 = $wpdb->get_col( "SELECT initiator_user_id FROM $k_table WHERE friend_user_id = $k_user_id AND is_confirmed = 1" );
$wpdb->print_error();
$k_friends2 = $wpdb->get_col( "SELECT friend_user_id FROM $k_table WHERE initiator_user_id = $k_user_id AND is_confirmed = 1" );
$wpdb->print_error();
$k_friends = array_merge($k_friends1, $k_friends2);
print_r($k_friends);

/*
foreach($workers as $x) {
if(!in_array($x, $k_friends, TRUE)) {
unset($workers[$x]);
}
}
*/

$k_workers = array_intersect($k_friends, $workers);
print_r($k_workers);


$wpdb->hide_errors();
// ---END---

When I try to load this page, right now all I get are the two SQL queries displayed above where the content of the page should be (however, no content populates after these queries):

WordPress database error: []
SELECT initiator_user_id FROM oyuvfn_bp_friends WHERE friend_user_id = 24 AND is_confirmed = 1
WordPress database error: []
SELECT friend_user_id FROM oyuvfn_bp_friends WHERE initiator_user_id = 24 AND is_confirmed = 1
Array ( [0] => 23 )

23 is the only value I'd expect, so that seems to be in working order.

However, as soon as I comment out this line thusly,

//$k_workers = array_intersect($k_friends, $workers);

The page loads just fine. (I've tried the $k_friends and $workers variables in both orders). And what's really frustrating here is that the $k_workers variable isn't even used after this line (the standard $workers variable is still used to populate the dropdown menu).

@Barand, to answer your question:

perhaps if you give an example or two

$workers = array(1,2,3);
$friends = array(2,4)


$required = ???


In this case, $required = 2. I only want to end up with values that are in both arrays (I'm checking the $workers variable against the $k_friends variable for common values...if they're in $workers, but not in $k_friends, they need to go away).

Edited by aikorei, 12 February 2013 - 06:34 PM.


#12 Barand

Barand

    Sen . ( ile || sei )

  • Gurus
  • 13,885 posts
  • LocationCheshire, UK

Posted 12 February 2013 - 06:37 PM

in which case

$workers = array(1,2,3);
$friends = array(2,4);

$res = array_intersect($workers, $friends);
echo '<pre>',print_r($res, true),'</pre>';

/*
result

Array
(
    [1] => 2
)


*/

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts
|baaSelect| generate js and php code for dynamic linked dropdowns

 


#13 aikorei

aikorei

    Member

  • Members
  • PipPip
  • 29 posts
  • LocationSeattle, WA

Posted 12 February 2013 - 06:43 PM

The page still isn't loading...

I reversed the order, as you have shown above, to this:

$k_workers = array_intersect($workers, $k_friends);

When I uncomment that line, the page still doesn't load. It breaks before reaching the print_r for that array (which is the very next line)....at least I assume so, since it never gets printed on the page.

#14 Jessica

Jessica

    This is not my name.

  • Gurus
  • 8,982 posts
  • LocationDallas, TX
  • Age:26

Posted 12 February 2013 - 06:52 PM

It must be other code on the page. You still need to enable error reporting.
My goal in replying to posts is to help you become a better programmer, including learning how to debug your own code and research problems. For that reason, rather than posting the solution, I reply with tips and hints on how to find the solution yourself. See below for useful links when you get stuck.

How to Get Good Help: How to Ask Questions | Don't be a help vampire
Debugging Your Code: Debugging your SQL | What does a php function do? | What does a term mean? | Don't see any errors?
Things You Should Do: Normalize Your Data | use print_r() or var_dump()
Lulz: "Functions should not have side effects." - trq

Please take a look at my new PHP/Web Dev blog: The Web Mason - Thanks!!

#15 aikorei

aikorei

    Member

  • Members
  • PipPip
  • 29 posts
  • LocationSeattle, WA

Posted 12 February 2013 - 06:54 PM

It must be other code on the page. You still need to enable error reporting.


OK, I admit I don't know how to do that. My second line down has a line that I thought would accomplish this, but obviously it hasn't worked (forgive my ignorance). Where should I look to find the results? (or correctly enable error reporting, for that matter)

Edited by aikorei, 12 February 2013 - 06:56 PM.


#16 aikorei

aikorei

    Member

  • Members
  • PipPip
  • 29 posts
  • LocationSeattle, WA

Posted 12 February 2013 - 07:37 PM

OK, so apparently I have an error_log file on my server. That's good to know...

I'm getting a fatal error for that line that's giving me a headache:

$k_workers = array_intersect($workers, $k_friends);

It says "PHP Catchable fatal error: Object of class stdClass could not be converted to string"

As far as I can tell, though, both of those values should be integers.

Edited by aikorei, 12 February 2013 - 07:39 PM.


#17 Barand

Barand

    Sen . ( ile || sei )

  • Gurus
  • 13,885 posts
  • LocationCheshire, UK

Posted 12 February 2013 - 07:47 PM

What do these give

var_dump($workers);
var_dump($k_friends);

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts
|baaSelect| generate js and php code for dynamic linked dropdowns

 


#18 aikorei

aikorei

    Member

  • Members
  • PipPip
  • 29 posts
  • LocationSeattle, WA

Posted 12 February 2013 - 10:29 PM

Wow. Thanks for bringing up var_dump. The $workers variable is a lot more complicated than I first realized from reviewing the code. $k_friends behaves exactly as I thought it would (since I created that variable, that's fairly fortunate) and only contains a few strings of user IDs:

array(3) { [0]=> string(2) "23" [1]=> string(2) "21" [2]=> string(2) "22" }

$workers is much more complicated, but the data I want is in there, I just don't know how to get it out:

array(7) { [0]=> object(stdClass)#131 (5) { ["ID"]=> string(1) "2" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } [1]=> object(stdClass)#127 (5) { ["ID"]=> string(1) "3" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } [2]=> object(stdClass)#126 (5) { ["ID"]=> string(2) "15" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } [3]=> object(stdClass)#125 (5) { ["ID"]=> string(2) "21" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } [4]=> object(stdClass)#113 (5) { ["ID"]=> string(2) "22" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } [5]=> object(stdClass)#112 (5) { ["ID"]=> string(2) "23" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } [6]=> object(stdClass)#111 (5) { ["ID"]=> string(2) "24" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } } 

So from what I gather, there are 7 objects in this array (which correspond with the 7 "service providers" I have listed on the site for testing). Within each of those objects I find the ID information I want to filter for (e.g.: [5]=> object(stdClass)#112 (5) { ["ID"] => string(2) "23"... the 23 is what I need to be comparing against the $k_friends array to see if it's present).

Can I do an array_intersect() in a two-dimensional (or whatever it is) array?

#19 aikorei

aikorei

    Member

  • Members
  • PipPip
  • 29 posts
  • LocationSeattle, WA

Posted 12 February 2013 - 11:51 PM

I tried to modify my foreach loop to the following:

  foreach($workers as $innerArray) {
   if(is_array($innerArray)) {
    foreach($innerArray as $x) {
	 if(!in_array($x, $k_friends, TRUE)) {
	  unset($workers[$innerArray]);
	 }
    }
   }
  }

The good news is that the page loads when I do this, and seems to function correctly. However, it doesn't actually seem to unset any of the first level arrays. The idea, if I understand right, is that I need to search the nested arrays for my value, and if it's not there then I need to unset the first-level array. I did a var_dump on the $workers array before and after my piece of code and it did exactly nothing. Any insights here?

#20 aikorei

aikorei

    Member

  • Members
  • PipPip
  • 29 posts
  • LocationSeattle, WA

Posted 13 February 2013 - 02:17 AM

After several hours in the trenches of syntax warfare, I finally produced (or stumbled upon):

  foreach( $workers as $key => $innerArray ) {
   foreach( $innerArray as $x => $y ) {
    if($x == 'ID' && !in_array($y, $k_friends, TRUE)) {
	 unset( $workers[$key] );
    }
   }
  }

This does what I need it to do.

Jessica, Barand...thanks so much to the both of you for your time and efforts. I really do appreciate it.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Cheap Linux VPS from $5
SSD Storage, 30 day Guarantee
1 TB of BW, 100% Network Uptime

AlphaBit.com