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

Unbinding $this of closure is deprecated #29411

Closed
kylekatarnls opened this issue Aug 4, 2019 · 11 comments
Closed

Unbinding $this of closure is deprecated #29411

kylekatarnls opened this issue Aug 4, 2019 · 11 comments
Labels

Comments

@kylekatarnls
Copy link
Contributor

  • Laravel Version: 5.8 / 6.0
  • PHP Version: 7.4.0 / 8.0.0

Description:

PHP deprecate closure unbinding, so the following line:
https://github.com/laravel/framework/blob/master/src/Illuminate/Support/Traits/Macroable.php#L110

throws:
Unbinding $this of closure is deprecated

since PHP 7.4.0

As having a similar macro system in Carbon, I'm working on possible alternatives.

Do you plan to support PHP 7.4 and 8? And to still support mixin/macro in those new versions?

@driesvints
Copy link
Member

Hmm. We should try to get this fixed before v6.0 is out since PHP 7.4 drops in fall this year.

@driesvints driesvints added the bug label Aug 5, 2019
@kylekatarnls
Copy link
Contributor Author

@driesvints The option I took for next Carbon release is muting the errors with @. Of course it just postpones the problem to a later version. But it would give a few more time.

@driesvints
Copy link
Member

@kylekatarnls yeah I'd opt to actually provide a fix already if we can.

kylekatarnls added a commit to kylekatarnls/framework that referenced this issue Aug 5, 2019
@kylekatarnls
Copy link
Contributor Author

Here is for the quick fix: #29418

But some testing utils throws other deprecation notices with PHP 7.4 in Travis-CI. I will try to fix them.

No fix for Laravel 5.8?

@yaayes
Copy link

yaayes commented Aug 5, 2019

Using error control symbol @ is a bad practice, it can prevent other errors from being shown and/or handled, and you'll have a more time just to know what the heck is happening.
From PHP docs:

Warning: Currently the "@" error-control operator prefix will even disable error reporting for critical errors that will terminate script execution. Among other things, this means that if you use "@" to suppress errors from a certain function and either it isn't available or has been mistyped, the script will die right there with no indication as to why.

IMO, and from PR #29418 you shouldn't use @ before a call_user_func_array, because we'll never know if the closure or the function typed by the developer is working and does not have any typos or any kind of errors!

@driesvints
Copy link
Member

@kylekatarnls I've closed your temp fix pr. Let's try to fix the actual problem before we release 6.0

@driesvints
Copy link
Member

No fix for Laravel 5.8?

No, we can't make breaking changes here.

@driesvints
Copy link
Member

Okay so here's the gist: everything will still work as is except for static macro calls. When you perform a static macro call which is a closure you'll need to make sure it's also marked the closure as static. Only the unbinding of $this for non-static closures is deprecated. The error message above is actually a bit misleading.

So basically the following won't work anymore:

FooClass::macro('tryStatic', function () {
    return 'foo';
});

FooClass::tryStatic();

Because the closure is non-static you can't unbind $this anymore. But if you do the following, everything will work as expected:

FooClass::macro('tryStatic', static function () {
    return 'foo';
});

FooClass::tryStatic();

Notice the static keyword. The closure is marked as static now and $this cannot be called from within anymore.

I've sent in a PR here: #29482

@faliure
Copy link
Contributor

faliure commented Aug 10, 2019

In Macroable.php:110 we're inside __call, I don't see how we'd get that error there: return call_user_func_array($macro->bindTo($this, static::class), $parameters);. It's binding to $this, in a non-static context, $this cannot be null.

Maybe the error comes from line 84? That'd make more sense unless I'm missing something big.

The way I see it, there are a few options:

  1. Remove the special handling (the conditional) for closures altogether in __callStatic.
    Cons: can't use static:: within those macros.
    I found only one instance where a macro uses static and it's in a test: tests/Support/SupportMacroableTest.php:45. It's still a breaking change, though.

  2. Make sure static macros are declared as such (static function X(){ ...}).
    Pros: it's the right way to do it (Symphony did this as well)
    Cons: it's a breaking change

The great solution would be to be able to change the context (for static::) without touching the $newthis. However, it seems like they didn't think of that when deprecating unbinding non-static Closures...

@GrahamCampbell
Copy link
Member

This will be fixed in PHP 7.4.0 RC1.

n0099 added a commit to n0099/open-tbm that referenced this issue Aug 25, 2021
#1 /be/vendor/laravel/framework/src/Illuminate/Macroable/Traits/Macroable.php(85): Closure->bindTo()
#2 /be/routes/api.php(35): Illuminate\\Http\\Request::__callStatic()
` when visiting /stat(u)s route, related to laravel/framework#29411 @ routes/api.php
* revert f7c2753, remove ctor param $startPage since it's hardcoded, the same as the ReplyQueue @ Jobs\Crawler\SubReplyQueue.php
* remove outdated comments and invoke getContents() on the body stream @ Tieba\Cralwer\(Thread|Reply|SubReply)Crawler.php
@ fe
n0099 added a commit to n0099/open-tbm that referenced this issue Aug 25, 2021
#1 /be/vendor/laravel/framework/src/Illuminate/Macroable/Traits/Macroable.php(85): Closure->bindTo()
#2 /be/routes/api.php(35): Illuminate\\Http\\Request::__callStatic()
` when visiting /stat(u)s route, related to laravel/framework#29411 @ routes/api.php
* revert f7c2753, remove ctor param $startPage since it's hardcoded, the same as the ReplyQueue @ Jobs\Crawler\SubReplyQueue.php
* remove outdated comments and invoke getContents() on the body stream @ Tieba\Cralwer\(Thread|Reply|SubReply)Crawler.php
@ fe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants