wiznetic / corenetic-base
Corenetic Framework — bare core skeleton. A modular PHP framework with attribute-based routing, middleware pipeline and event-driven kernel.
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Type:project
pkg:composer/wiznetic/corenetic-base
Requires
- php: ^8.2
- symfony/var-dumper: ^7.0
- wiznetic/kernel: ^1.0
README
A modular PHP framework with attribute-based routing, middleware pipeline, and an event-driven kernel. Install only what you need — nothing more.
Installation
composer create-project corenetic/base my-project
cd my-project
php -S localhost:8000 -t public
Directory Structure
app/
├── System/ → framework core (module loader, helpers)
└── Base/ → your application code
app_modules/ → installed modules (Router, Blade, Cache, etc.)
public/
└── index.php → HTTP entry point
console → CLI entry point
.env → environment variables
app/Base/ — Your Application
All your application code lives here, organized by convention:
app/Base/
└── app/
├── Http/
│ ├── Controllers/ → HTTP controllers
│ └── Middleware/ → HTTP middleware
├── Console/
│ └── Commands/ → CLI commands
├── Events/ → event classes
├── Listeners/ → event listeners
├── Jobs/ → queue jobs
├── Notifications/ → notification classes
├── Models/ → Eloquent models
├── Services/ → business logic
├── Config/ → configuration files
└── Migrations/ → database migrations
The Kernel
The kernel (wiznetic/kernel) is the heart of the framework.
It runs a three-phase pipeline on every HTTP request:
request → process → response
Each phase has three hooks: before, on, after.
Modules attach their logic to these hooks during register().
// Example: a module that runs on every request Kernel::on('request', function ($ctx) { // $ctx->request — the incoming request // $ctx->response — set this to send a response // $ctx->data — shared data between hooks });
HTTP entry (public/index.php):
Kernel::handle(); // fires the full pipeline
CLI entry (console):
// bootstrap.php runs Modules::register() — all module register() methods are called // Kernel::handle() is NOT called — CLI modules boot themselves in their commands Application::create()->run();
Module System
What is a Module?
A module is a self-contained directory in app_modules/ that encapsulates a single responsibility.
The framework auto-discovers and registers every module at startup — no manual wiring needed.
app_modules/
└── Cache/
├── module.json → module metadata
├── required/ → dependencies and configuration
│ ├── modules → required module names (one per line)
│ ├── env → environment variables with example values
│ ├── commands → install commands (composer require, etc.)
│ └── conflict → conflicting module names
└── app/
├── Bootstrap/ → registration — no logic here
├── Dependencies/ → one class per external dependency
├── Containers/ → assembles Dependencies, builds the module
└── Services/ → public API — the only exit point
Module Registration
At startup, System\Bootstrap\Modules loops through every directory in app_modules/,
registers its PSR-4 namespace, and calls ModuleName\Bootstrap\ModuleName::register().
// app_modules/Cache/app/Bootstrap/Cache.php class Cache { public static function register(): void { Kernel::on('request', function () { $config = Config::get('cache'); Store::boot(new CacheContainer($config)); }); } }
Module Architecture
Dependencies (input) ─┐
├→ Container (assembly) → Services (logic) → Public API (output)
Models (data) ─┘
| Layer | Role |
|---|---|
Bootstrap |
Registers the module with the Kernel. No logic. |
Dependencies |
One class per external dependency (Composer package or another module). |
Containers |
Assembles Dependencies and Models. The only place that knows how the module is built. |
Services |
Business logic. Receives the Container. The only public API. |
Rule: Other modules only use Services. Never Dependencies, Models, or Containers directly.
Dependency Types
Required Dependency
The module cannot function without it.
Add to required/modules and import directly.
// required/modules
Discovery
Cache
Optional Dependency
The module works without it — the other module just enhances it.
Use class_exists() in Bootstrap instead of listing in required/modules.
// Consumer Bootstrap — checks if provider exists before hooking in if (class_exists(\Cache\Services\Store::class)) { \Cache\Services\Store::addResolver( fn(string $key, callable $cb) => Discovery::cache($key, $cb) ); }
Rule: If removing module B breaks module A → required. If removing module B only reduces performance or features of A → optional.
Creating a Module
1. Create the directory
mkdir -p app_modules/MyModule/app/{Bootstrap,Dependencies,Containers,Services}
2. Add module.json
{
"name": "MyModule",
"version": "1.0.0",
"description": "What this module does"
}
3. Create the Bootstrap
// app_modules/MyModule/app/Bootstrap/MyModule.php namespace MyModule\Bootstrap; use Wiznetic\Kernel\Kernel; use MyModule\Containers\MyContainer; use MyModule\Services\MyService; class MyModule { public static function register(): void { Kernel::on('request', function () { MyService::boot(new MyContainer()); }); } }
4. Create the Service (Public API)
// app_modules/MyModule/app/Services/MyService.php namespace MyModule\Services; class MyService { private static ?MyContainer $container = null; public static function boot(MyContainer $container): void { static::$container = $container; } public static function doSomething(): string { return static::$container->dependency->run(); } }
5. Use it anywhere
use MyModule\Services\MyService; MyService::doSomething();
Running the Application
HTTP Server
# Built-in PHP server php -S localhost:8000 -t public # Apache / Nginx — point document root to public/
CLI
php console list # list all registered commands php console <command> # run a command
Official Modules
Install any module by copying it into app_modules/ and running its required commands.
| Module | Description | Requires |
|---|---|---|
Config |
PHP config files, auto-discovered | — |
Discovery |
Attribute & class scanner (no direct Reflection) | — |
Router |
Attribute-based HTTP routing #[Get('/')] |
Discovery |
Middleware |
HTTP middleware pipeline | Discovery |
Blade |
Blade template engine | — |
Cache |
Multi-driver cache (file, Redis, APCu) | — |
Session |
Session management | — |
Auth |
Authentication & authorization | Session, Cache |
Eloquent |
Eloquent ORM + migrations | — |
Storage |
File storage | — |
Validator |
Input validation | — |
RateLimiter |
Rate limiting by IP or user | Cache |
Events |
Synchronous event dispatcher | — |
Notifications |
Multi-channel notification dispatcher | — |
Queue |
Async job queue (file driver built-in) | — |
QueueEloquent |
Database driver for Queue | Queue, Eloquent |
Mail |
Email via Symfony Mailer, async via Queue | Queue, Notifications |
MailBlade |
Blade templates for Mail | Mail, Blade |
Scheduler |
Cron task scheduler | — |
HttpClient |
Fluent HTTP client (Guzzle) | — |
Pagination |
Pagination data container | — |
Lang |
Key-based multi-language translations | Eloquent |
Naming Conventions
| Pattern | Example | Meaning |
|---|---|---|
Queue{Driver} |
QueueEloquent, QueueRedis |
Queue driver extension |
Mail{Template} |
MailBlade, MailMarkdown |
Mail template engine extension |
Notifications{Channel} |
NotificationsTwilio, NotificationsSlack |
Notification channel |
Environment Variables
Each module declares its env variables in required/env.
Copy them to your .env file as needed.
# Minimum .env for bare core
APP_URL=http://localhost
APP_DEBUG=true
License
MIT