Introduction
Basic Concepts
Understanding Routing
Intercepting Requests
Module Fundamentals
Database Operations
Templates
Helpers
Form Handling
Form Validation
Working With Files
Image Manipulation
Working With Dates & Times
Language Control
Authorization & Authentication
Controller Files
Every module gets one controller file. Every controller file contains one PHP class. The boss.
Trongate v2 killed the controllers/ subfolder.
We got rid of this →
And, now we do this →
You’re welcome.
Where They Live Now
The text above demonstrates some file and directory locations for a hypothetical 'users' module.
Naming Rules
| Thing | Rule | Example |
|---|---|---|
| Module Directory Name | lowercase, usually plural | luxury_wristwatches |
| Controller File Name | UppercaseFirst, snake_case + .php |
Luxury_wristwatches.php |
| Class Name | UppercaseFirst, snake_case | class Luxury_wristwatches |
Bare Minimum Controller
Visit: https://yoursite.com/dice/roll → rolls a die. No config. No YAML. No drama.
Real-World Example: Users
URL → Method magic:
/users→index()/users/profile/42→profile(42)
Constructors? Optional.
Don’t need one? Don’t write one. Need CORS? Read this. Auth? Go nuts:
Never call parent::__construct(). It’s 2005. Let it go!
Multiple Classes? Don’t.
Want another class? Make a child module. Not another file in the same folder.
Copy. Paste. Works. No require_once hell.
Third-Party? Sure. But Why?
Need Guzzle? Stripe? Fine. Drop Composer in vendor/, autoload it:
But 99% of the time Native PHP wins. Faster. Cleaner. No 3 AM updates.
Namespaces? Only When Forced
Using Packagist? Use their PascalCase namespaces. Otherwise? Snake case everything.
One file. One class. Native PHP rules!