laminas/laminas-code
Generate, analyze, and manipulate PHP code with Laminas Code. Provides reflection utilities, code generators, docblock parsing, and class/file generation helpers for building frameworks, tooling, and meta-programming workflows.
Start with the core classes: Laminas\Code\Generator\ClassGenerator, Laminas\Code\Reflection\ClassReflection, and Laminas\Code\DocBlock\DocBlock. These form the foundation for most day-to-day usage.
First use case: Generate a simple class with properties and methods programmatically, now fully compatible with PHP 8.5.
use Laminas\Code\Generator\ClassGenerator;
use Laminas\Code\Generator\PropertyGenerator;
use Laminas\Code\Generator\MethodGenerator;
$class = new ClassGenerator('App\Domain\User');
$class->addPropertyFromGenerator(new PropertyGenerator('name', 'protected'))
->addMethodFromGenerator(
MethodGenerator::fromArray([
'name' => 'getName',
'flags' => MethodGenerator::FLAG_PUBLIC,
'body' => 'return $this->name;',
'returnType' => 'string', // Note: Cleaner return-type formatting (no extra space before colon)
])
);
echo $class->generate();
Check the updated Laminas Code documentation for PHP 8.5-specific examples and full API details.
PHP 8.5+ feature support: Leverage PHP 8.5’s new features (e.g., array_unpack, str_contains) in generated code. The package now fully supports PHP 8.5’s type system and reflection capabilities.
Scaffolding pipelines: Integrate code generation into CLI tools or build scripts (e.g., php bin/generate:user --name=Product). Use FileGenerator to write files directly to disk, ensuring compatibility with PHP 8.5’s stricter type hints.
Runtime introspection & orchestration: Use ClassReflection to inspect classes at runtime, now optimized for PHP 8.5’s reflection improvements. Ideal for dependency injection, event subscribers, or command discovery.
Annotation-style metadata extraction: Parse docblocks to extract custom metadata (e.g., @Route("/users")) using DocBlock::createAttached() or DocBlockFactory. Combine with code generation to create lightweight DTOs or value objects, ensuring compatibility with PHP 8.5’s stricter docblock parsing.
Code transformation layers: Build tools that read source files, apply transformations (e.g., add logging, enforce PSR rules), and write them back. Use Laminas\Code\Scanner\DocBlockScanner and FileParser for static analysis workflows, now fully aligned with PHP 8.5’s syntax.
CI integration: Run generation/validation steps in pre-commit hooks or CI jobs. Since laminas-code is PHPSB-compliant and supports PHP 8.5, it’s ideal for static tooling in modern environments.
PHP version compatibility:
array_unpack or new attribute syntax (#[SomeAttribute]). Use ClassReflection for runtime checks if needed.DocBlock parsing quirks: Custom annotations require careful tag naming and ordering. The @param and @return types must match the actual code or PhpScanner may misinterpret offsets. Prefer strict types (int, string) over @var when possible, especially in PHP 8.5 where type hints are stricter.
Mutable generator objects: Methods like addPropertyFromGenerator() return the generator instance — not the added property — for chaining. Don’t expect them to give you a reference to the newly added item unless you capture it separately.
Code style control:
MethodGenerator now removes extra spaces before the return-type colon (e.g., function foo(): string instead of function foo(): string). Override generate() only if you need custom formatting.Native reflection fallback: In performance-sensitive contexts (e.g., hot paths), prefer ClassReflection over ClassGenerator — the latter is for writing code, not inspecting at scale. You can use ReflectionClass alongside laminas-code safely, but ClassReflection is now optimized for PHP 8.5.
Extensibility points:
Laminas\Code\Generator\DocBlockGenerator or Laminas\Code\Generator\PropertyGenerator for domain-specific concerns (e.g., ORM metadata).generate() only as a last resort — prefer composition.ReflectionProperty::setAccessible() calls (deprecated in PHP 8.5) and replace them with ReflectionProperty::setAccessible(true) or visibility modifiers in generated code.Performance: The removal of defunct setAccessible() calls in ClassReflection may improve performance in large-scale projects. Benchmark if you rely heavily on runtime introspection.
How can I help you explore Laravel packages today?