php-scoper
php-scoper copied to clipboard
[Scoper] Add polyfill support
Bug report
| Question | Answer |
|---|---|
| Box version | 0.13.9 |
| PHP version | 7.3.22 |
| Platform with version | Alpine (docker) |
| Github Repo | - |
Function aliasing described in docs seems not working with symfony polyfills functions. File scoped by namespace, but not function_exist check, also no aliases in scoper-autoload.php.
Can this caused because they all are oneliners? For example, dd function from symfony/var-dumper prefixed and aliased as expected.
Original vendor/symfony/polyfill-php80/bootstrap.php
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Symfony\Polyfill\Php80 as p;
if (PHP_VERSION_ID >= 80000) {
return;
}
if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) {
define('FILTER_VALIDATE_BOOL', FILTER_VALIDATE_BOOLEAN);
}
if (!function_exists('fdiv')) {
function fdiv(float $num1, float $num2): float { return p\Php80::fdiv($num1, $num2); }
}
if (!function_exists('preg_last_error_msg')) {
function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); }
}
if (!function_exists('str_contains')) {
function str_contains(string $haystack, string $needle): bool { return p\Php80::str_contains($haystack, $needle); }
}
if (!function_exists('str_starts_with')) {
function str_starts_with(string $haystack, string $needle): bool { return p\Php80::str_starts_with($haystack, $needle); }
}
if (!function_exists('str_ends_with')) {
function str_ends_with(string $haystack, string $needle): bool { return p\Php80::str_ends_with($haystack, $needle); }
}
if (!function_exists('get_debug_type')) {
function get_debug_type($value): string { return p\Php80::get_debug_type($value); }
}
if (!function_exists('get_resource_id')) {
function get_resource_id($res): int { return p\Php80::get_resource_id($res); }
}
Prefixed one
<?php
namespace _PhpScoper07cbd2d8c7e4;
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use _PhpScoper07cbd2d8c7e4\Symfony\Polyfill\Php80 as p;
if (\PHP_VERSION_ID >= 80000) {
return;
}
if (!\defined('FILTER_VALIDATE_BOOL') && \defined('FILTER_VALIDATE_BOOLEAN')) {
\define('FILTER_VALIDATE_BOOL', \FILTER_VALIDATE_BOOLEAN);
}
if (!\function_exists('fdiv')) {
function fdiv(float $num1, float $num2) : float
{
return \_PhpScoper07cbd2d8c7e4\Symfony\Polyfill\Php80\Php80::fdiv($num1, $num2);
}
}
if (!\function_exists('preg_last_error_msg')) {
function preg_last_error_msg() : string
{
return \_PhpScoper07cbd2d8c7e4\Symfony\Polyfill\Php80\Php80::preg_last_error_msg();
}
}
if (!\function_exists('str_contains')) {
function str_contains(string $haystack, string $needle) : bool
{
return \_PhpScoper07cbd2d8c7e4\Symfony\Polyfill\Php80\Php80::str_contains($haystack, $needle);
}
}
if (!\function_exists('str_starts_with')) {
function str_starts_with(string $haystack, string $needle) : bool
{
return \_PhpScoper07cbd2d8c7e4\Symfony\Polyfill\Php80\Php80::str_starts_with($haystack, $needle);
}
}
if (!\function_exists('str_ends_with')) {
function str_ends_with(string $haystack, string $needle) : bool
{
return \_PhpScoper07cbd2d8c7e4\Symfony\Polyfill\Php80\Php80::str_ends_with($haystack, $needle);
}
}
if (!\function_exists('get_debug_type')) {
function get_debug_type($value) : string
{
return \_PhpScoper07cbd2d8c7e4\Symfony\Polyfill\Php80\Php80::get_debug_type($value);
}
}
if (!\function_exists('get_resource_id')) {
function get_resource_id($res) : int
{
return \_PhpScoper07cbd2d8c7e4\Symfony\Polyfill\Php80\Php80::get_resource_id($res);
}
}
scoper.inc.php
<?php
declare(strict_types=1);
use Isolated\Symfony\Component\Finder\Finder;
return [
'finders' => [
Finder::create()
->files()
->in([
__DIR__ . '/resources',
__DIR__ . '/src',
]),
Finder::create()
->files()
->ignoreVCS(true)
->notName('/LICENSE|.*\\.md|.*\\.dist|Makefile|composer\\.json|composer\\.lock/')
->exclude([
'doc',
'test',
'test_old',
'tests',
'Tests',
'vendor-bin',
])
->in(__DIR__ . '/vendor'),
Finder::create()->append([
'bin/apidoc',
'composer.json',
]),
],
'whitelist' => [
'spaceonfire\\ApiDoc\\*',
'Composer\\Autoload\\*',
],
];
I can confirm this.
The problem is, how shall we approach this from within scoper?
Quick workaround, add the following to your scoper.inc.php
<?php
declare(strict_types=1);
use Isolated\Symfony\Component\Finder\Finder;
$symfonyPolyfills = (static function (): array {
$files = [];
foreach (
Finder::create()
->files()
->in(__DIR__ . '/vendor/symfony/polyfill-*')
->name('bootstrap.php') as $bootstrap
) {
$files[] = $bootstrap->getPathName();
}
return $files;
})();
return [
'whitelist' => [
'\Phpcq\PluginApi\*'
],
'files-whitelist' => $symfonyPolyfills,
];
Scratch my last comment, this results in the bootstrap files not being scoped but the classes implementing the polyfills are still scoped. So this is only half of the way to go.
The scoper should emit classes/functions from whitelisted files "as is" while still changing scoped class usage within. This is apparently not implemented yet.
Scratch my last comment, this results in the bootstrap files not being scoped but the classes implementing the polyfills are still scoped. So this is only half of the way to go.
In addition to workaround Symfony\Polyfill namespace should be also whitelisted like this:
<?php
declare(strict_types=1);
use Isolated\Symfony\Component\Finder\Finder;
$polyfillsBootstrap = Finder::create()
->files()
->in(__DIR__ . '/vendor/symfony/polyfill-*')
->name('bootstrap.php');
return [
'whitelist' => [
'spaceonfire\\ApiDoc\\*',
'Symfony\\Polyfill\\*',
],
'files-whitelist' => array_map(
static function ($file) {
return $file->getPathName();
},
iterator_to_array($polyfillsBootstrap)
),
];
You are right, I also stumbled upon that one also.
However, I feel we should address the root cause some how. What do you think might be the best approach?
I'm not too sure yet how this should be handled to be honest. A few ideas & notes:
- How to detect a polyfill? Should it be convention based (on the package name)? Passable via the config? (if via the config there can be a few default ones)
- Can this be done in one scoping process? For example by knowing what is being polyfilled we could correct some scoping or add the appropriate aliases. Or maybe this should be another scoping process with a different configuration
Hi, I recently stumbled upon this as well, my solution is the following: https://github.com/skaut/skaut-google-drive-gallery/blob/824202615bf397aae03d5be0fd74f0679b483507/scoper.inc.php#L44-L46
This works just fine for me, however, I'm using php-scoper with #457 and #460
Fixed it within PHP-Scoper this way https://github.com/humbug/php-scoper/pull/481; thanks all for the leads.
As we are all aware though, this is but a workaround. I am however not too sure how we could fix this yet
We stumbled upon this as well, when we tried to box a laravel zero application under php 7.4 but the box.phar requires php 8 as the get_debug_type gets the global namespace and the polyfills are scoped far far away.
Box has not been patched yet IIRC, but it shouldn’t be too hard to do so
On Sun 15 Aug 2021 at 02:57, Joshua Behrens @.***> wrote:
We stumbled upon this as well, when we tried to box a laravel zero application under php 7.4 but the box.phar requires php 8 as the get_debug_type gets the global namespace and the polyfills are scoped far far away.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/humbug/php-scoper/issues/440#issuecomment-898978164, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABHPVAPMRIRQKBAFKDTSVGLT44GIVANCNFSM4UCSSWCA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email .
So there is no pul request on box yet about it? ðŸ’
A doc entry has been added since then: https://github.com/humbug/php-scoper/blob/main/docs/further-reading.md#polyfills and with the new upcoming release this should also be drastically simper.