Skip to content

Instantly share code, notes, and snippets.

@noopable
Created September 5, 2012 01:22
Show Gist options
  • Save noopable/3628859 to your computer and use it in GitHub Desktop.
Save noopable/3628859 to your computer and use it in GitHub Desktop.
Bad injection problem (Zend\Di ZF 2.0.0 rc7)
<?php
// Bad injection problem in ZF 2.0.0 rc7
// Foo Module namespace
namespace Foo {
class AdminArea {
protected $isMemberOnly = true;
public function setMemberOnly($memberOnly)
{
$this->isMemberOnly = (bool) $bool;
}
public function isMemberOnly()
{
return $this->isMemberOnly;
}
}
}
// Bug Module namespace
namespace Bug {
class Resource {
protected $isMemberOnly;
public function setMemberOnly($memberOnly)
{
$this->isMemberOnly = (bool) $bool;
}
public function isMemberOnly()
{
return $this->isMemberOnly;
}
}
class SomeResource extends Resource {
}
}
// usecase
namespace {
//Foo Module's Definition
$adminAreaDefinition = new \Zend\Di\Definition\ClassDefinition("Foo\AdminArea");
$adminAreaDefinition->setInstantiator("__construct");
//Bug Module's Definition
$resourceDefinition = new \Zend\Di\Definition\ClassDefinition("Bug\Resource");
$resourceDefinition->setInstantiator("__construct");
$resourceDefinition->addMethod("setMemerOnly");
$resourceDefinition->addMethodParameter("setMemberOnly", "memberOnly", array('type' => "boolean", 'required' => true));
$someResourceDefinition = new \Zend\Di\Definition\ClassDefinition("Bug\SomeResource");
$someResourceDefinition->setSupertypes(array("Bug\Resource"));
$someResourceDefinition->setInstantiator("__construct");
//make DefinitionList
$definitionList = new \Zend\Di\DefinitionList(array($resourceDefinition, $someResourceDefinition, $adminAreaDefinition));
//make Di
$di = new \Zend\Di\Di($definitionList);
// tell instanceManager to use the parameter for Bug\Resource
$di->instanceManager()
->setParameters("Bug\Resource", array("memberOnly" => false));
echo "[instantiate by Zend\Di] \n";
// get Bug\Resource instance
$resource = $di->get("Bug\Resource");
echo "\n" . get_class($resource) . " : expects false : actually ";
var_dump($resource->isMemberOnly());
// get another Module's instance
$adminArea = $di->get("Foo\AdminArea");
echo "\n" . get_class($adminArea) . " : expects true : actually ";
var_dump($adminArea->isMemberOnly());
echo " (It should be true!) \n\n\n";
// it should be ...
echo "[simple construction] \n";
$expectedAdminArea = new \Foo\AdminArea;
echo "\n" . get_class($expectedAdminArea) . " : ";
var_dump($expectedAdminArea->isMemberOnly());
echo "\n The source of this trouble is that the ClassDefinition returns wrong supertypes. \n";
echo '$di->definitions()->getClassSupertypes("Foo\AdminArea")' . "\n";
var_dump($di->definitions()->getClassSupertypes("Foo\AdminArea"));
}
<?php
// Bad injection problem in ZF 2.0.0 rc7
// Foo Module namespace
namespace Foo {
class AdminArea {
protected $isMemberOnly = true;
public function setMemberOnly($memberOnly)
{
$this->isMemberOnly = (bool) $bool;
}
public function isMemberOnly()
{
return $this->isMemberOnly;
}
}
}
// Bug Module namespace
namespace Bug {
class Resource {
protected $isMemberOnly;
public function setMemberOnly($memberOnly)
{
$this->isMemberOnly = (bool) $bool;
}
public function isMemberOnly()
{
return $this->isMemberOnly;
}
}
class SomeResource extends Resource {
}
}
// usecase
namespace {
//Foo Module's Definition
$adminAreaDefinition = new \Zend\Di\Definition\ClassDefinition("Foo\AdminArea");
$adminAreaDefinition->setInstantiator("__construct");
//Bug Module's Definition
$resourceDefinition = new \Zend\Di\Definition\ClassDefinition("Bug\Resource");
$resourceDefinition->setInstantiator("__construct");
$resourceDefinition->addMethod("setMemerOnly");
$resourceDefinition->addMethodParameter("setMemberOnly", "memberOnly", array('type' => "boolean", 'required' => true));
$someResourceDefinition = new \Zend\Di\Definition\ClassDefinition("Bug\SomeResource");
$someResourceDefinition->setSupertypes(array("Bug\Resource"));
$someResourceDefinition->setInstantiator("__construct");
//make DefinitionList
$definitionList = new \Zend\Di\DefinitionList(array($resourceDefinition, $someResourceDefinition, $adminAreaDefinition));
//make Di
$di = new \Zend\Di\Di($definitionList);
// tell instanceManager to use the parameter for Bug\Resource
$di->instanceManager()
->setParameters("Bug\Resource", array("memberOnly" => false));
echo "[instantiate by Zend\Di] \n";
// get Bug\Resource instance
$resource = $di->get("Bug\Resource");
echo "\n" . get_class($resource) . " : expects false : actually ";
var_dump($resource->isMemberOnly());
// get another Module's instance
$adminArea = $di->get("Foo\AdminArea");
echo "\n" . get_class($adminArea) . " : expects true : actually ";
var_dump($adminArea->isMemberOnly());
echo " (It should be true!) \n\n\n";
// it should be ...
echo "[simple construction] \n";
$expectedAdminArea = new \Foo\AdminArea;
echo "\n" . get_class($expectedAdminArea) . " : ";
var_dump($expectedAdminArea->isMemberOnly());
echo "\n The source of this trouble is that the ClassDefinition returns wrong supertypes. \n";
echo '$di->definitions()->getClassSupertypes("Foo\AdminArea")' . "\n";
var_dump($di->definitions()->getClassSupertypes("Foo\AdminArea"));
}
/**
result
[instantiate from Zend\Di]
Bug\Resource : expects false : actually bool(false)
Foo\AdminArea : expects true : actually bool(false)
(It should be true!)
[simple construction]
Foo\AdminArea : bool(true)
The source of this trouble is that the ClassDefinition returns wrong supertypes.
$di->definitions()->getClassSupertypes("Foo\AdminArea")
array(1) {
[0]=>
string(12) "Bug\Resource"
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment