julienlinard / php-skeleton
Skeleton minimal utilisant mes libraries PHP (router, core, auth, doctrine).
Installs: 73
Dependents: 0
Suggesters: 0
Security: 0
Stars: 4
Watchers: 0
Forks: 0
Open Issues: 0
Type:project
pkg:composer/julienlinard/php-skeleton
Requires
- php: ^8.1
- julienlinard/core-php: ^1.0
- julienlinard/php-router: ^1.0
README
🇫🇷 Read in French | 🇬🇧 Read in English
💝 Support the project
If this skeleton is useful to you, consider becoming a sponsor to support the development and maintenance of this open source project.
A minimal PHP project skeleton using my PHP libraries (router, core, auth, doctrine). Perfect starting point for building modern PHP applications with clean architecture and production-ready structure.
✨ Features
- 🚀 Production-Ready - Fully configured and optimized out of the box
- 🏗️ Clean Architecture - Well-organized structure with service layer
- 🔒 Security First - Secure configuration, CSRF protection, session security
- 📦 Auto-Generated Services - EnvValidator, BootstrapService, EventListenerService
- 🌐 Multilingual Support - Validation messages in French, English, Spanish
- 🐳 Docker Ready - Complete Docker setup with Apache and MariaDB
- ⚡ Zero Configuration - Works immediately after installation
🚀 Installation
Create a new project using Composer:
composer create-project julienlinard/php-skeleton my-app
This will create a new directory my-app with the skeleton structure and launch an interactive installer.
📦 What's Included
- Core PHP Framework - MVC structure with dependency injection container
- Router - Modern routing with PHP 8 attributes
- Form Validation - Advanced validation powered by php-validator with multilingual support
- Logging - Integrated SimpleLogger with structured logging
- Error Handling - Comprehensive error handling with debug/production modes
- Session Management - Secure session handling with flash messages
- Optional: Doctrine PHP - ORM for database management
- Optional: Auth PHP - Authentication and authorization system
🎯 Interactive Installation
After running composer create-project, an interactive installer will guide you through the setup:
Step 1: Choose Environment
- Use Docker? - Choose
yfor Docker setup orNfor local development
Step 2: Docker Configuration (if Docker selected)
The installer will ask you to configure:
- Apache container name and port
- MariaDB container name and port
- Database credentials (root password, database name, user, password)
- PHP error reporting settings
Two .env files will be automatically generated:
- Root
.env- For Docker Compose configuration www/.env- For application configuration
Step 3: Optional Packages
- Install Doctrine? - Adds database ORM capabilities
- Install Auth? - Adds authentication system
Simply answer y for yes or N for no (default).
The autoloader is automatically regenerated after installation, so your application is ready to run immediately!
⚡ Quick Start
Option A: Docker Setup
If you chose Docker during installation:
cd my-app # Load aliases (optional but recommended) source aliases.sh # Start Docker containers docker compose up -d # Install dependencies in container cd www ccomposer install # Visit your application # http://localhost (or the port you configured)
Useful Docker aliases (after sourcing aliases.sh):
ccomposer- Run Composer commands in containercapache- Enter Apache container shellcmariadb- Enter MariaDB container shelldb-export- Export database backupdb-import- Import database backup
Option B: Local Setup
If you chose local development:
cd my-app # Install dependencies composer install # Start the development server php -S localhost:8000 -t public # Visit your application # http://localhost:8000
📁 Project Structure
Docker Setup Structure
my-app/
├── apache/ # Docker Apache configuration
│ ├── Dockerfile
│ └── custom-php.ini
├── db/ # Database scripts
│ ├── backup.sh
│ └── restore.sh
├── www/ # Application root (Docker)
│ ├── config/ # Configuration files
│ │ └── database.php # Secure database config
│ ├── migrations/ # Database migrations
│ ├── public/ # Public entry point
│ │ ├── index.php # Bootstrap file
│ │ └── .htaccess # Apache rewrite rules
│ ├── src/ # Application source code
│ │ ├── Controller/ # Controllers
│ │ ├── Entity/ # Doctrine entities
│ │ ├── Middleware/ # Custom middlewares
│ │ ├── Repository/ # Data repositories
│ │ └── Service/ # Business logic services
│ │ ├── BootstrapService.php # Bootstrap configuration
│ │ ├── EnvValidator.php # Environment validation
│ │ └── EventListenerService.php # Event listeners
│ ├── storage/ # Storage directory
│ │ └── logs/ # Application logs
│ ├── views/ # View templates
│ │ ├── _templates/ # Layout templates
│ │ └── home/ # Page views
│ ├── .env # Application environment variables
│ ├── .env.example # Environment template
│ ├── .gitignore # Git ignore rules
│ └── composer.json # Project dependencies
├── .env # Docker Compose environment variables
├── .env.example # Docker environment template
├── aliases.sh # Docker aliases
├── docker-compose.yml # Docker Compose config
└── composer.json # Root composer.json
Local Setup Structure
my-app/
├── config/ # Configuration files
├── migrations/ # Database migrations
├── public/ # Public entry point
├── src/ # Application source code
│ └── Service/ # Auto-generated services
├── storage/ # Storage directory
│ └── logs/ # Application logs
├── views/ # View templates
├── .env # Environment variables
├── .env.example # Environment template
└── composer.json # Project dependencies
🛠️ Auto-Generated Services
The skeleton automatically generates three essential services:
1. EnvValidator
Validates environment variables on application startup:
APP_SECRETvalidation (minimum 32 characters)APP_LOCALEvalidation (supported: fr, en, es)
2. BootstrapService
Centralizes bootstrap configuration:
- Debug mode configuration
- Error handler setup with logging
- Session security configuration
3. EventListenerService
Registers application event listeners:
- Request logging
- Response logging
- Exception logging
📚 Available Packages
This skeleton uses the following packages:
- julienlinard/php-router - Modern router with PHP 8 attributes
- julienlinard/core-php - MVC framework with DI container
- julienlinard/php-validator - Advanced validation with multilingual support
- julienlinard/doctrine-php - ORM (optional)
- julienlinard/auth-php - Authentication (optional)
🛠️ Development
Adding Controllers
Create controllers in the src/Controller/ directory. Controllers should extend the base Controller class:
<?php namespace App\Controller; use JulienLinard\Core\Controller\Controller; use JulienLinard\Router\Attributes\Route; use JulienLinard\Router\Response; class MyController extends Controller { #[Route(path: '/about', methods: ['GET'], name: 'about')] public function about(): Response { return $this->json(['page' => 'About']); } #[Route(path: '/contact', methods: ['GET'], name: 'contact')] public function contact(): Response { return $this->view('contact/index', [ 'title' => 'Contact Us' ]); } }
Register routes in public/index.php (or www/public/index.php for Docker):
$router->registerRoutes(MyController::class);
Form Validation
The skeleton includes php-validator with multilingual support:
<?php namespace App\Controller; use JulienLinard\Core\Controller\Controller; use JulienLinard\Core\Form\Validator as CoreValidator; use JulienLinard\Router\Attributes\Route; use JulienLinard\Router\Request; use JulienLinard\Router\Response; class ContactController extends Controller { public function __construct( private CoreValidator $validator ) {} #[Route(path: '/contact', methods: ['POST'], name: 'contact.submit')] public function submit(Request $request): Response { $result = $this->validator->validate($request->getData(), [ 'name' => 'required|min:3|max:100', 'email' => 'required|email', 'message' => 'required|min:10|max:1000' ]); if ($result->hasErrors()) { return $this->json([ 'success' => false, 'errors' => $result->getErrors() ], 422); } // Process valid data return $this->json(['success' => true, 'message' => 'Contact form submitted']); } }
Using Dependency Injection
Services are automatically registered in the DI container. Access them in controllers:
<?php namespace App\Controller; use JulienLinard\Core\Controller\Controller; use JulienLinard\Doctrine\EntityManager; use JulienLinard\Auth\AuthManager; class MyController extends Controller { public function __construct( private EntityManager $em, private AuthManager $auth ) {} }
Flash Messages
Flash messages are automatically displayed in the header template:
use JulienLinard\Core\Session\Session; // Set flash message Session::setFlash('success', 'Operation completed successfully!'); Session::setFlash('error', 'An error occurred!');
Logging
Use SimpleLogger for structured logging:
use JulienLinard\Core\Logging\SimpleLogger; $logger = new SimpleLogger('/path/to/logs/app.log'); $logger->info('User logged in', ['user_id' => 123]); $logger->error('Database connection failed', ['error' => $e->getMessage()]);
Configuration
Environment variables are automatically loaded from .env:
# Application APP_DEBUG=true APP_LOCALE=fr APP_SECRET=your-secret-key-here-min-32-chars # Database (for Docker, use service name as host) MARIADB_CONTAINER=mariadb_app MARIADB_PORT=3306 MYSQL_DATABASE=app_db MYSQL_USER=app_user MYSQL_PASSWORD=app_password
🔒 Security Features
- CSRF Protection - Automatic CSRF token generation and validation
- Session Security - HttpOnly, SameSite, and secure cookies
- Environment Validation - Automatic validation of required environment variables
- Secure Database Config - No hardcoded credentials, strict validation
- Error Handling - Production-safe error handling with logging
📝 Requirements
- PHP 8.1 or higher
- Composer
- Docker (optional, for Docker setup)
🆕 What's New in v1.5.3
- ✅ Automatic autoloader regeneration after installation
- ✅ Clean architecture with service layer
- ✅ Auto-generated services (EnvValidator, BootstrapService, EventListenerService)
- ✅ Multilingual validation support (fr, en, es)
- ✅ Secure configuration out of the box
- ✅ Flash messages with auto-hide
- ✅ Production-ready structure
📄 License
MIT License - See the LICENSE file for more details.
🤝 Contributing
Contributions are welcome! Feel free to open an issue or a pull request.
📧 Support
For any questions or issues, please open an issue on GitHub.
💝 Support the project
If this skeleton is useful to you, consider becoming a sponsor to support the development and maintenance of this open source project.
Developed with ❤️ by Julien Linard