Download the PHP package xphp-lang/xphp-symfony-bundle without Composer
On this page you can find all versions of the php package xphp-lang/xphp-symfony-bundle. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download xphp-lang/xphp-symfony-bundle
More information about xphp-lang/xphp-symfony-bundle
Files in xphp-lang/xphp-symfony-bundle
Package xphp-symfony-bundle
Short Description Symfony bundle to write XPHP (PHP with native generics) inside a Symfony app and deploy the auto-generated PHP.
License MIT
Homepage https://github.com/xphp-lang/xphp-symfony-bundle
Informations about the package xphp-symfony-bundle
XPHP Symfony Bundle
Write XPHP — PHP 8.4 with native generics via compile-time monomorphization — inside a Symfony application, and have the auto-generated vanilla PHP produced as part of your normal build/deploy.
The bundle wires xphp's transpiler into the Symfony lifecycle:
- a
xphp:compileconsole command to compile on demand during development; - a cache warmer so
bin/console cache:warmup(run by every production build) emits the generated PHP as a deterministic deploy artifact; - a runtime autoloader for the generated
XPHP\Generated\*classes, so the app boots against fresh output without acomposer dump-autoload.
Requirements
- PHP
^8.4 - Symfony
^8.0 xphp-lang/xphp^0.1(pulled in automatically)
Installation
Register the bundle (Symfony Flex does this for you):
Configuration
Defaults (override only what you need):
These map directly to the upstream CLI: xphp compile <source> <target> <cache>.
Layout & autoloading
A .xphp source uses standard PSR-4 namespace-to-directory mapping. Compilation
produces two outputs:
| Output | Namespace | Goes to |
|---|---|---|
| Rewritten user code | original (e.g. App\…) |
target dir |
| Specialized classes | XPHP\Generated\… |
<cache>/Generated/ |
The bundle autoloads XPHP\Generated\* at runtime out of the box. For the
rewritten code you choose where the application loads App\ from. For a
production deploy, point composer at the compiled output and dump an optimized
classmap:
When composer owns the classmap, you can set register_runtime_autoloader: false.
Usage
-
Put your generics under the
sourcedirectory, e.g.: -
Compile during development:
…or just warm the cache (also runs the compiler):
- Reference the generated classes from your app as usual; instantiations like
Collection<User>are monomorphized to concrete classes with native type hints and zero runtime penalty.
Generic services (dependency injection)
Service-like generics — Repository<User>, CachedFinder<User>, Handler<Cmd> —
can be registered in the container and autowired. This is opt-in: declare each
instantiation under xphp.services.bindings. Value-type generics (Box<T>,
Collection<T>) are not meant for DI — keep new-ing those.
The bundle resolves each binding to the class the transpiler monomorphizes it into
(XPHP\Generated\…\T_<hash>, via the transpiler's own Registry::generatedFqn) and
registers it as a service under that class name.
The class that consumes the generic must itself be .xphp — only .xphp can
name CachedFinder<User> as a type. Write that consumer (a service, a command, a
controller) in .xphp, register it as a service, and inject the generic directly;
its compiled constructor type is the hash class, so autowiring matches with no
seam needed:
(If a specialization does implement a stable interface, set alias: on the binding
to that interface so handwritten .php can inject it — but a generic implementing a
type-specific interface is usually a smell.)
Declaring a binding makes compilation run at container-build time (so the
generated classes exist for autowiring/autoconfigure), and the container is rebuilt
when any .xphp source changes. No separate xphp:compile step is needed.
Two rules for DI-bound generics
- Write collaborator types fully-qualified in the template (no
use): monomorphization fully-qualifies type parameters but copies other type references verbatim, so a shortuse-imported name would resolve into the generatedXPHP\Generated\…namespace. Write\App\Finder\SourceInterface, not ausedSourceInterface. - You don't need a call site. A generic that's only injected is never written as
new Foo::<Bar>()anywhere, yet monomorphization is usage-driven. The bundle bridges this by synthesizing a throwaway instantiation for each declared binding at compile time (transparent; cleaned up afterwards). (Stopgap: a future xphp release may accept specialization roots directly.)
Autowire the specialization (or its alias), not the bare template name —
App\Generic\CachedFindercompiles to an empty marker interface that every specialization implements, so it is ambiguous across type arguments.
Deploy
A typical build step needs nothing xphp-specific beyond what you already run:
Commit .xphp sources; treat var/xphp/ as generated (gitignored), regenerated
on each build. If you prefer to ship precompiled PHP without xphp on the target,
run xphp:compile in CI and include the target/cache dirs in the artifact.
The cache warmer is mandatory and fail-loud: if compilation fails during
cache:warmup, the command exits non-zero and the build aborts, so a broken
artifact (missing or stale XPHP\Generated\* classes) never ships.
Compiling in a separate step (compile_on_warmup: false)
If you'd rather drive compilation explicitly — e.g. a dedicated CI stage, or to
keep cache:warmup free of transpilation — turn the warmer off:
The bundle then never compiles on its own; you own the step and must run it
before the app is deployed (and before composer dump-autoload, since the
optimized classmap is built from the generated output):
xphp:compile is itself fail-loud — it exits non-zero on a compilation error —
so a CI stage running it will stop the pipeline just like the warmer would.
With the warmer disabled, cache:warmup no longer regenerates var/xphp/, so
make sure your build runs xphp:compile on every deploy; otherwise the app
boots against whatever output happens to be on disk.
Try the demo
A runnable, console-only example app lives in demo/. It writes .xphp
generics alongside plain PHP in one src/, compiles them through this bundle, and
calls the generated code from a Symfony command:
Development
License
MIT
All versions of xphp-symfony-bundle with dependencies
symfony/config Version ^8.0
symfony/console Version ^8.0
symfony/dependency-injection Version ^8.0
symfony/http-kernel Version ^8.0
xphp-lang/xphp Version ^v0.2.0