ZF2-509: Zend\Di\DefinitionList with ClassDefinition collecting supertypes problem

Issue Type: Bug Created: 2012-08-30T06:43:11.000+0000 Last Updated: 2012-09-13T01:22:43.000+0000 Status: Resolved Fix version(s): - Next Mini Release (04/Oct/12)

Reporter: Tomoaki Kosugi (kosugiatkips) Assignee: Matthew Weier O'Phinney (matthew) Tags: - Zend\Di

Related issues: Attachments:


If DefinitionList has multiple classDefinition, Zend\Di\DefinitionList::getClassSupertypes or Zend\Di\DefinitionList::getInstantiator call each classDefinition. A classDefinition instance is per-Class definition. And ClassDefinition::getClassSupertypes($class) returns simply its supertypes . In this flow, the class-name-parameter is meaningless.…

DefinitionInterface expects getClassSupertypes to return array filtered with the classname parameter.

public function getClassSupertypes($class)
    if ($this->class !== $class) return array();
    return $this->supertypes;


Posted by Tomoaki Kosugi (kosugiatkips) on 2012-08-31T00:47:43.000+0000

I made up pull request about this.… And this is reproductive codes.

<pre class="highlight">

use Zend\Di\Definition\ClassDefinition;
use Zend\Di\DefinitionList;

$definitionClassA = new ClassDefinition("A");
$definitionClassB = new ClassDefinition("B");
$definitionList = new DefinitionList(array($definitionClassA, $definitionClassB));

$resultA = $definitionList->getClassSuperTypes("A");
$resultB = $definitionList->getClassSuperTypes("B");


A: array("superA") B: array("superB")

Actual: A: array(2) { [0]=> string(6) "superA" [1]=> string(6) "superB" } B: array(2) { [0]=> string(6) "superA" [1]=> string(6) "superB" }

Posted by Tomoaki Kosugi (kosugiatkips) on 2012-08-31T10:34:39.000+0000

And these cause wrong injection to new-instance. Zend\Di\Di::newInstance

<pre class="highlight">
        foreach ($definitions->getClassSupertypes($class) as $supertype) {
            $injectionMethods[$supertype] = $definitions->getMethods($supertype);
        $this->handleInjectDependencies($instance, $injectionMethods, $params, $class, $alias, $name);

it collects wrong injectionMethods from wrong supertypes. and so pass to handleInjectDependencies. In Zend\Di\Di::handleInjectDependencies, It uses wrong injection methods and wrong parameters.

Posted by Alrik Zachert (az) on 2012-08-31T12:42:25.000+0000

I think it should be discussed whether the ClassDefinition in its current implementation should implement DefinitionInterface. As i understand the documentation of DefinitionInterface, it describes/is a collection of class definitions, whereas ClassDefinition is a single class definition...

So, in my opinion, the above solution solves a bug that was caused by a deeper, conceptually problem.

Shouldn't Array-, Builder-, Compiler- and RuntimeDefinitions hold a map of ClassDefinition instances? More abstract: Map DefinitionInterface

pros: - operate with ClassDefinitionInterface instances within DefinitionInterfaces rather then with "plain" arrays - more intuitive API (avoid "if($this->class === $class) ..." - absurdity for a specific class definition)

cons: - BC break

Posted by Tomoaki Kosugi (kosugiatkips) on 2012-08-31T15:18:58.000+0000

I agree with you about DefinitionInterface concepts.

ArrayDefinition is "Class definitions based on a given array", so it is a Definition for multiple class. ClassDefinition's description is that "Class definitions for a single class". I feel it should be abstractive signature representing the class structure. For example, Zend\Di\Config::configure makes an ArrayDefinition that it has a collection of ClassDefinition instances.

On the other hand, we already have a Definition's collection ,the DefinitionList. I think the current implementation is not bad. A DefinitionInterface usually has multiple class, but specially it has only a single class. And so single is specially, it should have codes "if($this->class === $class) ..."

Posted by Marco Pivetta (ocramius) on 2012-09-05T08:30:28.000+0000

[~az] I think there's nothing wrong in having a ClassDefinition implement the DefinitionInterface. It is just a "map" with a single element in it. What is weird is that $definition->getClassSupertypes($class) seems to retrieve wrong data.

Posted by Marco Pivetta (ocramius) on 2012-09-05T08:56:00.000+0000

As told on the mailing list, PR #2265 seems fine to me, but should also add checks on the rest of the ClassDefinition

Posted by Tomoaki Kosugi (kosugiatkips) on 2012-09-05T14:07:35.000+0000

I closed the pull-requests #2265,#2277 .And I remade a commit squashed. Please review it.


Posted by Tomoaki Kosugi (kosugiatkips) on 2012-09-06T07:01:12.000+0000

I'm sorry. #2295 had several problems. I made an amendment in it.

Posted by Tomoaki Kosugi (kosugiatkips) on 2012-09-12T11:23:52.000+0000

fixed in 2.0.1 Thanks.

Have you found an issue?

See the Overview section for more details.


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

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