FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

MADEVAL/ATOM: PHP 8.5 micro‑framework. Single PCRE router, template engine, DI, validation, sessions, database, CLI · GitHub

/ ATOM Public

Repository files navigation

Atom

PHP 8.5 micro‑framework. Single PCRE router, template engine, DI, validation, sessions, database, CLI.


Why Atom

Zero dependencies. Just PHP 8.5. No HTTP factory, no annotations - pure PHP with PCRE at its core.

Minimal codebase. Read the entire framework in 20 minutes. Current suite: 728 tests, 1108 assertions, 85.29% line coverage, clean PHPStan level 5.

One regex dispatches all routes. 10 000 routes = one preg_match via (?|...(*:N)) branch-reset + MARK. JIT-compiled, O(1) per request.

Batteries included. Validation on 18 attribute rules, Twig-like templates, sessions with CSRF rotation, CORS, file uploads, database, logger with rotation, CLI with help - things you'd otherwise compose from 5 packages.

Built for APIs and full-stack. JSON body parsing, Bearer token extraction, method spoofing, cache headers - everything you need for a REST API. Templates with inheritance, blocks, filters - everything you need for server-rendered pages.

Use it for: REST APIs, microservices, admin panels, static-site backends, MVPs, prototyping, educational projects, anything where you want full control without a framework fighting you.


Scope of Application

Scenario Fit Notes
REST API Excellent JSON body auto-parse, Bearer token, method spoofing, CORS, status codes
Microservice Excellent Zero deps, single-file deploy, 850 lines of code
Admin panel Good Templates with inheritance, CSRF, sessions, validation
Static-site backend Good Template engine, routing, config from .env
MVP / Prototype Excellent Full stack in one file, rapid iteration
Hobby project Excellent Easy to learn, zero config needed
High-traffic API Good O(1) routing, JIT-compiled PCRE, route cache
Real-time / WebSocket Good Built-in WebSocket server, rooms, broadcast
Enterprise CMS Not suitable No migrations, no admin generator
E-commerce Possible Would need custom cart/payment logic, DB only
SPA backend Good JSON API + CORS + JWT via Bearer token
Server-rendered pages Good Template inheritance, blocks, filters, auto-escape

Install

composer require globus-studio/atom

Quick start

use Atom\{Application, Config};

$app = new Application(Config::fromEnv(__DIR__ . '/.env'));

$app->router->get('/', 'HomeController@index');
$app->router->group('/api', ['Auth'], fn($r) => {
    $r->get('/users/{id}', 'UserController@show', 'user.show');
    $r->post('/users', 'UserController@create');
});

$app->run();

Features

Component Description
Router Single preg_match dispatch via (?|...(*:N)). Groups, URL gen, attributes, signature-aware cache.
Templates Twig-like → compiled PHP classes. Extends, blocks, filters, raw blocks.
Validation 18 attribute rules: #[Required] #[Email] #[Regex] #[Min] #[Max] #[Integer] #[Between] #[In] #[Url] #[Nullable] #[Confirmed] #[Ip] #[Domain] #[Mac] #[FloatVal] #[Boolean] #[Uuid] #[Each]
Database Minimal PDO wrapper: all(), one(), single(), run(), prepared statements.
Middleware Closure
Session get/set/flash/regenerate, CSRF token generation & rotation.
CLI `bin/atom list/help/routes/cache/ws:serve`, custom commands with descriptions, `NO_COLOR` support.
Request Property hooks, JSON body, Bearer token, _method spoofing, file uploads.
Response html/json/text/redirect/noContent, cookies, cache headers, header injection shield.
Container DI: bind, singleton, instance, has, recursive autowire.
Config `fromEnv('.env')` with `APP_ENV` profiles (`.env.production`), `APP_DEBUG`, `APP_CACHE_DIR`, `APP_VIEWS_DIR`, `APP_TIMEZONE`, `APP_LOG_LEVEL`, `APP_LOG_MAX_SIZE`, `APP_NAME`, `APP_ROUTE_CACHE`, `APP_VIEW_CACHE`, `APP_CACHE_DRIVER`, `WS_HOST`, `WS_PORT`.
Logger File-based, 7 levels, min-level filter, context, atomic writes, rotation, clear.
HTTP Test Client HttpClient — fluent API: $client->get('/users')->assertOk()->assertJson(['id' => 1]).
Rate Limiter #[RateLimit(max: 60, window: 60)] middleware — per-IP request limiting.
Health Check $router->health('/health', fn() => ['db' => true]) — Kubernetes-ready.
Paginator Paginator::from($req)->paginate($items, $total) — page/perPage/total/pages.
Encryption `Encrypt::encrypt()` / `Encrypt::decrypt()` — AES-256-GCM with key derivation.
Cache `$app->cache()`, PSR-16-like: `set/get/has/delete/flush`, TTL, `remember`, atomic counters, ArrayDriver, FileDriver.
ORM Model, guarded Query builder, Relations (`hasMany`, `belongsTo`, `hasOne`), eager loading, Pagination.
WebSocket `$app->ws()`, room management, broadcast, RFC 6455 handshake/frame validation, CLI `ws:serve`.

Example

// .env
APP_DEBUG=true
DB_DSN=sqlite:/var/app/db.sqlite
APP_TIMEZONE=Europe/Moscow
// public/index.php
use Atom\{Application, Config};
use Atom\Database\Database;
use Atom\Http\Response;
use Atom\Support\Logger;
use Atom\Validation\{Required, Email};

$config = Config::fromEnv(__DIR__ . '/../.env');
$app = new Application($config);

$app->container->singleton(Database::class,
    fn() => new Database($config->get('DB_DSN')));
$app->container->singleton(Logger::class,
    fn() => new Logger($config->get('APP_LOG_FILE'), $config->logLevel));

final class CreateUser {
    #[Required] public string $name = '';
    #[Required] #[Email] public string $email = '';
}

$app->router->post('/users', 'UserController@create');
$app->router->get('/users/{id}', 'UserController@show', 'user.show');

class UserController {
    public function __construct(private Database $db, private Logger $log) {}

    public function create(Request $req): Response {
        try {
            $dto = $req->validate(CreateUser::class);
        } catch (ValidationException $e) {
            return Response::json($e->errors, StatusCode::BAD_REQUEST);
        }
        $this->db->run('INSERT INTO users (name,email) VALUES (?,?)', [$dto->name, $dto->email]);
        $this->log->info('user created', ['name' => $dto->name]);
        return Response::json(['id' => $this->db->lastId()], StatusCode::CREATED);
    }

    public function show(string $id): Response {
        $user = $this->db->one('SELECT * FROM users WHERE id = ?', [$id]);
        return $user ? Response::json($user) : Response::json(['error' => 'Not found'], StatusCode::NOT_FOUND);
    }
}

$app->run();

Project structure

src/Atom/
├── Config.php              # debug, cacheDir, viewsDir, timezone, logFile, logLevel, logMaxSize, appName, fromEnv(), get()
├── Constants.php           # framework constants
├── Application.php         # entry point, boot, run
├── Console/Console.php     # CLI: list, help, routes, cache, custom commands, NO_COLOR
├── Cache/
│   ├── Cache.php             # PSR-16-like: set, get, has, delete, flush, remember
│   ├── Driver.php            # driver interface
│   ├── ArrayDriver.php       # in-memory TTL driver
│   └── FileDriver.php        # file-based TTL driver
├── Container/Container.php # DI: bind, singleton, instance, has, autowire
├── Database/Database.php   # PDO wrapper: all, one, single, run
├── Orm/
│   ├── Model.php              # base model class
│   ├── Query.php              # query builder
│   ├── Relation.php           # base relation
│   ├── HasMany.php            # hasMany relation
│   ├── BelongsTo.php          # belongsTo relation
│   ├── HasOne.php             # hasOne relation
│   ├── Column.php             # column attribute
│   ├── PrimaryKey.php         # primary key attribute
│   └── Table.php              # table name attribute
├── Http/
│   ├── Request.php         # hooks, JSON body, Bearer, _method, file(), validate()
│   ├── Response.php        # html, json, text, redirect, cookies, cache, send()
│   ├── Session.php         # get/set, flash, regenerate, csrfToken, validateCsrf
│   ├── StatusCode.php      # enum 200..503
│   └── UploadedFile.php    # typed $_FILES: ok, size, ext, root-bound move()
├── Middleware/
│   ├── MiddlewareInterface.php
│   ├── Cors.php            # preflight + CORS headers, origin reflection
│   ├── Csrf.php            # CSRF token validation with rotation
│   ├── Pipeline.php        # onion: Closure | object | string
│   └── RateLimit.php       # per-IP request rate limiting
├── Routing/
│   ├── Route.php           # #[Route] attribute
│   ├── CompiledRoute.php   # internal representation
│   ├── RouteCompiler.php   # single PCRE regex
│   └── Router.php          # dispatch, groups, url(), cache, routes(), health()
├── WebSocket/
│   ├── Server.php             # RFC 6455 event loop, rooms, broadcast
│   └── Connection.php         # connection wrapper, send, sendJson, ping, close
├── Support/
│   ├── Logger.php          # file logger: 7 levels, rotate, clear, maxSize
│   ├── Regex.php           # PCRE wrapper
│   ├── Paginator.php       # page/perPage/total/pages from request
│   └── Encrypt.php         # AES-256-GCM encryption
├── Test/
│   └── HttpClient.php      # fluent API test client
├── Validation/
│   └── Validator.php       # 18 attribute rules + ValidationException
└── View/
    ├── Compiler.php         # Twig-like → PHP, nested braces, for-loop shadow restore
    ├── Engine.php           # render, filters, globals
    └── Template.php         # base template class

Running tests

composer test
composer test-coverage
composer stan

Docs & resources

  • Full documentation — sidebar, all components, code examples
  • Skill set — AI‑assistant knowledge: routing, HTTP, templates, validation, ORM, DI, CLI, middleware
  • License — GPL-3.0-or-later

License

GPL-3.0-or-later. See LICENSE.

About

PHP 8.5 micro‑framework. Single PCRE router, template engine, DI, validation, sessions, database, CLI

Topics

Resources

Contributing

Stars

26 stars

Watchers

17 watching

Forks

Releases

Packages

Contributors

Languages


Back | FazBrowse Home | New Git URL