Phalcon is a high-performance PHP framework known for being delivered as a C-extension, making it incredibly fast and resource-efficient compared to traditional PHP frameworks. While Phalcon offers a full-stack MVC architecture, many developers prefer using its Micro Framework version due to its simplicity, speed, and flexibility for building lightweight APIs, microservices, and small applications.
This guide covers the fundamentals of the Phalcon Micro Framework, including how to set it up, how Dependency Injection works, how routing is handled, and how Micro Collections make route organization cleaner and modular. Whether you’re a beginner or transitioning from MVC frameworks like Laravel, Symfony, or Express.js in Node.js, this guide will help you understand the core workflow of Phalcon Micro.
1. Introduction to Phalcon Micro Framework
Phalcon Micro is a minimalist component of the Phalcon ecosystem designed for building simple and fast applications. Instead of forcing a specific directory structure or complex architecture, Phalcon Micro allows you to define everything directly in code with full flexibility.
Why Use Phalcon Micro?
Some of its main advantages include:
✔ Ultra-fast performance
Because Phalcon is compiled as a C-extension, it runs faster than frameworks written in PHP itself.
✔ Small footprint
No heavy boilerplate—only the essentials.
✔ Ideal for microservices and APIs
Its efficiency makes it suitable for high-load API environments.
✔ Flexible architecture
You can structure your application however you want.
✔ Easy to integrate with other Phalcon components
ORM, models, services, queue, caching, and more.
A Micro application is essentially a single file (or a few files) that control routing and service registration, making it easy to prototype or build production-level microservices.
2. Setting Up a Phalcon Micro Application
To start with Phalcon Micro, you need to have Phalcon installed on your system. Because it’s a PHP extension, installation differs from regular PHP libraries.
2.1 Installing Phalcon
Phalcon installation depends on your operating system.
Linux (Ubuntu example)
sudo apt-get install php-phalcon
MacOS (via Homebrew)
brew tap phalcon/phalcon
brew install phalcon@5
Windows
Phalcon provides DLLs for Windows. You can download them and update your php.ini:
extension=php_phalcon.dll
Once installed, verify it worked:
php -m | grep phalcon
2.2 Installing Composer and Phalcon Components
Although Phalcon itself is a PHP extension, additional libraries like DevTools or annotations can be installed using Composer:
composer require phalcon/incubator
2.3 Creating a Micro Application (Basic Example)
Create a file named:
public/index.php
Add the following code:
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Micro;
require_once '../vendor/autoload.php';
$di = new FactoryDefault();
$app = new Micro($di);
$app->get('/', function () {
return "Hello from Phalcon Micro!";
});
$app->handle($_SERVER["REQUEST_URI"]);
What this code does:
- Loads Composer
- Creates the Dependency Injection container
- Creates a Micro application instance
- Defines a simple GET route
- Handles incoming requests
Running the Application
Use PHP’s built-in server:
php -S localhost:8000 -t public
Visit:
http://localhost:8000/
You should see:
Hello from Phalcon Micro!
Your micro application is ready!
3. Understanding Dependency Injection (DI) in Phalcon Micro
Phalcon heavily uses Dependency Injection (DI) as a core pattern. DI helps keep your application loosely coupled, modular, and easy to maintain.
3.1 What Is Dependency Injection?
Dependency Injection means that objects do not create their own dependencies. Instead, these dependencies are provided externally through a container.
Phalcon’s DI container manages services such as:
- Database connection
- Request and response objects
- Router
- Dispatcher
- Session and cookies
- Models metadata
- Custom services
Phalcon Micro uses FactoryDefault as the default DI container.
3.2 Registering Services
Example of registering a database service:
$di->set('db', function () {
return new \Phalcon\Db\Adapter\Pdo\Mysql([
"host" => "localhost",
"username" => "root",
"password" => "",
"dbname" => "test_db",
]);
});
Now you can use it in routes:
$app->get('/users', function () use ($app) {
$users = $app->di->get('db')->fetchAll("SELECT * FROM users");
return json_encode($users);
});
3.3 Built-in DI Services
Phalcon’s DI container provides commonly-used services by default, such as:
- request – HTTP request handling
- response – HTTP responses
- router – Routes definitions
- cookies – Handling cookies
- filter – Filtering values
- security – Hashing and security tools
You can access them using:
$request = $app->di->get('request');
Phalcon also supports lazy-loading, meaning services are only loaded when first used, improving performance.
3.4 Custom Services
DI also allows registering your own services:
$di->set('logger', function () {
return new \Phalcon\Logger\Adapter\Stream('../logs/app.log');
});
Then use it inside a route:
$app->post('/log', function () use ($app) {
$logger = $app->di->get('logger');
$logger->info("Something happened!");
return "Logged successfully.";
});
Dependency Injection is fundamental to how Phalcon Micro works. Every service you need can be placed in DI for clean code and easy reuse across routes.
4. Routing in Phalcon Micro Framework
Routing defines how your application responds to HTTP requests. Routes in Phalcon Micro are extremely simple and readable.
4.1 Basic Routing
You can define routes for various HTTP methods:
GET
$app->get('/about', function () {
return "About page";
});
POST
$app->post('/submit', function () {
return "Form submitted";
});
PUT
$app->put('/update', function () {
return "Updated.";
});
DELETE
$app->delete('/delete', function () {
return "Deleted.";
});
4.2 Handling Route Parameters
You can capture dynamic URL segments:
$app->get('/user/{id}', function ($id) {
return "User ID: " . $id;
});
Multiple parameters
$app->get('/product/{category}/{id}', function ($category, $id) {
return "$category product with ID $id";
});
4.3 JSON Responses
Phalcon makes it easy to return JSON:
$app->get('/api', function () use ($app) {
$data = ["status" => "success", "message" => "API is working"];
$response = $app->response;
$response->setJsonContent($data);
return $response;
});
4.4 Not Found Handler
Define a custom 404 handler:
$app->notFound(function () use ($app) {
$response = $app->response;
$response->setStatusCode(404, "Not Found");
$response->setJsonContent(["message" => "Route not found"]);
return $response;
});
4.5 Before and After Middleware
Phalcon supports middleware functions:
Before Handler
$app->before(function () {
// Authentication check
return true; // return false to stop request
});
After Handler
$app->after(function () use ($app) {
$app->response->setHeader('X-Powered-By', 'Phalcon Micro');
});
4.6 Mounting Routes Using Micro Collections
Micro Collections allow you to group routes under a common prefix or controller. This helps clean up large applications.
We explore Micro Collections in full detail next.
5. Micro Collections in Phalcon Micro
Micro Collections are the best way to organize routes in a micro application. They group related routes together under a namespace or URL prefix, similar to controllers in MVC frameworks.
5.1 What Are Micro Collections?
Micro Collections allow you to:
- Group related routes (e.g., /users, /products)
- Assign handlers (classes) to handle routes
- Apply a common URL prefix
- Keep routing modular and manageable
5.2 Creating a Handler Class
Create a handler for user routes:
<?php
class UsersController
{
public function list()
{
return "Listing all users";
}
public function get($id)
{
return "User with ID: " . $id;
}
public function create()
{
return "User created";
}
}
5.3 Registering Micro Collection
Now define the collection:
use Phalcon\Mvc\Micro\Collection;
$users = new Collection();
$users->setPrefix('/users');
$users->setHandler(UsersController::class, true);
$users->get('/', 'list');
$users->get('/{id}', 'get');
$users->post('/create', 'create');
$app->mount($users);
What this does:
- All routes begin with
/users - The handler class is
UsersController - The collection maps URI + HTTP method → class method
Examples:
GET /users/→UsersController::list()GET /users/22→UsersController::get(22)POST /users/create→UsersController::create()
5.4 Using DI in Collection Handlers
Injecting services inside handlers:
class UsersController
{
protected $db;
public function __construct()
{
$this->db = \Phalcon\Di\Di::getDefault()->get('db');
}
public function list()
{
return $this->db->fetchAll("SELECT * FROM users");
}
}
5.5 Adding Middleware to Collections
You can attach middleware to specific collections.
Before Middleware Example
$users->before(function () {
// Check if user is authenticated
});
5.6 Organizing Your Application Using Collections
Instead of one huge index.php, you can create:
app/handlers/
app/routes/
app/services/
public/index.php
Each route group becomes a dedicated class for better scalability and maintainability.
6. Example: A Complete Phalcon Micro Application Structure
Below is an example of a clean application structure using DI, Routing, and Collections.
6.1 Directory Layout
app/
handlers/
UsersController.php
config/
services.php
routes/
users.php
public/
index.php
composer.json
6.2 index.php
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Micro;
require_once '../vendor/autoload.php';
$di = new FactoryDefault();
require_once '../app/config/services.php';
$app = new Micro($di);
require_once '../app/routes/users.php';
$app->handle($_SERVER['REQUEST_URI']);
6.3 services.php
$di->set('db', function () {
return new \Phalcon\Db\Adapter\Pdo\Mysql([
"host" => "localhost",
"username" => "root",
"password" => "",
"dbname" => "test_db",
]);
});
6.4 users.php
use Phalcon\Mvc\Micro\Collection;
$users = new Collection();
$users->setPrefix('/users');
$users->setHandler(\App\Handlers\UsersController::class, true);
$users->get('/', 'list');
$users->get('/{id}', 'get');
$users->post('/', 'create');
$app->mount($users);
6.5 UsersController.php
namespace App\Handlers;
class UsersController
{
protected $db;
public function __construct()
{
$this->db = \Phalcon\Di\Di::getDefault()->get('db');
}
public function list()
{
return json_encode($this->db->fetchAll("SELECT * FROM users"));
}
public function get($id)
{
$user = $this->db->fetchOne("SELECT * FROM users WHERE id = ?", \Phalcon\Db\Enum::FETCH_ASSOC, [$id]);
return json_encode($user);
}
public function create()
{
return json_encode(["message" => "User created successfully"]);
}
}
This modular structure is production-ready and follows best practices.
7. Best Practices for Phalcon Micro Applications
1. Use Collections for Larger Projects
This keeps routing clean and scalable.
2. Register core services in DI
Everything from database to helper classes should be injected.
3. Use Middleware for Authentication and Security
Implement before() handlers for validating tokens.
4. Return JSON responses for APIs
Phalcon’s response->setJsonContent() is ideal for REST APIs.
5. Keep Handlers Slim
Business logic should be in separate service classes.
6. Use Phalcon ORM when needed
Integrate models for database operations.
7. Leverage caching for performance
Phalcon supports APCu, Redis, Memcached, and other drivers.
Leave a Reply