Ghost is a PHP nano framework for quickly writing REST APIs.
- PHP 7.0+ (with
random_bytesor OpenSSL extension forcreateToken()) - MySQLi extension (for MySQL), MSSQL driver, or OCI8 (for Oracle)
fileinfoextension (recommended, for MIME validation insave_file())
require 'ghost.php';
$ghost = new Ghost();
$ghost->connect('localhost', 'root', '', 'my_db');
$ghost->service('post', 'employee', ['name' => 'text', 'lastname' => 'text']);
$ghost->service('get', 'employee', ['name' => 'text']);
$ghost->service('put', 'employee', ['name' => 'text', 'lastname' => 'text', 'id' => 'key']);
$ghost->service('delete', 'employee', ['id' => 'key']);
$ghost->run();Connects to the database.
$ghost->connect('localhost', 'root', 'secret', 'my_db');Selects the database engine. Default is mysql.
| Value | Engine |
|---|---|
mysql |
MySQL / MariaDB |
mssql |
Microsoft SQL Server |
oracle |
Oracle |
$ghost->set_db_type('oracle');By default Ghost sends no CORS headers (same-origin only). Set $allowedOrigins to an explicit list of allowed origins before calling run():
$ghost->allowedOrigins = ['https://myapp.com', 'https://admin.myapp.com'];
$ghost->run();Only requests whose Origin header matches an entry in the list will receive an Access-Control-Allow-Origin response header. An empty array means no cross-origin access is granted.
$ghost->service($method, $option, $rules, $function);| Parameter | Type | Description |
|---|---|---|
$method |
string | HTTP method: post, get, put, delete, or crud |
$option |
string | Route/table name |
$rules |
array|null | Validation rules (optional) |
$function |
callable|null | Custom callback (optional) |
When no $function is given, Ghost automatically runs the corresponding SQL operation against $option as the table name.
Registers all four methods at once:
$ghost->service('crud', 'employee', [
'name' => 'text',
'lastname' => 'text',
'id' => 'key',
]);$ghost->service('post', 'login', ['email' => 'email', 'password' => 'text'], function($ghost) {
$email = $ghost->param->email;
$password = $ghost->param->password;
// ... custom logic
$ghost->response(['token' => '...'], 200);
});Inside the callback, $ghost->param is an object and $ghost->params is an array with all validated parameters.
Defined as an associative array ['field' => 'type'].
| Type | Description |
|---|---|
text |
Any string |
int |
Numeric value |
bool |
Boolean (true / false) |
email |
Valid email address |
file |
File upload ($_FILES) |
json |
Valid JSON string |
array |
PHP array |
key |
Numeric identifier — marks the primary key for put/delete |
You can also pass a callable as the type for custom validation:
$ghost->service('post', 'register', [
'username' => function($g) {
// $g->username contains the value, $g->con is the DB connection
return strlen($g->username) >= 3;
},
]);Or use the extended rule array for combined checks:
'token' => ['type' => 'text', 'length' => 32, 'function' => $myValidator]Ghost supports two syntaxes.
Send option and params as request parameters:
// POST
fetch('api.php', {
method: 'POST',
body: new URLSearchParams({ option: 'employee', 'params[name]': 'Martin', 'params[lastname]': 'Doe' })
});
// GET
fetch('api.php?option=employee¶ms[name]=Martin');
// PUT / DELETE — same as GET params in body
fetch('api.php', {
method: 'PUT',
body: new URLSearchParams({ option: 'employee', 'params[id]': 1, 'params[name]': 'John' })
});Use the route name directly as the first query string key:
GET /api.php?employee&name=Martin
The first key in $_GET is treated as the option, and the remaining params are passed as-is.
Sends a JSON response and stops execution.
$ghost->response(['user' => $user], 200);
$ghost->response('Unauthorized', 401);Response body format: {"message": ..., "code": ...}
Simpler alternative — sends raw JSON or plain text without wrapping.
$ghost->resp(['data' => $rows], 200);
$ghost->resp(FALSE); // sends 500Sends a plain text response.
$ghost->responseText('OK', 200);Sends an array as JSON and stops execution.
$ghost->jsonEncode($myArray);Sends 200 if $bool is TRUE, 500 if FALSE.
$ghost->boolResponse($result);These can be used freely inside custom callbacks.
$rows = $ghost->get('employee', ['id', 'name'], ['name' => 'Martin'], 10);Returns an array of rows, or FALSE if none found.
Like get() but without a limit.
$all = $ghost->getAll('employee', ['id', 'name']);Inserts a row.
$ghost->post('employee', ['name' => 'Martin', 'lastname' => 'Doe']);Updates rows matching $where.
$ghost->put('employee', ['name' => 'John'], ['id' => 5]);Deletes rows matching $where.
$ghost->delete('employee', ['id' => 5]);Runs a raw SQL query.
$res = $ghost->query("SELECT * FROM employee WHERE active = 1");
$rows = $ghost->queryToArray($res);Merges two result arrays by a shared key — like a PHP-side JOIN.
Generates a cryptographically secure random token using random_bytes() (PHP 7+) or openssl_random_pseudo_bytes() as fallback. Throws a RuntimeException if neither is available.
$token = $ghost->createToken(32);Moves an uploaded file to $path (or uploads/ by default) with a random name.
Validates the file extension against $allowedExtensions and verifies the real MIME type using finfo_file() to prevent disguised uploads (e.g. a .php renamed to .jpg).
Default allowed extensions: jpg, jpeg, png, gif, pdf, xlsx, xls, csv, txt, doc, docx.
// Use default whitelist
$path = $ghost->save_file($_FILES['avatar'], 'uploads/avatars/');
// Custom whitelist
$path = $ghost->save_file($_FILES['document'], 'uploads/docs/', ['pdf', 'docx']);Returns the final file path on success, or FALSE if the extension/MIME is not allowed or the move fails.
Returns TRUE if the string matches the given date format.
$ghost->validateDate('2024-01-15'); // TRUE
$ghost->validateDate('15/01/2024', 'd/m/Y'); // TRUE| Property | Type | Description |
|---|---|---|
$ghost->params |
array | All validated parameters |
$ghost->param |
object | Same as params but as an object |
$ghost->option |
string | The matched route name |
$ghost->method |
string | HTTP method in lowercase |
$ghost->con |
resource | Active database connection |
$ghost->files |
array | Names of uploaded file fields |
| Property | Default | Description |
|---|---|---|
$ghost->allowedOrigins |
[] |
List of allowed CORS origins. Empty = no CORS headers sent |
