Issues

ZF-5754: ArrayOfTypeComplex does not allow recursive types

Issue Type: Bug Created: 2009-02-11T17:11:33.000+0000 Last Updated: 2009-02-12T15:45:57.000+0000 Status: Resolved Fix version(s): - 1.7.5 (16/Feb/09)

Reporter: Quentin Zervaas (qzervaas) Assignee: Benjamin Eberlei (beberlei) Tags: - Zend_Soap_Wsdl

Related issues: - ZF-5604

Attachments: - DefaultComplexType2.php

Description

Since the fix of job #5604, it's not possible to have recursive types.

The following code fails in ZF 1.7.4 (Fatal error: Maximum function nesting level of '100' reached, aborting!)

<pre class="highlight">
<?php
    ini_set('include_path', dirname(__FILE__) . '/1.7.4');

    require_once('Zend/Soap/AutoDiscover.php');
    require_once('Zend/Soap/Wsdl/Strategy/ArrayOfTypeComplex.php');

    class WebservicesTestClass
    {
        /**
         * @var WebservicesTestClass[]
         */
        public $children = array();
    }

    class WebservicesTest
    {
        /**
         * @return WebservicesTestClass[]
         */
        public function test()
        {
            return array();
        }
    }

    $auto = new Zend_Soap_AutoDiscover('Zend_Soap_Wsdl_Strategy_ArrayOfTypeComplex');
    $auto->setClass('WebservicesTest');
    $auto->handle();
?>

Note however when working in <= 1.7.3pl1, the type is incorrectly returned in the WSDL as WebservicesTestClass[] rather than ArrayOfWebservicesTestClass

Comments

Posted by Quentin Zervaas (qzervaas) on 2009-02-11T17:21:31.000+0000

Further testing indicates that if not specifying the types as arrays, it also fails in older versions

Sample code:

<pre class="highlight">
<?php
    ini_set('include_path', dirname(__FILE__) . '/1.7.3');

    require_once('Zend/Soap/AutoDiscover.php');
    require_once('Zend/Soap/Wsdl/Strategy/ArrayOfTypeComplex.php');

    class WebservicesTestClass
    {
        /**
         * @var WebservicesTestClass
         */
        public $child;
    }

    class WebservicesTest
    {
        /**
         * @return WebservicesTestClass
         */
        public function test()
        {
            return array();
        }
    }

    $auto = new Zend_Soap_AutoDiscover('Zend_Soap_Wsdl_Strategy_ArrayOfTypeComplex');
    $auto->setClass('WebservicesTest');
    $auto->handle();
?>

The Zend_Soap_Wsdl_Strategy_DefaultComplexType->addComplexType() method needs to check what types are currently being added since it won't yet be available in $this->getContext()->getTypes()

Posted by Quentin Zervaas (qzervaas) on 2009-02-11T17:29:41.000+0000

The following patch solves the issue:

<pre class="highlight">
24a25,26
>     protected static $_processing = array();
> 
32a35,40
>         if (in_array($type, self::$_processing)) {
>             return;
>         }
> 
>         self::$_processing[$type] = $type;
> 
65a74
>         unset(self::$_processing[$type]);

Posted by Quentin Zervaas (qzervaas) on 2009-02-11T17:31:42.000+0000

This file contains my changes to Zend/Soap/Wsdl/Strategy/DefaultComplexType.php

Posted by Benjamin Eberlei (beberlei) on 2009-02-12T11:10:49.000+0000

confirmed! i'll look into it for the next mini release.

Posted by Benjamin Eberlei (beberlei) on 2009-02-12T14:45:14.000+0000

your patch prevents recursion from happening, but it doesnt fix the bug. Your nested value is empty because you return nothing from the function.

Actually in the current implementation recursion objects is not even possible i think. I am changing this to throw an exception.

Posted by Benjamin Eberlei (beberlei) on 2009-02-12T14:56:24.000+0000

Fix in trunk and merged back into 1.7 release branch.

Throw an Exception on possible infinite recursion now.

Posted by Quentin Zervaas (qzervaas) on 2009-02-12T15:00:21.000+0000

This doesn't really solve my issue... why should it not be possible to recurse into itself?

Can you not just change my implementation slightly to return "tns:$type" rather than just return?

Posted by Benjamin Eberlei (beberlei) on 2009-02-12T15:28:53.000+0000

well if you require recursion, then you might need to stop somewhere. but wsdl types are rather strict, so how would you do that? The current ArrayOfTypeComplex does not support minOccurs which is the only way to handle this situation according to http://stackoverflow.com/questions/148988/… (i couldnt find it in the XSD doc, its dull to read).

I will have to look into it for the future, but i can't support this right now because if have to test it further.

So long the infinite recursion protection will be added.

Would that be ok?

The problem with returning tns:$type is, it might be the wrong name.

Back to your recursive example, how does it "stop" when you return "tns:$type" anyways? Doesnt SOAP then require an infinite stream of objects in your definition?

Posted by Benjamin Eberlei (beberlei) on 2009-02-12T15:42:59.000+0000

closed the issue by fault, now resolved.

Posted by Quentin Zervaas (qzervaas) on 2009-02-12T15:45:56.000+0000

Fair enough. I thought you could effectively "end the recursion" by returning a null object.

Is it worth creating a new feature request in this tracker to support such functionality?

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts