Part of Jardis — the Domain-Driven Design platform for PHP. You model your domain; Jardis generates the production-ready hexagonal code (DTOs, Command/Query handlers, repositories, persistence). This package is part of the open-source foundation that generated code runs on.
Jardis Foundation is the runtime heart of every Jardis DDD project and the ENV-driven entry point for hexagonal architecture in PHP. It provides the DDD building blocks — database connections, caching, logging, event dispatching, HTTP communication — assembled automatically from a single .env file.
When Jardis generates a DDD project, the resulting code extends JardisApp. Foundation takes care of assembling all infrastructure services so your domain code stays clean, portable and focused on business logic.
- Pure Hexagonal Architecture — your domain core has zero knowledge of infrastructure. Foundation wires adapters behind PSR interfaces, respecting the Dependency Inversion Principle at every layer.
- Built for generated code — Jardis generates BoundedContexts, Aggregates, Repositories and Commands that run on Foundation out of the box. No manual wiring, no bootstrap ceremony.
- Jardis Ecosystem in one place — Foundation brings together 8+ specialized Jardis packages (Kernel, Cache, DbConnection, Logger, EventDispatcher, HTTP, Mailer, Filesystem) through a unified ENV configuration. Install what you need, ignore what you don't.
- Convention over Configuration — a single
.envfile replaces hundreds of lines of container configuration. Every service auto-assembles from environment variables. - PSR-compliant throughout — PSR-3 (Logger), PSR-14 (Event Dispatcher), PSR-16 (Cache), PSR-18 (HTTP Client). Your domain code depends on standards, never on implementations.
Jardis (development-time) Jardis Foundation
───────────────────────── ─────────────────
Generates: Provides at runtime:
BoundedContexts Database (PDO / ConnectionPool)
Aggregates + Entities Redis (shared connection)
Repositories + Pipeline Cache (multi-layer: memory, apcu, redis, db)
Commands + Queries Logger (multi-handler: file, slack, loki, ...)
Domain Events Event Dispatcher (PSR-14)
│ HTTP Client (PSR-18)
│ Mailer (SMTP)
│ Filesystem (Local + S3)
│ │
└──── extends JardisApp ─────────────┘
DomainApp (Kernel) |
JardisApp (Foundation) |
|
|---|---|---|
| Package | jardiscore/kernel |
jardiscore/foundation |
| Dependencies | Only Kernel + PSR interfaces | Kernel + optional adapters |
| Services | Override hooks manually | Hooks filled from ENV |
| Use when | Full control, own infrastructure | Jardis ecosystem, generated projects |
// Full control — wire everything yourself:
class Ecommerce extends DomainApp { }
// Jardis ecosystem — services from .env:
class Ecommerce extends JardisApp { }composer require jardiscore/foundationOptional adapters — install only what you need:
composer require jardisadapter/cache # Multi-layer caching (Memory, APCu, Redis, Database)
composer require jardisadapter/dbconnection # ConnectionPool with read/write splitting
composer require jardisadapter/logger # Log handlers (File, Slack, Teams, Loki, etc.)
composer require jardisadapter/eventdispatcher # PSR-14 Event Dispatching
composer require jardisadapter/http # PSR-18 HTTP Client with handler pipeline
composer require jardisadapter/mailer # SMTP Mailer with STARTTLS, AUTH, HTML/Text
composer require jardisadapter/filesystem # Local + S3 filesystem abstractionDB_DRIVER=mysql
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=secret
DB_DATABASE=shop
REDIS_HOST=localhost
CACHE_LAYERS=memory,redis
LOG_HANDLERS=file:INFO,console:DEBUG
LOG_CONTEXT=shop
LOG_FILE_PATH=/var/log/shop.log
HTTP_BASE_URL=https://api.payment.example.com
HTTP_BEARER_TOKEN=pk_live_...use JardisCore\Foundation\JardisApp;
class Ecommerce extends JardisApp
{
public function order(): PlaceOrder
{
return new PlaceOrder($this->kernel());
}
}$shop = new Ecommerce();
$response = $shop->order()(['customer' => 'Acme', 'total' => 99.90]);
$response->isSuccess(); // true
$response->getData(); // ['PlaceOrder' => ['orderId' => 42]]That's it. No bootstrap file. No container setup. Services assembled from .env.
DB_DRIVER=mysql # mysql|pgsql|sqlite
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=secret
DB_DATABASE=myapp
DB_CHARSET=utf8mb4
# Optional: Read Replicas (auto-builds ConnectionPool when jardisadapter/dbconnection is installed)
DB_READER1_HOST=replica1
DB_READER2_HOST=replica2
# Missing values inherit from writerREDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DATABASE=0# Available layers: memory, apcu, redis, db (order = lookup priority, left first)
CACHE_LAYERS=memory,redis,db
CACHE_NAMESPACE=myapp
CACHE_DB_TABLE=cache # only for db layer# Handlers: file, console, errorlog, syslog, browserconsole, redis, slack, teams, loki, webhook, null
# Manual (via hook override): database, email, stash, redismq, kafkamq, rabbitmq
# Levels: DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY
# Syntax: handler:LEVEL,handler:LEVEL
LOG_HANDLERS=file:ERROR,console:DEBUG
LOG_CONTEXT=myapp
LOG_FILE_PATH=/var/log/app.log
#LOG_SLACK_URL=
#LOG_TEAMS_URL=
#LOG_LOKI_URL=
#LOG_WEBHOOK_URL=No ENV configuration needed — the PSR-14 event dispatcher is a pure in-memory service. Install jardisadapter/eventdispatcher and it's available automatically.
HTTP_BASE_URL=https://api.example.com
HTTP_TIMEOUT=30
HTTP_CONNECT_TIMEOUT=10
HTTP_VERIFY_SSL=true
# Authentication (one of):
HTTP_BEARER_TOKEN=
HTTP_BASIC_USER=
HTTP_BASIC_PASSWORD=
# Retry (optional):
HTTP_MAX_RETRIES=3
HTTP_RETRY_DELAY_MS=100JardisApp fills hooks from ENV — but you can override any of them:
class Ecommerce extends JardisApp
{
// Own cache instead of ENV-based:
protected function cache(): CacheInterface|false|null
{
return new MySpecialCache();
}
// Rest (connection, redis, logger, eventDispatcher, httpClient, mailer, filesystem) still comes from ENV
}Three-state resolution (inherited from DomainApp):
| Return | Meaning |
|---|---|
| object | Use this service. Share it with other DomainApps (first-write-wins). |
| null | No local service. Use shared from another DomainApp if available. |
| false | Explicitly disabled. Don't use shared fallback. |
DomainApp (jardiscore/kernel)
|
JardisApp (jardiscore/foundation) extends DomainApp
|-- connection() -> ConnectionHandler -> PDO or ConnectionPool from ENV
|-- redis() -> RedisHandler -> shared Redis from ENV
|-- cache() -> CacheHandler -> multi-layer Cache (PSR-16)
|-- logger() -> LoggerHandler -> multi-handler Logger (PSR-3)
|-- eventDispatcher() -> EventDispatcherHandler -> Event Dispatcher (PSR-14)
|-- httpClient() -> HttpClientHandler -> HTTP Client (PSR-18)
|-- mailer() -> MailerHandler -> SMTP Mailer
|-- filesystem() -> FilesystemHandler -> Filesystem Factory
src/
├── JardisApp.php # Extends DomainApp, overrides service hooks
├── Data/
│ ├── CacheLayer.php # Enum: memory, apcu, redis, db
│ └── LogHandler.php # Enum: file, console, errorlog, syslog, ...
└── Handler/
├── ConnectionHandler.php # DB_* -> PDO or ConnectionPool
├── RedisHandler.php # REDIS_* -> shared Redis connection
├── CacheHandler.php # CACHE_LAYERS -> multi-layer Cache
├── LoggerHandler.php # LOG_HANDLERS -> multi-handler Logger
├── EventDispatcherHandler.php # -> PSR-14 Event Dispatcher
├── HttpClientHandler.php # HTTP_* -> PSR-18 HTTP Client
├── MailerHandler.php # MAIL_* -> SMTP Mailer
└── FilesystemHandler.php # -> Filesystem Factory
11 source files. Adapters are optional — Foundation checks class_exists() at runtime.
jardissupport/contract Interfaces (PSR + Jardis contracts)
│
jardiscore/kernel DDD Core (DomainApp, DomainKernel, BoundedContext, Response Pipeline)
│
jardiscore/foundation Integration Platform (JardisApp + ENV-driven Handlers)
│
┌───┼───┬───────────┬───────────────┬──────────┬──────────┬────────────┐
│ │ │ │ │ │ │
cache dbconnection logger eventdispatcher http mailer filesystem
(PSR-16) (PSR-3) (PSR-14) (PSR-18)
Foundation brings together these packages at runtime:
| Package | Role | PSR |
|---|---|---|
jardiscore/kernel |
DDD core: DomainApp, DomainKernel, BoundedContext, Response Pipeline | — |
jardissupport/contract |
Shared interfaces across all packages | — |
jardisadapter/cache |
Multi-layer caching (Memory, APCu, Redis, Database) | PSR-16 |
jardisadapter/dbconnection |
ConnectionPool with read/write splitting | — |
jardisadapter/logger |
Log handlers (File, Console, Redis, Slack, Teams, Loki, Webhook) | PSR-3 |
jardisadapter/eventdispatcher |
Event dispatching with priority and type-hierarchy matching | PSR-14 |
jardisadapter/http |
HTTP client with handler pipeline, retry, auth | PSR-18 |
jardisadapter/mailer |
SMTP mailer with STARTTLS, AUTH, HTML/Text, attachments | — |
jardisadapter/filesystem |
Local + S3 filesystem abstraction with unified API | — |
All adapters are optional. Install what your project needs — Foundation detects availability at runtime.
Full documentation, guides, and API reference:
docs.jardis.io/en/core/foundation
Licensed under the MIT License.
Jardis · Documentation · Headgent
Dieses Package liefert einen Skill für Claude Code, Cursor, Continue und Aider mit. Installation im Konsumentenprojekt:
composer require --dev jardis/dev-skillsMehr Details: https://docs.jardis.io/en/skills