php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #20681 array_search(:object, :array) fails
Submitted: 2002-11-27 11:41 UTC Modified: 2002-12-21 10:02 UTC
From: dparks at verinform dot com Assigned:
Status: Closed Package: Feature/Change Request
PHP Version: 4.2.3 OS: Win 2K SP3
Private report: No CVE-ID: None
 [2002-11-27 11:41 UTC] dparks at verinform dot com
array_search() does not seem to work when the needle is an object.

Sample code:

<?php

class A {
	function A () {
	}
}

class B {
	function B () {
	}
}

$g_b = new B ();

$g_array = array ( new A (), 'test', $g_b );

$g_key = array_search(new A (), $g_array);
var_dump($g_key);

$g_key = array_search($g_b, $g_array);
var_dump($g_key);

$g_key = array_search('test', $g_array);
var_dump($g_key);

?>

Output:
<br />
<b>Warning</b>:  Wrong datatype for first argument in call to array_search in <b>C:\dparks\Documents\html\tmp.php</b> on line <b>17</b><br />
bool(false)
<br />
<b>Warning</b>:  Wrong datatype for first argument in call to array_search in <b>C:\dparks\Documents\html\tmp.php</b> on line <b>20</b><br />
bool(false)
int(1)

Environment:
This is PHP 4.2.3 (binary from Zend or PHP.net) running on Apache 2.0.40 on Win 2K SP3.

Please email me if you would like me to run more tests, or try another build (it may be awhile before I can try another build though -- someone else here had trouble with 4.3rc1 and I am behind schedule).

Thanks,

Daniel

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-11-27 11:48 UTC] dparks at verinform dot com
<?php

class A {
	function A () {
	}
}

class B {
	function B () {
	}
}

$g_b = new B ();

$g_array = array (
	array ( new A () ),
	array ( 'test' ),
	array ( $g_b ) );

$g_key = array_search(array ( new A () ), $g_array);
var_dump($g_key);

$g_key = array_search(array ( $g_b ), $g_array);
var_dump($g_key);

$g_key = array_search(array ( 'test' ), $g_array);
var_dump($g_key);

?>

Seems to work as I exect it to:

int(0)
int(2)
int(1)

Also, the original example still produces warnings and doesn't find the elements if you change the array_search() calls to in_array().
 [2002-11-27 14:08 UTC] moriyoshi@php.net
As it's been said enough that identity or equalness of two objects is somewhat obscure in ZendEngine1, I don't see any reason to implement this feature unless ZendEngine2 becomes ready for release versions.

So I'm reclassifying this report as a feature request in this point of view.

 [2002-11-27 14:31 UTC] dparks at verinform dot com
I don't understand what this has to do with how equality is handled by the Zend engine. The documentation states that array_search can accept "mixed" data in the first parameter, which would seem to imply that objects should work. They don't. Therefore, array_search() is broken. What am I missing?

Also, I have seen no mention in the PHP manual about how equality is handled by the Zend engine. Should I file a documentation bug?

Thanks,

Daniel
 [2002-11-28 14:02 UTC] moriyoshi@php.net
My apologies, I should have give more explanation on this.

The following script is nearly an equivalent of array_search().

<?php
function _array_search($needle, $haystack, $strict = false)
{
    reset($haystack);
    while ((list($key, $element) = each($haystack))) {
        if ($strict) {
            if ($element === $needle) {
                return $key;
            }
        } else {
            if ($element == $needle) {
                return $key;
            }
        }
    }
    return false;
}
?>

This function actually accepts objects as a needle, but array_search() doesn't. In this sense, array_search() should go along with objects as you said.

However IMO it might be too kind to offer this functionality.

<?php
    class foo {
        var $value;

        function foo($val) {
            $this->value = val;
        }
    }

    $a = new foo(1);
    $b = new foo(2);
    $c = $a;
    $d = &$a;

    var_dump($a == $b);
    var_dump($a == $c);
    var_dump($a == $d);
    var_dump($c == $d);
    var_dump($a === $b);
    var_dump($a === $c);
    var_dump($a === $d);
    var_dump($c === $d);
    var_dump($a == new foo(1));
    var_dump($a == new foo(2));
    var_dump($b === new foo(2));
?>

What do you think of the result? Some say this could be preferrable, but others couldn't.

That's the reason I said the function doesn't need that feature. Isn't this enough?

 [2002-12-05 16:12 UTC] dparks at verinform dot com
Yes, I understand now. I will be very happy when Zend Engine 2 is released!
 [2002-12-05 19:59 UTC] dparks at verinform dot com
Um, actually I was wrong about understanding. The code you posted contains this line:

$this->value = val;

Which means that all comparisons come out to true. Two of my coworkers missed this bug too, and so we all thought that comparing objects in PHP always returned true.

Since objects seem to be compared in a more or less rational fashion, it seems like array_search() and in_array() should be able to take objects as the needle. I understand that PHP is only slowly moving toward being OO (or something like it), but this should at least be documented.

Also, it should at least be documented that objects cannot be used as array indices.
 [2002-12-21 10:02 UTC] moriyoshi@php.net
I agree with you. Actually object oriented programming in PHP is somewhat troublesome, as numerous bug reports on this language feature shows.

BTW, I committed the patch for array_search() that enables to look up objects in an array properly under ZendEngine2.

Thank you for the report.

closing...

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu May 02 04:01:30 2024 UTC