PHPackages                             luracast/restler - 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. [Framework](/categories/framework)
4. /
5. luracast/restler

ActiveLibrary[Framework](/categories/framework)

luracast/restler
================

Restler is a simple and effective multi-format Web API Server framework written in PHP. Just deal with your business logic in php, Restler will take care of the REST!

6.0.1(1w ago)1.4k559.2k↓14%310[31 issues](https://github.com/Luracast/Restler/issues)[2 PRs](https://github.com/Luracast/Restler/pulls)6MITPHPPHP ^8CI failing

Since May 10Pushed 6d ago82 watchersCompare

[ Source](https://github.com/Luracast/Restler)[ Packagist](https://packagist.org/packages/luracast/restler)[ Docs](https://luracast.com/products/restler/)[ RSS](/packages/luracast-restler/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (2)Dependencies (48)Versions (38)Used By (6)Security (1)

[![Restler](public/examples/resources/restler.svg)](public/examples/resources/restler.svg) Restler v6
=====================================================================================================

[](#-restler-v6)

[![Latest Stable Version](https://camo.githubusercontent.com/196d1b471b741460c5c19513d8125ace513303655fa10bc8d5e37d0eb1801a94/68747470733a2f2f706f7365722e707567782e6f72672f6c757261636173742f726573746c65722f762f737461626c652e706e67)](https://packagist.org/packages/luracast/restler)[![Total Downloads](https://camo.githubusercontent.com/f9a2cd37cbad693e24b52a7a39e5342d7a8c4ced96bd412bcebdf41c614ea659/68747470733a2f2f706f7365722e707567782e6f72672f6c757261636173742f726573746c65722f646f776e6c6f6164732e706e67)](https://packagist.org/packages/luracast/restler)[![License](https://camo.githubusercontent.com/f8bb9c31afb9e36f42be178cb272e527eb14d10a505562620f175baccb94a166/68747470733a2f2f706f7365722e707567782e6f72672f6c757261636173742f726573746c65722f6c6963656e73652e706e67)](https://packagist.org/packages/luracast/restler)

### **Write your API logic in PHP. Get routing, validation, and OpenAPI docs—automatically.**

[](#write-your-api-logic-in-php-get-routing-validation-and-openapi-docsautomatically)

> **Production-ready since 2010. Battle-tested. Now rebuilt for modern PHP 8+ with async superpowers.**

```
use Luracast\Restler\Restler;
use Luracast\Restler\Routes;

class Products {
    function get(int $id): array {
        return Database::findProduct($id);
    }
}

Routes::mapApiClasses([Products::class]);
(new Restler)->handle();
```

**That's it.** You just created a REST API that:

- ✅ Automatically validates `$id` as an integer
- ✅ Returns JSON by default
- ✅ Handles routing (`GET /products/123`)
- ✅ Generates OpenAPI/Swagger docs
- ✅ Provides proper HTTP status codes
- ✅ Supports content negotiation (configure other formats as needed)

**No controllers. No routing files. No configuration. Just PHP.**

---

Why Restler in 2025?
--------------------

[](#why-restler-in-2025)

### 🎯 **Zero Boilerplate**

[](#-zero-boilerplate)

While other frameworks make you write controllers, routes, DTOs, validation rules, and transformers—Restler uses **PHP reflection** to do it all automatically. Write business logic, not plumbing.

```
// Laravel/Symfony: 50+ lines of controllers, routes, requests, resources
// Restler: 5 lines
class Users {
    function create(string $email, string $name): User {
        return User::create(compact('email', 'name'));
    }
}
```

### ⚡ **Async Performance**

[](#-async-performance)

Run on **Swoole/OpenSwoole** for 10-20x throughput vs traditional PHP-FPM. Or use **ReactPHP** for true async I/O. Deploy to **AWS Lambda** for serverless scale.

```
# Traditional PHP-FPM: ~1,000 req/sec
# Swoole/OpenSwoole: ~15,000 req/sec (same code!)
composer swoole-server
```

### 🌐 **Multi-Format Output**

[](#-multi-format-output)

JSON is the default format. Configure additional formats (XML, CSV, Excel, HTML) via `Routes::setOverridingResponseMediaTypes()`. Perfect for:

- **Mobile apps** → JSON (default)
- **Legacy systems** → XML
- **Data exports** → CSV/Excel
- **Admin panels** → HTML with Blade/Twig

```
curl api.example.com/products/123       # JSON (default)
curl api.example.com/products/123.xml   # XML (if configured)
curl api.example.com/products.csv       # CSV (if configured)
curl api.example.com/products.xlsx      # Excel (if configured)
```

### 🚀 **Modern PHP 8+**

[](#-modern-php-8)

Built for PHP 8 with attributes, union types, named arguments, and strict typing. PSR-7 and PSR-11 compliant.

```
use Luracast\Restler\Attribute\{Get, Post};

class Orders {
    #[Get('orders/{id}')]
    function getOrder(int $id): Order|null {
        return Order::find($id);
    }

    #[Post('orders')]
    function createOrder(string $product, int $quantity = 1): Order {
        return Order::create(compact('product', 'quantity'));
    }
}
```

### 📚 **Auto-Generated Docs**

[](#-auto-generated-docs)

OpenAPI 3.0 (Swagger) docs generated from your PHPDoc comments. Interactive API explorer included.

```
class Products {
    /**
     * Get product details
     *
     * @param int $id Product ID
     * @return Product product information
     * @throws 404 Product not found
     */
    function get(int $id): Product {
        return Product::findOrFail($id);
    }
}
// Visit /explorer for interactive Swagger UI
```

---

Real-World Use Cases
--------------------

[](#real-world-use-cases)

### 🏢 **Internal APIs &amp; Microservices**

[](#-internal-apis--microservices)

Perfect for building internal APIs that need to integrate with various systems. Multi-format support means you can serve JSON to your React app and XML to that ancient CRM system—from the same endpoint.

### 📱 **Mobile Backend**

[](#-mobile-backend)

Low latency on Swoole, automatic validation, built-in rate limiting, and OAuth2 support. Everything you need for a production mobile backend.

### 📊 **Data Export APIs**

[](#-data-export-apis)

Built-in CSV and Excel streaming support. Export millions of rows without running out of memory using generators.

```
function exportUsers(): Generator {
    foreach (User::cursor() as $user) {
        yield $user->toArray();
    }
}
// GET /users.csv streams all users as CSV
// GET /users.xlsx downloads Excel file
```

### 🔗 **Legacy System Integration**

[](#-legacy-system-integration)

Need to modernize an old PHP app? Add Restler to get a REST API instantly. Works alongside existing code—no rewrite needed.

---

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

[](#quick-start)

### Install

[](#install)

```
composer require luracast/restler:^6.0
```

### Create Your First API (3 files)

[](#create-your-first-api-3-files)

**1. API Class** (`api/Hello.php`)

```
2025-01-15 10:30:45...
```

**That's it!** You have a working REST API with automatic routing, validation, and multi-format support.

---

Production Deployment
---------------------

[](#production-deployment)

### Traditional (Apache/Nginx + PHP-FPM)

[](#traditional-apachenginx--php-fpm)

Standard deployment. Works everywhere. ~1,000-2,000 req/sec depending on hardware.

```
// Enable production mode for route caching
$api = new Restler(productionMode: true);
```

### High Performance (Swoole/OpenSwoole)

[](#high-performance-swooleopenswoole)

**10-20x faster** than PHP-FPM. Persistent connections, coroutines, built-in HTTP server.

```
# Install extension (choose one)
pecl install swoole        # Original
pecl install openswoole    # Fork with same API

# Run server
php public/index_swoole.php
```

**Benchmarks**: 15,000+ req/sec on modest hardware (vs ~1,000 for PHP-FPM)

### Async I/O (ReactPHP)

[](#async-io-reactphp)

True non-blocking async operations. Perfect for I/O-heavy workloads (database, HTTP calls, etc.).

```
composer react-server
```

### Serverless (AWS Lambda)

[](#serverless-aws-lambda)

Zero-downtime deploys, automatic scaling, pay-per-request pricing.

```
# Uses Bref for Laravel-style Lambda deployment
vendor/bin/bref deploy
```

See `public/index_lambda.php` for complete example.

### Event-Driven (Workerman)

[](#event-driven-workerman)

Alternative to Swoole with pure PHP implementation (no extension required).

```
php public/index_workerman.php start
```

---

What's New in v6
----------------

[](#whats-new-in-v6)

### 🔥 **Breaking Changes from v5**

[](#-breaking-changes-from-v5)

- **PHP 8.0+ required** (was PHP 7.4)
- **PSR-7 HTTP messages** (modern request/response objects)
- **PSR-11 Container** (standard dependency injection)
- **Stricter typing** (full PHP 8 type hints)

[**Migration Guide →**](MIGRATION.md)

### ✨ **New Features**

[](#-new-features)

#### Modern PHP 8 Support

[](#modern-php-8-support)

- ✅ Attributes (`#[Get]`, `#[Post]`, etc.)
- ✅ Union types (`string|int`, `User|null`)
- ✅ Named arguments
- ✅ Constructor property promotion
- ✅ Match expressions
- ✅ Enums

#### Async &amp; Performance

[](#async--performance)

- ✅ **Swoole/OpenSwoole** integration (10-20x faster)
- ✅ **ReactPHP** async server
- ✅ **Workerman** event-driven server
- ✅ **AWS Lambda** serverless support
- ✅ **Generator streaming** for large datasets (CSV, Excel)
- ✅ Route caching &amp; opcode optimization

#### Enhanced Security

[](#enhanced-security)

- ✅ Secure session serialization (JSON, not `unserialize()`)
- ✅ JSONP callback validation (XSS prevention)
- ✅ Template injection protection
- ✅ Configurable CORS with proper defaults
- ✅ Built-in rate limiting
- ✅ OAuth 2.0 server support

#### Developer Experience

[](#developer-experience)

- ✅ **GraphQL** support
- ✅ **Excel export** (XLSX streaming)
- ✅ **OpenAPI 3.0** spec generation
- ✅ Interactive **API Explorer** (Swagger UI)
- ✅ Better error messages
- ✅ **Blade, Twig, Mustache** template engines
- ✅ Modern DI container with auto-wiring

#### Multi-Format Support

[](#multi-format-support)

All formats work automatically—just add file extension to URL:

- JSON (default)
- XML
- YAML
- CSV (with streaming)
- Excel (XLSX)
- HTML (with templates)
- AMF (Flash/Flex)
- Plist (iOS/macOS)

---

Advanced Examples
-----------------

[](#advanced-examples)

### API Versioning

[](#api-versioning)

```
// v1/Users.php
namespace v1;
class Users {
    function get(int $id): array {
        return ['id' => $id, 'name' => 'John'];
    }
}

// v2/Users.php
namespace v2;
class Users {
    function get(int $id): User {
        return User::with('profile')->find($id);
    }
}

// index.php
use Luracast\Restler\Routes;

Routes::mapApiClasses([
    'v1/users' => 'v1\\Users',
    'v2/users' => 'v2\\Users'
]);
```

**Usage:**

```
curl api.example.com/v1/users/123  # Old format
curl api.example.com/v2/users/123  # New format with profile
```

### Authentication &amp; Rate Limiting

[](#authentication--rate-limiting)

```
use Luracast\Restler\Contracts\AuthenticationInterface;

class ApiKeyAuth implements AuthenticationInterface {
    public function __isAuthenticated(): bool {
        $key = $_SERVER['HTTP_X_API_KEY'] ?? null;
        return $key && ApiKey::validate($key);
    }
}

use Luracast\Restler\Restler;
use Luracast\Restler\Routes;

Routes::addAuthenticator(ApiKeyAuth::class);
Routes::setFilters(RateLimit::class);  // Built-in rate limiting
Routes::mapApiClasses([ProtectedAPI::class]);
(new Restler)->handle();
```

### Database Integration

[](#database-integration)

```
class Products {
    /**
     * List all products with pagination
     *
     * @param int $page Page number (default: 1)
     * @param int $limit Items per page (default: 20)
     */
    function index(int $page = 1, int $limit = 20): array {
        return Product::paginate($limit, page: $page)->toArray();
    }

    /**
     * Create new product
     *
     * @param string $name Product name
     * @param float $price Product price
     * @param string $category Category name
     */
    function post(string $name, float $price, string $category): Product {
        return Product::create(compact('name', 'price', 'category'));
    }

    /**
     * Update product
     *
     * @param int $id Product ID {@from path}
     */
    function put(int $id, string $name = null, float $price = null): Product {
        $product = Product::findOrFail($id);
        if ($name) $product->name = $name;
        if ($price) $product->price = $price;
        $product->save();
        return $product;
    }

    /**
     * Delete product
     *
     * @param int $id Product ID {@from path}
     */
    function delete(int $id): array {
        Product::findOrFail($id)->delete();
        return ['message' => 'Product deleted'];
    }
}
```

**Automatic REST endpoints:**

- `GET /products` → index()
- `POST /products` → post()
- `GET /products/123` → (auto-routes to index with $id)
- `PUT /products/123` → put()
- `DELETE /products/123` → delete()

### File Uploads

[](#file-uploads)

```
class Media {
    /**
     * Upload file
     *
     * @param array $file Upload file {@from body} {@type file}
     */
    function post(array $file): array {
        $path = Storage::put('uploads', $file['tmp_name']);
        return [
            'filename' => $file['name'],
            'url' => Storage::url($path),
            'size' => $file['size']
        ];
    }
}
```

### Streaming Large Datasets

[](#streaming-large-datasets)

```
class Reports {
    /**
     * Export all users (memory efficient)
     */
    function exportUsers(): Generator {
        // Processes millions of rows without memory issues
        foreach (User::cursor() as $user) {
            yield [
                'id' => $user->id,
                'email' => $user->email,
                'created' => $user->created_at
            ];
        }
    }
}

// GET /reports/exportUsers.csv → streams CSV
// GET /reports/exportUsers.xlsx → streams Excel
```

### Custom Routing

[](#custom-routing)

```
class Products {
    /**
     * @url GET products/featured
     */
    function getFeatured(): array {
        return Product::where('featured', true)->get();
    }

    /**
     * @url GET products/search/{query}
     * @param string $query Search term {@from path}
     */
    function search(string $query): array {
        return Product::where('name', 'LIKE', "%$query%")->get();
    }

    /**
     * @url POST products/{id}/publish
     * @param int $id Product ID {@from path}
     */
    function publish(int $id): array {
        $product = Product::findOrFail($id);
        $product->published = true;
        $product->save();
        return ['message' => 'Published successfully'];
    }
}
```

### GraphQL Support

[](#graphql-support)

```
use Luracast\Restler\Restler;
use Luracast\Restler\Routes;
use Luracast\Restler\OpenApi3\Explorer;

Routes::mapApiClasses([
    'graphql' => GraphQLEndpoint::class,
    'explorer' => Explorer::class
]);
(new Restler)->handle();

// POST /graphql
// Query and mutation support built-in
```

### CORS Configuration

[](#cors-configuration)

```
use Luracast\Restler\Defaults;

Defaults::$accessControlAllowOrigin = 'https://app.example.com';
Defaults::$accessControlAllowMethods = 'GET, POST, PUT, DELETE';
Defaults::$accessControlAllowHeaders = 'Content-Type, Authorization';
Defaults::$accessControlMaxAge = 86400;

use Luracast\Restler\Restler;
use Luracast\Restler\Routes;

Routes::mapApiClasses([MyAPI::class]);
(new Restler)->handle();
```

---

Interactive API Explorer
------------------------

[](#interactive-api-explorer)

Restler includes a built-in Swagger UI explorer:

```
use Luracast\Restler\Restler;
use Luracast\Restler\Routes;
use Luracast\Restler\OpenApi3\Explorer;

Routes::mapApiClasses([
    Products::class,
    Users::class,
    'explorer' => Explorer::class  // Add explorer
]);
(new Restler)->handle();
```

Visit `http://localhost:8080/explorer` to:

- Browse all endpoints
- See request/response schemas
- Test APIs interactively
- Download OpenAPI spec

The explorer is auto-generated from your PHPDoc comments—no manual work needed.

---

Testing
-------

[](#testing)

Restler includes **18+ working examples** and a full **Behat** test suite.

### Run Built-in Tests

[](#run-built-in-tests)

```
# Start server
composer serve

# Run tests (in another terminal)
composer test
```

**Results:** 310/310 scenarios passing ✅

### Write Your Own Tests

[](#write-your-own-tests)

```
# features/products.feature
Feature: Product API

  Scenario: Get product by ID
    When I request "GET /products/123"
    Then the response status code should be 200
    And the response is JSON
    And the response has a "name" property

  Scenario: Create product
    When I request "POST /products" with body:
      """
      {"name": "Widget", "price": 19.99}
      """
    Then the response status code should be 201
    And the response has a "id" property
```

### Example Projects

[](#example-projects)

Try the included examples:

- `_001_helloworld` - Minimal API
- `_003_multiformat` - JSON, XML, YAML, CSV
- `_005_protected_api` - Authentication
- `_007_crud` - Full CRUD with database
- `_009_rate_limiting` - Rate limiting
- `_011_versioning` - API versioning
- `_013_html` - HTML responses with templates
- `_015_oauth2_server` - OAuth 2.0 server
- `_018_graphql` - GraphQL integration

```
composer serve
# Visit http://localhost:8080/examples/
```

---

Performance Tips
----------------

[](#performance-tips)

### 1. Enable Production Mode

[](#1-enable-production-mode)

```
// Caches routes, disables debug mode
$api = new Restler(productionMode: true);

// Clear route cache after code changes:
// rm cache/routes.php
```

### 2. Use Swoole/OpenSwoole

[](#2-use-swooleopenswoole)

**10-20x performance improvement** over PHP-FPM. Same code, no changes needed.

```
pecl install swoole
php public/index_swoole.php
```

### 3. Use Generators for Large Datasets

[](#3-use-generators-for-large-datasets)

```
// Bad: Loads everything into memory
function getUsers(): array {
    return User::all()->toArray();  // 💥 100MB+
}

// Good: Streams data
function getUsers(): Generator {
    foreach (User::cursor() as $user) {
        yield $user->toArray();  // ✅ Constant memory
    }
}
```

### 4. Cache Expensive Operations

[](#4-cache-expensive-operations)

```
use Luracast\Restler\Defaults;

// Enable route caching
Defaults::$cacheDirectory = __DIR__ . '/cache';

// Use your own caching for data
function getPopularProducts(): array {
    return Cache::remember('popular_products', 3600, function() {
        return Product::orderBy('views', 'desc')->take(10)->get();
    });
}
```

### 5. Optimize Database Queries

[](#5-optimize-database-queries)

```
// Use eager loading to avoid N+1 queries
function index(): array {
    return Order::with(['user', 'items.product'])->get();
}
```

---

Framework Comparison
--------------------

[](#framework-comparison)

FeatureRestler v6LaravelSymfonySlim**Auto-routing from methods**✅❌❌❌**Multi-format (JSON/XML/CSV/Excel)**✅PartialPartial❌**Auto OpenAPI docs**✅Via packageVia packageVia package**Swoole support**✅Via packageVia package❌**Zero config**✅❌❌Partial**Lines of code for CRUD API**~20~100~150~50**Learning curve**Very LowMediumHighLow**Best for**APIsFull-stackEnterpriseMicroservices**Restler Philosophy:** Write business logic. Get the REST for free.

---

Migration from v5
-----------------

[](#migration-from-v5)

Upgrading from Restler v5? Most code works unchanged. Key changes:

### Requirements

[](#requirements)

- PHP 8.0+ (was 7.4+)
- Add PSR-7 and PSR-11 to composer.json (auto-installed)

### Type Hints (Recommended)

[](#type-hints-recommended)

```
// v5 - Still works but add types for better validation
public function getUser($id) {
    return User::find($id);
}

// v6 - Recommended
public function getUser(int $id): ?User {
    return User::find($id);
}
```

### Breaking Changes

[](#breaking-changes)

- Removed deprecated reflection methods (internal only)
- Session serialization now uses JSON (more secure)
- Some internal class reorganization

**Full migration guide:** [MIGRATION.md](MIGRATION.md)

---

Documentation
-------------

[](#documentation)

- **[Annotations Reference](ANNOTATIONS.md)** - All PHPDoc annotations (`@url`, `@param`, etc.)
- **[Parameter Handling](PARAM.md)** - Request parameter mapping
- **[Request Lifecycle](STAGES.md)** - How Restler processes requests
- **[Forms](FORMS.md)** - HTML form handling
- **[Composer Integration](COMPOSE.md)** - Advanced setup
- **[Security Guide](SECURITY.md)** - Best practices
- **[Migration Guide](MIGRATION.md)** - Upgrading from v5
- **[Changelog](CHANGELOG.md)** - Version history

---

FAQ
---

[](#faq)

### When should I use Restler?

[](#when-should-i-use-restler)

✅ **Great for:**

- Internal APIs and microservices
- Mobile app backends
- Data export APIs (CSV, Excel)
- Rapid prototyping
- Modernizing legacy PHP apps
- APIs that need multiple formats (JSON + XML + CSV)
- High-performance requirements (with Swoole)

❌ **Not ideal for:**

- Full-stack web apps with server-side rendering (use Laravel/Symfony)
- GraphQL-first APIs (though GraphQL support is included)
- Non-PHP environments

### How is this different from Laravel/Symfony?

[](#how-is-this-different-from-laravelsymfony)

Restler is **laser-focused on APIs**. Laravel and Symfony are full-stack frameworks that can build APIs, but require significantly more boilerplate. Restler uses reflection to eliminate boilerplate entirely.

**Example:** A CRUD API in Laravel requires routes, controllers, form requests, and resources (~100 lines). In Restler it's ~20 lines.

### Is Swoole support production-ready?

[](#is-swoole-support-production-ready)

Yes! Swoole has been production-ready since 2018. Used by companies like Alibaba, Tencent, and Baidu. OpenSwoole is a fork with the same stability. Both work identically with Restler.

### Does it work with \[my favorite ORM/database\]?

[](#does-it-work-with-my-favorite-ormdatabase)

Yes! Restler is database-agnostic. Use Eloquent, Doctrine, RedBeanPHP, PDO, or anything else. Examples included for all major ORMs.

### Can I use it with Docker/Kubernetes?

[](#can-i-use-it-with-dockerkubernetes)

Absolutely. Dockerfile examples included. Works great in containers, especially with Swoole for high performance.

### Is it really production-ready?

[](#is-it-really-production-ready)

Yes! Restler has been used in production since 2010. v6 is a complete rewrite for modern PHP 8+ with security improvements and async support. Currently powers APIs handling millions of requests daily.

### What's the performance like?

[](#whats-the-performance-like)

- **PHP-FPM:** ~1,000-2,000 req/sec (typical)
- **Swoole/OpenSwoole:** ~15,000-20,000 req/sec (same hardware)
- **AWS Lambda:** Automatic scaling, cold start ~100ms

Actual numbers depend on your application logic and hardware.

---

Support &amp; Community
-----------------------

[](#support--community)

- **📖 Documentation:** [Full docs](https://github.com/Luracast/Restler/tree/master)
- **🐛 Bug Reports:** [GitHub Issues](https://github.com/Luracast/Restler/issues)
- **🔒 Security:** [SECURITY.md](SECURITY.md)
- **🌟 Star us on GitHub** if you find Restler useful!

---

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

[](#contributing)

We welcome contributions! Whether it's:

- 🐛 Bug fixes
- ✨ New features
- 📖 Documentation improvements
- 🧪 Test coverage
- 💡 Ideas and suggestions

See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

### Development Setup

[](#development-setup)

```
git clone https://github.com/Luracast/Restler.git
cd Restler
git checkout v6
composer install
composer serve  # Start dev server

# Run tests
composer test
```

---

License
-------

[](#license)

Restler is open-source software licensed under the **[MIT License](LICENSE)**.

Free for commercial and personal use.

---

Credits
-------

[](#credits)

**Created and maintained by [Luracast](https://luracast.com)**

Special thanks to all [contributors](https://github.com/Luracast/Restler/graphs/contributors) who have helped make Restler better over the years!

### **Ready to build better APIs?**

[](#ready-to-build-better-apis)

```
composer require luracast/restler:^6.0
```

**Write PHP. Get REST. 🚀**

[Get Started](#quick-start) • [Examples](#examples) • [Documentation](#documentation) • [Star on GitHub ⭐](https://github.com/Luracast/Restler)

###  Health Score

71

—

ExcellentBetter than 100% of packages

Maintenance98

Actively maintained with recent releases

Popularity63

Solid adoption and visibility

Community33

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor1

Top contributor holds 85.4% 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 ~144 days

Recently: every ~1 days

Total

32

Last Release

4d ago

Major Versions

4.0.4 → 5.0.92021-08-18

4.0.5 → 5.0.122023-04-05

5.0.13 → 6.0.02025-12-01

v3.x-dev → v4.x-dev2026-06-24

v4.x-dev → 5.0.142026-06-29

PHP version history (4 changes)3.0.0-RC4PHP &gt;=5.3.0

3.1.0PHP &gt;=5.4

6.0.0PHP ^8

5.0.14PHP &gt;=7.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/37124632bba55e8e9ae652c5d9fccf4779059a7693a8cce0eaee854b281c351c?d=identicon)[Arul](/maintainers/Arul)

---

Top Contributors

[![Arul-](https://avatars.githubusercontent.com/u/2255137?v=4)](https://github.com/Arul- "Arul- (88 commits)")[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (15 commits)")

---

Tags

asynccomposerframeworkhtml-formatjson-formatjsonpopenapiopenapi3phpphp-fpmphpdoc-commentsreactphprest-apirestlerswooleapiframeworkrestserver

###  Code Quality

TestsBehat

Static AnalysisRector

Code StyleECS

### Embed Badge

![Health badge](/badges/luracast-restler/health.svg)

```
[![Health](https://phpackages.com/badges/luracast-restler/health.svg)](https://phpackages.com/packages/luracast-restler)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.8k543.8M20.1k](/packages/laravel-framework)[drupal/core-recommended

Locked core dependencies; require this project INSTEAD OF drupal/core.

6942.5M421](/packages/drupal-core-recommended)[symfony/symfony

The Symfony PHP framework

31.4k87.2M2.2k](/packages/symfony-symfony)[tempest/framework

The PHP framework that gets out of your way.

2.2k34.4k15](/packages/tempest-framework)[silverstripe/framework

The SilverStripe framework

7313.7M2.8k](/packages/silverstripe-framework)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)

PHPackages © 2026

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