Repository navigation
Controllers & Models (Inverted MVC)
Traditional monolithic frameworks rely on heavy Model-View-Controller (MVC) patterns where Controllers handle view rendering, complex object hydration, and session state, while Models rely on bloated Object-Relational Mappers (ORMs) that consume significant RAM and CPU time.
mouse-php inverts this pattern. In a decoupled, API-first architecture, the server’s primary job is data marshaling: accepting incoming JSON, querying state, and returning JSON as fast as possible.
In mouse-php, Controllers do not render HTML templates or hold session state. They act strictly as Data Marshals positioned at the end of the request pipeline.
A Controller has four responsibilities:
- Receive injected dependencies (
$DB,$SQLITE, and$REQUEST_DATA). - Extract validated variables from dynamic URL parameters or
$request_data['middleware_data']. - Delegate database queries to lightweight Model methods.
- Emit a structured JSON response and exit.
namespace controllers;
class User_Controller
{
public $DB;
public $SQLITE;
public $REQUEST_DATA;
/**
* Dependencies are injected directly by Mouse_Core upon route execution.
*/
public function __construct($db, $sqlite, $request_data)
{
$this->DB = $db;
$this->SQLITE = $sqlite;
$this->REQUEST_DATA = $request_data;
}
public function get_user_profile()
{
// 1. Extract data injected by Middleware
$auth_user = $this->REQUEST_DATA['middleware_data']['User_Authentication'];
// 2. Delegate query execution to Model
$user_model = new \models\User_Model();
$profile = $user_model->fetch_profile_by_id($this->DB, $auth_user['id']);
// 3. Emit structured response
if ($profile) {
echo json_encode(["status" => true, "data" => $profile]);
} else {
http_response_code(404);
echo json_encode(["status" => false, "error" => "Profile not found"]);
}
}
}mouse-php rejects heavy ORM patterns (like Active Record or Data Mappers) that instantiate massive PHP objects for every database row.
Instead, mouse-php Models operate as Pure Query Pipelines. They consist of explicit SQL statements executed through a lightweight PDO wrapper. This wrapper provides the raw performance of PDO while enforcing structural guardrails against SQL injection: because queries require an explicit $vals parameter array, direct variable concatenation into query strings stands out as an obvious defect. To learn more about this wrapper and how to use it visit the Utilities Page.
namespace models;
class User_Model
{
/**
* Fetches user profile data as a raw associative array or returns false
*/
public function fetch_profile_by_id($db, $user_id)
{
$query = "SELECT * FROM profiles WHERE user_id = :id";
$vals = [
[
"name" => ":id",
"value" => $user_id,
"type" => "i" // Integer binding flag
]
];
try {
$resp = $db->make_query("select", $query, $vals);
if($resp && sizeof($resp) > 0) {
return $resp[0]; // Return single profile record
}
return false;
}
catch (\PDOException $e) {
return false;
}
}
}One of the largest performance sinks in traditional web frameworks is initializing database connections prematurely. Frameworks often establish database socket connections during bootstrapping, before checking if the route exists or if the request is valid.
mouse-php defers database initialization until after route matching succeeds:
┌─────────────────────────────────────────────────────────────┐
│ DEFERRED CONNECTION LIFECYCLE │
├─────────────────────────────────────────────────────────────┤
│ 1. Request Received │
│ 2. O(1) Route Lookup ─────────────► (Unmatched? 404 Exit) │
│ │ [ZERO DB Sockets Opened]│
│ │ (Route Matched) │
│ ▼ │
│ 3. DB Connections Initialized ────► (Socket opened LATE) │
│ 4. Middleware Pipeline Execution ─► (Modules query DB) │
│ 5. Controller & Model Executed │
└─────────────────────────────────────────────────────────────┘
Because database sockets are opened only after a route is successfully matched, invalid requests (404 Not Found) incur zero database connection overhead.
| Architectural Attribute | Traditional Monolithic MVC |
mouse-php Inverted MVC |
|---|---|---|
| Primary Output | Server-rendered HTML/Templating | Serialized JSON payloads |
| Database Handling | Heavy ORMs (ActiveRecord/Entities) | Wrapped PDO/Raw SQL array mapping |
| Connection Timing | Opened during core framework boot | Deferred until successful route match |
| Memory Lifecycle | Hydrates complex object graphs | Immediate raw array emission |
| State Management | Server-side sessions/cookies | Stateless/Token-driven (mRPC) |