/spiral-framework

Full-stack PHP7/PSR framework with military grade DDD tools

Primary LanguagePHPMIT LicenseMIT

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, powerful Database tools, code re-usability, extremely friendly IoC, IDE integration, PSR-* standards, simple syntax and customizable scaffolding mechanisms.

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



Installation

composer create-project spiral/application
cd application

Once application installed you can ensure that it was configured properly by executing:

./spiral configure -k && vendor/bin/phpunit

Examples:

class HomeController extends Controller
{
    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'));
    }
}

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

public function indexAction(ServerRequestInterface $request, SomeService $service): array
{    
    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'
        ],
        
        //Statically binded 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']));

// automatic transaction management
$post->save();

// or: transactional approach
$transaction->store($post);

And much more: Skeleton App | Guide

Tests

$ composer install
$ vendor/bin/phpunit