New PHP Framework
I spent the last year working on the new PHP framework to push this programming language further into the modern era.
I firmly believe that the future of PHP lies in Fibers, Coroutines, and libraries like Swoole.
The Bright Future of PHP
Most people know PHP just as a website framework, but it's much more - it can serve as a communication hub in your infrastructure that interconnects all your services through REST API, GraphQL, WebSockets, gRPC, and more.
It's effortless to prototype and write new features in PHP. PHP is also straightforward to extend; if necessary, replacing parts of your application with code written in a different language is simple. It's the perfect starting point when creating new applications.
About Resonance
Resonance is centered around this idea - to quickly start from the ground up in the asynchronous environment and be able to set up all the necessary services and APIs and then swap, replace, or expand all the application's components.
Attributes First
Everything is as modular as possible, with only minimal central configuration files - everything is configured through Attributes. For example:
<?php
namespace App\HttpResponder;
use App\DatabaseEntity\BlogPostForDisplay;
use App\HttpRouteSymbol;
use Distantmagic\Resonance\Attribute\RespondsToHttp;
use Distantmagic\Resonance\Attribute\RouteParameter;
use Distantmagic\Resonance\Attribute\Singleton;
use Distantmagic\Resonance\HttpInterceptableInterface;
use Distantmagic\Resonance\HttpResponder;
use Distantmagic\Resonance\HttpResponder\HttpController;
use Distantmagic\Resonance\RequestMethod;
use Distantmagic\Resonance\SingletonCollection;
use Distantmagic\Resonance\TwigTemplate;
#[RespondsToHttp(
method: RequestMethod::GET,
pattern: '/blog/{blog_post_slug}',
routeSymbol: HttpRouteSymbol::BlogPostShow,
)]
#[Singleton(collection: SingletonCollection::HttpResponder)]
final readonly class BlogPostShow extends HttpController
{
public function handle(
#[RouteParameter(from: 'blog_post_slug')]
BlogPostForDisplay $blogPost,
): HttpInterceptableInterface {
return new TwigTemplate('turbo/website/blog_post.twig', [
'blog_post' => $blogPost,
]);
}
}
Asynchronous GraphQL in PHP
You can build the entire GraphQL schema in PHP using attributes:
<?php
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use Distantmagic\Resonance\Framework\Attribute\Singleton;
use Distantmagic\Resonance\Framework\SwooleFuture;
#[Singleton]
final class PingType extends ObjectType
{
public function __construct()
{
parent::__construct([
'name' => 'Ping',
'description' => 'Test field',
'fields' => [
'message' => [
'type' => Type::string(),
'description' => 'Always responds with pong',
'resolve' => $this->resolveMessage(...),
],
],
]);
}
private function resolveMessage(): SwooleFuture
{
return new SwooleFuture(function () {
sleep(1);
return 'pong';
});
}
}
This query is going to take 1 second (instead of 3), since the field is resolved asynchronously:
query MultiPing() {
ping1: ping { message }
ping2: ping { message }
ping3: ping { message }
}
Promise-like Objects in PHP
Swoole's coroutines are wrapped inside a SwooleFuture object, which provides easy access to asynchronous features:
<?php
use Distantmagic\Resonance\SwooleFuture;
$future1 = new SwooleFuture(function (int $value) {
assert($value === 1);
return $value + 2;
});
$future2 = $future1->then(new SwooleFuture(function (int $value) {
assert($value === 3);
return $value + 4;
}));
assert($future2->resolve(1)->result === 7);
Much more
The project is free and open source.
You can check the documentation here: https://resonance.distantmagic.com/docs/features/
GitHub repo: https://github.com/distantmagic/resonance
Feel free to join the community: https://resonance.distantmagic.com/community/
Resonance is new, and it's my first open-source project of this magnitude. Currently, I am working on it full-time. If you try it out and Resonance will help you with your projects, I'd be the happiest man alive.
If you find the project interesting please leave me a star on GitHub!