Skip to content

[DI][Config] Add ContainerBuilder::classExists() for checking and tracking class, interface or trait existence #21452

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

Conversation

nicolas-grekas
Copy link
Member

Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? /no
Tests pass? yes
Fixed tickets -
License MIT
Doc PR -

Subset of #21419

*
* @final
*/
public function getClassExists($class)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is the best name for this method. What about registerClass() or trackClass() or something like that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok for a better name, but it should convey the fact that the return value has a meaning

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard but I agree, ::trackedClassExists()... ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, tracking is a side effect, so I'm not sure the name should convey that. When a method logs, we don't call it doThatAndLogIt

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So why not just doesClassExist/classExists?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to propose isTracked() ... but if tracking is not important...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not that it's not important : it's a side effect. A conditional one also. What matters most is that this returns if a class exists or not.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed to classExists

@nicolas-grekas nicolas-grekas force-pushed the di-class-exists branch 3 times, most recently from 2839a7e to 6140a26 Compare January 29, 2017 18:42
@nicolas-grekas nicolas-grekas changed the title [DI][Config] Add ContainerBuilder::getClassExists() for checking and tracking class, interface or trait existence [DI][Config] Add ContainerBuilder::classExists() for checking and tracking class, interface or trait existence Jan 29, 2017
$this->addResource(new ClassExistenceResource($class));
$this->classReflectors[$class] = false;
} else {
$class = $this->classReflectors[$class] = new \ReflectionClass($class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to store the reflection class, we can store true instead, right ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do, preparing #21419

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolas-grekas wouldn't this hurt here as we create the reflector without adding a reflection resource, and the getter for the class reflector would not add it later as it is already there in the array

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that could be an issue, but the code in #21419 is free from it, see
https://github.com/symfony/symfony/pull/21419/files#diff-a10c9afd8feaccd1ff66ffd54e2835bcR356

The reflection resource is always added, even if the cache is hit. This creates duplicate resources, but they are free, and deduplicated later on so not an issue.

*
* @return bool
*
* @final
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why using the annotation?

Copy link
Member Author

@nicolas-grekas nicolas-grekas Jan 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because final is a non by-passable imperative keyword, and I don't like it at all for this reason.
@final is way enough to press the intent. We don't need to be dictatorial if people want to do clever things like lazy proxies.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then imo we should have a solution that wouldn't throw a deprecation when used as a proxy. What about checking for a keyword such as mockable and don't throw a deprecation when common proxy interfaces are implemented?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in fact, we already have one: proxies are not loaded via standard autoloading, so they don't get through DebugClassLoader :)

Copy link
Contributor

@GuilhemN GuilhemN Jan 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I did not know that, it's logic indeed :)

@@ -65,6 +66,9 @@ private function updateDefinition(ContainerBuilder $container, $id, Definition $
if (is_string($factory)) {
try {
$m = new \ReflectionFunction($factory);
if (false !== $m->getFileName() && file_exists($m->getFileName())) {
$container->addResource(new FileResource($m->getFileName()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we use your new reflection resource instead, to invalidate less often ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you mean for the function, we don't have a ReflectionFunction resource, and I don't think we need one.

@chalasr
Copy link
Member

chalasr commented Jan 30, 2017

Some suggestions in nicolas-grekas#10

…tracking class, interface or trait existence
@nicolas-grekas
Copy link
Member Author

nicolas-grekas commented Jan 30, 2017

PR is ready, with all class_exists() replaced by $container->classExists().

BUT

I'm wondering if ClassExistenceResource is required at all and if we shouldn't deprecate it instead (we should not deprecate it because #21419 uses it for userland classes - but still, we could not use it for deps related checks).
ping @fabpot because you added it in #20121
should we really need to track things that change only when composer is used?
shouldn't we instead expect people/"a composer script" to clear the dumped container when deps change?

the benefit might be just DX, because checking a bunch of classes for existence takes time (even if this PR makes the situation a bit better by using only FileExistenceResource when possible).

WDYT?

@fabpot
Copy link
Member

fabpot commented Jan 30, 2017

We talked about ClassExistenceResource with @nicolas-grekas and I'm going to fix my edge case another way, so this class is not needed anymore for classes managed via Composer.

My use case was with projects that don't have symfony/console, so cache:clear is not run by Composer. That's mainly the case when using only the Symfony components with Flex, and I will find another way.

@nicolas-grekas nicolas-grekas deleted the di-class-exists branch January 30, 2017 20:54
fabpot added a commit that referenced this pull request Jan 31, 2017
…ekas)

This PR was merged into the 3.3-dev branch.

Discussion
----------

[DI] Remove usages of ClassExistenceResource

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

As discussed in #21452 (see last comments)

Commits
-------

ec8f1ad [DI] Remove usages of ClassExistenceResource
@stof
Copy link
Member

stof commented Feb 2, 2017

My use case was with projects that don't have symfony/console, so cache:clear is not run by Composer. That's mainly the case when using only the Symfony components with Flex, and I will find another way.

#21505 is the answer to this, right ?

@nicolas-grekas
Copy link
Member Author

yes!

@nicolas-grekas
Copy link
Member Author

Ans also to #21419 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants