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

PHP7 return types incompatibile with generate code #6106

Closed
mikeymike opened this issue Aug 10, 2016 · 27 comments
Closed

PHP7 return types incompatibile with generate code #6106

mikeymike opened this issue Aug 10, 2016 · 27 comments
Assignees
Labels
bug report Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development

Comments

@mikeymike
Copy link

Preconditions

  1. PHP 7.0.8 (any compatible PHP 7 release should be sufficient though)

Steps to reproduce

  1. Blank install
  2. Create a new block and add a method with a return type in PHP7 format e.g : string
  3. Use the block in some layout somewhere
  4. Hit the frontend to use the block

Expected result

  1. The page should load and the block code be executed correctly

Actual result

Instead you get a fatal error from PHP because the generated interceptor class doesn't have a return type at all.

PHP Fatal error:  Declaration of XX\YY\Block\CustomBlock\Interceptor::someMethod() must be compatible with XX\YY\Block\CustomBlock\::someMethod(): bool in .../var/generation/XX/YY/Block/CustomBlock/Interceptor.php on line X

This of course can be a tricky one to resolve purely based on the fact you wouldn't want to break BC with PHP 5.X.

The only resolutions I can think of at this point is...

  1. Check the version at runtime
  2. Set the PHP version (like we set the deploy mode)
@AydinHassan
Copy link
Contributor

It seems the version of zendframework/zend-code Magento 2 ships with does not support return type hints in code generation, nor is it easy to update the version of zendframework/zend-code due to conflicting dependencies.

We decided to temporarily patch this and bring in some zendframework/zend-code features to add return type hints. Here is a patch if anyone else wants this feature: https://gist.github.com/AydinHassan/064f4bbd33fc118f9fa655811df6a660.

Note that you will need to put it in your own module and rename the namespaces.

@mwgamble
Copy link

As the scanner code in the zend-code library is now set to be deprecated and removed, Magento should look towards replacing this altogether with another library.

zendframework/zend-code#91

@adragus-inviqa
Copy link
Contributor

M2 took "ownership" of ZF code, but I agree that the package should be replaced. But that's even more refactoring.
Maybe use another strategy for PHP 7+ (\Magento\Framework\Code\Generator\CodeGeneratorInterface) and keep the current one for older versions.

@tkacheva tkacheva added the Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development label Oct 13, 2016
@tkacheva
Copy link

internal issue MAGETWO-59661

@mcjwsk
Copy link
Contributor

mcjwsk commented Feb 24, 2017

@tkacheva any updates on this issue ?

@orlangur
Copy link
Contributor

Create a new block and add a method with a return type in PHP7 format e.g : string

Interesting case :) Never thought of writing PHP5-incompatible code within Magento 2.

@AydinHassan

nor is it easy to update the version of zendframework/zend-code due to conflicting dependencies

https://github.com/zendframework/zend-code/blob/release-3.1.0/composer.json#L17 which dependencies?

@mwgamble

As the scanner code in the zend-code library is now set to be deprecated and removed, Magento should look towards replacing this altogether with another library

Why another library if it is BC break anyway? Why not simply stick to zend-code 3.x?

At first glance https://github.com/zendframework/zend-code/blob/master/doc/book/migration.md does not seem to be really painful.

If you generate code that should run in PHP 5.x, it is advisable to ...

And this sentence looks exactly like the our case: we can use fancy new PHP7 features while all generated code will remain PHP5-compatible.

@mwgamble
Copy link

Why another library if it is BC break anyway? Why not simply stick to zend-code 3.x?

Because zend-code 3.x will never have support for scanning code that uses scalar type declarations.

@orlangur
Copy link
Contributor

@mwgamble
Copy link

@orlangur nope. see here: zendframework/zend-code#56

Also see the responses to my comments here: zendframework/zend-code#87 (comment)
And here: zendframework/zend-code#85

@orlangur
Copy link
Contributor

@mwgamble, thanks for the details, I'll look closer into it. If scanner will not be adopted in 3.x and then deprecated-removed in 4.x-5.x it's a problem :)

So, it's better switch to BetterReflection library for us?

@AydinHassan
Copy link
Contributor

AydinHassan commented Feb 27, 2017

@orlangur with zend-code requirement set to ^3:

  Problem 1
    - zendframework/zend-di 2.4.9 requires zendframework/zend-code 2.4.9 -> satisfiable by zendframework/zend-code[2.4.9] but these conflict with your requirements or minimum-stability.
    - zendframework/zend-di 2.4.8 requires zendframework/zend-code 2.4.8 -> satisfiable by zendframework/zend-code[2.4.8] but these conflict with your requirements or minimum-stability.
    - zendframework/zend-di 2.4.7 requires zendframework/zend-code 2.4.7 -> satisfiable by zendframework/zend-code[2.4.7] but these conflict with your requirements or minimum-stability.
    - zendframework/zend-di 2.4.6 requires zendframework/zend-code 2.4.6 -> satisfiable by zendframework/zend-code[2.4.6] but these conflict with your requirements or minimum-stability.
    - zendframework/zend-di 2.4.11 requires zendframework/zend-code 2.4.11 -> satisfiable by zendframework/zend-code[2.4.11] but these conflict with your requirements or minimum-stability.
    - zendframework/zend-di 2.4.10 requires zendframework/zend-code 2.4.10 -> satisfiable by zendframework/zend-code[2.4.10] but these conflict with your requirements or minimum-stability.
    - zendframework/zend-di 2.4.10 requires zendframework/zend-code 2.4.10 -> satisfiable by zendframework/zend-code[2.4.10] but these conflict with your requirements or minimum-stability.
    - Installation request for zendframework/zend-di ~2.4.6 -> satisfiable by zendframework/zend-di[2.4.10, 2.4.11, 2.4.6, 2.4.7, 2.4.8, 2.4.9].

On latest develop btw.

@orlangur
Copy link
Contributor

@AydinHassan, yeah, I tried it as well, zend-code v3 is not stable yet: https://github.com/zendframework/zend-code/blob/master/composer.json#L30

And as it requires zendframework/zend-eventmanager 2.6 or higher current 2.4 ZF2 components will need to be updated as well.

These changes does not seem to be painful.

@AydinHassan
Copy link
Contributor

@orlangur I'm not sure that means it's unstable - it's tagged as a stable release and uses stable dependencies. If you look at the blame for those lines - it's from 2+ years ago. In any case Composer only uses that info from the root package - It looks like that could have been added for local development of the package.

Regarding the zend-eventmanager package upgrade - it requires literally all of the zend-* packages to be updated. Not sure on Magento's policy of upgrading dependencies - but based on how old the 2.4 components being used are (18+ months) - sounds pretty painful to me 😄

@AydinHassan
Copy link
Contributor

Minimal set of changes to pull in zend-code 3.x was, for me:

diff --git a/composer.json b/composer.json
index 6f5db49..2ec5b81 100644
--- a/composer.json
+++ b/composer.json
@@ -9,31 +9,31 @@
     ],
     "require": {
         "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
-        "zendframework/zend-stdlib": "~2.4.6",
-        "zendframework/zend-code": "~2.4.6",
-        "zendframework/zend-server": "~2.4.6",
-        "zendframework/zend-soap": "~2.4.6",
-        "zendframework/zend-uri": "~2.4.6",
-        "zendframework/zend-validator": "~2.4.6",
-        "zendframework/zend-crypt": "~2.4.6",
-        "zendframework/zend-console": "~2.4.6",
-        "zendframework/zend-modulemanager": "~2.4.6",
-        "zendframework/zend-mvc": "~2.4.6",
-        "zendframework/zend-text": "~2.4.6",
-        "zendframework/zend-i18n": "~2.4.6",
-        "zendframework/zend-eventmanager": "~2.4.6",
-        "zendframework/zend-view": "~2.4.6",
-        "zendframework/zend-servicemanager": "~2.4.6",
-        "zendframework/zend-json": "~2.4.6",
-        "zendframework/zend-config": "~2.4.6",
-        "zendframework/zend-form": "~2.4.6",
-        "zendframework/zend-di": "~2.4.6",
-        "zendframework/zend-serializer": "~2.4.6",
-        "zendframework/zend-log": "~2.4.6",
-        "zendframework/zend-http": "~2.4.6",
-        "zendframework/zend-db": "~2.4.6",
-        "zendframework/zend-captcha": "~2.4.6",
-        "zendframework/zend-session": "~2.4.6",
+        "zendframework/zend-stdlib": "^3",
+        "zendframework/zend-code": "^3",
+        "zendframework/zend-server": "^2.6",
+        "zendframework/zend-soap": "^2.6",
+        "zendframework/zend-uri": "^2.5",
+        "zendframework/zend-validator": "^2.6",
+        "zendframework/zend-crypt": "^2.6",
+        "zendframework/zend-console": "^2.6",
+        "zendframework/zend-modulemanager": "^2.7",
+        "zendframework/zend-mvc": "^2.7",
+        "zendframework/zend-text": "^2.6",
+        "zendframework/zend-i18n": "^2.7",
+        "zendframework/zend-eventmanager": "^3",
+        "zendframework/zend-view": "^2.8",
+        "zendframework/zend-servicemanager": "^2.7",
+        "zendframework/zend-json": "^2.6",
+        "zendframework/zend-config": "^2.6",
+        "zendframework/zend-form": "^2.10",
+        "zendframework/zend-di": "^2.6",
+        "zendframework/zend-serializer": "^2.7",
+        "zendframework/zend-log": "^2.9",
+        "zendframework/zend-http": "^2.6",
+        "zendframework/zend-db": "^2.8",
+        "zendframework/zend-captcha": "^2.7",
+        "zendframework/zend-session": "^2.7",
         "magento/zendframework1": "~1.12.16",
         "colinmollenhour/credis": "1.6",
         "colinmollenhour/php-redis-session-abstract": "1.2",

Maybe we don't need to take all of the deps to the latest 2.x releases - but assuming there is a strict semver policy on those packages - it should be fine. I didn't run the unit tests to see if anything actually breaks yet tho.

@orlangur
Copy link
Contributor

Thanks! I was bored and did not come to an installable set of packages.

"zendframework/zend-stdlib": "^3"
"zendframework/zend-eventmanager": "^3",

Unavoidable?

https://github.com/zendframework/zend-stdlib/blob/master/doc/book/migration.md CallbackHandler is used in Setup which does not have separate composer.json currently unfortunately.

@AydinHassan
Copy link
Contributor

Seems it is avoidable:

^2.6 for zendframework/zend-eventmanager and ^2.7 for zendframework/zend-stdlib works!

@orlangur
Copy link
Contributor

That sounds way better) Thanks for your efforts.

@mwgamble
Copy link

I highly recommend Nikita Popov's PHP Parser library: https://github.com/nikic/PHP-Parser

It has full support for everything Magento 2 needs, and is actively maintained by one of the core developers of the PHP language itself.

@orlangur
Copy link
Contributor

Yeah, I really enjoyed using it for various code analysis, there is no surprise BetterReflection is built on top of it: https://github.com/Roave/BetterReflection/blob/master/composer.json#L7

You think it is an overkill and it's better to have own simple implementation on top of PHP-Parser instead of using reflection library?

@epson121
Copy link

Issue in progress @epson121

@joni-jones
Copy link
Contributor

#8938

jalogut added a commit to staempfli/magento2-module-image-resizer that referenced this issue Mar 20, 2017
magento-team pushed a commit that referenced this issue May 5, 2017
… code #6106

 - Updated Zend Code library to 3.x version and it dependencies
 - Refactored code generators to support PHP 7.x features
 - Refactored Setup module for new Zend Service Manager
 - Covered code generators by tests
magento-team pushed a commit that referenced this issue May 5, 2017
… code #6106

 - Updated reference blacklist
 - Added method description for event listener
magento-team pushed a commit that referenced this issue May 5, 2017
magento-team pushed a commit that referenced this issue May 5, 2017
magento-team pushed a commit that referenced this issue May 5, 2017
@joni-jones
Copy link
Contributor

The fix merged into develop branch.

@csdougliss
Copy link
Contributor

@joni-jones any chance 7.1 support will be backported to 2.1?

@joni-jones
Copy link
Contributor

Hi, @craigcarnell, unfortunately, I can't provide any information about backporting this functionality to 2.1.x version. At this moment this functionality will be only in 2.2.

@sablesoft
Copy link

sablesoft commented Oct 3, 2019

I use Magento v2.3.2
I need to enable MAGE_PROFILER=2, but got errors like this:

Fatal error: Declaration of Magento\Framework\App\Request\PathInfo\Logger::getPathInfo(string $requestUri, string $baseUrl) must be compatible with Magento\Framework\App\Request\PathInfo::getPathInfo(string $requestUri, string $baseUrl): string in /var/www/magento/generated/code/Magento/Framework/App/Request/PathInfo/Logger.php on line 83

It looks like the same problem but with loggers generation in this time.
How can I fix it?

@multipasko
Copy link

the same problem as above

@dchaykas
Copy link

Magento 2.3.3

Fatal error: Declaration of Magento\Framework\App\Request\PathInfo\Logger::getPathInfo(string $requestUri, string $baseUrl) must be compatible with Magento\Framework\App\Request\PathInfo::getPathInfo(string $requestUri, string $baseUrl): string in /srv/www/alberta_dev/magento/generated/code/Magento/Framework/App/Request/PathInfo/Logger.php on line 0

As soon as SetEnv MAGE_PROFILER 2 is enabled in .htaccess.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug report Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development
Projects
None yet
Development

No branches or pull requests