Projectsphp-builderClasses

PHP Builder

Package

A PHP code builder for programmatically generating classes, interfaces, traits, and enums.

Classes

PhpClass is the primary file builder. Call toPhp() with no indent to emit a complete PHP file (opening tag, strict types, namespace, imports, and the class body). Nested/indented output is also supported when you pass $indent > 0.

use BradieTilley\Builder\PhpClass;
use BradieTilley\Builder\PhpMethod;

$class = new PhpClass(
    namespace: 'App\\Models',
    name: 'Post',
    extends: 'App\\Models\\Model',
    implements: [
        'App\\Contracts\\Sluggable',
    ],
    traits: [
        'App\\Models\\Concerns\\HasSlug',
    ],
    description: 'A blog post',
    abstract: false,
    final: false,
    readonly: false,
    strictTypes: true,
);

echo $class->toPhp();

Constructor options

ArgumentTypeDefaultNotes
namestringShort class name
namespacestring''Empty omits the namespace declaration
extends?stringnullFQCN or short name
implementslist<string>|string[]One interface or a list
traitslist<PhpUseTrait|string>[]Strings become simple use Trait;
constantslist<PhpClassConstant>[]See Attributes & Constants
propertieslist<PhpProperty>[]See Properties & Hooks
methodslist<PhpMethod>[]See Methods & Arguments
attributeslist<PhpAttribute>[]Class-level attributes
description?stringnullClass docblock summary
templateslist<PhpTemplate|string>[]@template tags on the class docblock
abstractboolfalseMutually exclusive with final in practice (abstract wins in the signature)
finalboolfalseEmitted when not abstract
readonlyboolfalsereadonly class
strictTypesbooltrueControls declare(strict_types=1);

All of these are public properties, so you can append members after construction:

$class->methods[] = new PhpMethod(name: 'boot', visibility: PhpMethod::protected());
$class->properties[] = new PhpProperty(type: 'string', name: 'title');

Class modifiers

new PhpClass(name: 'Base', abstract: true);
new PhpClass(name: 'Sealed', final: true);
new PhpClass(name: 'Config', readonly: true);

Inheritance & traits

Pass FQCNs for extends, implements, and traits. They are reserved early so later type imports alias correctly when basenames collide (e.g. your App\Models\Model parent vs Illuminate\Database\Eloquent\Model in a return type).

For trait adaptations (as / insteadof), pass a PhpUseTrait instead of a string — see Traits.

Generics templates

use BradieTilley\Builder\PhpTemplate;

new PhpClass(
    name: 'Collection',
    templates: [
        new PhpTemplate(name: 'TKey', of: 'array-key', covariant: true),
        new PhpTemplate(name: 'TValue'),
        'TExtra', // string shorthand → @template TExtra
    ],
);

Mutating after construction

Builders are ordinary objects. A common pattern is to create the class, call import() to reserve an alias for use inside method bodies, then push methods that reference that alias:

$class = new PhpClass(namespace: 'App\\Models', name: 'Post');

$tagQuery = $class->import('App\\Support\\TagQuery'); // "TagQuery" or an auto alias
// Or force a name when you know of a clash:
// $tagQuery = $class->import('App\\Support\\TagQuery', 'SupportTagQuery');

$class->methods[] = new PhpMethod(
    name: 'syncTags',
    return: 'static',
    lines: [
        "\$query = {$tagQuery}::make(\$tags);",
        'return $this;',
    ],
);

File output

toPhp() (with default indent 0) produces:

  1. <?php
  2. Optional declare(strict_types=1);
  3. Optional namespace …;
  4. Sorted use lines from the import bag
  5. Class attributes, signature, and body sections (traits → constants → properties → methods), separated by blank lines

Optionally pipe the result through PhpFormatter.

Continue to Interfaces, or jump to Methods & Arguments.