Model Generation

Generate Doctrine ORM entity models with three different approaches: simple generation, interactive wizard, or quick CLI syntax. Choose the method that fits your workflow.

Three Ways to Create Models

ZephyrPHP offers three commands for model generation, each suited to different scenarios:

Command Best For Complexity
make:model Simple models, quick scaffolding Low
model:wizard Complex models, interactive building Medium to High
model:build Quick one-liners, scripting Medium

make:model - Simple Model Generation

Create a basic Doctrine ORM entity model with standard id, timestamps, and any additional fields you specify.

Command
php craftsman make:model [name] [fields]

Arguments

Argument Type Description
name Required Model name in PascalCase (e.g., User, BlogPost)
fields Optional Comma-separated field definitions (name:type)

Examples

# Basic model with just id and timestamps
php craftsman make:model Product

# Model with custom fields
php craftsman make:model User name:string,email:string,age:integer

# Model with various field types
php craftsman make:model Post title:string,content:text,published:boolean,views:integer

Supported Field Types

Type Database Type PHP Type Example
string VARCHAR(255) string name:string
text TEXT string content:text
integer INT int age:integer
boolean TINYINT(1) bool active:boolean
datetime DATETIME DateTime publishedAt:datetime
decimal DECIMAL(10,2) float price:decimal
json JSON array metadata:json

What Gets Generated

A model file is created at src/Models/ModelName.php with:

  • Doctrine ORM #[Entity] annotation
  • Auto-incrementing id field
  • created_at and updated_at timestamps
  • All specified custom fields with appropriate types
  • Getter and setter methods for all properties
  • Proper namespace and imports

Example Generated Model

<?php

namespace App\Models;

use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\GeneratedValue;

#[Entity]
#[Table(name: 'products')]
class Product
{
    #[Id]
    #[GeneratedValue]
    #[Column(type: 'integer')]
    private int $id;

    #[Column(type: 'string', length: 255)]
    private string $name;

    #[Column(type: 'decimal', precision: 10, scale: 2)]
    private float $price;

    #[Column(type: 'datetime')]
    private \DateTime $createdAt;

    #[Column(type: 'datetime')]
    private \DateTime $updatedAt;

    public function __construct()
    {
        $this->createdAt = new \DateTime();
        $this->updatedAt = new \DateTime();
    }

    // Getters and setters...
}

Common Use Cases

Quick Prototyping

# Rapidly create multiple simple models
php craftsman make:model Category name:string
php craftsman make:model Tag name:string,slug:string
php craftsman make:model Comment content:text,approved:boolean

Basic CRUD Resources

# Create a simple model then build CRUD around it
php craftsman make:model Article title:string,content:text
php craftsman make:crud Article

model:wizard - Interactive Model Builder

An interactive wizard that guides you through creating complex models with relationships, indexes, constraints, and advanced field options.

Command
php craftsman model:wizard

Functionality

  • Step-by-step interactive prompts
  • Define unlimited fields with detailed configuration
  • Configure relationships (OneToMany, ManyToOne, ManyToMany)
  • Set up indexes and unique constraints
  • Customize field lengths, nullable status, defaults
  • Preview generated code before saving

Example Wizard Session

$ php craftsman model:wizard

ZephyrPHP Model Wizard
======================

Model name (PascalCase): User

Add fields to your model
------------------------

Field name (or 'done' to finish): name
Field type [string]: string
Length [255]: 100
Nullable? [no]: no
✓ Added field: name (string, length: 100)

Field name (or 'done' to finish): email
Field type [string]: string
Length [255]: 255
Nullable? [no]: no
Unique? [no]: yes
✓ Added field: email (string, length: 255, unique)

Field name (or 'done' to finish): bio
Field type [string]: text
Nullable? [no]: yes
✓ Added field: bio (text, nullable)

Field name (or 'done' to finish): age
Field type [string]: integer
Nullable? [no]: yes
✓ Added field: age (integer, nullable)

Field name (or 'done' to finish): done

Add relationships
-----------------

Add a relationship? [yes/no]: yes
Relationship type [ManyToOne/OneToMany/ManyToMany]: OneToMany
Related entity: Post
Mapped by: user
✓ Added relationship: posts (OneToMany → Post)

Add another relationship? [yes/no]: no

Summary
-------
Model: User
Fields: name, email, bio, age
Relationships: posts (OneToMany → Post)

Create this model? [yes/no]: yes
✓ Model created: src/Models/User.php

Advanced Features

Field Configuration Options

  • Type: string, text, integer, boolean, datetime, decimal, json
  • Length: Custom length for string fields
  • Nullable: Allow NULL values
  • Unique: Enforce unique constraint
  • Default: Set default value
  • Precision/Scale: For decimal fields

Relationship Types

Type Use Case Example
OneToMany One parent has many children User has many Posts
ManyToOne Many children belong to one parent Post belongs to User
ManyToMany Many-to-many relationship Post has many Tags, Tag has many Posts
OneToOne One-to-one relationship User has one Profile

When to Use the Wizard

Complex Models

# Models with many fields and relationships
php craftsman model:wizard
# Create User with name, email, password, profile, posts, comments

Learning Doctrine

# Interactive prompts teach you Doctrine features
php craftsman model:wizard
# Learn about annotations, relationships, constraints

Team Collaboration

# Guided process ensures consistency
php craftsman model:wizard
# All team members create models the same way

model:build - Quick CLI Syntax

Create models with a concise CLI syntax, perfect for one-liners and scripting. More powerful than make:model, faster than model:wizard.

Command
php craftsman model:build [name] [definition]

Arguments

Argument Type Description
name Required Model name in PascalCase
definition Required Field definitions with modifiers

Definition Syntax

fieldName:type:modifiers

Available modifiers:

  • nullable - Allow NULL values
  • unique - Enforce unique constraint
  • index - Create index on field
  • length:N - Set custom length (string fields)
  • default:value - Set default value

Examples

# Basic model with modifiers
php craftsman model:build User \
  name:string:length:100 \
  email:string:unique \
  bio:text:nullable \
  age:integer:nullable

# E-commerce product model
php craftsman model:build Product \
  name:string:length:200 \
  sku:string:unique:index \
  price:decimal \
  stock:integer:default:0 \
  active:boolean:default:true \
  description:text:nullable

# Blog post model
php craftsman model:build Post \
  title:string:length:255 \
  slug:string:unique:index \
  content:text \
  excerpt:text:nullable \
  published:boolean:default:false \
  views:integer:default:0 \
  publishedAt:datetime:nullable

Advanced Usage

Multiple Modifiers

# Field can have multiple modifiers
php craftsman model:build Category \
  name:string:unique:index:length:100 \
  slug:string:unique:index:length:100 \
  description:text:nullable \
  active:boolean:default:true

Complex Data Types

# JSON and decimal types
php craftsman model:build Order \
  total:decimal:default:0.00 \
  items:json \
  metadata:json:nullable \
  status:string:default:pending:length:50

Scripting and Automation

#!/bin/bash
# Create multiple models in a script

php craftsman model:build User name:string:unique email:string:unique
php craftsman model:build Post title:string content:text
php craftsman model:build Comment content:text approved:boolean:default:false

# Generate schema
php craftsman db:schema

model:build vs model:wizard

Feature model:build model:wizard
Speed Fast (one command) Slower (interactive)
Fields Unlimited Unlimited
Modifiers Via syntax Via prompts
Relationships Not supported Fully supported
Scripting Excellent Difficult
Learning curve Medium Low

Choosing the Right Command

Use make:model When...

  • You need a simple model quickly
  • You're prototyping or learning
  • You don't need relationships or constraints
  • You'll manually edit the model afterward

Use model:wizard When...

  • You're creating a complex model with relationships
  • You want guidance through the process
  • You need to configure indexes and constraints
  • You're new to Doctrine ORM
  • You want to see a preview before creating

Use model:build When...

  • You know exactly what you need
  • You're scripting or automating
  • You want a concise, one-line command
  • You don't need relationships (add manually later)
  • You're comfortable with CLI syntax

After Creating Models

Update Database Schema

# Always run after creating/modifying models
php craftsman db:schema

Add Relationships Manually

If you used make:model or model:build, add relationships by editing the model file:

use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

#[OneToMany(mappedBy: 'user', targetEntity: Post::class)]
private Collection $posts;

public function __construct()
{
    $this->posts = new ArrayCollection();
    // ... existing constructor code
}

public function getPosts(): Collection
{
    return $this->posts;
}

Customize the Model

Add custom methods, validation, or business logic:

public function getFullName(): string
{
    return $this->firstName . ' ' . $this->lastName;
}

public function isAdmin(): bool
{
    return in_array('ROLE_ADMIN', $this->roles);
}

public function publish(): void
{
    $this->published = true;
    $this->publishedAt = new \DateTime();
}

Best Practices

Naming Conventions

  • Model names: PascalCase, singular (User, BlogPost, OrderItem)
  • Field names: camelCase (firstName, createdAt, isActive)
  • Table names: snake_case, plural (users, blog_posts, order_items)
  • Foreign keys: singular_id (user_id, post_id, order_id)

Choosing Field Types

Data Type Reason
Short text (< 255 chars) string Indexed, fast searches
Long text (> 255 chars) text No length limit
True/false boolean Efficient storage
Whole numbers integer Fast calculations
Money, precise decimals decimal No rounding errors
Dates with time datetime Timezone support
Arrays, objects json Structured data

Model Organization

src/Models/
├── User.php
├── Post.php
├── Comment.php
├── Category.php
├── Tag.php
└── Traits/
    ├── Timestampable.php
    └── SoftDeletable.php

Troubleshooting

Model File Not Created

# Check src/Models directory exists
mkdir -p src/Models

# Check permissions
chmod 755 src/Models

Namespace Errors

Ensure your composer.json has proper autoloading:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

# Regenerate autoloader
composer dump-autoload

Schema Not Created

# Verify database connection
php craftsman db:test

# Ensure database module is installed
php craftsman add database

# Generate schema
php craftsman db:schema

Next Steps

Now that you can create models: