Zend Framework

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

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 1.7.2
  • Fix Version/s: 1.7.3
  • Component/s: Zend_Amf
  • Labels:
    None

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, '.'));
}

Issue Links

Activity

Hide
Satoru Yoshida added a comment -

Set component

Show
Satoru Yoshida added a comment - Set component
Hide
Darby Felton added a comment -

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.

Show
Darby Felton added a comment - 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.
Hide
Jurrien Stutterheim added a comment -

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?

Show
Jurrien Stutterheim added a comment - 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?
Hide
Jurrien Stutterheim added a comment -

Resolved in revision 13581

Show
Jurrien Stutterheim added a comment - Resolved in revision 13581
Hide
Wade Arnold added a comment -

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.

Show
Wade Arnold added a comment - 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.
Hide
Wade Arnold added a comment -

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!

Show
Wade Arnold added a comment - 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!
Hide
Jurrien Stutterheim added a comment -

Actually, I did add a unit test ; )

http://framework.zend.com/code/changelog/Zend_Framework/?cs=13581

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.

Show
Jurrien Stutterheim added a comment - Actually, I did add a unit test ; ) http://framework.zend.com/code/changelog/Zend_Framework/?cs=13581 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.
Hide
Wade Arnold added a comment -

Awesome thanks!

Show
Wade Arnold added a comment - Awesome thanks!
Hide
Darby Felton added a comment -

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.

Show
Darby Felton added a comment - 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.
Hide
Andrea Montemaggio added a comment -

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.

Show
Andrea Montemaggio added a comment - 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.
Hide
Andrea Montemaggio added a comment -

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

Show
Andrea Montemaggio added a comment - I'm sorry, the version of ZF I'm using is 1.7.4 and NOT 1.7.6 as I reported.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: