Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[DI] Randomize private services #19683

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
try public randomized definitions
  • Loading branch information
ro0NL committed Aug 21, 2016
commit 2cc36db448b3c071d3251f1d36fb6a7e70759cd6
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public function process(ContainerBuilder $container)
if (!$definition->isPublic()) {
$this->idMap[$id] = $this->randomizer ? (string) call_user_func($this->randomizer, $id) : hash('sha256', mt_rand().$id);
$definition->setOriginId($id);
$definition->setPublic(true);
}
}

Expand Down
39 changes: 13 additions & 26 deletions 39 src/Symfony/Component/DependencyInjection/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class Container implements ResettableContainerInterface
protected $methodMap = array();
protected $aliases = array();
protected $loading = array();
protected $serviceMetadata = array();
protected $privateOriginIds = array(); // for BC

private $underscoreMap = array('_' => '', '.' => '_', '\\' => '_');

Expand Down Expand Up @@ -172,19 +172,18 @@ public function set($id, $service)
unset($this->aliases[$id]);
}

if ($this->isPrivateService($id)) {
if (isset($this->privateOriginIds[$id])) {
if (null === $service) {
@trigger_error(sprintf('Unsetting the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED);
unset($this->privateOriginIds[$id]);
} else {
@trigger_error(sprintf('Setting the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0. A new public service will be created instead.', $id), E_USER_DEPRECATED);
$id = $this->privateOriginIds[$id];
}
}

if (null === $service) {
if (null !== $originId = $this->getServiceOriginId($id)) {
unset($this->services[$originId], $this->serviceMetadata[$originId]);
}
unset($this->services[$id], $this->serviceMetadata[$id]);
unset($this->services[$id]);
} else {
$this->services[$id] = $service;
}
Expand All @@ -210,9 +209,9 @@ public function has($id)
if (--$i && $id !== $lcId = strtolower($id)) {
$id = $lcId;
} else {
if ($this->isPrivateService($id)) {
if (isset($this->privateOriginIds[$id])) {
@trigger_error(sprintf('Checking for the existence of the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED);
$id = $this->getServiceOriginId($id) ?: $id;
$id = $this->privateOriginIds[$id];
}

return method_exists($this, 'get'.strtr($id, $this->underscoreMap).'Service');
Expand Down Expand Up @@ -267,13 +266,10 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
} elseif (method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) {
// $method is set to the right value, proceed
} else {
if ($this->isPrivateService($id) && null === $this->getServiceOriginId($id)) {
if (isset($this->privateOriginIds[$id])) {
@trigger_error(sprintf('Requesting the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED);
foreach ($this->serviceMetadata as $serviceId => $metadata) {
if (isset($metadata['origin_id']) && $id === $metadata['origin_id']) {
return $this->get($serviceId, $invalidBehavior);
}
}

return $this->get($this->privateOriginIds[$id]);
}

if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {
Expand Down Expand Up @@ -349,11 +345,12 @@ public function reset()
public function getServiceIds()
{
$ids = array();
$reversedPrivateOriginIds = array_flip($this->privateOriginIds);
foreach (get_class_methods($this) as $method) {
if (preg_match('/^get(.+)Service$/', $method, $match)) {
$id = self::underscore($match[1]);
if ($this->isPrivateService($id)) {
$id = $this->getServiceOriginId($id) ?: $id;
if (isset($reversedPrivateOriginIds[$id])) {
$id = $reversedPrivateOriginIds[$id];
}
$ids[] = $id;
}
Expand Down Expand Up @@ -387,16 +384,6 @@ public static function underscore($id)
return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), str_replace('_', '.', $id)));
}

final protected function isPrivateService($id)
{
return isset($this->serviceMetadata[$id]['private']) && true === $this->serviceMetadata[$id]['private'];
}

final protected function getServiceOriginId($id)
{
return isset($this->serviceMetadata[$id]['origin_id']) ? $this->serviceMetadata[$id]['origin_id'] : null;
}

private function __clone()
{
}
Expand Down
10 changes: 2 additions & 8 deletions 10 src/Symfony/Component/DependencyInjection/ContainerBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -541,17 +541,11 @@ public function compile()
$compiler->compile($this);
$this->compiled = true;

$this->serviceMetadata = array();
$this->privateOriginIds = array();

foreach ($this->definitions as $id => $definition) {
if (!$definition->isPublic()) {
$this->serviceMetadata[$id]['private'] = true;
}
if (null !== $originId = $definition->getOriginId()) {
$this->serviceMetadata[$id]['origin_id'] = $originId;
if (!$definition->isPublic()) {
$this->serviceMetadata[$originId]['private'] = true;
}
$this->privateOriginIds[$originId] = $id;
}
if ($this->trackResources && $definition->isLazy() && ($class = $definition->getClass()) && class_exists($class)) {
$this->addClassResource(new \ReflectionClass($class));
Expand Down
32 changes: 5 additions & 27 deletions 32 src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ public function __construct()
EOF;

$code .= $this->addMethodMap();
$code .= $this->addServiceMetadata();
$code .= $this->addPrivateOriginIdServices();
$code .= $this->addAliases();

$code .= <<<'EOF'
Expand Down Expand Up @@ -839,7 +839,7 @@ public function __construct()

$code .= "\n \$this->services = array();\n";
$code .= $this->addMethodMap();
$code .= $this->addServiceMetadata();
$code .= $this->addPrivateOriginIdServices();
$code .= $this->addAliases();

$code .= <<<'EOF'
Expand Down Expand Up @@ -895,7 +895,7 @@ private function addMethodMap()
*
* @return string
*/
private function addServiceMetadata()
private function addPrivateOriginIdServices()
{
if (!$definitions = $this->container->getDefinitions()) {
return '';
Expand All @@ -904,38 +904,16 @@ private function addServiceMetadata()
$code = '';
ksort($definitions);
foreach ($definitions as $id => $definition) {
$metadata = array();
if (!$definition->isPublic()) {
$metadata['private'] = true;
}
if (null !== $originId = $definition->getOriginId()) {
$metadata['origin_id'] = $originId;
}
if ($metadata) {
$code .= ' '.var_export($id, true)." => array(\n";
foreach ($metadata as $k => $v) {
$code .= ' '.var_export($k, true).' => '.var_export($v, true).",\n";
}
$code .= " ),\n";
}
if (null === $originId) {
continue;
}
unset($metadata['origin_id']);
if ($metadata) {
$code .= ' '.var_export($originId, true)." => array(\n";
foreach ($metadata as $k => $v) {
$code .= ' '.var_export($k, true).' => '.var_export($v, true).",\n";
}
$code .= " ),\n";
$code .= ' '.var_export($originId, true).' => '.var_export($id, true).",\n";
}
}

if (empty($code)) {
return '';
}

$out = " \$this->serviceMetadata = array(\n";
$out = " \$this->privateOriginIds = array(\n";
$out .= $code;
$out .= " );\n";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,15 +400,7 @@ public function __construct()
$this->__internal = new \stdClass();
$this->__sharing_internal = new \stdClass();
$this->aliases = array('alias' => 'bar');
$this->serviceMetadata = array(
'semirandom_internal' => array(
'private' => true,
'origin_id' => 'internal',
),
'internal' => array(
'private' => true,
),
);
$this->privateOriginIds = array('internal' => 'semirandom_internal');
}

protected function getSemirandomInternalService()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,6 @@ public function __construct()
'shared_private_dep1' => 'getSharedPrivateDep1Service',
'shared_private_dep2' => 'getSharedPrivateDep2Service',
);
$this->serviceMetadata = array(
'configurator_service' => array(
'private' => true,
),
'configurator_service_simple' => array(
'private' => true,
),
'factory_simple' => array(
'private' => true,
),
'inlined' => array(
'private' => true,
),
'new_factory' => array(
'private' => true,
),
'shared_private' => array(
'private' => true,
),
);
$this->aliases = array(
'alias_for_alias' => 'foo',
'alias_for_foo' => 'foo',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,8 @@ public function __construct()
'shared_private_dep1' => 'getSharedPrivateDep1Service',
'shared_private_dep2' => 'getSharedPrivateDep2Service',
);
$this->serviceMetadata = array(
'semirandom_shared_private' => array(
'private' => true,
'origin_id' => 'shared_private',
),
'shared_private' => array(
'private' => true,
),
$this->privateOriginIds = array(
'shared_private' => 'semirandom_shared_private',
);
$this->aliases = array(
'alias_for_alias' => 'foo',
Expand Down Expand Up @@ -341,6 +335,19 @@ protected function getRequestService()
throw new RuntimeException('You have requested a synthetic service ("request"). The DIC does not know how to construct this service.');
}

/**
* Gets the 'semirandom_shared_private' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return \stdClass A stdClass instance
*/
protected function getSemirandomSharedPrivateService()
{
return $this->services['semirandom_shared_private'] = new \stdClass();
}

/**
* Gets the 'service_from_static_method' service.
*
Expand Down Expand Up @@ -388,23 +395,6 @@ protected function getSharedPrivateDep2Service()
return $instance;
}

/**
* Gets the 'semirandom_shared_private' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* This service is private.
* If you want to be able to request this service from the container directly,
* make it public, otherwise you might end up with broken code.
*
* @return \stdClass A stdClass instance
*/
protected function getSemirandomSharedPrivateService()
{
return $this->services['semirandom_shared_private'] = new \stdClass();
}

/**
* {@inheritdoc}
*/
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.