A custom .xphp file extension that automatically injects <?php and declare(strict_types=1) — write strict PHP without the boilerplate.

Maintainers

Package info

github.com/roastrofficial-ctrl/xphp

pkg:composer/roastrofficial-ctrl/xphp

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-03-22 13:43 UTC

This package is not auto-updated.

Last update: 2026-03-22 13:52:31 UTC


README

Write strict PHP without the boilerplate.

Every .xphp file automatically gets <?php declare(strict_types=1); — you never have to type it again.

// src/Services/UserService.xphp — just start writing

class UserService
{
    public function getUser(int $id): User
    {
        return User::find($id); // strict types enforced, no boilerplate needed
    }
}

Installation

composer require roastrofficial-ctrl/xphp

That's it. After composer install, the package:

  • Registers the xphp:// stream wrapper
  • Registers an SPL autoloader for .xphp files, reading your PSR-4 mappings automatically
  • Writes IDE config for PhpStorm and VS Code
  • Patches psalm.xml / phpstan.neon if they exist

Usage

Rename any .php file to .xphp and drop the opening boilerplate. The autoloader picks up your existing PSR-4 mappings from composer.json, so App\Services\UserService maps to src/Services/UserService.xphp exactly as you'd expect.

Files can start with raw code, or keep <?php if your editor needs it for syntax highlighting — both work:

// Option A — raw (no opening tag needed)
class MyClass { }

// Option B — keep the tag, skip the declare
<?php
class MyClass { }

Linting

# Lint a single file
vendor/bin/xphp-lint src/Services/UserService.xphp

# Lint an entire directory recursively
vendor/bin/xphp-lint src/

# Use in CI
vendor/bin/xphp-lint src/ && echo "All good"

Auto-detection of linters

xphp-lint automatically detects and runs any of these tools if they're installed in your project:

Linter Docs What it checks
php -l N/A Syntax errors (always runs)
pint laravel/pint Code style & formatting
phpstan phpstan.org Static type analysis
psalm psalm.dev Static type analysis + runtime errors

Zero configuration. If you have vendor/bin/pint in your project, it runs automatically on xphp-lint — with the .xphp file header transparently injected so all checks work correctly.

Examples

With only syntax checking (default):

$ vendor/bin/xphp-lint src/
✓ src/Services/UserService.xphp (php)
✓ src/Models/User.xphp (php)

With pint + syntax checking:

$ vendor/bin/xphp-lint src/
✓ src/Services/UserService.xphp (php + pint)
✓ src/Models/User.xphp (php + pint)

With pint, phpstan, and syntax checking:

$ vendor/bin/xphp-lint src/
✓ src/Services/UserService.xphp (php + pint + phpstan)
✓ src/Models/User.xphp (php + pint + phpstan)

If a file fails any check, all failing checks are reported:

$ vendor/bin/xphp-lint src/BadFile.xphp
✗ src/BadFile.xphp
  [php] Parse error: syntax error, unexpected end of file
  [pint] 5 style issues found

The lint command integrates seamlessly with your existing tooling — just install pint, phpstan, or psalm normally, and xphp-lint will pick them up automatically.

IDE Config

IDE config is written automatically after composer install. To re-run it manually:

vendor/bin/xphp-ide           # Write/update config
vendor/bin/xphp-ide --force   # Overwrite existing config
vendor/bin/xphp-ide --dry-run # Preview what would be written

What gets written

File Purpose
.idea/fileTypes/xphp.xml PhpStorm: treat .xphp as PHP
.vscode/settings.json VS Code/Cursor + Intelephense: treat .xphp as PHP
psalm.xml Psalm: scan .xphp files (if Psalm is installed)
phpstan.neon PHPStan: scan .xphp files (if PHPStan is installed)

These files are safe to commit to version control.

How it works

When PHP's autoloader encounters App\Services\UserService, it:

  1. Resolves the class to src/Services/UserService.xphp
  2. Loads the file via include 'xphp://...'
  3. The xphp:// stream wrapper intercepts, prepends the strict types header
  4. PHP compiles it — strict types enforced, no boilerplate ever written

The stream wrapper approach is used internally by Laravel, Psalm, and others. It carries no meaningful performance overhead.

Xdebug & line numbers

The header is injected on the same line as <?php (or as a single prepended line), so line numbers stay accurate for Xdebug.

Static analysis

PHPStan and Psalm will scan .xphp files after composer install. Since the strict types declaration is injected at runtime, not present in the source, you may want to tell your analyser to assume it globally:

Psalm: add useStrictTypes="true" to <psalm> in psalm.xml.

PHPStan: this is the default behaviour in strict mode (--level=max).

Running with lint command

Both tools are automatically integrated into vendor/bin/xphp-lint if installed:

# If phpstan is installed, it runs automatically
vendor/bin/xphp-lint src/
# Output: ✓ src/MyClass.xphp (php + phpstan)

# Same with psalm
vendor/bin/xphp-lint src/
# Output: ✓ src/MyClass.xphp (php + psalm)

No additional setup needed — the lint command handles header injection and transparently passes .xphp files to your analyser.

License

MIT