lengthofrope/treehouse

TreeHouse - Modern PHP Framework with Zero Dependencies

dev-main / 1.0.x-dev 2025-06-28 09:14 UTC

This package is auto-updated.

Last update: 2025-06-28 20:21:19 UTC


README

A modern, lightweight PHP framework built from scratch with zero external dependencies.

WORK IN PROGRESS

Please note that this framework is in WIP state. It is nowhere near production ready.

Features

  • Zero Dependencies: Pure PHP implementation with no external libraries
  • Modern PHP 8.4+: Built for the latest PHP features
  • MVC Architecture: Clean separation of concerns
  • Dependency Injection: Built-in container with automatic resolution
  • Routing: Flexible HTTP routing with middleware support
  • Template Engine: ThymeLeaf-inspired template engine with components and layouts
  • Database ORM: Active Record pattern with relationships
  • Console Commands: CLI interface for development and maintenance
  • Caching: Multi-driver caching system
  • Validation: Comprehensive form and data validation
  • Security: Built-in CSRF protection, encryption, and sanitization

Installation

Create a New Project

composer create-project lengthofrope/treehouse my-app
cd my-app
composer install
./bin/th serve

Or Install via Composer

composer require lengthofrope/treehouse

Using the CLI Tool

Create a new project:

# Install TreeHouse globally
composer global require lengthofrope/treehouse

# Create new project
./bin/treehouse new my-app
cd my-app
composer install
./bin/treehouse serve

Quick Start

1. Create a Controller

<?php

namespace App\Controllers;

use LengthOfRope\TreeHouse\Http\Request;
use LengthOfRope\TreeHouse\Http\Response;

class HomeController
{
    public function index(): string
    {
        return view('home', [
            'title' => 'Welcome to TreeHouse',
            'message' => 'Your application is running!'
        ]);
    }
}

2. Define Routes

In config/routes/web.php:

<?php

use App\Controllers\HomeController;

$router->get('/', [HomeController::class, 'index']);
$router->get('/users/{id}', [UserController::class, 'show'])
       ->where('id', '\d+');
       
$router->group(['middleware' => 'auth'], function($router) {
    $router->get('/dashboard', [DashboardController::class, 'index']);
});

3. Create Models

<?php

namespace App\Models;

use LengthOfRope\TreeHouse\Database\ActiveRecord;

class User extends ActiveRecord
{
    protected array $fillable = ['name', 'email'];
    protected array $hidden = ['password'];
    
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

4. Use the Database

// Create
$user = User::create([
    'name' => 'John Doe',
    'email' => 'john@example.com'
]);

// Query
$users = User::query()
    ->where('active', true)
    ->orderBy('name')
    ->get();

// Relations
$posts = $user->posts()->where('published', true)->get();

Directory Structure

my-app/
├── src/App/              # Application code
│   ├── Controllers/      # HTTP controllers
│   ├── Models/          # Database models
│   ├── Services/        # Business logic
│   └── Middleware/      # HTTP middleware
├── config/              # Configuration files
├── public/              # Web root
├── resources/views/     # Templates
├── storage/             # Cache, logs, compiled views
├── tests/               # Test files
├── database/migrations/ # Database migrations
└── bin/th              # CLI command

CLI Commands

TreeHouse includes a comprehensive CLI tool:

# Development server
./bin/th serve --port=8000

# Cache management
./bin/th cache:clear
./bin/th cache:stats

# Database
./bin/th migrate:run

# Testing
./bin/th test:run

# Create new project
./bin/treehouse new my-app

Configuration

Configuration files are stored in the config/ directory:

  • app.php - Application settings
  • database.php - Database connections
  • cache.php - Cache configuration
  • routes/web.php - Web route definitions
  • routes/api.php - API route definitions

Template Engine

TreeHouse includes a powerful ThymeLeaf-inspired template engine:

Layout Template (layouts/app.th.html):

<!DOCTYPE html>
<html>
<head>
    <title th:text="${title}">Default Title</title>
</head>
<body>
    <main th:fragment="content">
        <!-- Content will be inserted here -->
    </main>
</body>
</html>

Page Template (home.th.html):

<div th:extends="layouts/app" th:fragment="content">
    <h1 th:text="${title}">Welcome</h1>
    <p th:text="${message}">Default message</p>
    
    <div th:if="${user}">
        <p>Welcome, <span th:text="${user.name}">User</span>!</p>
    </div>
    
    <div th:each="post : ${posts}">
        <article>
            <h2 th:text="${post.title}">Post Title</h2>
            <p th:text="${post.excerpt}">Post excerpt</p>
        </article>
    </div>
</div>

Template Features:

  • th:text - Set element text content
  • th:if - Conditional rendering
  • th:each - Loop over collections
  • th:extends - Extend layout templates
  • th:fragment - Define reusable fragments
  • ${variable} - Variable interpolation

Middleware

Create and register middleware for request processing:

<?php

namespace App\Middleware;

use LengthOfRope\TreeHouse\Router\Middleware\MiddlewareInterface;
use LengthOfRope\TreeHouse\Http\Request;
use LengthOfRope\TreeHouse\Http\Response;

class AuthMiddleware implements MiddlewareInterface
{
    public function handle(Request $request, callable $next): Response
    {
        if (!auth()->check()) {
            return redirect('/login');
        }
        
        return $next($request);
    }
}

Testing

TreeHouse applications come with PHPUnit configured:

<?php

namespace Tests\Unit;

use Tests\TestCase;
use App\Models\User;

class UserTest extends TestCase
{
    public function test_user_creation()
    {
        $user = User::create([
            'name' => 'Test User',
            'email' => 'test@example.com'
        ]);
        
        $this->assertEquals('Test User', $user->name);
        $this->assertTrue($user->exists);
    }
}

Run tests:

./bin/th test:run
composer test

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

The TreeHouse framework is open-sourced software licensed under the MIT license.

Author

Bas de Kort
Email: bdekort@proton.me
GitHub: @lengthofrope

Support