3

I have two arrays (records returned from a database query) that I'm merging. I then need to get a count of the elements in the combined array.

Here are the print_r results of the two original arrays:

Array(
    [0] => stdClass Object([id] => 25590)
    [1] => stdClass Object([id] => 40657)
    [2] => stdClass Object([id] => 60685)
    [3] => stdClass Object([id] => 61900)
    [4] => stdClass Object([id] => 65224)
)

Array(
    [0] => stdClass Object([id] => 88406)
)

Merged array created like this:

$licensed_users = array_unique(array_merge($lu, $lu2));

And the results of the merge (in this case there weren't any duplicates, but there could be, hence the array_unique)

Array(
    [0] => stdClass Object([id] => 25590)
    [1] => stdClass Object([id] => 40657)
    [2] => stdClass Object([id] => 60685)
    [3] => stdClass Object([id] => 61900)
    [4] => stdClass Object([id] => 65224)
    [5] => stdClass Object([id] => 88406)
)

The array is assigned to a session variable, to be used on another page:

    $_SESSION['licensed_users'] = $licensed_users;

I now want to know how many elements are in the merged array via the session variable.

count($_SESSION['licensed_users'])

I would expect this to return 6. Instead, it returns 1. Any idea why?

EDITED TO ADD CODE FOR @SURREALDREAMS

$_SESSION['licensed_users'] = array_unique(array_merge($lu, $lu2));
print_r($lu);
print_r($lu2);
print_r($_SESSION['licensed_users']);
echo "there are ". count($_SESSION['licensed_users']) . " licensed users";

This code returns the following:

$lu Array(
    [0] => stdClass Object([id] => 25590)
    [1] => stdClass Object([id] => 40657)
    [2] => stdClass Object([id] => 60685)
    [3] => stdClass Object([id] => 61900)
    [4] => stdClass Object([id] => 65224)
)

$lu2 Array(
    [0] => stdClass Object([id] => 88406)
)

$_SESSION['licensed_users'] Array(
    [0] => stdClass Object([id] => 25590)
)

The echo line returns 1.

If I try it the other way you suggested:

$licensed_users = array_unique(array_merge($lu, $lu2));
$_SESSION['licensed_users'] = $licensed_users;
echo "there are ". count($_SESSION['licensed_users'], COUNT_RECURSIVE) -1 . " licensed users";

the arrays returned have the same contents, but the echo line returns -1.

3
  • 1
    What does var_dump($licensed_users) show? Commented Dec 1, 2011 at 16:03
  • It's very strange how the assigning the unique merged arrays to the session variable only has 1 entry in the array. Try ditching the array_unique() function and see what happens. Commented Dec 1, 2011 at 16:45
  • @SurrealDreams - removing the array_unique() does give me the correct count in this case. But as I said in the original post, there are instances where there will be duplicates, and those need to be removed from the final array. Looping through the arrays and comparing each element is too high overhead - the example only has a small array, but in reality there could be thousands of elements. Commented Dec 1, 2011 at 16:49

3 Answers 3

1

It's counting the contents of $_SESSION['licensed_users'], which is 1 - your $licensed_users array. You could instead try:

count($_SESSION['licensed_users'], COUNT_RECURSIVE);

This will return 7. You could approach this knowing your structure and use:

count($_SESSION['licensed_users'], COUNT_RECURSIVE) -1;

Which returns the expected 6.

To simplify a bit more, consider this:

$_SESSION['licensed_users'] = array_unique(array_merge($lu, $lu2));

Then count($_SESSION['licensed_users']; should return 6.

Sign up to request clarification or add additional context in comments.

1 Comment

Nope, I tried your simplified version, and it still returns 1. And your other version returns something even stranger. I'm updating the OP to show what I tried and what it returned.
0

The issue is in the array_unique() call. From the documentation:

Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same.

Those objects are being converted to strings before being compared. You may have to manually prune them based on some other property.

4 Comments

Hmm. I'd really prefer to not have to loop through the array, run a conditional on each element, and basically rebuild them from scratch. Is there any way to convert an array of objects to an array of strings? (i.e. an existing function)
Sure, use array_map(). You define the callback function for each element in the array, so you could essentially do whatever you wanted with each object. I don't know much about what object you're using, but you could always do something like: $as_str = array_map( function($elem) { return $elem->asString(); }, $the_array);. I wouldn't be too worried about looping through the array and using a conditional. That's essentially what array_unique() is doing in the background.
That seems kind of labor-intensive. The arrays are returned by a query using ezSQL; I wonder if there's some param I can use in the query call that would just return an array of strings instead of an array of objects.
Giving you the answer flag because your comments prompted me to find the actual answer. Turns out there's a function in ezSQL that will return a single-dimension array of strings if you're only returning one column from a table. We apparently didn't have the most recent documentation, so I wasn't aware of it until I went looking.
0
<?
$my_array = array(0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5);

$your_array = array(0 => 1, 1 => 2);

$the_array = array_unique(array_merge($my_array, $your_array)); 

$_SESSION['test'] = $the_array;

print_r($the_array);

echo(count($_SESSION['test']));
?>

yields:

Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 ) 5

<?
$my_array = array(0 => 1, 1 => 1, 2 => 1, 3 => 1, 4 => 1);

$your_array = array(0 => 1, 1 => 1);

$the_array = array_unique(array_merge($my_array, $your_array)); 

$_SESSION['test'] = $the_array;

print_r($the_array);

echo(count($_SESSION['test']));
?>

yields:

Array ( [0] => 1 ) 1

my guess would be your stdClass Object([id] => xxxxx) are all the same...

EDIT

another test:

<?
$my_array = array(0 => array('id' => 11), 1 => array('id' => 22), 
                  2 => array('id' => 22), 3 => array('id' => 33), 4 => array('id' => 445));

$your_array = array(0 => array('id' => 11), 1 => array('id' => 7908));

$the_array = array_unique(array_merge($my_array, $your_array), SORT_REGULAR); 

$_SESSION['test'] = $the_array;

print_r($the_array);

echo(count($_SESSION['test']));
?>

yields:

Array ( [0] => Array ( [id] => 11 ) [1] => Array ( [id] => 22 ) [3] => Array ( [id] => 33 ) [4] => Array ( [id] => 445 ) [6] => Array ( [id] => 7908 ) ) 5

I think this is what you're looking for.

3 Comments

I'm sorry, I have no idea what you're trying to illustrate here. I posted the print_r results of the arrays; the ids are NOT all the same.
Essentially what he's trying to show is that the array_unique() function only inspects the values of items in an array. Simply having different keys is not enough. For array_unique(), array(0 => 'apple') is exactly the same as array('banana' => 'apple').
my guess is that PHP can't see any difference between all your stdClass Object([id] => nnnnn)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.