Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

README.md

XPHP Symfony bundle — demo app

A minimal, console-only Symfony app that uses the xphp-lang/xphp-symfony-bundle (consumed locally via a Composer path repository). It shows the whole loop: write .xphp generics → compile them with the bundle → call the generated PHP from a handwritten Symfony command.

Layout: one src/, two kinds of file

.xphp and plain .php files live side by side under src/:

src/
├── Command/DemoCommand.php   # handwritten PHP — calls into the compiled Catalog
├── Models/Plastic.php        # handwritten PHP — left untouched by the build
├── Containers/Box.xphp       # generic template  class Box<T>
├── Demo/Catalog.xphp         # uses new Box::<Plastic>()  (so it must be .xphp)
└── Kernel.php

The bundle's compiler is pointed at src/ (see config/packages/xphp.yaml) but only ever processes *.xphp; your *.php files are ignored and stay byte-for-byte the same. Compiled output goes to var/xphp/ and App\ is mapped (in composer.json) to both src/ and var/xphp/dist/, so each class resolves to exactly one real .php:

Class Loaded from Kind
App\Command\DemoCommand src/Command/DemoCommand.php handwritten
App\Models\Plastic src/Models/Plastic.php handwritten, untouched
App\Containers\Box var/xphp/dist/Containers/Box.php compiled (supertype)
App\Demo\Catalog var/xphp/dist/Demo/Catalog.php compiled
XPHP\Generated\…\T_<hash> var/xphp/generated/Generated/… generated (specialized)

The generated XPHP\Generated\* classes are autoloaded by the bundle's runtime autoloader — no extra composer config needed.

Run it

Requires PHP 8.4+.

cd demo
composer install
bin/console xphp:compile     # src/*.xphp -> var/xphp/dist + var/xphp/generated
bin/console app:demo

Expected output: the colors red, blue produced by the compiled Catalog, plus the concrete XPHP\Generated\App\Containers\Box\T_<hash> class that Box<Plastic> was monomorphized into — proving it's the generated PHP that actually runs.

In a real deploy you'd skip the explicit xphp:compile: bin/console cache:warmup runs the compiler as part of the standard build (see the bundle README).

Two patterns, side by side

The demo shows both ways to use a generic:

1. Value type — app:demo (Box<Plastic> / Catalog). You new the generic inside .xphp; handwritten code calls the compiled class. No DI involved.

2. Service via DI — app:find (CachedFinder<User>). The generic is registered as a service and constructor-autowired, with real service dependencies:

bin/console app:find
  lookup #1:        Ada
  lookup #1 again:  Ada
  source queried:   1 time(s) for 2 lookups (cache-aside works)
 [OK] Autowired concrete type: XPHP\Generated\App\Generic\CachedFinder\T_<hash>

FindCommand is itself an .xphp file — that's what lets it name CachedFinder<User> as a constructor type. Its compiled form injects the monomorphized class directly (no interface, no alias), and that class's own CacheInterface + SourceInterface deps were autowired. No xphp:compile needed first — declaring the binding in config/packages/xphp.yaml makes compilation run at container build.

Inspect the wiring:

bin/console debug:container 'App\Command\FindCommand'
# -> ctor arg autowired to XPHP\Generated\App\Generic\CachedFinder\T_<hash>

What to look at

  • src/Demo/Catalog.xphp — the only place that writes Box<Plastic> (value-type path).
  • src/Generic/CachedFinder.xphp — the generic service. It implements no interface (a T-generic class can't honestly implement a User-specific one); note its collaborator types are written fully-qualified (\App\Finder\SourceInterface), not used.
  • src/Command/FindCommand.xphp — a .xphp command whose constructor takes CachedFinder<User>. Compare it with var/xphp/dist/Command/FindCommand.php: the #[AsCommand] attribute and use statements survive; only the generic type-hint is rewritten to the hash class.
  • config/packages/xphp.yaml — the services.bindings entry that turns CachedFinder<User> into an autowireable service.
  • src/Models/Plastic.php — compare before/after a compile; it never changes.