nikic / PHP-Parser

A PHP parser written in PHP
BSD 3-Clause "New" or "Revised" License
16.98k stars 1.09k forks source link

Hexadecimal representation of strings #1014

Closed sergio-fferreira closed 1 month ago

sergio-fferreira commented 1 month ago

Hi, I want to create a string node that, when pretty printed, outputs strings in its hexadecimal representation, for example:

echo "\x68\x65\x6c\x6c\x6f";    // hello

I tried to use the kind attribute to force the use of double quotes:

new Scalar\String_('\x68\x65\x6c\x6c\x6f', ['kind' => String_::KIND_DOUBLE_QUOTED]);

However, that returns escaped strings:

"\\x68\\x65\\x6c\\x6c\\x6f"

Similarly, I also set the rawValue attribute, but it doesn't seem to affect the result, so I assume the value is only created when parsing code to AST, for reading purposes.

Thank you in advance.

nikic commented 1 month ago

The only way to achieve this currently would be to override pScalar_String in the pretty printer to produce the desired escaping.

sergio-fferreira commented 1 month ago

Thank you, indeed I got it working.

For those who want to achieve the same thing, you must override pScalar_String:

class MyPrettyPrinter extends PrettyPrinter\Standard {
    #[Override]
    protected function pScalar_String(Scalar\String_ $node): string {
        $literalString = $node->getAttribute('literal', false);

        if ($literalString) {
            return '"' . $node->value . '"';
        } else {
            return parent::pScalar_String($node);
        }
    }
}

Then, use this new class instead of the standard pretty printer and finally create strings with the literal attribute set:

new String_('\x68\x65\x6c\x6c\x6f', ['literal' => true])

Notice the single quotes used in the value. This will create a string such as:

echo "\x68\x65\x6c\x6c\x6f";