Skip to content
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

Doctrine-bridge with PHP 7.2.20 implements non-existant interface FormTypeGuesserInterface #32396

Closed
wimg opened this issue Jul 5, 2019 · 23 comments

Comments

@wimg
Copy link
Contributor

wimg commented Jul 5, 2019

Symfony version(s) affected: 4.2.8

Description
doctrine-bridge uses symfony-form in require-dev.
However, during cache:clear in non-dev mode it does load Form/DoctrineOrmTypeGuesser.php which implements FormTypeGuesserInterface.
The interface FormTypeGuesserInterface can not be found if symfony/form is not installed.

PHP <7.2.0 allowed for such scenario (see https://bugs.php.net/bug.php?id=76980). Starting at PHP 7.2.0 a fatal error is thrown.

How to reproduce

  • Install PHP 7.2.0
  • require symfony/doctrine-bridge in composer.json
  • run 'composer install'

Possible Solution
Move symfony/form from require-dev to require

Additional context
Output :

  • Configuring symfony/security-bundle (>=3.3): From github.com/symfony/recipes:master
  • Configuring symfony/validator (>=4.1): From github.com/symfony/recipes:master
    Executing script cache:clear [KO]
    [KO]
    Script cache:clear returned with error code 255
    !!
    !! // Clearing the cache for the prod environment with debug
    !! // false
    !!
    !! PHP Fatal error: During class fetch: Uncaught ReflectionException: Class Symfony\Component\Form\FormTypeGuesserInterface not found in /opt/releases/20190626075527/api/vendor/symfony/doctrine-bridge/Form/DoctrineOrmTypeGuesser.php:25
    !! Stack trace:
    !! #0 /opt/releases/20190626075527/api/vendor/composer/ClassLoader.php(444): include('/opt/releases/2...')
    !! Untitled #1 /opt/releases/20190626075527/api/vendor/composer/ClassLoader.php(322): Composer\Autoload\includeFile('/opt/releases/2...')
    !! Renaming "Entities" to "Entity" #2 [internal function]: Composer\Autoload\ClassLoader->loadClass('Symfony\Bridge\...')
    !! Untitled #3 [internal function]: spl_autoload_call('Symfony\Bridge\...')
    !! Same change for mapping files #4 /opt/releases/20190626075527/api/vendor/symfony/config/Resource/ClassExistenceResource.php(76): class_exists('Symfony\Bridge\...')
    !! Using ORM and MongoDB both in the same bundle. #5 /opt/releases/20190626075527/api/vendor/symfony/dependency-injection/ContainerBuilder.php(353): Symfony\Component\Config\Resource\ClassExistenceResource->isFresh(0)
    !! [Form] Outstanding patches for Choice/Collection fields #6 /opt/releases/20190626075527/api/vendor/symfony/dependency-injection/Compiler/AutowirePass.php(338): Sy in /opt/releases/20190626075527/api/vendor/symfony/doctrine-bridge/Form/DoctrineOrmTypeGuesser.php on line 25
    !! 14:00:50 CRITICAL [php] Fatal Error: During class fetch: Uncaught ReflectionException: Class Symfony\Component\Form\FormTypeGuesserInterface not found in /opt/releases/20190626075527/api/vendor/symfony/doctrine-bridge/Form/DoctrineOrmTypeGuesser.php:25
    !! Stack trace:
    !! #0 /opt/releases/20190626075527/api/vendor/composer/ClassLoader.php(444): include('/opt/releases/2...')
    !! Untitled #1 /opt/releases/20190626075527/api/vendor/composer/ClassLoader.php(322): Composer\Autoload\includeFile('/opt/releases/2...')
    !! Renaming "Entities" to "Entity" #2 [internal function]: Composer\Autoload\ClassLoader->loadClass('Symfony\Bridge\...')
    !! Untitled #3 [internal function]: spl_autoload_call('Symfony\Bridge\...')
    !! Same change for mapping files #4 /opt/releases/20190626075527/api/vendor/symfony/config/Resource/ClassExistenceResource.php(76): class_exists('Symfony\Bridge\...')
    !! Using ORM and MongoDB both in the same bundle. #5 /opt/releases/20190626075527/api/vendor/symfony/dependency-injection/ContainerBuilder.php(353): Symfony\Component\Config\Resource\ClassExistenceResource->isFresh(0)
    !! [Form] Outstanding patches for Choice/Collection fields #6 /opt/releases/20190626075527/api/vendor/symfony/dependency-injection/Compiler/AutowirePass.php(338): Sy ["exception" => Symfony\Component\Debug\Exception\FatalErrorException { â¦}]
    !!
    !! In DoctrineOrmTypeGuesser.php line 25:
    !!
    !! Error: During class fetch: Uncaught ReflectionException: Class Symfony\Comp
    !! onent\Form\FormTypeGuesserInterface not found in /opt/releases/201906260755
    !! 27/api/vendor/symfony/doctrine-bridge/Form/DoctrineOrmTypeGuesser.php:25
    !! Stack trace:
    !! #0 /opt/releases/20190626075527/api/vendor/composer/ClassLoader.php(444): i
    !! nclude('/opt/releases/2...')
    !! Untitled #1 /opt/releases/20190626075527/api/vendor/composer/ClassLoader.php(322): C
    !! omposer\Autoload\includeFile('/opt/releases/2...')
    !! Renaming "Entities" to "Entity" #2 [internal function]: Composer\Autoload\ClassLoader->loadClass('Symfony\
    !! Bridge\...')
    !! Untitled #3 [internal function]: spl_autoload_call('Symfony\Bridge\...')
    !! Same change for mapping files #4 /opt/releases/20190626075527/api/vendor/symfony/config/Resource/ClassExi
    !! stenceResource.php(76): class_exists('Symfony\Bridge\...')
    !! Using ORM and MongoDB both in the same bundle. #5 /opt/releases/20190626075527/api/vendor/symfony/dependency-injection/Con
    !! tainerBuilder.php(353): Symfony\Component\Config\Resource\ClassExistenceRes
    !! ource->isFresh(0)
    !! [Form] Outstanding patches for Choice/Collection fields #6 /opt/releases/20190626075527/api/vendor/symfony/dependency-injection/Com
    !! piler/AutowirePass.php(338): Sy
    !!
    !!
    !! cache:clear [--no-warmup] [--no-optional-warmers] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-e|--env ENV] [--no-debug] [--test-mode TEST-MODE] [--]
    !!
    !!
    Script @auto-scripts was called via post-install-cmd
@xabbuh
Copy link
Member

xabbuh commented Jul 5, 2019

Maybe the same as #32395?

@wimg
Copy link
Contributor Author

wimg commented Jul 5, 2019

It occurs after the same change in PHP 7.2.20, but the cause is different here (different package).

@derrabus
Copy link
Member

derrabus commented Jul 5, 2019

Looks like the same issue to me (if you meant 7.2.20 instead of 7.2.0 in the issue description.)

@wimg wimg changed the title Doctrine-bridge with PHP 7.2.0 implements non-existant interface FormTypeGuesserInterface Doctrine-bridge with PHP 7.2.20 implements non-existant interface FormTypeGuesserInterface Jul 6, 2019
@wimg
Copy link
Contributor Author

wimg commented Jul 6, 2019

Correct. And it's 7.2.20 indeed... typo ;-)

@derrabus
Copy link
Member

derrabus commented Jul 7, 2019

Let's close this issue then.

@wimg wimg closed this as completed Jul 7, 2019
mikeSimonson added a commit to mikeSimonson/symfony that referenced this issue Jul 8, 2019
The src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php implements
the FormTypeGuesserInterface and that interface is only defined in the
symfony/form component.
By implementing that interface that code depends on it not only for test but
also in production use.

We discovered it because we have an api which doesn't require symfony form
who blew up with the update to php 7.2.20.
The release of php 7.2.20 fixed a bug that was allowing the implementation
of interface that are not available.
@wimg wimg reopened this Jul 8, 2019
@mikeSimonson
Copy link
Contributor

We reopened that issue because it's not exactly about the same problem although it's related. I have also opened a PR that fix the dependency requirement.

@derrabus
Copy link
Member

derrabus commented Jul 8, 2019

It is the same problem. 😃

@mikeSimonson
Copy link
Contributor

@derrabus not really because the problem described there and the proof of concept show a change of behavior when you use the functionality of the bundle with your own code and that your own code reference an unknown interface.
Here the problem is that the package/bundle itself is referencing an unknown interface because of a mistake in the composer package requirements.

This issue is fixed by fixing the composer.json the other one is fixed by either changing the code to produce the same behavior as before or changing the doc if it's not possible.

@teohhanhui
Copy link
Contributor

@mikeSimonson

Here the problem is that the package/bundle itself is referencing an unknown interface because of a mistake in the composer package requirements.

It's not a mistake. It's an optional dependency.

@mikeSimonson
Copy link
Contributor

@teohhanhui optional dependency doesn't mean anything. The code use it thus it's not optional. The proof is that now php blow up because it's not optional. You can't validate that the code is correct if you implement an interface that you don't have.

@teohhanhui
Copy link
Contributor

The code use it thus it's not optional.

Except DoctrineOrmTypeGuesser is not actually used. Triggering autoload is not the same as actually using the class.

If you look at the discussion in the PHP bug:

What's the expected behavior here? That Foo should not be defined at all since the interface couldn't be loaded?

Which means DoctrineOrmTypeGuesser should just not be defined.

But looks like they fixed it in a bad way.

@mikeSimonson
Copy link
Contributor

@teohhanhui if the class if available in the package, someone use it. If you want to keep the package without the dependency of the form component you can delete that class or remove the implements and both are major BC breaks.

@derrabus
Copy link
Member

derrabus commented Jul 8, 2019

@derrabus not really because the problem described there and the proof of concept show a change of behavior when you use the functionality of the bundle with your own code and that your own code reference an unknown interface.

Yes, it's a minimal reproducer to isolate the problem. If you have a look at @wimg's stack trace, you will find that the method call that I isolated in my reproducer (ClassExistenceResource::isFresh) is in there as well. Trust me: As soon as the problem is fixed for my reproducer, your problem will be fixed as well. Without any added dependencies.

@mikeSimonson
Copy link
Contributor

@derrabus The root cause of the problem is that there is code is your package that depends on an interface that is not available. There is no way this can ever make sense. Either way you move that part of the code in another package that depends on that interface or that interface is a dependency of this package and no amount of catching exception can change that.

@derrabus
Copy link
Member

derrabus commented Jul 9, 2019

@mikeSimonson You keep saying the same things, yet ignoring all attempts by @teohhanhui and myself to explain the situation to you. I doubt that this is discussion getting us anywhere, I'm sorry.

@nicolas-grekas
Copy link
Member

Closing as duplicate of #32395

@db306
Copy link
Contributor

db306 commented Jul 19, 2019

FYI: This error appears too when autowiring tries to wire an Implementation of an interface that has no implementations.

@OGProgrammer
Copy link

api-platform users (im on mac using brew 7.3.7) - I had to add this to my composer.json file and all works after an update

"symfony/form": "4.2.*",

@BonBonSlick
Copy link

@OGProgrammer very bad way to fix this issue should be another.

@doozookn
Copy link

Same problem. I use php-fpm:7.2.20-alpine
Doctrine bridge v. 4.2.4

@BonBonSlick
Copy link

BonBonSlick commented Jul 31, 2019

@doozookn rollback and wait for php fix or newer version. #32395 (comment)

@ctx2002
Copy link

ctx2002 commented Aug 2, 2019

what @mikeSimonson said is right, this is not a PHP problem. this is a problem of class implementation.
@derrabus , and @teohhanhui you explanation make no sense.

"Except DoctrineOrmTypeGuesser is not actually used. Triggering autoload is not the same as actually using the class."

@nicolas-grekas , please re-open this case, this is a Symfony's problem, not PHP.

@nicolas-grekas
Copy link
Member

To me this is a duplicate of #32395 and everything is explained there (while in the middle of "me too" comments...)

Please upgrade to PHP 7.2.21 and report back if you still experience the issue. This is the criteria to decide if I'm wrong or not.

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

No branches or pull requests