Aegis Framework Library for PHP

Installs: 46

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Forks: 0

pkg:composer/aegis-framework/ikaros

0.1.0-rc.11 2019-08-01 23:14 UTC

README

Aegis Framework Library for PHP.

A lightweight PHP microframework providing routing, templating, database ORM, authentication, encryption, and more.

Requirements

  • PHP ^8.2
  • MySQL (for database features)
  • Composer

Installation

composer require aegis-framework/ikaros

Quick Start

<?php

declare(strict_types=1);

require 'vendor/autoload.php';

use Ikaros\Ikaros;
use Ikaros\Router;
use Ikaros\HTTP;
use Ikaros\Enum\ContentType;

$app = new Ikaros();
$container = $app->container();

$router = $container->get(Router::class);
$http = $container->get(HTTP::class);

$router->domain('example.com');

$router->get('/', function () {
    return '<h1>Hello, World!</h1>';
});

$router->get('/api/status', function () {
    return ['status' => 'ok'];
});

$router->listen();

Architecture

Ikaros uses a PSR-11 compliant dependency injection container. Services are registered as lazy singletons and resolved through constructor injection.

Container Usage

$app = new Ikaros();
$container = $app->container();

// Get framework services
$router = $container->get(Router::class);
$session = $container->get(Session::class);
$http = $container->get(HTTP::class);

// Register your own services
$container->set(MyService::class, function ($c) {
    return new MyService($c->get(SomeDependency::class));
});

Default Services

The following services are registered automatically:

ServiceDependencies
SessionNone
RequestNone
HTTPNone
FileSystemNone
RouterHTTP
DebugHTTP
ConfigurationFileSystem

Additional services (DB, Token, Crypt, Authenticator, etc.) must be registered manually since they require configuration values.

// Database
$container->set(DB::class, function () {
    return new DB('user', 'password', 'database');
});

// Encryption
$container->set(Crypt::class, function () {
    return new Crypt('your-encryption-key');
});

// Tokens
$container->set(Token::class, function ($c) {
    return new Token('your-branca-key', $c->get(Router::class));
});

// Authentication
$container->set(Authenticator::class, function ($c) {
    return new Authenticator(
        $c->get(Session::class),
        $c->get(Token::class),
        new Password(),
        $c->get(HTTP::class),
    );
});

Features

Routing

$router->get('/users/{id}', function (string $id) {
    return UserSchema::get($id);
});

$router->post('/users', function () use ($request) {
    $data = $request->post(['name', 'email']);
    return UserSchema::create($data->all());
});

$router->put('/users/{id}', function (string $id) use ($request) {
    $data = $request->put(['name']);
    return UserSchema::update($id, $data->all());
});

$router->delete('/users/{id}', function (string $id) {
    UserSchema::delete($id);
    return ['deleted' => true];
});

Database & ORM

use Ikaros\DB;
use Ikaros\Schema;
use Ikaros\Scheme;

$db = new DB('user', 'pass', 'mydb');
Schema::setDB($db);

// Define a schema
class UserSchema extends Schema {
    protected static string $name = 'users';

    public static function init(): void {
        parent::init();
        static::$scheme
            ->string('name', 255)->notNull('name')
            ->string('email', 255)->notNull('email')->unique('email');
    }
}

// CRUD
$user = UserSchema::create(['name' => 'John', 'email' => 'john@example.com']);
$user = UserSchema::get(1);
$users = UserSchema::all();
UserSchema::update(1, ['name' => 'Jane']);
UserSchema::delete(1);

Query Builder

use Ikaros\Query;

$query = new Query($db);
$results = $query
    ->select(['name', 'email'])
    ->from('users')
    ->where('active')
    ->equals(1)
    ->orderBy([['name', 'ASC']])
    ->limit(10)
    ->commit()
    ->results();

Templating

Templates use {{variable}} for HTML-escaped output and {{{variable}}} for raw output.

$template = new Template($fileSystem, $router, 'page.html');
$template->setData('title', 'My Page');
$template->setData('content', '<p>Hello</p>');
echo $template;

Template syntax:

  • {{variable}} - Escaped output (XSS-safe)
  • {{{variable}}} - Raw output (use with trusted content only)
  • {{if condition}}...{{/if}} - Conditionals
  • {{if condition}}...{{else}}...{{/if}} - If/else
  • {{>partial}} - Include partial template
  • {{repeat TemplateName for list}} - Repeat template

Sessions & CSRF

$session = $container->get(Session::class);
$session->start();

// CSRF protection
$token = $session->generateCsrfToken();
// Include $token in your form as a hidden field

// Verify on submission
if (!$session->verifyCsrfToken($submittedToken)) {
    $http->error(HttpStatus::FORBIDDEN);
}

Authentication

$auth = $container->get(Authenticator::class);

// Login with session
$auth->login('session', $password, $hash, $userId);

// Login with token
$token = $auth->login('token', $password, $hash, $userId);

// Check authentication
$auth->authenticate('session');
$auth->authenticate('token', $tokenString);

// Logout
$auth->logout('session');

Enums

Ikaros provides backed enums for type-safe configuration:

use Ikaros\Enum\HttpMethod;
use Ikaros\Enum\ContentType;
use Ikaros\Enum\HttpStatus;
use Ikaros\Enum\DebugLevel;

// Content type negotiation
$http->type(ContentType::JSON);
$http->type(ContentType::HTML);

// Error responses
$http->error(HttpStatus::NOT_FOUND);
$http->error(HttpStatus::FORBIDDEN);

// Debug levels
$debug->init(DebugLevel::ALL);    // Show all errors
$debug->init(DebugLevel::ERROR);  // Errors only
$debug->init(DebugLevel::NONE);   // Silent

Request Handling

$request = $container->get(Request::class);

// Read request data (returns a Collection or null)
$data = $request->post(['name', 'email']);
$data = $request->get(['page', 'limit']);
$data = $request->put(['name']);
$data = $request->patch(['status']);
$data = $request->delete(['id']);

// Allow empty values or raw HTML
$data = $request->post(['bio'], allowEmpty: true, allowHTML: true);

// Access headers
$contentType = $request->header('Content-Type');
$allHeaders = $request->headers();
$userAgent = $request->userAgent();
$ip = $request->ip();

// File uploads
$file = $request->file('avatar');

// Trust proxy headers (disabled by default)
$request->trustProxies(true);

Encryption

$crypt = new Crypt('your-encryption-key');

// Encrypt and decrypt data
$encrypted = $crypt->encrypt('sensitive data');
$decrypted = $crypt->decrypt($encrypted);

// Hashing
$hash = $crypt->hash('data', 'optional-salt');

File Uploads

// Configure allowed extensions and max size
Upload::extensions([
    'image' => ['jpg', 'jpeg', 'png', 'gif'],
    'text' => ['txt', 'pdf', 'doc'],
]);
Upload::size(10); // 10 MB

// Handle upload
$upload = new Upload($file, '/uploads', $text, $fileSystem, $image);
$upload->name = 'custom-filename';  // Sanitized automatically
$upload->path = '/var/uploads';
$location = $upload->upload();

Collection

Collection is a versatile array wrapper used throughout the framework:

$collection = new Collection(['a' => 1, 'b' => 2, 'c' => 3]);

$collection->get('a');          // 1
$collection->set('d', 4);
$collection->hasKey('b');       // true
$collection->contains(2);       // true
$collection->first();           // 1
$collection->last();            // 3
$collection->length();          // 3 (or 4 after set)
$collection->keys();            // ['a', 'b', 'c']
$collection->all();             // Full array
$collection->push(5);           // Append value
$collection->merge([4, 5, 6]);  // Merge arrays
$collection->pop();             // Remove and return last
$collection->json();            // JSON string

// Iterable
foreach ($collection as $key => $value) {
    // ...
}

Configuration

Load JSON configuration files:

$config = $container->get(Configuration::class);
$config->load('config/app.json');
$value = $config->get('database.host');

Password Hashing

$password = new Password();

$hash = $password->hash('user-password');
$valid = $password->verify('user-password', $hash);

Debugging

$debug = $container->get(Debug::class);
$debug->init(DebugLevel::ALL);
// Errors are now caught and displayed with stack traces

Service Reference

All services accept their dependencies via constructor injection:

ClassConstructor Parameters
DB$user, $pass, $database, $host, $charset
ConfigurationFileSystem
RouterHTTP
DebugHTTP
Token$key, Router
Crypt$key (string or Key)
TemplateFileSystem, Router, ?$template
QueryDB, ?$query, ?$bindings, ?$results
AuthenticatorSession, Token, Password, HTTP
Upload$file, $path, Text, FileSystem, Image
Scheme$name, $engine, $charset, $collation, DB
SchemaAbstract — call Schema::setDB($db) before use

Development

# Install dependencies
composer install

# Run tests
composer test

# Static analysis
composer analyse

# Code style fix
composer cs-fix

License

MIT