Skip to content

Commit

Permalink
Fixed Zend\Di\DependnecyInjector matching of preferred classes with i…
Browse files Browse the repository at this point in the history
…s_subclass_of due to a bug in PHP: https://bugs.php.net/bug.php?id=53727
  • Loading branch information
Ralph Schindler committed Jun 29, 2011
1 parent 800bb09 commit c2863d5
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 5 deletions.
23 changes: 18 additions & 5 deletions library/Zend/Di/DependencyInjector.php
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,20 @@ protected function handleInjectionMethodForObject($object, $method, $params, $al
*/
protected function resolveMethodParameters($class, $method, array $userParams, $isInstantiator, $alias)
{
static $isSubclassFunc = null;
static $isSubclassFuncCache = null;

$isSubclassFunc = function($class, $type) use (&$isSubclassFuncCache) {
/* @see https://bugs.php.net/bug.php?id=53727 */
if ($isSubclassFuncCache === null) {
$isSubclassFuncCache = array();
}
if (!array_key_exists($class, $isSubclassFuncCache)) {
$isSubclassFuncCache[$class] = class_parents($class, true) + class_implements($class, true);
}
return (isset($isSubclassFuncCache[$class][$type]));
};

$resolvedParams = array();

$injectionMethodParameters = $this->definition->getInjectionMethodParameters($class, $method);
Expand All @@ -296,7 +310,6 @@ protected function resolveMethodParameters($class, $method, array $userParams, $
$computedLookupParams = array();

foreach ($injectionMethodParameters as $name => $type) {
//$computedValueParams[$name] = null;

// first consult user provided parameters
if (isset($userParams[$name])) {
Expand Down Expand Up @@ -326,9 +339,9 @@ protected function resolveMethodParameters($class, $method, array $userParams, $
foreach ($pInstances as $pInstance) {
$pInstanceClass = ($this->instanceManager->hasAlias($pInstance)) ?
$this->instanceManager->getClassFromAlias($pInstance) : $pInstance;
if ($pInstanceClass === $type || is_subclass_of($pInstanceClass, $type)) {
if ($pInstanceClass === $type || $isSubclassFunc($pInstanceClass, $type)) {
$computedLookupParams[$name] = array($pInstance, $pInstanceClass);
continue;
continue 2;
}
}
}
Expand All @@ -339,9 +352,9 @@ protected function resolveMethodParameters($class, $method, array $userParams, $
foreach ($pInstances as $pInstance) {
$pInstanceClass = ($this->instanceManager->hasAlias($pInstance)) ?
$this->instanceManager->getClassFromAlias($pInstance) : $pInstance;
if ($pInstanceClass === $type || is_subclass_of($pInstanceClass, $type)) {
if ($pInstanceClass === $type || $isSubclassFunc($pInstanceClass, $type)) {
$computedLookupParams[$name] = array($pInstance, $pInstanceClass);
continue;
continue 2;
}
}
}
Expand Down
20 changes: 20 additions & 0 deletions tests/Zend/Di/DependencyInjectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,4 +279,24 @@ public function testNewInstanceThrowsExceptionWhenEnteringInMiddleOfCircularDepe
$di->newInstance('ZendTest\Di\TestAsset\CircularClasses\D');
}

/**
* Fix for PHP bug in is_subclass_of
*
* @see https://bugs.php.net/bug.php?id=53727
*/
public function testNewInstanceWillUsePreferredClassForInterfaceHints()
{
$di = new DependencyInjector();
$di->getInstanceManager()->addPreferredInstance(
'ZendTest\Di\TestAsset\PreferredImplClasses\A',
'ZendTest\Di\TestAsset\PreferredImplClasses\BofA'
);

$c = $di->get('ZendTest\Di\TestAsset\PreferredImplClasses\C');
$a = $c->a;
$this->assertType('ZendTest\Di\TestAsset\PreferredImplClasses\BofA', $a);
$d = $di->get('ZendTest\Di\TestAsset\PreferredImplClasses\D');
$this->assertSame($a, $d->a);
}

}
7 changes: 7 additions & 0 deletions tests/Zend/Di/TestAsset/PreferredImplClasses/A.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace ZendTest\Di\TestAsset\PreferredImplClasses;

interface A
{
}
7 changes: 7 additions & 0 deletions tests/Zend/Di/TestAsset/PreferredImplClasses/BofA.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace ZendTest\Di\TestAsset\PreferredImplClasses;

class BofA implements A
{
}
12 changes: 12 additions & 0 deletions tests/Zend/Di/TestAsset/PreferredImplClasses/C.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace ZendTest\Di\TestAsset\PreferredImplClasses;

class C
{
public $a = null;
public function setA(A $a)
{
$this->a = $a;
}
}
8 changes: 8 additions & 0 deletions tests/Zend/Di/TestAsset/PreferredImplClasses/D.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace ZendTest\Di\TestAsset\PreferredImplClasses;

class D extends C
{

}

0 comments on commit c2863d5

Please sign in to comment.