criq / katu
katu
Installs: 100
Dependents: 11
Suggesters: 0
Security: 0
Stars: 2
Watchers: 2
Forks: 0
Open Issues: 0
pkg:composer/criq/katu
Requires
- php: >=7
- aws/aws-sdk-php: ^3.0
- endroid/qr-code: 4.6.1
- flynsarmy/slim-monolog: @stable
- google/apiclient: @stable
- google/cloud: @stable
- gregwar/cache: @stable
- guzzlehttp/guzzle: @stable
- illuminate/support: @stable
- intervention/image: ^2
- ircmaxell/random-lib: @stable
- jbroadway/urlify: @stable
- jenssegers/agent: @stable
- jwage/easy-csv: @stable
- lcobucci/jwt: @stable
- league/color-extractor: @stable
- league/csv: @stable
- mandrill/mandrill: @stable
- michelf/php-markdown: @stable
- mischiefcollective/colorjizz: @stable
- monolog/monolog: @stable
- mtdowling/cron-expression: @stable
- mustangostang/spyc: 0.6.2
- oscarotero/psr7-middlewares: @stable
- php-curl-class/php-curl-class: @stable
- php-di/php-di: ^6
- php-di/slim-bridge: @stable
- phpseclib/bcmath_compat: @stable
- predis/predis: @stable
- ralouphie/mimey: @stable
- sendgrid/sendgrid: @stable
- slim/extras: @stable
- slim/slim: ^4
- squizlabs/php_codesniffer: @stable
- symfony/cache: @stable
- symfony/console: ^5.4
- symfony/css-selector: @stable
- symfony/dom-crawler: @stable
- symfony/intl: @stable
- symfony/string: @stable
- twig/extensions: @stable
- twig/twig: @stable
- vlucas/phpdotenv: @stable
- 4.20251008.3
- 4.20251008.2
- 4.20251008.1
- 4.20251007.2
- 4.20251007.1
- 4.20251002.1
- 4.20250924.1
- 4.20250922.3
- 4.20250922.2
- 4.20250922.1
- 4.20250921.2
- 4.20250921.1
- 4.20250918.2
- 4.20250918.1
- 4.20250913.1
- 4.20250911.1
- 4.20250902.1
- 4.20250829.2
- 4.20250829.1
- 4.20250828.1
- 4.20250827.1
- 4.20250826.1
- 4.20250813.1
- 4.20250811.2
- 4.20250811.1
- 4.20250806.1
- 4.20250803.2
- 4.20250803.1
- 4.20250726.1
- 4.20250719.1
- 4.20250627.2
- 4.20250627.1
- 4.20250625.1
- 4.20250622.3
- 4.20250622.2
- 4.20250622.1
- 4.20250619.1
- 4.20250615.2
- 4.20250615.1
- 4.20250526.1
- 4.20250523.1
- 4.20250509.1
- 4.20250507.2
- 4.20250507.1
- 4.20250506.3
- 4.20250506.2
- 4.20250506.1
- 4.20250504.3
- 4.20250504.2
- 4.20250504.1
- 4.20250430.1
- 4.20250428.1
- 4.20250417.1
- 4.20250416.1
- 4.20250413.1
- 4.20250411.3
- 4.20250411.2
- 4.20250411.1
- 4.20250404.2
- 4.20250404.1
- 4.20250331.1
- 4.20250328.1
- 4.20250327.1
- 4.20250326.1
- 4.20250325.1
- 4.20250324.1
- 4.20250321.1
- 4.20250318.2
- 4.20250318.1
- 4.20250314.3
- 4.20250314.2
- 4.20250314.1
- 4.20250313.1
- 4.20250312.1
- 4.20250310.1
- 4.20250305.4
- 4.20250305.3
- 4.20250305.2
- v4.20250305.1.x-dev
- 4.20250305.1
- 4.20250304.2
- 4.20250304.1
- 4.20250302.2
- 4.20250302.1
- 4.20250228.1
- 4.20250226.1
- 4.20250224.1
- 4.20250223.2
- 4.20250223.1
- 4.20250221.1
- 4.20250203.2
- 4.20250203.1
- 4.20250131.1
- 4.20250130.2
- 4.20250130.1
- 4.20250129.2
- 4.20250129.1
- 4.20250119.1
- 4.20250113.1
- 4.20250105.1
- 4.20241229.1
- 4.20241227.2
- 4.20241227.1
- 4.20241223.1
- 4.20241215.7
- 4.20241215.6
- 4.20241215.5
- 4.20241215.4
- 4.20241215.3
- 4.20241215.2
- 4.20241215.1
- 4.20241210.1
- 4.20241206.1
- 4.20241205.1
- 4.20241124.1
- 4.20241012.1
- 4.20241005.1
- 4.20240922.1
- 4.20240921.1
- 4.20240913.3
- 4.20240913.2
- 4.20240913.1
- 4.20240912.2
- 4.20240912.1
- 4.20240906.1
- 4.20240904.5
- 4.20240904.4
- 4.20240904.3
- 4.20240904.2
- 4.20240904.1
- 4.20240825.2
- 4.20240825.1
- 4.20240817.2
- 4.20240817.1
- 4.20240814.2
- 4.20240814.1
- 4.20240809.2
- 4.20240809.1
- 4.20240805.1
- 4.20240803.2
- 4.20240803.1
- 4.20240802.1
- 4.20240730.3
- 4.20240730.2
- 4.20240730.1
- 4.20240728.4
- 4.20240728.3
- 4.20240728.2
- 4.20240728.1
- 4.20240727.1
- 4.20240724.1
- 4.20240720.1
- 4.20240716.2
- 4.20240716.1
- 4.20240715.4
- 4.20240715.3
- 4.20240715.2
- 4.20240715.1
- 4.20240714.1
- 4.20240712.1
- 4.20240703.1
- 4.20240629.1
- 4.20240625.2
- 4.20240625.1
- 4.20240624.4
- 4.20240624.3
- 4.20240624.2
- 4.20240624.1
- 4.20240620.1
- 4.20240619.1
- 4.20240618.2
- 4.20240618.1
- 4.20240616.1
- 4.20240612.2
- 4.20240612.1
- 4.20240611.1
- 4.20240607.2
- 4.20240607.1
- 4.20240604.1
- 4.20240602.1
- 4.20240529.1
- 4.20240528.3
- 4.20240528.2
- 4.20240528.1
- 4.20240527.1
- 4.20240524.1
- 4.20240523.1
- 4.20240522.2
- 4.20240522.1
- 4.20240513.1
- 4.20240507.1
- 4.20240504.1
- 4.20240502.1
- 4.20240422.1
- 4.20240420.1
- 4.20240328.1
- 4.20240326.1
- 4.20240324.1
- 4.20240308.1
- 4.20240307.1
- 4.20240306.1
- 4.20240301.2
- 4.20240301.1
- 4.20240215.4
- 4.20240215.3
- 4.20240215.2
- 4.20240215.1
- 4.20240214.6
- 4.20240214.5
- 4.20240214.4
- 4.20240214.3
- 4.20240214.2
- 4.20240214.1
- 4.20240211.2
- 4.20240211.1
- 4.20240209.1
- 4.20240204.2
- 4.20240204.1
- 4.20240202.2
- 4.20240202.1
- 4.20240131.1
- 4.20240130.3
- 4.20240130.2
- 4.20240130.1
- 4.20240129.3
- 4.20240129.2
- 4.20240129.1
- 4.20240128.1
- 4.20240126.1
- 4.20240125.1
- 4.20240124.4
- 4.20240124.3
- 4.20240124.2
- 4.20240124.1
- 4.20240121.1
- 4.20240120.1
- 4.20240118.1
- 4.20240114.1
- 4.20240108.1
- 4.20240107.1
- 4.20240103.2
- 4.20240103.1
- 4.20231229.1
- 4.20231221.1
- 4.20231216.1
- 4.20231215.4
- 4.20231215.3
- 4.20231215.2
- 4.20231215.1
- 4.20231120.1
- 4.20231115.1
- 4.20231114.1
- 4.20231027.1
- 4.20231026.2
- 4.20231026.1
- 4.20231024.3
- 4.20231024.2
- 4.20231024.1
- 4.20231005.1
- 4.20230926.1
- 4.20230925.1
- 4.20230923.1
- 4.20230921.1
- 4.20230914.1
- 4.20230828.1
- 4.20230823.1
- 4.20230802.5
- 4.20230802.4
- 4.20230802.3
- 4.20230802.2
- 4.20230802.1
- 4.20230727.1
- 4.20230724.1
- 4.20230718.1
- 4.20230717.1
- 4.20230716.2
- 4.20230716.1
- 4.20230710.1
- 4.20230703.1
- 4.20230629.5
- 4.20230629.4
- 4.20230629.3
- 4.20230629.2
- 4.20230629.1
- 4.20230622.1
- 4.20230621.1
- 4.20230620.1
- 4.20230618.1
- 4.20230616.1
- 4.20230611.1
- 4.20230609.2
- 4.20230609.1
- 4.20230608.2
- 4.20230608.1
- 4.20230604.1
- 4.20230534.1
- 4.20230531.1
- 4.20230526.4
- 4.20230526.3
- 4.20230526.2
- 4.20230526.1
- 4.20230524.3
- 4.20230524.2
- 4.20230523.2
- 4.20230523.1
- 4.20230520.1
- 4.20230519.4
- 4.20230519.3
- 4.20230519.2
- 4.20230519.1
- 4.20230507.2
- 4.20230507.1
- 4.20230506.1
- 4.20230430.1
- 4.20230418.1
- 4.20230404.2
- 4.20230404.1
- 4.20230331.1
- 4.20230328.1
- 4.20230327.2
- 4.20230327.1
- 4.20230323.1
- 4.20230319.1
- 4.20230318.1
- 4.20230316.1
- 4.20230315.1
- 4.20230310.1
- 4.20230309.1
- 4.20230308.1
- 4.20230305.1
- 4.20230228.2
- 4.20230228.1
- 4.20230223.1
- 4.20230220.1
- 4.20230217.2
- 4.20230217.1
- 4.20230216.1
- 4.20230211.3
- 4.20230211.2
- 4.20230211.1
- 4.20230210.3
- 4.20230210.2
- 4.20230210.1
- 4.20230209.1
- 4.20230208.3
- 4.20230208.2
- 4.20230208.1
- 4.20230207.7
- 4.20230207.6
- 4.20230207.5
- 4.20230207.4
- 4.20230207.3
- 4.20230207.2
- 4.20230207.1
- 4.20230206.6
- 4.20230206.5
- 4.20230206.4
- 4.20230206.3
- 4.20230206.2
- 4.20230206.1
- 4.20230204.1
- 4.20230128.1
- 4.20230125.2
- 4.20230125.1
- 4.20230124.1
- 4.20230119.1
- 4.20230115.1
- 4.20230114.2
- 4.20230114.1
- 4.20230108.2
- 4.20230108.1
- 4.20230107.1
- 4.20230104.1
- 4.20221230.1
- 4.20221228.1
- 4.20221213.2
- 4.20221213.1
- 4.20221211.1
- 4.20221208.1
- 4.20221207.3
- 4.20221207.2
- 4.20221207.1
- 4.20221130.1
- 4.20221128.1
- 4.20221125.1
- 4.20221123.1
- 4.20221122.2
- 4.20221122.1
- 4.20221119.3
- 4.20221119.2
- 4.20221119.1
- 4.20221118.5
- 4.20221118.4
- 4.20221118.3
- 4.20221118.2
- 4.20221118.1
- 4.20221117.1
- 4.20221115.2
- 4.20221115.1
- 4.20221112.1
- 4.20221109.1
- 4.20221108.1
- 4.20221106.1
- 4.20221105.2
- 4.20221105.1
- 4.20221029.1
- 4.20221025.2
- 4.20221025.1
- 4.20221015.2
- 4.20221013.1
- 4.20221012.1
- 4.20220914.1
- 4.20220911.1
- 4.20220909.1
- 4.20220908.2
- 4.20220908.1
- 4.20220907.1
- 4.20220905.3
- 4.20220905.2
- 4.20220905.1
- 4.20220904.1
- 4.20220831.3
- 4.20220831.2
- 4.20220831.1
- 4.20220830.1
- 4.20220829.1
- 4.20220828.1
- 4.20220827.2
- 4.20220827.1
- 4.20220826.2
- 4.20220826.1
- 4.20220821.1
- 4.20220810.1
- 4.20220710.1
- v4.x-dev
- 4
- 3
- dev-tmp1
- dev-tmp
- dev-v4-model-refactor
This package is auto-updated.
Last update: 2025-10-08 12:51:17 UTC
README
A comprehensive PHP framework built on Slim 4, providing MVC architecture, database abstraction, routing, and extensive utility classes for modern web applications.
Table of Contents
- Overview
- Installation
- Quick Start
- Architecture
- Core Components
- Configuration
- Models & Database
- Controllers
- Views & Templates
- Routing
- Utilities
- Security
- Caching
- File Management
- Email System
- API Documentation
- Best Practices
- Examples
- Contributing
Overview
KATU is a modern PHP framework that extends Slim 4 with additional functionality for building robust web applications. It provides:
- MVC Architecture: Clean separation of concerns with Models, Controllers, and Views
- Database ORM: Active Record pattern with custom query builder integration
- Dependency Injection: PHP-DI container for service management
- PSR Compliance: PSR-4 autoloading, PSR-7 HTTP messages, PSR-3 logging
- Extensive Utilities: Calendar, validation, HTML generation, file management, and more
- Security Features: JWT handling, password encoding, encryption
- Modern PHP: Optimized for PHP 7.4+ with enhanced PSR compliance
Installation
Requirements
- PHP 7.4 or higher
- Composer
- MySQL/PostgreSQL database (optional)
Composer Installation
composer require criq/katu
Dependencies
KATU includes 30+ carefully selected packages:
- Framework: Slim 4, Twig, PHP-DI
- Database: Custom ORM with Sexy query builder
- Security: JWT, encryption, OAuth2
- Utilities: Guzzle, Monolog, Symfony components
- Cloud Services: AWS SDK, Google Cloud, SendGrid
- Image Processing: Intervention Image, QR codes
- Development: PHPUnit, CodeSniffer
Quick Start
1. Basic Application Setup
<?php // bootstrap.php require_once 'vendor/autoload.php'; use Katu\App; use Katu\Config\AppConfig; // Initialize the application $app = App::getInstance(); // Your application logic here
2. Simple Route
// In your RouterConfig public function getRoutes(): array { return [ 'home' => (new Route) ->setPattern('/') ->setMethods(['GET']) ->setCallback(function($request, $response) { return $response->withJson(['message' => 'Hello KATU!']); }) ]; }
3. Basic Model
<?php namespace App\Models; use Katu\Models\Model; class User extends Model { const DATABASE = "app"; const TABLE = "users"; public $id; public $name; public $email; public $timeCreated; public static function getIdColumn(): Column { return static::getColumn("id"); } }
Architecture
Core Components
KATU Framework
├── App (Bootstrap)
├── Config (Configuration System)
├── Models (ORM & Database)
├── Controllers (Request Handling)
├── Views (Template System)
├── Tools (Utilities)
├── Types (Type System)
├── Storage (File Storage)
└── Cache (Caching System)
MVC Pattern
- Models: Database entities with Active Record pattern
- Controllers: Request handling and business logic
- Views: Twig templates with custom extensions
- Routing: Pattern-based routing with parameter extraction
Core Components
Application Bootstrap (Katu\App
)
The main application class that bootstraps the entire framework:
// Get application instance $app = App::getInstance(); // Get dependency injection container $container = App::getContainer(); // Get configuration $config = App::getAppConfig(); // Get logger $logger = App::getLogger(new TIdentifier("my-component"));
Configuration System
All configurations extend Katu\Config\Config
:
class MyConfig extends \Katu\Config\Config { public function getDatabaseHost(): string { return "localhost"; } public function getDatabaseName(): string { return "myapp"; } }
Configuration
Environment Configuration
// .env file APP_ENV=production DB_HOST=localhost DB_NAME=myapp DB_USER=user DB_PASS=password
Database Configuration
class DatabaseConfig extends \Katu\Config\DatabaseConfig { public function getHost(): string { return $_ENV['DB_HOST'] ?? 'localhost'; } public function getName(): string { return $_ENV['DB_NAME'] ?? 'myapp'; } }
Models & Database
Active Record Pattern
class User extends Model { const DATABASE = "app"; const TABLE = "users"; public $id; public $name; public $email; public $timeCreated; // Create a new user public static function createUser(string $name, string $email): User { $user = new User(); $user->name = $name; $user->email = $email; $user->timeCreated = new Time(); return $user->persist(); } // Find users by criteria public static function findActiveUsers(): array { return static::getBy(['active' => true]); } }
Database Queries
use Sexy\Sexy as SX; // Simple query $users = User::getBy(['active' => true]); // Complex query with Sexy ORM $sql = SX::select() ->from(User::getTable()) ->where(SX::eq(User::getColumn("active"), true)) ->orderBy(SX::orderBy(User::getColumn("name"))); $users = User::getBySQL($sql);
Model Relationships
class Post extends Model { const DATABASE = "app"; const TABLE = "posts"; public $id; public $title; public $content; public $userId; public function getUser(): ?User { return User::get($this->userId); } public function getComments(): array { return Comment::getBy(['postId' => $this->id]); } }
Controllers
Base Controller
class UserController extends \Katu\Controllers\Controller { public function getResponse(ServerRequestInterface $request): ResponseInterface { $users = User::getBy(['active' => true]); return $this->getViewResponse('users/index', [ 'users' => $users ]); } public function createUser(ServerRequestInterface $request): ResponseInterface { if ($this->isSubmitted($request)) { $name = $request->getParsedBody()['name'] ?? ''; $email = $request->getParsedBody()['email'] ?? ''; if ($name && $email) { $user = User::createUser($name, $email); return $this->getRedirectResponse('/users'); } } return $this->getViewResponse('users/create'); } }
Form Handling
public function handleForm(ServerRequestInterface $request): ResponseInterface { if ($this->isSubmittedWithToken($request)) { $data = $request->getParsedBody(); // Validate data $param = new Param('name', $data['name'] ?? ''); $param->forwardInput(); if ($param->getOutput()) { // Process form $user = new User(); $user->name = $param->getOutput(); $user->persist(); return $this->getRedirectResponse('/success'); } } return $this->getViewResponse('form'); }
Views & Templates
Twig Integration
{# users/index.twig #} {% extends "layout.twig" %} {% block content %} <h1>Users</h1> <ul> {% for user in users %} <li>{{ user.name }} - {{ user.email }}</li> {% endfor %} </ul> {% endblock %}
Custom Twig Extensions
// Custom Twig functions available in templates {{ url('user.show', {id: user.id}) }} {{ asset('css/style.css') }} {{ csrf_token() }}
Routing
Route Definition
class RouterConfig extends \Katu\Config\RouterConfig { public function getRoutes(): array { return [ 'home' => (new Route) ->setPattern('/') ->setMethods(['GET']) ->setCallback([HomeController::class, 'index']), 'user.show' => (new Route) ->setPattern('/users/{id}') ->setMethods(['GET']) ->setCallback([UserController::class, 'show']), 'api.users' => (new Route) ->setPattern('/api/users') ->setMethods(['GET', 'POST']) ->setCallback([UserApiController::class, 'handle']) ]; } }
URL Generation
// Generate URLs $url = URL::getRoute('user.show', ['id' => 123]); // Result: /users/123 $url = URL::getRoute('home'); // Result: /
Utilities
Calendar System
use Katu\Tools\Calendar\Time; use Katu\Tools\Calendar\Day; use Katu\Tools\Calendar\Interval; // Time manipulation $time = new Time(); $tomorrow = $time->add(new Interval('P1D')); $lastWeek = $time->subtract(new Interval('P1W')); // Date periods $day = new Day($time); $week = new Week($time); $month = new Month($time);
Validation System
use Katu\Tools\Validation\Param; use Katu\Tools\Validation\Rules\IsNotEmpty; use Katu\Tools\Validation\Rules\IsEmail; $param = new Param('email', $request->getParsedBody()['email'] ?? ''); $param->addRule(new IsNotEmpty()) ->addRule(new IsEmail()) ->forwardInput(); if ($param->getOutput()) { // Valid email $email = $param->getOutput(); }
HTML Generation
use Katu\Tools\HTML\HTML; use Katu\Tools\HTML\A; use Katu\Tools\HTML\Div; // Create HTML elements $link = new A('Click here', '/some-url'); $div = new Div('Content', ['class' => 'container']); // Combine elements $html = new HTML($div->getHTML() . $link->getHTML());
Type System
use Katu\Types\TString; use Katu\Types\TURL; use Katu\Types\TEmailAddress; // Enhanced string handling $string = new TString('Hello World'); $urlString = $string->getForURL(); // "hello-world" // URL handling $url = new TURL('https://example.com'); $domain = $url->getDomain(); // "example.com" // Email handling $email = new TEmailAddress('user@example.com'); $isValid = $email->isValid(); // true
Security
Password Handling
use Katu\Tools\Security\PlainPassword; $password = new PlainPassword('user-password'); $hashed = $password->getHashed(); // Secure hash $isValid = $password->verify($hashed, 'user-password'); // true
JWT Tokens
use Katu\Tools\Security\JWT; $jwt = new JWT(); $token = $jwt->create(['user_id' => 123]); $payload = $jwt->verify($token);
Encryption
use Katu\Types\Encryption\TEncryptedString; $encrypted = new TEncryptedString('sensitive-data'); $encryptedString = $encrypted->getEncrypted(); $decrypted = $encrypted->getDecrypted();
Caching
Runtime Caching
use Katu\Cache\Runtime; $cache = new Runtime(); $cache->set('key', 'value', 3600); // 1 hour $value = $cache->get('key');
General Caching
use Katu\Cache\General; $cache = new General(); $cache->set('user:123', $userData); $userData = $cache->get('user:123');
File Management
File Operations
use Katu\Files\File; $file = new File('/path/to/file.txt'); $content = $file->get(); $file->set('new content'); if ($file->exists()) { $size = $file->getSize(); $mimeType = $file->getMimeType(); }
File Uploads
use Katu\Files\Upload; $upload = new Upload($_FILES['file']); if ($upload->isValid()) { $file = $upload->moveTo('/uploads/'); $url = $file->getURL(); }
File Collections
use Katu\Files\FileCollection; $files = new FileCollection(); $files->add($file1); $files->add($file2); foreach ($files as $file) { echo $file->getPath(); }
Email System
Email Composition
use Katu\Tools\Emails\Email; $email = new Email(); $email->setTo('user@example.com') ->setSubject('Welcome!') ->setBody('Welcome to our application!') ->send();
Email Providers
use Katu\Tools\Emails\Provider\SendGrid; $provider = new SendGrid(); $email->setProvider($provider); $email->send();
API Documentation
REST API Responses
use Katu\Tools\Rest\RestResponse; $data = ['users' => $users]; $response = new RestResponse($data); return $response->getStream();
JSON API
public function apiUsers(ServerRequestInterface $request): ResponseInterface { $users = User::getBy(['active' => true]); return (new RestResponse([ 'data' => $users, 'meta' => [ 'count' => count($users), 'timestamp' => (new Time())->getDbDateTimeFormat() ] ]))->getStream(); }
Best Practices
Model Development
class User extends Model { const DATABASE = "app"; const TABLE = "users"; public $id; public $name; public $email; public $timeCreated; // Always implement getIdColumn for custom primary keys public static function getIdColumn(): Column { return static::getColumn("id"); } // Use callbacks for business logic public function beforePersist(): void { if (!$this->timeCreated) { $this->timeCreated = new Time(); } } }
Controller Development
class UserController extends \Katu\Controllers\Controller { public function getResponse(ServerRequestInterface $request): ResponseInterface { try { $users = User::getBy(['active' => true]); return $this->getViewResponse('users/index', [ 'users' => $users ]); } catch (\Exception $e) { $this->addError(new Error('Failed to load users')); return $this->getViewResponse('error'); } } }
Error Handling
use Katu\Errors\Error; use Katu\Errors\ErrorCollection; $errors = new ErrorCollection(); $errors->add(new Error('Invalid email format')); if ($errors->count() > 0) { // Handle errors foreach ($errors as $error) { echo $error->getMessage(); } }
Examples
Complete User Management
// Model class User extends Model { const DATABASE = "app"; const TABLE = "users"; public $id; public $name; public $email; public $active; public $timeCreated; public static function createUser(string $name, string $email): User { $user = new User(); $user->name = $name; $user->email = $email; $user->active = true; $user->timeCreated = new Time(); return $user->persist(); } } // Controller class UserController extends \Katu\Controllers\Controller { public function index(ServerRequestInterface $request): ResponseInterface { $users = User::getBy(['active' => true]); return $this->getViewResponse('users/index', ['users' => $users]); } public function create(ServerRequestInterface $request): ResponseInterface { if ($this->isSubmitted($request)) { $data = $request->getParsedBody(); $name = $data['name'] ?? ''; $email = $data['email'] ?? ''; if ($name && $email) { User::createUser($name, $email); return $this->getRedirectResponse('/users'); } } return $this->getViewResponse('users/create'); } } // Route 'users.index' => (new Route) ->setPattern('/users') ->setMethods(['GET']) ->setCallback([UserController::class, 'index']), 'users.create' => (new Route) ->setPattern('/users/create') ->setMethods(['GET', 'POST']) ->setCallback([UserController::class, 'create'])
API Endpoint
class UserApiController extends \Katu\Controllers\Controller { public function getUsers(ServerRequestInterface $request): ResponseInterface { $users = User::getBy(['active' => true]); return (new RestResponse([ 'data' => $users, 'meta' => [ 'count' => count($users), 'timestamp' => (new Time())->getDbDateTimeFormat() ] ]))->getStream(); } }
Contributing
Development Setup
- Clone the repository
- Install dependencies:
composer install
- Run tests:
composer test
- Check code style:
composer cs-check
Code Standards
- Follow PSR-12 coding standards
- Write comprehensive tests
- Document all public methods
- Use type hints where possible
Testing
# Run all tests composer test # Run specific test suite vendor/bin/phpunit tests/Models/ # Generate coverage report vendor/bin/phpunit --coverage-html coverage/
License
This project is licensed under the MIT License. See the LICENSE file for details.
Support
For support and questions:
- Create an issue on GitHub
- Check the documentation
- Review the examples
KATU Framework - Building modern PHP applications with ease.