Builder Pattern
Also Known As
builder
fluent builder
step builder
TL;DR
Constructs complex objects step-by-step using a fluent interface, separating construction from representation.
Explanation
The Builder pattern addresses constructors with many parameters (especially optional ones) by providing a step-by-step construction API: $query = QueryBuilder::select('users')->where('active', true)->orderBy('name')->limit(10)->build(). Each setter returns $this (fluent interface), and build() returns the final immutable object. In PHP, Builders appear in query builders (Doctrine DBAL), HTTP client requests, and test fixture factories. Compared to long constructors or setters, Builders make invalid intermediate states visible and enable validation at build() time.
Diagram
flowchart LR
subgraph Without_Builder
CONS[new QueryBuilder<br/>table conditions joins<br/>order limit offset columns]
PROB[Constructor with 8 params<br/>positional - error prone]
end
subgraph With_Builder
B[QueryBuilder::for users]
B -->|chained| W[->where id > 5]
W -->|chained| J[->join orders on user_id]
J -->|chained| O[->orderBy created_at]
O -->|chained| L[->limit 20]
L -->|build| QUERY[SELECT ... built query]
end
style PROB fill:#f85149,color:#fff
style QUERY fill:#238636,color:#fff
style B fill:#1f6feb,color:#fff
Common Misconception
✗ The builder pattern is just a verbose alternative to constructors. Builders enforce construction order, validate intermediate state, and make optional parameters explicit — they are most valuable when objects have many optional fields or complex construction rules.
Why It Matters
The Builder pattern constructs complex objects step by step, separating construction from representation — it eliminates telescoping constructors and makes optional parameters explicit.
Common Mistakes
- Using a builder for simple objects with 2-3 parameters — a plain constructor or named arguments is cleaner.
- Not validating required fields in the build() method — the builder produces an invalid object silently.
- Forgetting to return $this from each setter — breaks the fluent chain.
- Reusing the same builder instance for multiple objects without resetting state between builds.
Code Examples
✗ Vulnerable
// Telescoping constructor — hard to read and extend:
function __construct(
string $name, ?string $email = null, ?string $phone = null,
?string $address = null, bool $active = true, int $role = 1
) {} // 6 params, optional ones hard to manage — use a builder
✓ Fixed
class QueryBuilder {
private array $wheres = [];
private ?int $limit = null;
private string $orderBy = 'id';
public function where(string $col, mixed $val): static {
$this->wheres[] = [$col, $val];
return $this;
}
public function limit(int $n): static {
$this->limit = $n;
return $this;
}
public function orderBy(string $col): static {
$this->orderBy = $col;
return $this;
}
public function build(): string { /* assemble SQL */ }
}
$sql = (new QueryBuilder())
->where('status', 'active')
->where('role', 'admin')
->orderBy('created_at')
->limit(10)
->build();
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
22 Mar 2026
Views
21
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 1
No pings yesterday
Amazonbot 6
Perplexity 5
Unknown AI 2
Google 2
ChatGPT 2
SEMrush 2
Also referenced
How they use it
crawler 16
crawler_json 3
Related categories
⚡
DEV INTEL
Tools & Severity
🟢 Low
⚙ Fix effort: Medium
⚡ Quick Fix
Use a builder when constructing an object requires many optional parameters or multi-step configuration — it makes invalid states unrepresentable if you validate in build()
📦 Applies To
PHP 5.0+
web
cli
queue-worker
🔗 Prerequisites
🔍 Detection Hints
Constructor with 6+ parameters many optional; complex object requiring multi-step setup before it is valid
Auto-detectable:
✗ No
phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: High
✗ Manual fix
Fix: Medium
Context: Class
Tests: Update