PHPackages                             concept-labs/expression - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. concept-labs/expression

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

concept-labs/expression
=======================

(C)oncept-Labs Expression

1.1.4(6mo ago)0351Apache-2.0PHPPHP &gt;=8.2

Since Nov 17Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/Concept-Labs/expression)[ Packagist](https://packagist.org/packages/concept-labs/expression)[ RSS](/packages/concept-labs-expression/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (3)Versions (16)Used By (1)

Expression
==========

[](#expression)

[![Concept](https://camo.githubusercontent.com/e745f492a31d791af8a19eee36a1fa98382320b3e17d448c76596dbf5b41011d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6e636570742d65636f73797374656d2d76696f6c65742e737667)](https://github.com/Concept-Labs)[![License](https://camo.githubusercontent.com/a549a7a30bacba7bfceebdc207a8e86c3f2c02995a2527640dca30048fd2b64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d417061636865253230322e302d626c75652e737667)](https://opensource.org/licenses/Apache-2.0)[![PHP Version](https://camo.githubusercontent.com/d840cef9807c8f76051ad687841d67f4d830c84e0d83236968e53124ef6742d5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e322d3838393242462e737667)](https://www.php.net/)

A flexible and powerful PHP library for building and composing expressions with decorators. Build **SQL queries**, **HTML/XML**, **JSON/API responses**, **CLI commands**, **configuration files**, **code generators**, and any text-based output with elegant, fluent syntax.

> **More than a query builder** - Expression is a universal text composition framework that makes complex string building simple, maintainable, and beautiful.

Features
--------

[](#features)

- 🔧 **Fluent API** - Chain methods for clean, readable code
- 🎨 **Decorator Pattern** - Transform expressions with decorators
- 🏗️ **Composable** - Nest expressions within expressions
- 🔄 **Immutable Context** - Safe context interpolation
- 🧩 **Extensible** - Easy to extend with custom decorators
- ✨ **Type Safe** - Full PHP 8.2+ type hints
- 🧪 **Well Tested** - Comprehensive test coverage with PHPUnit and Pest
- 🚀 **Universal** - Build SQL, HTML, JSON, CLI commands, configs, and more

Why Expression?
---------------

[](#why-expression)

Traditional string building is **error-prone**, **hard to read**, and **difficult to maintain**:

```
// ❌ Traditional approach - messy and fragile
$query = "SELECT " . implode(', ', array_map(fn($c) => "`$c`", $columns)) .
         " FROM " . $table .
         (!empty($where) ? " WHERE " . implode(' AND ', $where) : "");
```

Expression makes it **elegant**, **composable**, and **maintainable**:

```
// ✅ Expression approach - clean and powerful
$columns = (new Expression())
    ->push(...$columns)
    ->wrapItem('`')
    ->join(', ');

$query = (new Expression())
    ->push('SELECT', $columns, 'FROM', $table);

if (!empty($where)) {
    $query->push((new Expression())
        ->push(...$where)
        ->join(' AND ')
        ->wrap('WHERE ', ''));
}
```

Installation
------------

[](#installation)

Install via Composer:

```
composer require concept-labs/expression
```

Quick Start
-----------

[](#quick-start)

```
use Concept\Expression\Expression;

// Create an expression
$expression = new Expression();

// Build a simple expression
$expression->push('SELECT', 'id', 'name', 'FROM', 'users');
echo $expression; // Output: SELECT id name FROM users

// Use decorators for more control
$columns = (new Expression())
    ->push('id', 'name', 'email')
    ->wrapItem('`')
    ->join(', ');

$query = (new Expression())
    ->push('SELECT', $columns, 'FROM', 'users');

echo $query; // Output: SELECT `id`, `name`, `email` FROM users
```

🚀 Power Showcase
----------------

[](#-power-showcase)

### Syntax Sugar - The Magic of `__invoke()`

[](#syntax-sugar---the-magic-of-__invoke)

Expressions are **callable**, enabling ultra-concise syntax:

```
// Instead of verbose push() calls
$expr = (new Expression())
    ->push('Hello')
    ->push('World');

// Use callable syntax - much cleaner!
$expr = (new Expression())
    ('Hello')
    ('World');

// Build complex expressions elegantly
$banner = (new Expression())
    ('╔════════════════════╗')
    ('║ Welcome to PHP!  ║')
    ('╚════════════════════╝')
    ->join("\n");

echo $banner;
```

### Decorator Stacking - Progressive Transformations

[](#decorator-stacking---progressive-transformations)

Chain decorators for powerful, layered transformations:

```
// Transform data through multiple steps
$pipeline = (new Expression())
    ('apple', 'banana', 'cherry')
    ->decorateItem(fn($item) => ucfirst($item))        // Step 1: Capitalize
    ->decorateItem(fn($item) => "🍎 $item")            // Step 2: Add emoji
    ->decorateItem(fn($item) => "[$item]")             // Step 3: Wrap
    ->join(' → ')                                       // Step 4: Join with arrows
    ->decorate(fn($str) => "Fruits: $str")             // Step 5: Add label
    ->decorate(fn($str) => "╭─────────────╮\n│ $str │\n╰─────────────╯"); // Step 6: Box it

echo $pipeline;
// Output:
// ╭─────────────╮
// │ Fruits: [🍎 Apple] → [🍎 Banana] → [🍎 Cherry] │
// ╰─────────────╯
```

### Beyond SQL - Universal Text Building

[](#beyond-sql---universal-text-building)

#### HTML Component Builder

[](#html-component-builder)

```
$card = (new Expression())
    ('')
    ('  Welcome!')
    ('  Experience the power of Expression')
    ('  Get Started')
    ('')
    ->join("\n");

echo $card;
```

#### CLI Command Builder

[](#cli-command-builder)

```
// Build complex Docker commands fluently
$docker = (new Expression())
    ('docker', 'run')
    ('-d')
    ('--name', 'my-app')
    ('-p', '8080:80')
    ('-v', '/host/data:/app/data')
    ('-e', 'ENV=production')
    ('nginx:latest');

echo $docker;
// Output: docker run -d --name my-app -p 8080:80 -v /host/data:/app/data -e ENV=production nginx:latest
```

#### JSON API Response Builder

[](#json-api-response-builder)

```
$response = (new Expression())
    ('{"status": "success"')
    ('"data": {"user_id": 123, "name": "Alice"}')
    ('"timestamp": "' . date('c') . '"}')
    ->join(',')
    ->decorate(fn($s) => json_encode(json_decode($s), JSON_PRETTY_PRINT));

echo $response;
```

#### Configuration File Generator

[](#configuration-file-generator)

```
$config = (new Expression())
    ('# Database Configuration')
    ('DB_HOST=localhost')
    ('DB_PORT=5432')
    ('DB_NAME=myapp')
    ('')
    ('# Application Settings')
    ('APP_ENV=production')
    ('APP_DEBUG=false')
    ->join("\n");

echo $config;
```

### Context Interpolation - Reusable Templates

[](#context-interpolation---reusable-templates)

```
// Create a template with placeholders
$template = (new Expression())
    ('Dear {name},', '', 'Your order #{order_id} is {status}.', '', 'Thank you!')
    ->join("\n");

// Generate multiple outputs from the same template
$email1 = $template->withContext([
    'name' => 'Alice',
    'order_id' => '12345',
    'status' => 'shipped'
]);

$email2 = $template->withContext([
    'name' => 'Bob',
    'order_id' => '67890',
    'status' => 'processing'
]);

// Original template remains unchanged!
echo $template; // Still has {name}, {order_id}, {status}
```

### Composition - Expressions Within Expressions

[](#composition---expressions-within-expressions)

```
// Build modular, reusable components
$header = (new Expression())
    ('╔════════════════════╗')
    ('║   {title}         ║')
    ('╚════════════════════╝')
    ->join("\n");

$body = (new Expression())
    ('Content: {content}');

$footer = (new Expression())
    ('───────────────────')
    ('Footer: {footer}')
    ->join("\n");

$page = (new Expression())
    ($header)
    ('')
    ($body)
    ('')
    ($footer)
    ->join("\n")
    ->withContext([
        'title' => 'My App',
        'content' => 'Hello World',
        'footer' => 'v1.0.0'
    ]);

echo $page;
```

Basic Usage
-----------

[](#basic-usage)

### Creating Expressions

[](#creating-expressions)

```
$expr = new Expression();

// Add expressions
$expr->push('SELECT', 'column');
$expr->push('FROM', 'table');

// Add to beginning
$expr->unshift('EXPLAIN');

echo $expr; // Output: EXPLAIN SELECT column FROM table
```

### Using \_\_invoke() for Concise Syntax

[](#using-__invoke-for-concise-syntax)

```
// You can also use the __invoke() method for a more concise syntax
$expr = new Expression();
$expr('SELECT', 'column')('FROM', 'table');

// Equivalent to:
// $expr->push('SELECT', 'column')->push('FROM', 'table');

echo $expr; // Output: SELECT column FROM table
```

### Nested Expressions

[](#nested-expressions)

```
$columns = (new Expression())
    ->push('id', 'name')
    ->join(', ');

$mainExpr = (new Expression())
    ->push('SELECT', $columns, 'FROM', 'users');

echo $mainExpr; // Output: SELECT id, name FROM users
```

### Using Decorators

[](#using-decorators)

#### Wrap Expressions

[](#wrap-expressions)

```
$expr = (new Expression())
    ->push('value')
    ->wrap('(', ')');

echo $expr; // Output: (value)
```

#### Wrap Items

[](#wrap-items)

```
$expr = (new Expression())
    ->push('id', 'name', 'email')
    ->wrapItem('`')
    ->join(', ');

echo $expr; // Output: `id`, `name`, `email`
```

#### Custom Decorators

[](#custom-decorators)

```
// Item decorator - applied to each item
$expr = (new Expression())
    ->push('select', 'from', 'where')
    ->decorateItem(fn($item) => strtoupper($item));

echo $expr; // Output: SELECT FROM WHERE

// Expression decorator - applied to final result
$expr = (new Expression())
    ->push('column')
    ->decorate(fn($str) => "SELECT $str FROM users");

echo $expr; // Output: SELECT column FROM users

// Join decorator - custom join logic
$expr = (new Expression())
    ->push('condition1', 'condition2')
    ->decorateJoin(fn($items) => implode(' AND ', $items));

echo $expr; // Output: condition1 AND condition2
```

### Context Interpolation

[](#context-interpolation)

```
$template = (new Expression())
    ->push('SELECT', '{column}', 'FROM', '{table}');

$concrete = $template->withContext([
    'column' => 'name',
    'table' => 'users'
]);

echo $concrete; // Output: SELECT name FROM users
echo $template; // Output: SELECT {column} FROM {table} (unchanged)
```

### Clone and Prototype

[](#clone-and-prototype)

```
$base = (new Expression())
    ->push('SELECT', 'id');

// Clone creates independent copy
$clone = clone $base;
$clone->push('FROM', 'users');

echo $base;  // Output: SELECT id
echo $clone; // Output: SELECT id FROM users

// Prototype is alias for clone
$proto = $base->prototype();
```

### Reset

[](#reset)

```
$expr = (new Expression())
    ->push('SELECT', 'column')
    ->type('select');

$expr->reset(); // Clears everything

echo $expr; // Output: (empty string)
```

Advanced Usage
--------------

[](#advanced-usage)

### Building Complex SQL Queries

[](#building-complex-sql-queries)

```
// Build a complex SELECT query
$columns = (new Expression())
    ->push('u.id', 'u.name', 'u.email', 'p.title')
    ->wrapItem('`')
    ->join(', ');

$joins = (new Expression())
    ->push('JOIN', 'posts', 'p', 'ON', 'u.id = p.user_id');

$where = (new Expression())
    ->push('u.active = 1', 'p.published = 1')
    ->join(' AND ')
    ->wrap('WHERE ', '');

$query = (new Expression())
    ->push('SELECT', $columns)
    ->push('FROM', 'users', 'u')
    ->push($joins)
    ->push($where);

echo $query;
// Output: SELECT `u.id`, `u.name`, `u.email`, `p.title` FROM users u JOIN posts p ON u.id = p.user_id WHERE u.active = 1 AND p.published = 1
```

### Multiple Decorator Layers

[](#multiple-decorator-layers)

```
$expr = (new Expression())
    ->push('a', 'b', 'c')
    ->decorateItem(fn($item) => strtoupper($item))  // Items: A, B, C
    ->decorateItem(fn($item) => "`$item`")          // Items: `A`, `B`, `C`
    ->join(', ')                                     // Join: `A`, `B`, `C`
    ->decorate(fn($str) => "SELECT $str")            // Wrap: SELECT `A`, `B`, `C`
    ->decorate(fn($str) => "$str FROM table");       // Wrap: SELECT `A`, `B`, `C` FROM table

echo $expr; // Output: SELECT `A`, `B`, `C` FROM table
```

API Reference
-------------

[](#api-reference)

For detailed API documentation, see [docs/api-reference.md](docs/api-reference.md).

### Main Classes

[](#main-classes)

- **Expression** - Main expression class
- **ExpressionInterface** - Interface for expressions
- **DecoratorManager** - Manages decorators for expressions
- **Decorator** - Static helper methods for common decorators

### Key Methods

[](#key-methods)

#### Expression Methods

[](#expression-methods)

- `__invoke(...$expressions)` - Add expressions (alias for push, enables callable syntax)
- `push(...$expressions)` - Add expressions to the end
- `unshift(...$expressions)` - Add expressions to the beginning
- `wrap($left, $right = null)` - Wrap the entire expression
- `wrapItem($left, $right = null)` - Wrap each item
- `join($separator)` - Set the join separator
- `decorate(callable ...$decorator)` - Add expression decorator
- `decorateItem(callable ...$decorator)` - Add item decorator
- `decorateJoin(callable $decorator)` - Set join decorator
- `withContext(array $context)` - Create new expression with context
- `reset()` - Reset the expression
- `type(string $type)` - Set expression type
- `isEmpty()` - Check if expression is empty
- `prototype()` - Create a clone

More Examples
-------------

[](#more-examples)

### 📊 Markdown Table Generator

[](#-markdown-table-generator)

```
class MarkdownTable
{
    public static function create(array $headers, array $rows): Expression
    {
        $header = (new Expression())
            (...$headers)
            ->wrapItem('| ', ' ')
            ->join('')
            ->wrap('', '|');

        $separator = (new Expression())
            (...array_fill(0, count($headers), '---'))
            ->wrapItem('| ', ' ')
            ->join('')
            ->wrap('', '|');

        $table = (new Expression())($header)($separator);

        foreach ($rows as $row) {
            $rowExpr = (new Expression())
                (...$row)
                ->wrapItem('| ', ' ')
                ->join('')
                ->wrap('', '|');
            $table->push($rowExpr);
        }

        return $table->join("\n");
    }
}

// Usage
$table = MarkdownTable::create(
    ['Name', 'Age', 'City'],
    [
        ['Alice', '30', 'New York'],
        ['Bob', '25', 'London'],
    ]
);
echo $table;
```

### 🎨 ASCII Art Generator

[](#-ascii-art-generator)

```
$banner = (new Expression())
    ('╔═══════════════════════════╗')
    ('║  Expression Library      ║')
    ('║  Build Anything!         ║')
    ('╚═══════════════════════════╝')
    ->join("\n");

echo $banner;
```

### 📝 Log Formatter

[](#-log-formatter)

```
class Logger
{
    public static function format(string $level, string $message, array $context = []): Expression
    {
        $icons = ['ERROR' => '❌', 'WARN' => '⚠️', 'INFO' => 'ℹ️', 'SUCCESS' => '✅'];

        $log = (new Expression())
            (date('[Y-m-d H:i:s]'))
            ("{$icons[$level]} [$level]")
            ($message);

        if (!empty($context)) {
            $log->push('Context: ' . json_encode($context));
        }

        return $log;
    }
}

echo Logger::format('SUCCESS', 'User logged in', ['user_id' => 123]);
// Output: [2026-01-04 00:00:00] ✅ [SUCCESS] User logged in Context: {"user_id":123}
```

### 🔧 Git Command Builder

[](#-git-command-builder)

```
class Git
{
    public static function commit(string $message, array $files = []): Expression
    {
        $cmd = (new Expression())('git');

        if (!empty($files)) {
            $cmd('add')(...$files)('&&')('git');
        }

        return $cmd('commit')('-m')("\"$message\"");
    }
}

echo Git::commit('Add new feature', ['src/Feature.php', 'tests/FeatureTest.php']);
// Output: git add src/Feature.php tests/FeatureTest.php && git commit -m "Add new feature"
```

### 🌐 ENV File Builder

[](#-env-file-builder)

```
class EnvBuilder
{
    private Expression $env;

    public function __construct()
    {
        $this->env = new Expression();
    }

    public function section(string $name): self
    {
        $this->env->push('')
                  ->push("# $name")
                  ->push(str_repeat('-', strlen($name) + 2));
        return $this;
    }

    public function set(string $key, $value): self
    {
        $this->env->push("$key=$value");
        return $this;
    }

    public function build(): string
    {
        return (string)$this->env->join("\n");
    }
}

$config = (new EnvBuilder())
    ->section('Database')
    ->set('DB_HOST', 'localhost')
    ->set('DB_PORT', '5432')
    ->section('Application')
    ->set('APP_ENV', 'production')
    ->build();
```

For **more advanced examples** including:

- 🏗️ HTML/XML Builders
- 🔌 GraphQL Query Builders
- 🐳 Docker Command Composers
- 💻 PHP Code Generators
- 📊 YAML Configuration Builders
- 🧪 Test Data Builders
- 🎯 DSL Creation
- 🎨 Creative Use Cases

See the comprehensive [**Advanced Examples Guide**](docs/advanced-examples.md)!

Testing
-------

[](#testing)

The package includes comprehensive tests using both PHPUnit and Pest.

```
# Run all tests with Pest
composer test

# Run PHPUnit tests
composer test:phpunit

# Run with coverage
composer test:coverage
```

Contributing
------------

[](#contributing)

Contributions are welcome! Please see [docs/contributing.md](docs/contributing.md) for details.

License
-------

[](#license)

This package is licensed under the Apache License 2.0. See [LICENSE](LICENSE) file for details.

Credits
-------

[](#credits)

- **Viktor Halytskyi** - Original author
- Part of the [Concept Labs](https://github.com/Concept-Labs) ecosystem

Links
-----

[](#links)

- [Extended Documentation](docs/README.md)
- [Architecture Overview](docs/architecture.md)
- [Examples](docs/examples.md)
- [**🚀 Advanced Examples**](docs/advanced-examples.md) - **NEW!** Showcase of powerful use cases
- [API Reference](docs/api-reference.md)

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance71

Regular maintenance activity

Popularity7

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 59.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~34 days

Recently: every ~3 days

Total

11

Last Release

206d ago

PHP version history (2 changes)1.0.0.0PHP &gt;=7.4

1.0.2.0PHP &gt;=8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/39bcfd110a5cc1f2d7ff687193670d00133cf415ad2b9959afaff24ff1e564fd?d=identicon)[vgalitsky](/maintainers/vgalitsky)

---

Top Contributors

[![vgalitsky](https://avatars.githubusercontent.com/u/1241206?v=4)](https://github.com/vgalitsky "vgalitsky (16 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (11 commits)")

---

Tags

phpexpressioncomposition

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/concept-labs-expression/health.svg)

```
[![Health](https://phpackages.com/badges/concept-labs-expression/health.svg)](https://phpackages.com/packages/concept-labs-expression)
```

###  Alternatives

[imanghafoori/laravel-anypass

A minimal yet powerful package to help you in development.

21421.6k](/packages/imanghafoori-laravel-anypass)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
