A framework agnostic, developer friendly wrapper around Fractal

Overview

A developer friendly wrapper around Fractal

Latest Version on Packagist Software License GitHub Workflow Status Quality Score Total Downloads

Fractal is an amazing package to transform data before using it in an API. Unfortunately working with Fractal can be a bit verbose.

Using Fractal data can be transformed like this:

use League\Fractal\Manager;
use League\Fractal\Resource\Collection;

$books = [
   ['id'=>1, 'title'=>'Hogfather', 'characters' => [...]], 
   ['id'=>2, 'title'=>'Game Of Thrones', 'characters' => [...]]
];

$manager = new Manager();

$resource = new Collection($books, new BookTransformer());

$manager->parseIncludes('characters');

$manager->createData($resource)->toArray();

This package makes that process a tad easier:

Fractal::create()
   ->collection($books)
   ->transformWith(new BookTransformer())
   ->includeCharacters()
   ->toArray();

There's also a very short syntax available to quickly transform data:

Fractal::create($books, new BookTransformer())->toArray();

If you want to use this package inside Laravel, it's recommend to use laravel-fractal instead. That package contains a few more whistles and bells specifically targetted at Laravel users.

Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects on our website.

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Install

You can pull in the package via composer:

composer require spatie/fractalistic

Usage

In the following examples were going to use the following array as example input:

$books = [['id'=>1, 'title'=>'Hogfather'], ['id'=>2, 'title'=>'Game Of Kill Everyone']];

But know that any structure that can be looped (for instance a collection) can be used.

Let's start with a simple transformation.

Spatie\Fractalistic\Fractal::create()
   ->collection($books)
   ->transformWith(function($book) { return ['id' => $book['id']];})
   ->toArray();

This will return:

['data' => [['id' => 1], ['id' => 2]]

In all following examples it's assumed that you imported the Spatie\Fractalistic\Fractal at the top of your php file.

Instead of using a closure you can also pass a Transformer:

Fractal::create()
   ->collection($books)
   ->transformWith(new BookTransformer())
   ->toArray();

You can also pass the classname of the Transformer:

Fractal::create()
   ->collection($books)
   ->transformWith(BookTransformer::class)
   ->toArray();

To make your code a bit shorter you could also pass the transform closure, class, or classname as a second parameter of the collection-method:

Fractal::create()->collection($books, new BookTransformer())->toArray();

Want to get some sweet json output instead of an array? No problem!

Fractal::create()->collection($books, new BookTransformer())->toJson();

A single item can also be transformed:

Fractal::create()->item($books[0], new BookTransformer())->toArray();

Using a serializer

Let's take a look again at the output of the first example:

['data' => [['id' => 1], ['id' => 2]];

Notice that data-key? That's part of Fractal's default behaviour. Take a look at Fractals's documentation on serializers to find out why that happens.

If you want to use another serializer you can specify one with the serializeWith-method. The Spatie\Fractalistic\ArraySerializer comes out of the box. It removes the data namespace for both collections and items.

Fractal::create()
   ->collection($books)
   ->transformWith(function($book) { return ['id' => $book['id']];})
   ->serializeWith(new \Spatie\Fractalistic\ArraySerializer())
   ->toArray();

//returns [['id' => 1], ['id' => 2]]

You can also pass the serializer classname instead of an instantiation:

Fractal::create()
   ->collection($books)
   ->transformWith(BookTransformer::class)
   ->serializeWith(MySerializer::class)
   ->toArray();

Changing the default serializer

You can change the default serializer by providing the classname or an instantiation of your favorite serializer in the config file.

Using includes

Fractal provides support for optionally including data on the relationships for the data you're exporting. You can use Fractal's parseIncludes which accepts a string or an array:

Fractal::create()
   ->collection($this->testBooks, new TestTransformer())
   ->parseIncludes(['characters', 'publisher'])
   ->toArray();

To improve readablity you can also use a function named include followed by the name of the include you want to... include:

Fractal::create()
   ->collection($this->testBooks, new TestTransformer())
   ->includeCharacters()
   ->includePublisher()
   ->toArray();

Using excludes

Similar to includes Fractal also provides support for optionally excluding data on the relationships for the data you're exporting. You can use Fractal's parseExcludes which accepts a string or an array:

Fractal::create()
   ->collection($this->testBooks, new TestTransformer())
   ->parseExcludes(['characters', 'publisher'])
   ->toArray();

To improve readability you can also use a function named exclude followed by the name of the include you want to... exclude:

Fractal::create()
   ->collection($this->testBooks, new TestTransformer())
   ->excludeCharacters()
   ->excludePublisher()
   ->toArray();

Including meta data

Fractal has support for including meta data. You can use addMeta which accepts one or more arrays:

Fractal::create()
   ->collection($this->testBooks, function($book) { return ['name' => $book['name']];})
   ->addMeta(['key1' => 'value1'], ['key2' => 'value2'])
   ->toArray();

This will return the following array:

[
   'data' => [
        ['title' => 'Hogfather'],
        ['title' => 'Game Of Thrones'],
    ],
   'meta' => [
        ['key1' => 'value1'], 
        ['key2' => 'value2'],
    ]
];

Using pagination

Fractal provides a Laravel-specific paginator, IlluminatePaginatorAdapter, which accepts an instance of Laravel's LengthAwarePaginator and works with paginated Eloquent results. When using some serializers, such as the JsonApiSerializer, pagination data can be automatically generated and included in the result set:

$paginator = Book::paginate(5);
$books = $paginator->getCollection();

Fractal::create()
    ->collection($books, new TestTransformer())
    ->serializeWith(new JsonApiSerializer())
    ->paginateWith(new IlluminatePaginatorAdapter($paginator))
    ->toArray();

Using a cursor

Fractal provides a simple cursor class, League\Fractal\Pagination\Cursor. You can use any other cursor class as long as it implements the League\Fractal\Pagination\CursorInterface interface. When using it, the cursor information will be automatically included in the result metadata:

$books = $paginator->getCollection();

$currentCursor = 0;
$previousCursor = null;
$count = count($books);
$newCursor = $currentCursor + $count;

Fractal::create()
  ->collection($books, new TestTransformer())
  ->serializeWith(new JsonApiSerializer())
  ->withCursor(new Cursor($currentCursor, $previousCursor, $newCursor, $count))
  ->toArray();

Setting a custom resource name

Certain serializers wrap the array output with a data element. The name of this element can be customized:

Fractal::create()
    ->collection($this->testBooks, new TestTransformer())
    ->serializeWith(new ArraySerializer())
    ->withResourceName('books')
    ->toArray();
Fractal::create()
    ->item($this->testBooks[0], new TestTransformer(), 'book')
    ->serializeWith(new ArraySerializer())
    ->toArray();

Limit recursion

To increase or decrease the level of embedded includes you can use limitRecursion.

Fractal::create()
    ->collection($this->testBooks, new TestTransformer())
    ->includesDataThatHasALotOfRecursion
    ->limitRecursion(5);

If you do not call limitRecursion a default value of 10 is used.

Quickly transform data with the short function syntax

You can also pass arguments to the fractal-function itself. The first arguments should be the data you which to transform. The second one should be a transformer or a closure that will be used to transform the data. The third one should be a serializer.

Here are some examples

Fractal::create($books, new BookTransformer())->toArray();

Fractal::create($books, new BookTransformer(), new ArraySerializer())->toArray();

Fractal::create($books, BookTransformer::class, ArraySerializer::class)->toArray();

Fractal::create(['item1', 'item2'], function ($item) {
   return $item . '-transformed';
})->toArray();

Changelog

Please see CHANGELOG for more information what has changed recently.

Testing

$ composer test

Contributing

Please see CONTRIBUTING for details.

Security

If you've found a bug regarding security please mail [email protected] instead of using the issue tracker.

Postcardware

You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.

Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.

We publish all received postcards on our company website.

Credits

License

The MIT License (MIT). Please see License File for more information.

Comments
  • Incorrectly determines datatype for single item

    Incorrectly determines datatype for single item

    Imagine this code:

    $one_book = [
        'id' => '1',
        'title' => 'Hogfather',
        'yr' => '1998',
        'author_name' => 'Philip K Dick',
        'author_email' => '[email protected]',
        'characters' => [['name' => 'Death'], ['name' => 'Hex']],
        'publisher' => 'Elephant books',
    ];
    
    Fractal::create($one_book, new BookTransformer())->toArray();
    

    Results in:

    TypeError: Argument 1 passed to BookTransformer::transform() must be of the type array, 
    string given, called in .../vendor/league/fractal/src/Scope.php on line 407
    

    This is because determineDataType() assumes that if you are passing an array, then you must be trying to transform to a Collection.

    Arguably, most people are going to pass in objects instead of arrays as the first argument of Fractal::create() if they are trying to transform an Item. But -- even as you do in the tests -- there is nothing stopping someone from transforming an array to an Item.

    I think the only way to determine correctly if passed data represents an Item or a Collection (or a Primative, with Fractal 0.17.0) is if the data is an array of the same type of object: an array of arrays, or an array of objects, or an array of primitives. This is probably not super performant. :(

    opened by cviebrock 7
  • Fractal::jsonSerialize() triggers a Type error (PHP 7.4.24)

    Fractal::jsonSerialize() triggers a Type error (PHP 7.4.24)

    This change done to support PHP 8.1 triggers a Type error.

    Commit: https://github.com/spatie/fractalistic/commit/4d3b8a68b6575e9b0202e842977c9c29224fd9ac#diff-9ebff18d48644c7d6e2c1006245d57ef9028099e796f76f967c8656aedadcf4bR458

    Change: https://github.com/spatie/fractalistic/blob/5a89b24d3153a9c4b17cd1ed523b0a5ef9143558/src/Fractal.php#L458

    Error:

    TypeError
    Return value of Spatie\Fractalistic\Fractal::jsonSerialize() must be an instance of Spatie\Fractalistic\mixed, array returned 
    

    Reason:

    • Fractal::toArray return type is array
    • Fractal::jsonSerialize() return type os mixed

    Further details:

    • PHP version: 7.4.24
    opened by albertoarena 6
  • Problem with ucfirst when using setlocale(LC_ALL,tr)

    Problem with ucfirst when using setlocale(LC_ALL,tr)

    I opened an issue here about that : https://github.com/spatie/laravel-fractal/issues/108

    When the locale setted to tr ucfirst not working as expected because of Turkish alphabet has capitalized i which is İ.

    $resourceClasss returning League\Fractal\Resource\item instead of League\Fractal\Resource\Item

    I don't know it was super necessary but this cost me 8 hours today :)

    opened by monurakkaya 6
  • Add support NullResource

    Add support NullResource

    Support NULL resource serialize

    /** @var $user User|null */
    $user = getCurrentUser();
    fractal($user, UserTransformer::class)
        ->serializeWith(new JsonApiSerializer())
        ->withResourceName('users')
        ->toArray();
    

    And result:

    {
      "data": null
    }
    

    or

    {
      "data": {
        "id": "1",
        "type": "users",
        "attributes": {}
      }
    }
    
    opened by oanhnn 4
  • PHP 8.1 deprecations

    PHP 8.1 deprecations

    Hey.

    There are PHP 8.1 deprecations that this package doesn't account for. One of them is with JsonSerializable:

    During inheritance of JsonSerializable: Uncaught ErrorException: Return type of Spatie\Fractalistic\Fractal::jsonSerialize() should either be compatible with JsonSerializable::jsonSerialize(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /app/vendor/spatie/fractalistic/src/Fractal.php:458
    Stack trace:
    #0 /app/vendor/spatie/fractalistic/src/Fractal.php(13): Tests\TestCase::{closure}()
    
    opened by oprypkhantc 3
  • Paginator links property is either array or object

    Paginator links property is either array or object

    I've checked in both this repo as well as laravel-fractal and I believe my issue originates here. I'm noticing an issue with the paginateWith method which adds pagination info to the meta key in my json responses. When there are no links for the pagination the meta property looks like this:

    "meta": {
            "pagination": {
    ...
                "links": []
            }
        }
    

    When there are, it looks like this:

    "meta": {
            "pagination": {
    ...
                "links": {
                    "next": "[url]"
                }
            }
        }
    

    You can see that in an empty resultset the links property is an array and when set, it's an object. This causes issues for client implementing our API. Any idea on where to fix this?

    opened by tomvo 3
  • include depth

    include depth

    Hi,

    I was wondering if it's possible to set and include depth. I have an API with might return a large collection of data. I know I can paginate but that's just not sufficient enough.

    I handle sports data statistics so let's say I have a paginated response with 25 seasons on a page. the season entity has and option to include fixtures which on it's turn has the possibility to include a lineup, events, stats etc.

    you can image that, since a season has around 380 fixtures, the response can be big. especially when including more related includes.

    so I was wondering if it's possible to set a max depth to set it for example to 1 so that on a given endpoint only fixtures can be included and all other related includes are not handled.

    or would there be any other solution to achieve such?

    opened by ronnievisser 3
  • Response code attachment?

    Response code attachment?

    Hello. I have a proposition regarding Fractal and response codes. If you feel like it is more Laravel connected, I'll make sure to move this issue there.

    The problem

    Fractal's main responsibility is to change given array into given format. But. By many (or almost everyone) it is (ab)used to create JSON responses in our APIs.

    return fractal()
        ->collection($users)
        ->transformWith(new UserTransformer)
        ->toArray();
    

    And this is awesome. There is just one problem though. It does everything except adding a status code into our response. And that is understandable, considering Fractal's main goal, but it makes creating responses with status codes pretty hairy:

    return response()->json(
        fractal()
            ->item('These credentials do not match our records.')
            ->transformWith(new ErrorTransformer)
            ->serializeWith(new ArraySerializer)
            ->toArray()
    , 401);
    

    Proposition

    My proposal is to add a public method to attach status codes like so:

    return fractal()
        ->item('These credentials do not match our records.')
        ->transformWith(new ErrorTransformer)
        ->serializeWith(new ArraySerializer)
        ->withStatusCode(403)
        ->respond();
    
    // and/or
    
    return fractal()
        ->item('These credentials do not match our records.')
        ->transformWith(new ErrorTransformer)
        ->serializeWith(new ArraySerializer)
        ->respond(403);
    

    This would generate a JSON response attaching provided status code.

    Concerns

    Whilst making responses in Laravel is easy (it is opinionated, the method's/function's/class' names are known. The method would be just a wrapper for response()->json()) in a generic package as this the response would need to be generated, either by a passed-in ResponseFactory, or by our own ResponseManager.

    Proposition

    My proposition is to make this functionality only into Laravel's package, while it would be too messy to include it in this generic package.

    TL;DR

    I suggest creating a helper method ->respond($statusCode) that would generate a HTTP JSON Response. I suggest doing that in Laravel's variant of this package, but I throw it here as it may be a good idea to include it in a more generic package.


    P.S. I really appreciate you making Fractal even better than it already is.

    opened by DCzajkowski 3
  • null return error

    null return error

    I had my ArraySerializer overriden to avoid "[]" values on ->null() to just return null

    public function null(): ?array
    {
        return null;
    }
    

    After upgrading from 2.9.1 -> 2.9.4 I get this error

    TypeError: Return value of Spatie\Fractalistic\Fractal::jsonSerialize() must be of the type array, null returned in file /var/www/app/vendor/spatie/fractalistic/src/Fractal.php on line 463

    #0 [internal function]: Spatie\Fractalistic\Fractal->jsonSerialize() #1 /var/www/app/vendor/laravel/framework/src/Illuminate/Http/JsonResponse.php(80): json_encode(Array, 0) #2 /var/www/app/vendor/symfony/http-foundation/JsonResponse.php(54): Illuminate\Http\JsonResponse->setData(Object(Spatie\Fractal\Fractal)) #3 /var/www/app/vendor/laravel/framework/src/Illuminate/Http/JsonResponse.php(32): Symfony\Component\HttpFoundation\JsonResponse->__construct(Object(Spatie\Fractal\Fractal), 200, Array, false) #4 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(818): Illuminate\Http\JsonResponse->__construct(Object(Spatie\Fractal\Fractal)) #5 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(789): Illuminate\Routing\Router::toResponse(Object(Illuminate\Http\Request), Object(Spatie\Fractal\Fractal)) #6 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(721): Illuminate\Routing\Router->prepareResponse(Object(Illuminate\Http\Request), Object(Spatie\Fractal\Fractal)) #7 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\Routing\Router->Illuminate\Routing{closure}(Object(Illuminate\Http\Request)) #8 /var/www/app/app/Core/Http/Middleware/Country.php(19): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(Object(Illuminate\Http\Request))

    opened by Casperhr 2
  • Declaration of Spatie\Fractalistic\ArraySerializer::collection(string $resourceKey, array $data) invalid

    Declaration of Spatie\Fractalistic\ArraySerializer::collection(string $resourceKey, array $data) invalid

    It seems guys at League\Fractal updated definitions that are used within Spatie\Fractalistic\ArraySerializer which in term broke whole library.

    Declaration of Spatie\Fractalistic\ArraySerializer::collection(string $resourceKey, array $data): array must be compatible with League\Fractal\Serializer\ArraySerializer::collection(?string $resourceKey, array $data): array

    opened by lukasvy 2
  •  Setting `withResourceName` results in an empty ParamBag for Includes.

    Setting `withResourceName` results in an empty ParamBag for Includes.

    I'm not yet sure if this issue ultimately rests on Fractalistic or the underlying Fractal package. Will close if I determine this is the inappropriate place for this issue.

    When \League\Fractal\TransformerAbstract::callIncludeMethod calls the \League\Fractal\Scope::getIdentifier method the resulting identifier is "incorrect" IF \Spatie\Fractalistic\Fractal::withResourceName was called to set a "top level identifier". It's "incorrect" in the sense that \League\Fractal\Manager::getIncludeParams method has no entry for the resulting identifier.

    Code example:

    url: /api/v1/abcd/users/36?include=comments:status_in(deleted)

    ... 
    return fractal($user, $transformer, new JsonApiSerializer($base_url))
                    ->withResourceName('abcd-users')
                    ->respond($status, $headers);
    

    Then in \League\Fractal\TransformerAbstract::callIncludeMethod

    protected function callIncludeMethod(Scope $scope, $includeName, $data)
        {
            $scopeIdentifier = $scope->getIdentifier($includeName);
            // resulting `$scopeIdentifer` is `abcd-users.comments`
            $params = $scope->getManager()->getIncludeParams($scopeIdentifier);
            // `$params` is empty as the manager only has `includeParams` for `comments` (not `abcd-users.comments`).
           ... 
    } 
    
    opened by PeterCat12 2
  • Change minimum requirement to PHP 8 and add type hints

    Change minimum requirement to PHP 8 and add type hints

    This PR contains:

    • [x] PHP 8 required as minimum PHP version
    • [x] Updated code to have type hints for properties, method arguments, return types.
    • [x] Initialized properties with null value where necessary
    • [x] Updated SparseFieldsetsTest to correctly follow the method signature of Fractal::item() in test (identified after adding type hints)
    • [ ] Remove docblocks
    opened by shahlin 0
  • Using `withResourceName` makes fractal include parameters not working

    Using `withResourceName` makes fractal include parameters not working

    Example:

    $fractal = Fractal::create($users, new UserTransformer())->withResourceName('users');
    $fractal->parseIncludes(['posts'])->toArray();
    

    In League\Fractal\TransformerAbstract at callIncludeMethod method we get the following result:

    // this line will get 'users.posts' as identifier
    $scopeIdentifier = $scope->getIdentifier($includeName);
    
    // this line will try to find include params for 'users.posts' identifier instead 'posts'
    $params = $scope->getManager()->getIncludeParams($scopeIdentifier);
    

    But League\Fractal\Scope object is being built like this:

    League\Fractal\Scope Object
    (
        [availableIncludes:protected] => Array
            (
                [0] => posts
            )
        [scopeIdentifier:protected] => users
        [manager:protected] => League\Fractal\Manager Object
            (
                [requestedIncludes:protected] => Array
                    (
                        [0] => posts
                    )
                [includeParams:protected] => Array
                    (
                        [posts] => Array
                            (
                                [limit] => Array
                                    (
                                        [0] => 5,
                                        [1] => 1,
                                    )
                            )
                    )
    

    As you can see League\Fractal\Manager will not find the posts include params because getIncludeParams method will look for users.posts key instead.

    opened by darkons 1
  • Invalid return value for resource

    Invalid return value for resource

    Hi all.

    I'm using transformer and includes. But if I return NullResource I'm getting an empty array instead of the null value.

    image

    image

    Why I'm getting an empty array instead null ?

    Thanks for advice.

    opened by siarheipashkevich 0
Releases(2.9.5)
Owner
Spatie
We create open source, digital products and courses for the developer community
Spatie
This package has framework agnostic Cross-Origin Resource Sharing (CORS) implementation.

Description This package has framework agnostic Cross-Origin Resource Sharing (CORS) implementation. It is complaint with PSR-7 HTTP message interface

null 60 Nov 9, 2022
DepDrop widget is a Yii 2 wrapper for the dependent-dropdown jQuery plugin by Krajee.

yii2-widget-depdrop The DepDrop widget is a Yii 2 wrapper for the dependent-dropdown jQuery plugin by Krajee. This plugin allows multi level dependent

Kartik Visweswaran 82 Nov 27, 2022
CleverStyle Framework is simple, scalable, fast and secure full-stack PHP framework

CleverStyle Framework is simple, scalable, fast and secure full-stack PHP framework. It is free, Open Source and is distributed under Free Public Lice

Nazar Mokrynskyi 150 Apr 12, 2022
I made my own simple php framework inspired from laravel framework.

Simple MVC About Since 2019, I started learning the php programming language and have worked on many projects using the php framework. Laravel is one

null 14 Aug 14, 2022
PHPR or PHP Array Framework is a framework highly dependent to an array structure.

this is new repository for php-framework Introduction PHPR or PHP Array Framework is a framework highly dependent to an array structure. PHPR Framewor

Agung Zon Blade 2 Feb 12, 2022
I made my own simple php framework inspired from laravel framework.

Simple MVC About Since 2019, I started learning the php programming language and have worked on many projects using the php framework. Laravel is one

Rizky Alamsyah 14 Aug 14, 2022
Framework X – the simple and fast micro framework for building reactive web applications that run anywhere.

Framework X Framework X – the simple and fast micro framework for building reactive web applications that run anywhere. Quickstart Documentation Tests

Christian Lück 620 Jan 7, 2023
Framework X is a simple and fast micro framework based on PHP

Framework X is a simple and fast micro framework based on PHP. I've created a simple CRUD application to understand how it works. I used twig and I created a custom middleware to handle PUT, DELETE methods.

Mahmut Bayri 6 Oct 14, 2022
Spiral Framework is a High-Performance PHP/Go Full-Stack framework and group of over sixty PSR-compatible components

Spiral HTTP Application Skeleton Spiral Framework is a High-Performance PHP/Go Full-Stack framework and group of over sixty PSR-compatible components.

Spiral Scout 152 Dec 18, 2022
Sunhill Framework is a simple, fast, and powerful PHP App Development Framework

Sunhill Framework is a simple, fast, and powerful PHP App Development Framework that enables you to develop more modern applications by using MVC (Model - View - Controller) pattern.

Mehmet Selcuk Batal 3 Dec 29, 2022
A PHP framework for web artisans.

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

The Laravel Framework 72k Jan 7, 2023
The Symfony PHP framework

Symfony is a PHP framework for web and console applications and a set of reusable PHP components. Symfony is used by thousands of web applications (in

Symfony 27.8k Jan 2, 2023
Open Source PHP Framework (originally from EllisLab)

What is CodeIgniter CodeIgniter is an Application Development Framework - a toolkit - for people who build web sites using PHP. Its goal is to enable

B.C. Institute of Technology 18.2k Dec 29, 2022
Yii 2: The Fast, Secure and Professional PHP Framework

Yii 2 is a modern framework designed to be a solid foundation for your PHP application. It is fast, secure and efficient and works right out of the bo

Yii Software 14k Dec 31, 2022
CakePHP: The Rapid Development Framework for PHP - Official Repository

CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Associative Data Mapping, Front Controller, and MVC. O

CakePHP 8.6k Dec 31, 2022
Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs.

Slim Framework Slim is a PHP micro-framework that helps you quickly write simple yet powerful web applications and APIs. Installation It's recommended

Slim Framework 11.5k Jan 4, 2023
High performance, full-stack PHP framework delivered as a C extension.

Phalcon Framework Phalcon is an open source web framework delivered as a C extension for the PHP language providing high performance and lower resourc

The Phalcon PHP Framework 10.7k Jan 8, 2023
Official Zend Framework repository

Welcome to the Zend Framework 3.0 Release! RELEASE INFORMATION Zend Framework 3.0.1dev This is the first maintenance release for the Zend Framework 3

Zend Framework 5.6k Dec 29, 2022
🚀 PHP Microservice Full Coroutine Framework

PHP microservice coroutine framework 中文说明 Introduction Swoft is a PHP microservices coroutine framework based on the Swoole extension. Like Go, Swoft

Swoft Cloud 5.5k Dec 28, 2022