feras_altaleb/mvc_php

MVC PHP Small Framework

dev-main 2026-03-21 20:32 UTC

This package is auto-updated.

Last update: 2026-03-21 20:32:50 UTC


README

MVC PHP Framework
Created by Feras Altaleb β€” for educational purposes only.

A lightweight, extensible MVC framework built with native PHP to help you kickstart web applications quickly and efficiently.

Requires PHP 8.0+ (uses native PHP Attributes for routing).

πŸš€ Features

  • MVC Architecture β€” Clean separation of concerns using the Model-View-Controller pattern.
  • Attribute-Based Routing β€” Symfony-style #[Route] attributes declared directly on controller methods. No central routes file needed.
  • Database Abstraction β€” Easy database interactions via PDO with a built-in AbstractRepository.
  • Security β€” Session hijacking protection, method spoofing, HTTPS detection, and real IP resolution.
  • Extensible β€” Easily add new controllers; routes are auto-discovered via Reflection.
  • Lightweight β€” Minimal dependencies for optimal performance.

πŸ› οΈ Getting Started

1. Clone the Repository

git clone https://github.com/AltalebFeras/template_empty_mvc_for_any_new_project_php_native.git

2. Install Dependencies

composer install

3. Configure Your Environment

  • Copy config_example.php and rename it to config.php.
  • Update the settings as needed for your environment (development or production):
    • Set up your database connection in config.php.
    • Set your base URL (HOME_URL) in config.php.
    • Configure mail settings in config.php.
    • Set your timezone in src/init.php.

4. Define Your Routes

Routes are defined with the #[Route] attribute directly above each controller method β€” no central routes file.

use src\Services\Route;

class UserController
{
    // Public page β€” GET only
    #[Route('/login', methods: ['GET'])]
    public function showLoginForm(): void
    {
        // render login view
    }

    // Form submission β€” POST only
    #[Route('/login', methods: ['POST'])]
    public function handleLogin(): void
    {
        // process credentials
    }

    // Protected page β€” requires active session
    #[Route('/dashboard', methods: ['GET'], authRequired: true)]
    public function showDashboard(): void
    {
        // render dashboard view
    }
}

#[Route] parameters:

Parameter Type Default Description
$path string (required) URL path to match (e.g. '/login')
$methods string|array ['GET'] Allowed HTTP methods
$name string '' Optional route name
$authRequired bool false Redirect to /login if not authenticated

The router auto-discovers every class inside src/Controllers/ β€” just create a new controller and add #[Route] attributes.

5. HTML Form Method Spoofing

HTML forms only support GET and POST. To send PUT, PATCH, or DELETE, add a hidden field:

<form method="POST" action="/resource/1">
    <input type="hidden" name="_method" value="DELETE">
    ...
</form>

ConfigRouter::getMethod() will resolve the effective method automatically.

6. Run the Application

Access your application in the browser:

http://localhost/path-to-your-project/public

πŸ“ Directory Structure

public/                   # Web root β€” point your server / virtual host here
β”‚   index.php             # Single entry point
β”‚   .htaccess             # URL rewriting (Apache)
└── assets/               # CSS, JS, images

src/
β”œβ”€β”€ init.php              # Bootstrap: session, autoloader, config, router
β”œβ”€β”€ Abstracts/
β”‚   β”œβ”€β”€ AbstractController.php   # render() and redirect() helpers
β”‚   └── AbstractRepository.php  # CRUD helpers (getAll, getById, create, …)
β”œβ”€β”€ Controllers/          # Your controllers β€” add #[Route] attributes here
β”œβ”€β”€ Entities/             # Plain PHP entity classes (hydrated via Hydration trait)
β”œβ”€β”€ Migrations/           # SQL migration files
β”œβ”€β”€ Repositories/         # Repository classes extending AbstractRepository
β”œβ”€β”€ Services/
β”‚   β”œβ”€β”€ Route.php         # #[Route] PHP attribute definition
β”‚   β”œβ”€β”€ router.php        # Auto-discovers and dispatches routes via Reflection
β”‚   β”œβ”€β”€ ConfigRouter.php  # HTTP utilities: getMethod, redirect, isAjax, getClientIp…
β”‚   β”œβ”€β”€ Database.php      # PDO connection wrapper
β”‚   β”œβ”€β”€ Encrypt_decrypt.php
β”‚   β”œβ”€β”€ Hydration.php     # Trait for automatic entity hydration
β”‚   β”œβ”€β”€ Mail.php          # PHPMailer wrapper
β”‚   └── Validator.php
└── Views/                # PHP view templates

πŸ”’ Security Utilities (ConfigRouter)

Method Description
ConfigRouter::getMethod() Returns the real HTTP method, supporting PUT/PATCH/DELETE spoofing via _method POST field
ConfigRouter::checkOriginConnection() Validates session IP & user-agent to detect session hijacking β€” returns false on mismatch
ConfigRouter::redirect($url, $code) Safe redirect with HTTP status code (default 302)
ConfigRouter::isAjax() Detects XMLHttpRequest / fetch requests
ConfigRouter::isHttps() Returns true if the connection is HTTPS
ConfigRouter::getClientIp() Resolves the real client IP (proxy-aware, validated)

🧰 Best Practices

  • Use $authRequired: true on routes that require a logged-in user.
  • Never expose the src/ directory β€” only public/ should be the web root.
  • Store passwords with password_hash() / password_verify().
  • Validate and sanitize all user input at the controller level.
  • Test your application thoroughly before deploying to production.

🀝 Contributing

Contributions are welcome!
If you have suggestions for improvements or new features, please open an issue or submit a pull request.

πŸ‘€ Author

Feras Altaleb
GitHub

⭐️ Enjoy building amazing web applications with this simple MVC framework!