Skip to content

lint-php always uses the php on PATH; .nette-claude.json fatals on a PHP 7.4 launcher #7

Description

@jancinert

Setup

Windows, several PHP runtimes side by side. php on PATH is 7.4 because the main project targets 7.4; other repositories on the same machine require PHP 8.3.

1. lint-php cannot use a different PHP than the one running the hook

hooks/lint-php.php lints with PHP_BINARY:

exec(escapeshellarg(PHP_BINARY) . ' -l ' . escapeshellarg($filePath) . ' 2>&1', $output, $exitCode);

hooks.json starts the hook as bare php, so the linting version is whatever php resolves to — one global choice for every project on the machine. Editing a PHP 8 file then reports a syntax error that is not one:

PHP syntax error in .../SchoolInquiryFormConfig.php:
Parse error: syntax error, unexpected 'private' (T_PRIVATE), expecting variable (T_VARIABLE) on line 12

Line 12 is constructor property promotion, in a project whose composer.json says "php": ">=8.3". The check is permanently red, which is worse than no check — a real syntax error looks exactly the same.

.nette-claude.json can only exclude paths, so the only workaround is switching the check off for the whole repository.

Suggestion. The hook already reads a project config; a binary key next to exclude would be enough:

{ "lint-php": { "binary": "C:\php8.4\php.exe" } }
$binary = configValue($filePath, 'lint-php', 'binary') ?? PHP_BINARY;

Deriving it from require.php in the nearest composer.json would work too and need no new configuration.

2. .nette-claude.json fatals when the hooks run on PHP 7.4

hooks/hook-config.php uses PHP 8.0+ functions:

$anchored = str_starts_with($pattern, '/');            // line 89
if (!$anchored && !str_contains($pattern, '/')) {      // line 96

The hooks are started with bare php, which is not guaranteed to be PHP 8. With a 7.4 launcher, any .nette-claude.json above the edited file turns every hook that reaches matchesPattern() into:

Fatal error: Uncaught Error: Call to undefined function str_starts_with()
  in hooks/hook-config.php:89

So on exactly the setups where the exclusion is needed — an old php on PATH — the exclusion cannot be used. hooks/lint-php.php itself is 7.4-compatible; only the shared config helper is not.

Suggestion. Polyfill the two calls, or document a minimum PHP version for the launcher. The file's own comment says it is duplicated into every plugin, so the fix applies to all of them.

Versions

nette-lint 1.1.0, launcher PHP 7.4.33, Windows.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions