|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2019-12-16 13:37 UTC] stanislav dot goldmann at gmail dot com
Description: ------------ In the proposal of short closures (https://wiki.php.net/rfc/arrow_functions_v2) the following is stated: "When a variable used in the expression is defined in the parent scope it will be implicitly captured by-value." With this example: $y = 1; $fn1 = fn($x) => $x + $y; $fn2 = function ($x) use ($y) { return $x + $y; }; These two behave exactly the same, as expected. However compact doesn't behave that way, as it doesn't recognize a variable from outer scope until it is explicitly called. Test script: --------------- $name = 'foo'; $array = ['bar']; $failing = fn($value) => compact('name', 'value'); $working = fn($value) => compact('name', 'value') + [$name]; var_dump(array_map($failing, $array)); var_dump(array_map($working, $array)); Expected result: ---------------- Short closures using compact should resolve outer scoped variables and behave like "long" closures using an use statement. fn($value) => compact('name', 'value') should work just like function($value) use ($name) { return compact('name', 'value'); } And return the following array(1) { [0]=> array(3) { ["name"]=> string(3) "foo" ["value"]=> string(3) "bar" } } Actual result: -------------- // Notice: compact(): Undefined variable: name array(1) { [0]=> array(1) { ["value"]=> string(3) "bar" } } PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 20:00:01 2025 UTC |
I believe this also applies to `require`-ing a file. Context: Working in the Laravel task scheduler. I have 2 relevant files: `tasks/sales.php` --- <?php use App\Console\Commands\Command; /** @var \Illuminate\Console\Scheduling\Schedule $schedule */ return [ $schedule->command(Command::class)->cron('* * * * *'), ]; --- `app/Console/Kernel.php` --- ... ->map(fn(SplFileInfo $file) => require $file->getPathname()) ... --- Results in an exception: --- ErrorException Undefined variable $schedule at tasks/sales.php:8 4▕ 5▕ use App\Console\Commands\Command; 6▕ 7▕ return [ ➜ 8▕ $schedule->command(Command::class)->cron('* * * * *'), 9▕ ]; 10▕ --- Whereas a traditional closure with `use()` works fine: --- ->map(function (SplFileInfo $file) use ($schedule) { return require $file->getPathname(); }) ---