The official application skeleton for building modular web and console applications with IviPHP.
iviphp/ivi provides a minimal project structure powered by iviphp/framework. It includes application bootstrapping, configuration, service providers, console commands and writable storage directories without imposing a large application architecture.
- PHP 8.2 or later
- Composer
- Required PHP extensions for the database driver used by the application
Create a new IviPHP application:
composer create-project iviphp/ivi my-applicationEnter the project directory:
cd my-applicationCreate the local environment file:
cp .env.example .envMake the console executable:
chmod +x bin/consoleDisplay the available commands:
php bin/consoleor:
./bin/console.
├── bin/
│ └── console
├── bootstrap/
│ └── app.php
├── config/
│ ├── app.php
│ └── database.php
├── public/
│ └── index.php
├── src/
│ ├── Console/
│ │ └── Commands/
│ │ └── AboutCommand.php
│ ├── Http/
│ │ └── Controllers/
│ └── Providers/
│ └── AppServiceProvider.php
├── storage/
│ ├── cache/
│ ├── logs/
│ └── views/
├── .env.example
├── composer.json
├── LICENSE
└── README.md
The application is created in:
bootstrap/app.php
This file:
- loads Composer;
- reads the local
.envfile; - loads application configuration;
- creates the framework instance;
- registers application service providers;
- registers console commands;
- returns the configured framework.
Example:
<?php
declare(strict_types=1);
use App\Console\Commands\AboutCommand;
use App\Providers\AppServiceProvider;
use Ivi\Config\Config;
use Ivi\Framework\Framework;
$basePath = dirname(__DIR__);
require_once $basePath
. '/vendor/autoload.php';
$config = Config::load(
$basePath . '/config'
);
$framework = Framework::create(
basePath: $basePath,
config: $config,
environment: (string) $config->get(
'app.environment',
'production'
),
consoleName: (string) $config->get(
'app.name',
'Ivi Application'
),
consoleVersion: (string) $config->get(
'app.version',
'0.1.0'
)
);
$framework->provider(
AppServiceProvider::class
);
$framework->registerCommand(
new AboutCommand()
);
return $framework;The bootstrap file may be reused by console and web entry points.
Create .env from the example file:
cp .env.example .envDefault values:
APP_NAME="Ivi Application"
APP_ENV=development
APP_DEBUG=true
APP_URL=http://localhost:8000
DB_DRIVER=sqlite
DB_DATABASE=storage/database.sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=ivi
DB_USERNAME=root
DB_PASSWORD=
CACHE_DRIVER=file
CACHE_PATH=storage/cache
LOG_CHANNEL=file
LOG_LEVEL=debug
LOG_PATH=storage/logs/app.logThe .env file is ignored by Git and should contain machine-specific or private configuration.
Do not commit production credentials.
Application configuration is stored in:
config/app.php
Available settings include:
return [
'name' => 'Ivi Application',
'version' => '0.1.0',
'environment' => 'production',
'debug' => false,
'url' => 'http://localhost:8000',
'timezone' => 'UTC',
'locale' => 'en',
];Retrieve configuration through the framework:
$name = $framework
->config()
->get(
'app.name',
'Ivi Application'
);Check the current environment:
if ($framework->isEnvironment('production')) {
// Production behavior.
}Check several environments:
if (
$framework->isEnvironment(
'development',
'testing'
)
) {
// Development or testing behavior.
}Database configuration is stored in:
config/database.php
The default driver is SQLite:
DB_DRIVER=sqlite
DB_DATABASE=storage/database.sqliteCreate the SQLite database file:
touch storage/database.sqliteDB_DRIVER=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=ivi
DB_USERNAME=root
DB_PASSWORD=DB_DRIVER=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_NAME=ivi
DB_USERNAME=postgres
DB_PASSWORD=The selected database package or provider is responsible for consuming this configuration and establishing connections.
Application services are registered through service providers.
The default provider is:
src/Providers/AppServiceProvider.php
It registers application metadata and common paths in the service container.
Available services include:
app.name
app.version
app.environment
app.debug
app.url
path.base
path.bootstrap
path.config
path.public
path.storage
path.cache
path.logs
path.views
Resolve a service:
$name = $framework->make('app.name');
$storagePath = $framework->make(
'path.storage'
);Check whether a service exists:
if ($framework->has('path.logs')) {
$logs = $framework->make(
'path.logs'
);
}Create a provider in:
src/Providers
Example:
<?php
declare(strict_types=1);
namespace App\Providers;
use App\Services\Mailer;
use Ivi\Framework\Contracts\ApplicationInterface;
use Ivi\Framework\Providers\ServiceProvider;
final class MailServiceProvider extends ServiceProvider
{
public function __construct(
ApplicationInterface $application
) {
parent::__construct(
$application,
[
Mailer::class,
'mailer',
]
);
}
protected function registerServices(): void
{
$mailer = new Mailer();
$this->container()->instance(
Mailer::class,
$mailer
);
$this->container()->instance(
'mailer',
$mailer
);
}
protected function bootServices(): void
{
$mailer = $this->make(
Mailer::class
);
$mailer->initialize();
}
}Register it in bootstrap/app.php:
use App\Providers\MailServiceProvider;
$framework->provider(
MailServiceProvider::class
);Register several providers:
$framework->providers([
App\Providers\DatabaseServiceProvider::class,
App\Providers\MailServiceProvider::class,
]);Service providers have two lifecycle stages.
protected function registerServices(): void
{
// Register container services.
}Registration happens when the provider is added to the framework.
Use this stage for:
- service instances;
- factories;
- aliases;
- configuration defaults;
- dependency bindings.
protected function bootServices(): void
{
// Complete application initialization.
}Booting happens after application bootstrap completes.
Use this stage for:
- resolving services;
- initializing components;
- registering listeners;
- preparing directories;
- connecting framework modules.
Console commands are stored in:
src/Console/Commands
The default application contains:
AboutCommand
Run it with:
php bin/console aboutor through its alias:
php bin/console infoExample output:
IviPHP
A modular PHP framework for web and console applications.
Application:
Name: Ivi Application
Version: 0.1.0
Environment: development
Runtime:
PHP: 8.2.x
SAPI: cli
Operating system: Linux
Create a command class:
<?php
declare(strict_types=1);
namespace App\Console\Commands;
use Ivi\Console\Contracts\CommandInterface;
use Ivi\Console\Contracts\InputInterface;
use Ivi\Console\Contracts\OutputInterface;
final class HelloCommand implements CommandInterface
{
public function name(): string
{
return 'hello';
}
public function description(): string
{
return 'Display a greeting.';
}
public function aliases(): array
{
return [];
}
public function usage(): string
{
return 'hello [name]';
}
public function isHidden(): bool
{
return false;
}
public function execute(
InputInterface $input,
OutputInterface $output
): int {
$name = $input->argument(
0,
'Developer'
);
$output->success(
"Hello, {$name}."
);
return 0;
}
}Register it in bootstrap/app.php:
use App\Console\Commands\HelloCommand;
$framework->registerCommand(
new HelloCommand()
);Run it:
php bin/console hello GaspardCommands may also be registered directly:
use Ivi\Console\Contracts\InputInterface;
use Ivi\Console\Contracts\OutputInterface;
$framework->command(
name: 'app:environment',
handler: static function (
InputInterface $input,
OutputInterface $output
) use ($framework): int {
$output->info(
'Environment: '
. $framework->environment()
);
return 0;
},
description: 'Display the application environment.',
aliases: [
'env',
]
);Run it:
php bin/console app:environmentor:
php bin/console envDisplay all commands:
php bin/consoleor:
php bin/console listDisplay help for one command:
php bin/console help aboutCommand help is also available with:
php bin/console about --helpDisplay the application version:
php bin/console --versionThe executable console file is:
bin/console
It:
- loads the application bootstrap;
- validates the returned framework instance;
- starts the framework;
- executes the requested command;
- returns the command exit code;
- displays startup failures safely.
Run it through PHP:
php bin/consoleMake it directly executable:
chmod +x bin/consoleThen run:
./bin/consoleEnable debug mode in .env:
APP_DEBUG=trueWhen console startup fails, debug mode displays:
- exception class;
- source file;
- source line;
- stack trace.
Disable it in production:
APP_DEBUG=falseWritable application files are stored in:
storage/
The default directories are:
storage/cache
storage/logs
storage/views
They are automatically created by Composer and by the default application service provider.
Create them manually when necessary:
mkdir -p \
storage/cache \
storage/logs \
storage/viewsThe contents of these directories are ignored by Git.
The framework safely resolves paths relative to the project root.
$configPath = $framework->path(
'config/app.php'
);
$storagePath = $framework->path(
'storage'
);
$logsPath = $framework->path(
'storage/logs'
);Absolute paths and parent-directory traversal are rejected.
Retrieve the application:
$application = $framework->application();Retrieve the service container:
$container = $framework->container();Retrieve configuration:
$config = $framework->config();Retrieve the console:
$console = $framework->console();Retrieve the framework manager:
$manager = $framework->manager();Start the application manually:
$framework->start();This performs:
Bootstrap application
Boot service providers
The lifecycle is idempotent. Completed stages are not executed again.
Bootstrap without booting providers:
$framework->bootstrap();Boot registered providers:
$framework->boot();Check the lifecycle state:
if ($framework->isBootstrapped()) {
// Bootstrap operations completed.
}
if ($framework->isBooted()) {
// Providers completed booting.
}
if ($framework->isStarted()) {
// Application is fully started.
}Register application initialization logic:
use Ivi\Framework\Contracts\ApplicationInterface;
$framework->bootstrapWith(
'prepare.uploads',
static function (
ApplicationInterface $application
): void {
$path = $application->path(
'storage/uploads'
);
if (!is_dir($path)) {
mkdir(
$path,
0775,
true
);
}
}
);Bootstrap operations execute in registration order.
Once the public HTTP entry point is configured, start PHP's built-in development server:
php -S 127.0.0.1:8000 -t publicOpen:
http://127.0.0.1:8000
The built-in PHP server is intended for local development only.
Install dependencies:
composer installUpdate dependencies:
composer updateRefresh autoload files:
composer dump-autoloadValidate the project configuration:
composer validate --strictBefore deploying:
composer install \
--no-dev \
--optimize-autoloaderUse production environment settings:
APP_ENV=production
APP_DEBUG=falseEnsure the storage directories are writable by the application process:
chmod -R 775 storageDeployment permissions should be adapted to the server and user configuration.
Application code belongs under:
src/
Recommended namespaces:
App\Console\Commands
App\Http\Controllers
App\Providers
App\Services
App\Repositories
App\Models
Composer maps the App namespace to src:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}After adding or moving classes, regenerate Composer autoload files:
composer dump-autoloadThe Ivi application skeleton follows these principles:
- minimal initial structure;
- modular framework packages;
- explicit application bootstrapping;
- service-provider based composition;
- dependency-container integration;
- console-first developer tooling;
- environment-based configuration;
- replaceable application services;
- predictable application lifecycle;
- no unnecessary application abstractions.
Ivi is open-source software released under the MIT License.
Maintained by Gaspard Kirira and Softadastra.