1

I've got an array of data containing stdClass Objects that looks like this if I do print_r($results):

Array ( 
    [0] => stdClass Object ( 
        [ID] => 1 
    ) 
    [1] => stdClass Object ( 
        [ID] => 2 
    ) 
    [2] => stdClass Object ( 
        [ID] => 3 
    ) 
) 

I need to get the values of ID as a comma seperated string. To do this, I intially tried to do implode(",", $results) but this gave errors due to the stdClass Objects. So after a reasonable amount of reading and checking SO etc, I've got to a point where I can access the value of ID on a given record: $results[0]->ID.

However, I don't know how many rows there will be due to this data coming from a DB query. So, I need to iterate through each row and add this to a string.

I -amongst other things- tried this:

$i = 0;
foreach ($results as $result){

    //$result->ID;
    $result[$i]['ID'];
    $i++

}

These return an error:

Fatal error: Uncaught Error: Cannot use object of type stdClass as array

I've literally no idea at this point how to get all the ID values as a comma seperated string.

I've checked out numerous SO posts include the following: - 'Cannot use object of type stdClass as array' using Wordpress - iterating through a stdClass object in PHP - PHP Loop stdClass Object

UPDATE I'm getting this data as follows:

global $wpdb;    
$query = "Select wp_users.ID from wp_users where wp_users.ID not in ( select wp_usermeta.user_id from wp_usermeta where wp_usermeta.meta_key = 'grp2_profile_visiblity' and wp_usermeta.meta_value = 1 order by wp_usermeta.user_id ) order by wp_users.ID"; 
$results = $wpdb->get_results( $query, OBJECT );

Thanks

miken32
  • 42,008
  • 16
  • 111
  • 154
Phill Healey
  • 3,084
  • 2
  • 33
  • 67
  • How do get the data from the DB query - you may be able to do this there rather than mangle the output. – Nigel Ren Dec 21 '18 at 17:07
  • Your provided code would return more than that error, since you've got an undefined constant `i` being used which I'm guessing you meant to be `$i` which doesn't make sense given the data you've shown. You may want to read up on how `foreach` works, the idea is to get rid of the iteration counter used in old fashioned `for` loops. – miken32 Dec 21 '18 at 17:46
  • @miken32 - Yeah that is messed up. I was frustrated and trying to type quickly whilst entertaining kids. – Phill Healey Dec 21 '18 at 17:58
  • No worries, give my answer a try and let me know how it works for you (once you get the kids to bed!) – miken32 Dec 21 '18 at 18:04
  • @miken32 Ive added the queury to my question. – Phill Healey Dec 21 '18 at 18:05
  • I think you're on the right track doing this on the PHP side. Much easier than trying to muck about with MySQL, especially through Wordpress' database API. – miken32 Dec 21 '18 at 18:07

2 Answers2

2

You're getting-

Fatal error: Uncaught Error: Cannot use object of type stdClass as array

Fatal error because PHP array's are accessible using bracket [] notation and object's are arrow ->

Let's do this way using foreach() and implode() to get comma separated id's like 1,2,3 but I also think you can fix it from your DB query end without mangling output here :) hope this helps sir.

$expected = [];
foreach ($results as $key=>$obj){
    $expected[] = $obj->ID;
}
echo implode(',',$expected);

WORKING DEMO: https://3v4l.org/oUCkL

A l w a y s S u n n y
  • 36,497
  • 8
  • 60
  • 103
  • Ive added the SQL query as an edit to my OP. If you can suggest a way to get the desired results, via SQL I'd love to learn it. Thanks. – Phill Healey Dec 21 '18 at 18:45
1

This is easily enough done with array_column() to get the ID values; it works just as well with objects as it does with arrays.

<?php
// some sample data
$results = json_decode('[{"ID": 1}, {"ID": 2}, {"ID": 3}]');

$return = implode(",", array_column($results, "ID"));
echo $return;

Output:

1,2,3
miken32
  • 42,008
  • 16
  • 111
  • 154
  • That’s surprising but as long as you got something that works. PHP’s functions for handling arrays are generally faster than loops. They’re certainly prettier ;) – miken32 Dec 21 '18 at 18:46
  • Ive added the SQL query as an edit to my OP. If you can suggest a way to get the desired results, via SQL I'd love to learn it. Thanks. – Phill Healey Dec 21 '18 at 18:46
  • I think you’d be looking for `GROUP_CONCAT` but I’ve never used it myself. – miken32 Dec 21 '18 at 18:47
  • Yeah, your solution was my preffered option until I checked the performance tab of Curious_Mind's demo. I then tried your's and it came out slower and slightly more memory. https://3v4l.org/oUCkL – Phill Healey Dec 21 '18 at 18:48
  • 1
    I would take those numbers with a grain of salt; 15 MB of memory for a 3 element array suggests that is almost entirely PHP overhead, and there's huge variability showing in the execution times between different minor versions. Larger arrays will give clearer ideas of performance, e.g. [this](https://3v4l.org/cE1NA/perf#output) versus [this](https://3v4l.org/6UQYF/perf#output), but even that is pretty inconclusive. – miken32 Dec 21 '18 at 19:37
  • (To be clear, I'm not trying to be an ass because you didn't accept my answer. I'd recommend sticking with whatever code you're most comfortable editing and maintaining, rather than worry about micro-optimizations when it runs. My personal preference is to get rid of `foreach` loops where I can, but I'm aware it's largely an aesthetic choice and I'd consider both these answers functionally equivalent.) – miken32 Dec 21 '18 at 19:37
  • Not at all. I appreciate it. I had nothing else to go on. I was initally in favour of solution as it's clearly simpler and I imagined it would be more efficient. But, that site seemed to suggest that the foreach was faster,despite the odd results. However, since your reputation is way higher than mine and Curious_Mind's -and you made such a passioned plea ;-) - I'll switch to yours. – Phill Healey Dec 21 '18 at 20:26