Getting Started with Forge

This guide will help you get Forge up and running. It's pretty straightforward.

Requirements

  • PHP 8.3 or higher
  • Composer (for dependency management)
  • SQLite, MySQL, or PostgreSQL (optional, for database features)
  • Web server (Apache, Nginx, or PHP CLI built-in server)

Installation

A few ways to get Forge running.

# Quick install with one command
bash <(curl -Ls https://raw.githubusercontent.com/forge-engine/installer/main/installer.sh)

Using Sections

Sections allow you to define content blocks that can be rendered in different parts of your layout:

<!-- In your view file -->
<?php
use Forge\Core\View\View;

View::layout(name: "layouts/app", loadFromModule: false);

View::startSection('title');
echo 'My Page Title';
View::endSection();
?>

<div>
    <h1>Page Content</h1>
</div>
<!-- In your layout file -->
<!DOCTYPE html>
<html>
<head>
    <title><?= View::section('title') ?></title>
</head>
<body>
    <main>
        <!-- Main content automatically included -->
    </main>
</body>
</html>

Configuration

Forge uses environment variables for configuration. Edit your .env file:

# Application Settings
APP_NAME="My Forge App"
APP_ENV=development
APP_DEBUG=true
APP_KEY=your-generated-key

# Database Configuration
DB_DRIVER=sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=forge_app
DB_USER=root
DB_PASS=password
SQLITE_PATH=/storage/database
SQLITE_DB=/database.sqlite

# Cache Configuration
CACHE_DRIVER=file

# Session Configuration
SESSION_DRIVER=file
SESSION_LIFETIME=1440

Start the development server to test your installation:

php forge.php serve

Visit http://localhost:8000 to see your application running!

Creating Your First Controller

Let's create a simple controller to handle HTTP requests:

# Generate a new controller
php forge.php make:controller WelcomeController

This creates a controller in app/Controllers/WelcomeController.php:

<?php

declare(strict_types=1);

namespace App\Controllers;

use Forge\Core\DI\Attributes\Service;
use Forge\Core\Http\Attributes\Middleware;
use Forge\Core\Http\Response;
use Forge\Core\Routing\Route;
use Forge\Core\Http\Request;
use Forge\Traits\ControllerHelper;

#[Service]
#[Middleware('web')]
final class WelcomeController
{
    use ControllerHelper;

    #[Route("/welcome")]
    public function index(Request $request): Response
    {
        $data = [
            "title" => "Welcome to Forge",
            "message" => "Hello from your first controller!"
        ];

        return $this->view(view: "pages/welcome/index", data: $data);
    }
}

Services & Dependency Injection

Forge uses attributes for dependency injection. Services are just PHP classes with the #[Service] attribute.

<?php
namespace App\Services;

use Forge\Core\DI\Attributes\Service;

#[Service]
class UserService
{
    public function findUser(int $id)
    {
        // Your logic here
        return User::find($id);
    }
}

Use services in controllers by adding them to the constructor:

<?php
namespace App\Controllers;

use App\Services\UserService;
use Forge\Core\DI\Attributes\Service;
use Forge\Core\Http\Response;
use Forge\Core\Routing\Route;

#[Service]
class UserController
{
    public function __construct(
        private readonly UserService $userService
    ) {}

    #[Route('/users/{id}')]
    public function show(string $id): Response
    {
        $user = $this->userService->findUser((int)$id);
        return $this->view('users/show', ['user' => $user]);
    }
}

Pro tip: Services are automatically resolved by the container. Just add them to your constructor and they'll be injected.

Routing

Forge uses attribute-based routing. Define routes directly on your controller methods:

#[Route("/")]
public function home(): Response
{
    return $this->view("pages/home");
}

#[Route("/users/{id}")]
public function showUser(Request $request, int $id): Response
{
    return $this->json(["user_id" => $id]);
}

#[Route("/api/posts", method: "POST")]
public function createPost(Request $request): Response
{
    // Handle POST request
    return $this->json(["status" => "created"]);
}

// Route with middleware parameter (for route-specific middleware)
#[Route("/admin", middlewares: ["auth", "admin"])]
public function admin(): Response
{
    return $this->view("admin/dashboard");
}

// Route with prefix
#[Route("/users", prefix: "api/v1")]
public function listUsers(): Response
{
    return $this->json(["users" => []]);
}

// Using Middleware attribute on controller/method (recommended)
use Forge\Core\Http\Attributes\Middleware;

#[Middleware("web")]
class WebController
{
    #[Middleware("auth")]
    #[Route("/profile")]
    public function profile(): Response
    {
        return $this->view("profile/index");
    }
}

Method Parameter: The method parameter accepts a single HTTP method as a string (e.g., "GET", "POST", "PUT", "DELETE"), not an array.

Pro Tip: Routes are automatically discovered from your controllers. No need for separate route files! Use #[Middleware] attribute for cleaner middleware application on controllers/methods.

Views & Templates

Forge uses PHP-first templating. Create views in app/resources/views/:

<!-- app/resources/views/pages/welcome/index.php -->
<?php
use Forge\Core\View\View;

View::layout(name: "layouts/app", loadFromModule: false);
?>

<div class="container mx-auto px-4 py-8">
    <h1 class="text-4xl font-bold text-gray-900 mb-4">
        <?= $title ?>
    </h1>
    <p class="text-xl text-gray-600">
        <?= $message ?>
    </p>
</div>

Create a layout file:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Forge App</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-50">
    <?php
    use Forge\Core\View\View;
    echo View::section('content');
    ?>
</body>
</html>

Database Models

Forge includes a lightweight ORM and migration system. Create your first migration:

# Create a migration
php forge.php make:migration CreateUsersTable

# Run migrations
php forge.php migrate

Create a simple model:

<?php

namespace App\Models;

use Forge\Core\Database\Model;
use Forge\Core\Database\Table;
use Forge\Core\Database\Column;
use Forge\Core\Database\Model;

#[Table('users')]
class User extends Model
{
use Hastimestamps;   
    protected array $hidden = ['password'];
    
    #[Column("integer", primary: true)]
    public int $id;
    
    #[Column("varchar(255)")]
    public string $status;
    
    #[Column("varchar(255)")]
    public string $identifier;
    
    #[Column("varchar(255)")]
    public string $email;
    
    #[Column("varchar(255)")]
    public string $password;
}

CLI Commands

Some commands to help you work:

# Generate files
php forge.php make:controller UserController
php forge.php make:middleware AuthMiddleware
php forge.php make:migration CreatePostsTable
php forge.php make:module BlogModule

# Database operations
php forge.php migrate
php forge.php migrate:rollback

# Development server
php forge.php serve

# Cache management
php forge.php cache:clear

# Application maintenance
php forge.php maintenance:down
php forge.php maintenance:up

# Generate application key
php forge.php key:generate

# Package management (ForgePackageManager)
php forge.php install:module ForgeAuth
php forge.php install:module ForgeAuth@1.2.0
php forge.php remove:module ForgeAuth
php forge.php list:modules

Run php forge.php help to see all available commands.

Next Steps

What you might want to look at next:

Core Concepts

How dependency injection, middleware, and the module system work.

Read More

Modules

Available modules and how to make your own.

Explore