adelowo / spiral

Simple PSR/PHP7 framework with military grade tools

Home Page:https://spiral-framework.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Spiral, PSR7/PHP7 Framework

Latest Stable Version Total Downloads License Build Status Scrutinizer Code Quality Coverage Status

Spiral Framework

The Spiral framework provides open and modular Rapid Application Development (RAD) environment, database tools, code re-usability, extremely friendly IoC, IDE integration, PSR-7, simple syntax and customizable scaffolding mechanisms.

Skeleton App | Guide | Twitter | Modules | CHANGELOG | Contributing | Forum



Examples:

class HomeController extends Controller
{
    /**
     * IoC Container can automatically decide what database/cache/storage
     * instance to provide for every action parameter based on it's 
     * name or type.
     *
     * @param Database   $database
     * @param Database   $logs     Can be physical or virtual database
     * @param HttpConfig $config   
     * @return string
     */
    public function indexAction(Database $database, Database $logs, HttpConfig $config): string 
    {
        dump($config->basePath());
    
        $logs->table('log')->insertOne(['message' => 'Yo!']);
    
        return $this->views->render('welcome', [
            'users' => $database->table('users')->select()->where(['name' => 'John'])->fetchAll()
        ]);
    }
}

Bootloaders, Factory Methods:

class MyBootloader extends Bootloader
{
    const BINDINGS = [
        ParserInterface::class => DefaultParser::class,
        'someService'          => SomeService::class
    ];
    
    const SINGLETONS = [
        ReaderInterface::class => [self::class, 'makeReader'],
    ];
    
    protected function makeReader(ParserInterface $parser, Database $database): Reader
    {
        return new Reader($parser, $database->table('some'));
    }
}

Declarative/lazy singletons and services:

class SomeService implements SingletonInterface
{
    private $reader;
    
    public function __construct(ReaderInterface $reader)
    {
        $this->reader = $reader;
    }

    public function readValue(string $value): string
    {
        return $this->reader->read($value);
    }
}

JSON responses, method injections, IoC scopes, container shortcuts, IDE helpers:

public function indexAction(ServerRequestInterface $request, SomeService $service): array
{
    dump($service->readValue('abc'));
    
    //Shortcuts
    dump($this->someService === $service);
    
    return [
        'status' => 200,
        'uri'    => (string)$request->getUri()
    ];
}

Short Bindings

Spiral application(s) can be used as middleware/endpoint inside other PSR7 frameworks:

use Zend\Diactoros\Server;
use Zend\Expressive\Application;
use Zend\Stratigility\MiddlewarePipe;

$app = new Application();
$app->any('/spiral', SpiralApp::init(...)->http);

ORM with scaffolding/migrations for MySQL, PostgreSQL, SQLite, SQL Server:

class Post extends RecordEntity
{
    use TimestampsTrait;

    //Database partitions, isolation and aliasing
    const DATABASE = 'blog';

    const SCHEMA = [
        'id'     => 'bigPrimary',
        'title'  => 'string(64)',
        'status' => 'enum(published,draft)',
        'body'   => 'text',
        
        //Simple relation definitions
        'comments' => [self::HAS_MANY => Comment::class],
        
        //Not very simple relation definitions
        'collaborators' => [
            self::MANY_TO_MANY  => User::class,
            self::PIVOT_TABLE   => 'post_collaborators_map',
            self::PIVOT_COLUMNS => [
                'time_assigned' => 'datetime',
                'type'          => 'string, nullable',
            ],
            User::INVERSE       => 'collaborated_posts'
        ],
        
        //Pre-compiled relations
        'author'   => [
            self::BELONGS_TO   => AuthorInterface::class,
            self::LATE_BINDING => true
        ],
               
        //Hybrid databases
        'metadata' => [
            Document::ONE => Mongo\Metadata::class
        ]
    ];
}
$posts = $postSource->find()->distinct()
    ->with('comments', ['where' => ['{@}.approved' => true]]) //Automatic joins
    ->with('author')->where('author_name', 'LIKE', $authorName) //Fluent
    ->load('comments.author') //Cascade eager-loading (joins or external query)
    ->paginate(10) //Quick pagination using active request
    ->getIterator();

foreach ($posts as $post) {
    echo $post->author->getName();
}
$post = new Post();
$post->publish_at = 'tomorrow 8am';
$post->author = new User(['name' => 'Antony']);

$post->tags->link(new Tag(['name' => 'tag A']));
$post->tags->link($tags->findOne(['name' => 'tag B']));

$transaction = new Transaction();
$transaction->store($post);
$transaction->run();

//--or--: Active record (optional)
$post->save();

//--or--: request specific transaction
$this->transaction->store($post);

This example uses IoC scope to properly resolve ORM connection manager, "no magic" way - $postSource->create([]);

And much more: Skeleton App | Guide

Tests

$ composer install
$ vendor/bin/phpunit

About

Simple PSR/PHP7 framework with military grade tools

https://spiral-framework.com

License:MIT License


Languages

Language:PHP 99.8%Language:HTML 0.2%