nette / php-generator

🐘 Generates neat PHP code for you. Supports new PHP 8.3 features.
https://doc.nette.org/php-generator
Other
2.11k stars 138 forks source link

Heredoc and Nowdoc converted to inline string when parsed #151

Closed GromNaN closed 9 months ago

GromNaN commented 9 months ago

Version: 4.1.2

PHP                              8.3.1
nette/php-generator              v4.1.2
nette/utils                      v4.0.4
nikic/php-parser                 v4.18.0

Bug Description

When a PHP file contains a heredoc or a nowdic, it is converted to a double-quoted string by the parsed. This transforms the contents of a the files that are modified using this package, and this can generate invalid PHP syntax if the string contains a double quote.

Steps To Reproduce

Create a file that contains a heredoc or a nowdoc (called file.php):

<?php

function test()
{
    return <<<'EOL'
        Hello "You"!
        EOL;
}

Create a script that reads this file, parse it and dump it:

<?php

use Nette\PhpGenerator\PhpFile;
use Nette\PhpGenerator\PsrPrinter;

require __DIR__ . '/vendor/autoload.php';

$file = PhpFile::fromCode(file_get_contents(__DIR__ . '/file.php'));

echo (new PsrPrinter())->printFile($file);

Run the script.

The result is an invalid PHP file with the string inlined in double quotes.

<?php

function test()
{
    return "Hello "You"!";
}

Expected Behavior

The output should be identical to the input file.php.

<?php

function test()
{
    return <<<'EOL'
        Hello "You"!
        EOL;
}

Possible Solution

No idea, sorry.

GromNaN commented 9 months ago

Thanks for the fix @dg. Isn't it possible to keep the heredoc/nowdoc in the function body?

dg commented 9 months ago

In principle, since PHP 7.3 it is possible, I will try to implement it.

dg commented 9 months ago

@GromNaN it should be working in master by now, can you test it?

GromNaN commented 9 months ago

Perfect, it works. The upgrade to nikic/php-parser: v5.0.0 was not required but nice to have. Thank you!