symfony / polyfill

PHP polyfills

Home Page:https://symfony.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

PHP 8.0 polyfill compatibility

IonBazan opened this issue · comments

I'm opening this issue to discuss the ways we could assure compatibility of symfony/polyfill-php80 with PHP versions < 7.0.
The only reason we require PHP >= 7.0 for this polyfill is fdiv() function that I found impossible to port to older versions and recently added type hints. However, all other features we polyfilled so far:

  • Stringable interface
  • ValueError class
  • FILTER_VALIDATE_BOOL constant
  • preg_last_error_msg function
  • str_contains function
  • get_debug_type function

would work just fine on PHP 5.3+! Maybe it would be worth considering enabling support for older versions of PHP and just conditionally disabling fdiv polyfill on older versions. I know it would add an extra condition in bootstrap.php but we should decide if we want more compatibility or more consistency of polyfilled features.

We can split the class in two Php80 and Php80Fdiv. Up for a PR?

But we could also let things as is. PHP 5 is getting old, why spend time on it now?

Do we wanna polyfill https://wiki.php.net/rfc/token_as_object too (assuming it is accepted).

Only if one needs it, so it should come by demand IMHO, not by anticipation. And the one demanding should be the implementer ideally also.

What about str_starts_with and str_ends_with? Looks like these were added as well.

https://php.watch/versions/8.0/str_starts_with-str_ends_with

@GrahamCampbell to follow your comment, I agree with you, and until it will include in polyfill-php80, an alternative exists at https://github.com/PHPWatch/phptoken-polyfill

There's also class Attribute - I didn't see any issues or PRs mentioning this.

E.g. in this example snippet, it would throw an Error in php 7 and older if there was no definition for Attribute

<?php

// This line crashes without a polyfill for Attribute.
const FUNCTIONLIKE_ATTRIBUTES = Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD; 

#[Attribute(FUNCTIONLIKE_ATTRIBUTES)]
function example() {
}

More broadly, in code which extracts attributes (e.g. from the tokenization in php 7 converting T_COMMENT to attributes), or in code which optionally supports attributes, it would also be useful to have a polyfill of attributes.

E.g. statically checking if an class could be a repeatable attribute, you'd need to know Attribute::TARGET_ATTRIBUTE.
(Context: I'm currently working on attribute static analysis support for https://github.com/phan/phan/ v4)

  • It's easy enough for an application to add its own polyfill/workarounds, and this is a rare use case, so I don't have strong opinions of whether it's required.
  • There's also the possibility that more class constants would get added to Attribute later. I guess any polyfill could just use the newest php 8.x version's functionality and be backwards compatible.

An reference polyfill to match php 8.0 would be

<?php

// EDIT: Attribute would have #[Attribute] to indicate that it is an attribute
#[Attribute(Attribute::TARGET_CLASS)]
final class Attribute {
    const TARGET_CLASS = 1;
    const TARGET_FUNCTION = 2;
    const TARGET_METHOD = 4;
    const TARGET_PROPERTY = 8;
    const TARGET_CLASS_CONSTANT = 16;
    const TARGET_PARAMETER = 32;
    const TARGET_ALL = 63;
    const IS_REPEATABLE = 64;

    /** @var int */
    public $flags;

    public function __construct(int $flags = Attribute::TARGET_ALL) {
        $this->flags = $flags;
    }
}

That'd make sense, PR welcome!