PHP-Parser/UPGRADE-5.0.md

125 lines
5.0 KiB
Markdown
Raw Normal View History

2022-06-04 12:20:20 +02:00
Upgrading from PHP-Parser 4.x to 5.0
====================================
2022-06-04 12:27:41 +02:00
### PHP version requirements
PHP-Parser now requires PHP 7.1 or newer to run. It is however still possible to *parse* code for older versions, while running on a newer version.
2022-06-06 16:45:02 +02:00
### PHP 5 parsing support
2022-06-12 21:14:22 +02:00
The dedicated parser for PHP 5 has been removed. The PHP 7 parser now supports a `phpVersion` option, which can be used to improve compatibility with older PHP versions.
2022-06-06 16:45:02 +02:00
In particular, if an older `phpVersion` is specified, then:
* For versions before PHP 7.0, `$foo =& new Bar()` assignments are allowed without error.
* For versions before PHP 7.0, invalid octal literals `089` are allowed without error.
* Type hints are interpreted as a class `Name` or as a built-in `Identifier` depending on PHP
version, for example `int` is treated as a class name on PHP 5.6 and as a built-in on PHP 7.0.
However, some aspects of PHP 5 parsing are no longer supported:
* Some variables like `$$foo[0]` are valid in both PHP 5 and PHP 7, but have different interpretation. In that case, the PHP 7 AST will always be constructed (`($$foo)[0]` rather than `${$foo[0]}`).
* Declarations of the form `global $$var[0]` are not supported in PHP 7 and will cause a parse error. In error recovery mode, it is possible to continue parsing after such declarations.
* The PHP 7 parser will accept many constructs that are not valid in PHP 5. However, this was also true of the dedicated PHP 5 parser.
2022-06-12 21:14:22 +02:00
The following symbols are affected by this removal:
* The `PhpParser\Parser\Php5` class has been removed.
* The `PhpParser\Parser\Multiple` class has been removed. While not strictly related to PHP 5 support, this functionality is no longer useful without it.
* The `PhpParser\ParserFactory::ONLY_PHP5` and `PREFER_PHP5` options have been removed.
* The `PhpParser\ParserFactory::PREFER_PHP7` option is now equivalent to `ONLY_PHP7`.
### Changes to the parser factory
The `ParserFactory::create()` method is deprecated in favor of three new methods that provide more fine-grained control over the PHP version being targeted:
* `createForNewestSupportedVersion()`: Use this if you don't know the PHP version of the code you're parsing. It's better to assume a too new version than a too old one.
* `createForHostVersion()`: Use this if you're parsing code for the PHP version you're running on.
* `createForVersion()`: Use this if you know the PHP version of the code you want to parse.
In all cases, the PHP version is a fairly weak hint that is only used on a best-effort basis. The parser will usually accept code for newer versions if it does not have any backwards-compatibility implications.
For example, if you specify version `"8.0"`, then `class ReadOnly {}` is treated as a valid class declaration, while using `public readonly int $prop` will lead to a parse error. However, `final public const X = Y;` will be accepted in both cases.
2022-06-12 21:18:11 +02:00
```php
use PhpParser\ParserFactory;
$factory = new ParserFactory;
# Before
$parser = $factory->create(ParserFactory::PREFER_PHP7);
# After (this is roughly equivalent to PREFER_PHP7 behavior)
$parser = $factory->createForNewestSupportedVersion();
# Or
$parser = $factory->createForHostVersion();
# Before
$parser = $factory->create(ParserFactory::ONLY_PHP5);
# After (supported on a best-effort basis)
$parser = $factory->createForVersion("5.6");
```
### Changes to the default pretty printer
A number of changes to the standard pretty printer have been made, to make it match contemporary coding style conventions (and in particular PSR-12). Options to restore the previous behavior are not provided, but it is possible to override the formatting methods (such as `pStmt_ClassMethod`) with your preferred formatting.
Return types are now formatted without a space before the `:`:
```php
# Before
function test() : Type
{
}
# After
function test(): Type
{
}
```
`abstract` and `final` are now printed before visibility modifiers:
```php
# Before
public abstract function test();
# After
abstract public function test();
```
2022-06-04 13:22:58 +02:00
A space is now printed between `use` and the following `(` for closures:
```php
# Before
function () use($var) {
};
# After
function () use ($var) {
};
```
### Changes to token representation
Tokens are now internally represented using the `PhpParser\Token` class, which exposes the same base interface as
the `PhpToken` class introduced in PHP 8.0. On PHP 8.0 or newer, `PhpParser\Token` extends from `PhpToken`, otherwise
it extends from a polyfill implementation. The most important parts of the interface may be summarized as follows:
```php
class Token {
public int $id;
public string $text;
public int $line;
public int $pos;
public function is(int|string|array $kind): bool;
}
```
The `Lexer::getTokens()` method will now return an array of `Token`s, rather than an array of arrays and strings.
2022-06-06 16:45:02 +02:00
Additionally, the token array is now terminated by a sentinel token with ID 0.
2022-06-12 21:14:22 +02:00
### Other removed functionality
* The deprecated `Builder\Param::setTypeHint()` method has been removed in favor of `Builder\Param::setType()`.