ZF-5393: Error when passing Zend_Amf_Server::setClass() an object instead of a string

Description

If you pass an object to Zend_Amf_Server and don't specify a namespace it will generate the following error:


Warning: strrpos() expects parameter 1 to be string, object given in /home/norm2782/library/Zend/Amf/Server.php on line 501

Propopsed patch:


// Use the class name as the name space by default. 
if ($namespace == '') {
    $className = is_object($class) ? get_class($class) : $class;
    
    $namespace = substr($className, 0, strrpos($className, '.'));
}

Comments

Set component

I don't experience this problem with version 1.7.2 of Zend_Amf_Server. I can call setClass(), passing it an object with no namespace, and I get no such error. I think this issue may have been resolved.

I'm actually using the latest trunk and I'm getting this error. Code to reproduce


class MyService
{
    /**
     * Returns foo
     *
     * @return string
     */
    public function foo()
    {
        return 'foo';
    }
}

require_once 'Zend/Amf/Server.php';

$server = new Zend_Amf_Server();
$server->setClass(new MyService());

Complete error:


Warning: strrpos() expects parameter 1 to be string, object given in /Users/norm2782/Projects/OSS/ZF/standard/trunk/library/Zend/Amf/Server.php on line 501

Catchable fatal error: Object of class MyService could not be converted to string in /Users/norm2782/Projects/OSS/ZF/standard/trunk/library/Zend/Amf/Server.php on line 501

Current code in Zend_Amf_Server (just did an SVN update):


public function setClass($class, $namespace = '', $argv = null)
{
    if (is_string($class) && !class_exists($class)){
        require_once 'Zend/Amf/Server/Exception.php';
        throw new Zend_Amf_Server_Exception('Invalid method or class');
    } elseif (!is_string($class) && !is_object($class)) {
        require_once 'Zend/Amf/Server/Exception.php';
        throw new Zend_Amf_Server_Exception('Invalid method or class; must be a classname or object');
    }

    $argv = null;
    if (2 < func_num_args()) {
        $argv = array_slice(func_get_args(), 2);
    }
    
    // Use the class name as the name space by default. 
    if ($namespace == '') { // EDIT: Evaluates as true, so next line is executed
        $namespace = substr($class, 0, strrpos($class, '.')); // EDIT: Calling substr() on an object... here's where it fails
    }
    $this->_methods[] = Zend_Server_Reflection::reflectClass($class, $argv, $namespace);
    $this->_buildDispatchTable();

    return $this;
}

Darby, do you have display_errors switched on? ;)

Resolved in revision 13581

It does not look like a unit test was written for this. Please don't mark an item as resolved without a corresponding unit test that tests the new feature.

Also do either of you have a use case for this that you could help me understand so that I can use it in the documentation as to why you would pass an instantiated object through setClass(). Thanks for the code submission and making Zend Amf better for everyone! Really appreciate the help!

Actually, I did add a unit test ; )

http://framework.zend.com/code/changelog/…

The primary use case for this is that Zend_Server_Reflection supports reflecting on an object. Because of this, it's better to have Zend_Amf_Server support this as well, because otherwise it would be unexpected behavior.

Awesome thanks!

Sorry, I wasn't using latest trunk version but the version included with 1.7.2. This issue says that it affects 1.7.2, but I can't see that it does.

When the object passed as argument is an instance of a class whose constructor requires arguments, an instantiation error is raised on service call. I'm using 1.7.6 version of ZF. I've done some debug and found that in Zend/Amf/Server.php on line 165 (_dispatch method) the method's declaring class obtained by reflection is called on a NEW instance created with default construction and not on the object passed to setClass() as I expected. This behavior seems to raise the instantiation trouble I've mentioned; moreover, this behavior seems to be inconsistent w.r.t. the one observed, for example, in Zend/Json/Server component.

I'm sorry, the version of ZF I'm using is 1.7.4 and NOT 1.7.6 as I reported.