Home Documentation Download Pricing Buy Now

Formatted PHP attributes leads to invalid PHP on next export

0 votes

We are using Prettier (with the PHP plugin) in our project, and after changing Doctrine data format from annotations to attributes in Skipper, we ran into issues. The first export from Skipper goes fine, then Prettier formats those attributes a little differently than Skipper did. They are still valid PHP after prettier formatting, but then when exporting from Skipper again, the result is a syntax error (Prettier's output of course depends on settings, but mostly I think the issue is with changing them from one single line to multiple lines, or the trailing comma).

Here's an example:

After first export from Skipper:

#[ORM\Entity(repositoryClass: "Our\AppBundle\Entity\Repository\DataRepository")]
#[ORM\Table(name: "data", options: ["collate"=>"utf8_swedish_ci"])]
class Data
{
  #[ORM\Id]
  #[ORM\ManyToOne(targetEntity: \Our\AppBundle\Entity\Document::class)]
  #[ORM\JoinColumn(name: "document", referencedColumnName: "id", nullable: false)]
  private $Document;
  // ...

After Prettier formatting:

#[
  ORM\Entity(
    repositoryClass: 'Our\AppBundle\Entity\Repository\DataRepository',
  ),
]
#[ORM\Table(name: 'data', options: ['collate' => 'utf8_swedish_ci'])]
class Data
{
  #[ORM\Id]
  #[
    ORM\ManyToOne(
      targetEntity: \Our\AppBundle\Entity\Document::class,
    ),
  ]
  #[
    ORM\JoinColumn(
      name: 'document',
      referencedColumnName: 'id',
      nullable: false,
    ),
  ]
  private $Document;
  // ...

Then exporting from Skipper again (without any schema changes):

#[, ORM\Entity(repositoryClass: "Our\AppBundle\Entity\Repository\DataRepository")]
#[ORM\Table(name: "data", options: ["collate"=>"utf8_swedish_ci"])]
class Data
{
  #[]
  #[, ORM\Id]
  #[ORM\ManyToOne(targetEntity: \Our\AppBundle\Entity\Document::class), ORM\JoinColumn(name: "document", referencedColumnName: "id", nullable: false)]
  private $Document;
  // ...

And that PHP file is invalid and causes syntax error when trying to run the app. Of course Skipper doesn't need to know how to output similar formatting as Prettier, but the expected result would be that when nothing has been changed, then Skipper export doesn't modify the files. And when something has been changed, it can output same way that it originally did, and any formatting on that can be done after the export.

Skipper version is the latest (3.5.0.1878)

asked 4 days ago in Bug report by cvuorinen (390 points)
edited 4 days ago by cvuorinen

thank you for the report. Can you please send my skipper project + before/after php file where we can simulate this issue? Please send it to [email protected]

Thank you

The trigger is not the multi-line layout itself, but the trailing comma that Prettier puts after the last attribute inside the group:

#[
    ORM\Entity(
        repositoryClass: 'Our\AppBundle\Entity\Repository\DataRepository',
    ),          <-- this comma
]

Our PHP attribute parser reads the comma as a separator and then expects another attribute after it. It finds the closing ] instead and records an empty attribute in the group. On the next export that empty entry is written out again, which produces #[, ORM\Entity(...)] and invalid PHP.

We confirmed the isolation with two test cases:

  • Multi-line attributes without the trailing comma: exported correctly.
  • Single-line attribute with a trailing comma, #[ORM\Entity(...),]: broken in the same way.

So any Prettier configuration that emits a trailing comma inside #[ ... ] will hit this, regardless of line breaks.

We are working on the fix. The parser will skip a trailing comma before the closing bracket. Please note that Skipper will still rewrite the attributes into its own single-line format on export; the fix makes the output valid PHP again, it does not preserve the Prettier layout. If keeping your formatting untouched between exports is important to you, please let us know and we will evaluate it separately.

As a workaround until the fix is released, you can disable trailing commas for PHP attributes in your Prettier configuration.

1 Answer

0 votes
 
Best answer

Fixed in beta 3.5.1.1887:
https://www.skipper18.com/support/402/downloads-skipper-beta

The trailing comma a formatter writes before the closing bracket made the parser record an
attribute that is not in the source, and the export wrote it back as a bare separator. Attribute
argument lists and docblock annotation argument lists are fixed as well.

This fixes the invalid PHP, not the formatting: mapped attributes are still written on a single
line with double quotes, so Prettier will still show a diff after an export.

Please try it and let us know. Thanks

answered 21 hours ago by ludek.vodicka Skipper developer (140,970 points)
selected 19 hours ago by cvuorinen

Yes, this fixed the problem. Thanks a lot for a quick fix.
Although, I found another problem. Opening a new ticket for that one...

thanks for quick test.
yes, feel free to open new ticket, we will check it.

...