AlexMorley-Finch
AlexMorley-Finch

Reputation: 6955

PHP: 'method doesnt exist', but it does

I have this strange error,

When I call $element_attrs = $element -> attributes(); I get a notice saying the attribute method does not exist:

Call to undefined method stdClass::attributes();

now when I call die( get_class( $element ) ); Right before the attributes() call, php returns Select_Element which is correct!

Form_Element contains the attribute(); method.

I am positive Select_Element extends Form_Element and both files are included indefinately.

HOWEVER

if I call:

if ( method_exists($element, "attributes") ) {
    $element_attrs = $element -> attributes();
}

IT WORKS! method_exists returns true, and attributes() is called! but when I remove the if command, I get the error notice again...

What the hell is going on!

CODE

interface Element{
    public function __construct( $element );
    public function parse();
}

class Form_Element implements Element{

    protected $element;

    public function __construct($json_element){
        $this -> element = $json_element;
    }

    public function parse(){
        // Removed parsing code, unrelated
    }

    ... removed unrelated methods ...

    public function attributes( $key = null, $value = null ){
        if ( is_null( $key ) ){
            return $this -> element -> attributes;
        }
        else{
            $this -> element -> attributes -> $key = $value;
        }
    }
}

class Select_Element extends Form_Element implements Element{

    public function __construct( $element ) {
        parent::__construct( $element );
    }

    public function parse(){
        // Removed parsing code, unrelated
    }
}

and this is where the code is called in a Form class :

// note: $this -> elements is an array of Form_Element objects

public function edit_form($name_of_element, $name_of_value, $value){
    foreach ( $this -> elements as $element ){
        if ( method_exists($element, "attributes") ) {
            $element_attrs = $element -> attributes();
        }
        if ( $element_attrs -> name == $name_of_element ){
            switch ( $name_of_value ){
                case "selected" :
                    $element -> selected( $value );
                    break;
                case "options" :
                    $element -> options( $value );
                    break;
                case "value" :
                    $element -> value( $value );
                    break;
                // add more support as needed
            }
        }
    }
}

Does anybody know why PHP thinks attributes(); doesnt exist? Even though method_exists($element, "attributes"); returns true ?

Upvotes: 3

Views: 1789

Answers (2)

Narek
Narek

Reputation: 3823

Probably you write die() after first step of your loop, but got error in other steps.

Change die( get_class( $element ) ); to print( get_class( $element ).'<br/>' ); and you'll see in which line you got error, and probably in that line attribute will be empty.

Upvotes: 1

Pekka
Pekka

Reputation: 449385

You say you are in a loop with this.

Most likely, the code you show is called twice, once with $element being the desired object, and once not - when you use method_exists(), the code walks past that point, and if you don't use it, it crashes.

When you use die(), the loop terminates at the first element. But that is not necessarily the element that is causing the problem.

The error message

Call to undefined method stdClass::attributes();

supports this: note the stdClass where it should read Form_Element.

So you need to find out why $element is not always the object you want it to be.

Upvotes: 3

Related Questions