nations-original/php-simple-framework

A simple PHP framework for Nations Original.

Maintainers

Package info

github.com/Ondottr/PHP_SF_Platform

pkg:composer/nations-original/php-simple-framework

Statistics

Installs: 49

Dependents: 1

Suggesters: 0

Stars: 3

Open Issues: 0

v1.1.5 2026-03-31 08:57 UTC

README

A lightweight, modern PHP 8.3+ framework built on top of Symfony and Doctrine, designed for rapid web application development with clean attribute-based configuration.

Package: nations-original/php-simple-framework Namespace: PHP_SF\System\ License: ISC Author: Dmytro Dyvulskyi — CEO & Lead Developer, Nations Original

Documentation

Full documentation is available at wiki.nations-original.com/framework.

The wiki covers every aspect of the framework in depth — from installation and first steps to advanced topics like dual-kernel architecture, caching, message queues, and testing. If you are new to the framework, start there.

Section Topics
Getting Started Installation, constants, creating your first page
Core Lifecycle, controllers, routing, middleware, views, sessions, redirects
Dual Kernel PHP_SF kernel + Symfony kernel coexistence, bootstrap order
Data & Persistence Entities, repositories, validation, cache, fixtures, enums
Infrastructure Docker, Redis, RabbitMQ, template cache, kernel config
Supporting Features Helper functions, translation, events, CRUD controller
Development & Testing PHPUnit, dev mode
Frontend Asset building with Webpack

Getting Started

This package is the framework core. To start a new project, use the template:

composer create-project nations-original/php-simple-framework-template my-app

To add the framework to an existing Symfony project:

composer require nations-original/php-simple-framework

Requires PHP 8.3+ with strict typing, plus ext-apcu, ext-redis. See Installation guide for full prerequisites.

Overview

PHP Simple Framework sits alongside Symfony's kernel inside the same PHP process. When a request comes in, the framework's router tries to match it first using its own attribute-based routing. If no match is found, the request falls through to Symfony. This gives you the performance and simplicity of a hand-rolled framework while retaining the full power of the Symfony ecosystem (DI container, console, bundles, Doctrine) when you need it.

See Dual Kernel Architecture for a detailed explanation.

Request Lifecycle

  1. public/index.php bootstraps autoloader, global functions, and constants
  2. PHP_SF\System\Kernel boots — registers controllers, translations and templates
  3. Router resolves the URL against registered #[Route] attributes (cached in Redis)
  4. Middleware chain executes (pre-dispatch)
  5. Controller method is called, producing a Response, RedirectResponse, or JSON
  6. Response is sent; output buffer is flushed

Full 17-step trace: Request & Response Lifecycle.

Core Concepts

Routing

Routes are declared with PHP 8 attributes directly on controller methods. No separate routing file needed.

use PHP_SF\System\Attributes\Route;

#[Route(url: 'posts/{id}', httpMethod: 'GET', name: 'post_show')]
public function show(int $id): Response { ... }
  • URL parameters use {param} syntax with automatic type casting
  • Named routes for URL generation via routeLink('post_show', ['id' => 42])
  • Route-level middleware assignment
  • Routes are cached in Redis after first resolution

Full reference: Routing.

Controllers

Extend AbstractController and return a Response, JSON, or redirect.

use PHP_SF\System\Classes\Abstracts\AbstractController;
use PHP_SF\System\Attributes\Route;

class PostController extends AbstractController
{
    #[Route(url: 'posts', httpMethod: 'GET', name: 'post_index')]
    public function post_list_view(): Response
    {
        return $this->render(new post_list_view());
    }

    #[Route(url: 'api/posts', httpMethod: 'GET', name: 'api_post_index')]
    public function api_posts(): Response
    {
        return $this->ok(['posts' => [...]]);
    }
}

Available JSON shortcut methods: ok(), created(), badRequest(), unauthorized(), forbidden(), notFound(), conflict(), unprocessableEntity(), etc.

Full reference: Controllers.

Views

Views are PHP classes that extend AbstractView and implement a show() method. Output buffering captures the rendered HTML; the framework injects the configured header and footer automatically.

Full reference: Views.

Middleware

Middleware files extend Middleware and are referenced by name on #[Route] attributes. Middleware can be composed with:

  • MiddlewareAll — all listed middleware must pass
  • MiddlewareAny — at least one must pass
  • MiddlewareCustom — custom composition logic

Full reference: Middleware.

Entities

Entities extend AbstractEntity and use Doctrine ORM attributes alongside PHP_SF validation attributes.

use PHP_SF\System\Classes\Abstracts\AbstractEntity;
use PHP_SF\System\Attributes\Validator as Validate;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: PostRepository::class)]
class Post extends AbstractEntity
{
    #[ORM\Column]
    #[Validate\Length(min: 3, max: 255)]
    #[TranslatablePropertyName]
    protected string $title;
}
  • Properties must be protected (AbstractEntity uses reflection)
  • #[TranslatablePropertyName] enables localized validation error messages
  • Doctrine lifecycle callbacks via App/DoctrineLifecycleCallbacks/

Full reference: Entities · Validation.

Multi-Database & EntityManager

The framework supports multiple simultaneous Doctrine entity managers. Use the em() helper with a connection name — never rely on the default EM.

em('postgresql')->getRepository(User::class)->find($id);
em('mysql')->persist($post);
em('mariadb')->flush();

Full reference: Repositories.

Caching

The ca() helper returns the best available cache adapter automatically. Specific adapters are also accessible directly.

ca()->set('key', $value, 3600);   // auto-selects APCu → Redis → Memcached
aca()->set('key', $value);        // APCu cache adapter
rca()->set('key', $value);        // Redis cache adapter
mca()->set('key', $value);        // Memcached cache adapter

Full reference: Cache · Redis.

Helper Functions

Global helper functions cover the most common framework operations without requiring dependency injection.

Function Purpose
em(string $name) Get a Doctrine EntityManager by connection name
qb(string $name) Get a Doctrine QueryBuilder
ca() Get the auto-selected cache adapter
rca() / aca() / mca() Get Redis / APCu / Memcached adapter
rc() Get the Redis client
s() Get the current Session
routeLink(string $name, array $params) Generate a URL from a named route
_t(string $key) Translate a string

Full reference: Helper Functions.

Translation

Translation files live in lang/ and are loaded during kernel boot. Use _t('key') anywhere in templates or controllers.

Full reference: Translation.

Message Queues (RabbitMQ)

RabbitMQ publisher and consumer are available via PHP_SF\System\Database\RabbitMQ and RabbitMQConsumer. Queue names are defined in App/Enums/Amqp/QueueEnum.php.

Full reference: RabbitMQ.

Namespace Structure

Namespace Path Purpose
PHP_SF\System\ src/ Framework core (routing, kernel, cache, base classes)
PHP_SF\Framework\ app/ Framework-provided app skeleton (controllers, middleware)
PHP_SF\Templates\ templates/ Built-in template files
PHP_SF\Tests\ tests/ Framework test suite

License

ISC — see LICENSE.MD.