Fork me on GitHub
Phalcon cheat sheet

MVC

                
// Setting route file on service
$di->set('router', function()
{
    return include __DIR__ . '[route file]';
}, true);

// Create custom routes - index.php
$application->useImplicitView(false);

// Grouping routes under same controller
$group = new \Phalcon\Mvc\Router\Group([
    'namespace' => '[namespace separed with double \\]',
    'controller' => '[controller name]',
]);

// All the routes start with /group
$group->setPrefix('/group');

// Adding route to group
$group->add('[route]', ['action' => '[method]'])->setName('[keyword]');
$router->mount($group);

// Getting parameters using dispatcher service
$this->dispatcher->getParam('[parameter]');

// Ways to define a route
$router->add(
    '[route]',
    array(
        'controller' => '[controller name]',
        'action' => '[method name]',
    )
);

// Single flexible route
$router->add(
    '/admin/:controller/a/:action/:params',
    array(
        'controller' => 1,
        'action' => 2,
        'params' => 3,
    )
);


// Flexible route with parameters with name
$router->add(
    '/news/([0-9]{4})/([0-9]{2})/([0-9]{2})/:params',
    array(
        'controller' => 'posts',
        'action' => 'show',
        'year' => 1, // ([0-9]{4})
        'month' => 2, // ([0-9]{2})
        'day' => 3, // ([0-9]{2})
        'params' => 4, // :params
    )
);

// Route with parameters with name
$router->add(
    '/documentation/{chapter}/{name}.{type:[a-z]+}',
    array(
        'controller' => 'documentation',
        'action'     => 'show'
    )
);

// Short form using statics
$router->add("/posts/{year:[0-9]+}/{title:[a-z\-]+}", "Posts::show");

// Array form
$router->add(
    "/posts/([0-9]+)/([a-z\-]+)",
    array(
       "controller" => "posts",
       "action"     => "show",
       "year"       => 1,
       "title"      => 2,
    )
);

// This route only will be matched if the HTTP method is GET
$router->addGet("/products/edit/{id}", "Products::edit");

// This route only will be matched if the HTTP method is POST
$router->addPost("/products/save", "Products::save");

// This route will be matched if the HTTP method is POST or PUT
$router->add("/products/update")->via(array("POST", "PUT"));

// Getting the processed controller
$router->getControllerName();

// Getting the processed action
$router->getActionName();

//Get the matched route
$route = $router->getMatchedRoute();

// Generate a link with predefined route
$this->url->get(['for' => '', 'paramN' => $paramN]);
                
            

Dispatching Controllers

                
// Forward flow to the index action
$this->dispatcher->forward(array(
    "controller" => "post",
    "action" => "index"
));

// Forward flow to another action in the current controller
$this->dispatcher->forward(array(
    "action" => "search"
));

// Forward flow to another action in the current controller passing parameters
$this->dispatcher->forward(array(
    "action" => "search",
    "params" => array(1, 2, 3)
));

// Get the post's title passed in the URL as parameter or prepared in an event
$title = $this->dispatcher->getParam('param');
                
            

Micro applications

                
// Without controller
$application->get('/', function(){
    echo 'Your app it\'s up';
});

// Using controller, same for get|post|put|delete
$application->post('[route]', [
    [instance of your controller]
    '[method]'
]);

// Not found route
$app->notFound(function () use ($app) {
    $app->response->setStatusCode(404, "Not Found")->sendHeaders();
    echo 'This is crazy, but this page was not found!';
});
                
            

ORM

                

// Find record by its primary id = 3
$robot = Robots::findFirst(3);

// Find one record with conditions + bind params and all phalcon options
$robots = Robots::findFirst([
            "columns" => "id, name",
            "conditions" => "type = ?1",
            "bind"       => [1 => "virtual"],
            "order" => "id DESC" ,
            "limit" => "limit" => 10 / "limit" => ["number" => 10, "offset" => 5],
            "group" => "name, status",
            "cache" => array("lifetime" => 3600, "key" => "my-find-key"),
           ]);

// Find all record with  conditions + bind params and all phalcon options
$robots = Robots::find([
            "columns" => "id, name",
            "conditions" => "type = ?1",
            "bind"       => [1 => "virtual"],
            "order" => "id DESC" ,
            "limit" => "limit" => 10 / "limit" => ["number" => 10, "offset" => 5],
            "group" => "name, status",
            "cache" => array("lifetime" => 3600, "key" => "my-find-key"),
           ]);

// Using any Models Query Builder
$model::query()
    ->where('field = :bindparam:')
    ->andWhere( "field2 = '1' ")
    ->bind( ['bindparam' => '2'] )
    ->order('field ASC')
    ->limit(10)
    ->cache(['key' => 'optionalifyouwant' , 'lifetime' => 'optionalalso'])
    ->execute();

// Catch Save / Update Model Exceptions
$model = new News();
$model->title = 'Update Phalcon is the fastest php framework';
$model->content = 'Use version 1.3+ or v2';

if (!$model->save())
{
    //messages
    foreach ($model->getMessages() as $message)
    {
        //throw error
       throw new Exception($message);

       //or flash message in controller
       $this->flash->error($message);

    }
}

// Validate if we have records
if($robots) if no records found it returns false

// Count the result set para saber si trajo algo
$robots->count();

                
            

ODM for Mongo

Pending contribution...

Template Engine (Volt)

                

// Registering Volt as template engine
$di->set('view', function() {
    $view = new \Phalcon\Mvc\View();
    $view->setViewsDir('../app/views/');
    $view->registerEngines(array(
        ".volt" => 'Phalcon\Mvc\View\Engine\Volt'
    ));
    return $view;
});

{# Variables #}

{# for $post->title #}
{{ post.title }}

{# for $post['title'] #}
{{ post['title'] }}


{# Filters #}

{# e or escape filter #}
{{ "<h1>Hello</h1>"|e }}
{{ "<h1>Hello</h1>"|escape }}

{# trim filter #}
{{ "   hello   "|trim }}

{# striptags filter #}
{{ "<h1>Hello</h1>"|striptags }}

{# slashes filter #}
{{ "'this is a string'"|slashes }}

{# stripslashes filter #}
{{ "\'this is a string\'"|stripslashes }}

{# capitalize filter #}
{{ "hello"|capitalize }}

{# lower filter #}
{{ "HELLO"|lower }}

{# upper filter #}
{{ "hello"|upper }}

{# length filter #}
{{ "robots"|length }}
{{ [1, 2, 3]|length }}

{# nl2br filter #}
{{ "some\ntext"|nl2br }}

{# sort filter #}
{% set sorted=[3, 1, 2]|sort %}

{# keys filter #}
{% set keys=['first': 1, 'second': 2, 'third': 3]|keys %}

{# json_encode filter #}
{% robots|json_encode %}

{# json_decode filter #}
{% set decoded='{"one":1,"two":2,"three":3}'|json_decode %}

{# url_encode filter #}
{{ post.permanent_link|url_encode }}

{# convert_encoding filter #}
{{ "désolé"|convert_encoding('utf8', 'latin1') }}


{# Comments #}
{# note: this is a comment
    {% set price = 100; %}
#}


{# Loops #}

{# Loop for #}
{% for robot in robots %}
    {{ robot.name|e }}
{% endfor  %}

{# Loop for with keys #}
{% for key, value in robots %}
    {{ value.name|e }}
{% endfor  %}

{# Loop with else condition #}
{% for key, value in robots %}
    {{ value.name|e }}
{% else %}
    There are no robots to show
{% endfor  %}

{# Break loop control #}
{% break %}

{# If statement #}
{% if robot.type == "cyborg" %}
    {{ robot.name|e }}
{% endif %}

{# If else statement #}
{% if robot.type == "cyborg" %}
    {{ robot.name|e }}
{% else %}
    {{ robot.name|e }} (not a cyborg)
{% endif %}

{# Elseif statement #}
{% if robot.type == "cyborg" %}
    {{ robot.name|e }}
{% elseif robot.type == "virtual" %}
    Robot is virtual
{% elseif robot.type == "mechanical" %}
    Robot is mechanical
{% else %}
    {{ robot.name|e }} (not a cyborg)
{% endif %}


{# Loop context #}

{# The current iteration of the loop. (1 indexed) #}
loop.index

{# The current iteration of the loop. (0 indexed) #}
loop.index0

{# The number of iterations from the end of the loop (1 indexed) #}
loop.revindex

{# The number of iterations from the end of the loop (0 indexed) #}
loop.revindex0

{# True if in the first iteration. #}
loop.first

{# True if in the last iteration. #}
loop.last

{# The number of items to iterate #}
loop.length

{# Setting values to var #}
{% set fruits = ['Apple', 'Banana', 'Orange'] %}
{% set name = robot.name %}

{# Multiple assignments #}
{% set fruits = ['Apple', 'Banana', 'Orange'], name = robot.name, active = true %}

{# Compound assignment #}
{% set price += 100.00 %}
{% set age *= 5 %}

{# Simple expression #}
{{ (1 + 1) * 2 }}

{# Expression evaluated without be printed #}
{% do (1 + 1) * 2 %}


{# Arrays #}

{# Simple array #}
{{ ['Apple', 'Banana', 'Orange'] }}

{# Other way simple array #}
{{ ['Apple', 1, 2.5, false, null] }}

{# Multidimensional array #}
{{ [[1, 2], [3, 4], [5, 6]] }}

{# Hash-style array #}
{{ ['first': 1, 'second': 4/2, 'third': '3'] }}

{# Curly braces to define arrays #}
{% set myArray = {'Apple', 'Banana', 'Orange'} %}


{# Operators #}

{# Return true if the left or right operand is evaluated as true #}
or

{# Return true if both left and right operands are evaluated as true #}
and

{# Negates an expression #}
not

{# Parenthesis groups expressions #}
(expr)

{# Concatenates both operands {{ “hello ” ~ “world” }} #}
~

{# Applies a filter in the right operand to the left {{ “hello”|uppercase }} #}
|

{# Creates a range {{ ‘a’..’z’ }} {{ 1..10 }} #}
..

{# Same as == (equals), also performs tests #}
is

{# To check if an expression is contained into other expressions if “a” in “abc” #}
in

{# Same as != (not equals) #}
is not

{# Ternary operator. The same as the PHP ternary operator #}
‘a’ ? ‘b’ : ‘c’

{# Increments a value #}
++

{# Decrements a value #}
--


{# Built-in tests available #}

{# Checks if a variable is defined (isset) #}
defined

{# Checks if a variable is empty #}
empty

{# Checks if a numeric value is even #}
even

{# Checks if a numeric value is odd #}
odd

{# Checks if value is numeric #}
numeric

{# Checks if value is scalar (not an array or object) #}
scalar

{# Checks if a value is iterable. Can be traversed by a “for” statement #}
iterable

{# Checks if a value is divisible by other value #}
divisibleby

{# Checks if a value is identical to other value #}
sameas

{# Checks if a value is of the specified type #}
type


{# Macros #}

{%- macro related_bar(related_links) %}
    {# Generate html links #}
{%- endmacro %}

{# Print related links #}
{{ related_bar(links) }}


{# Tag Helpers #}

{# Include js file #}
{{ javascript_include("js/jquery.js") }}

{# Tags helpers #}
Phalcon\Tag::linkTo                     link_to()
Phalcon\Tag::textField                  text_field()
Phalcon\Tag::passwordField              password_field()
Phalcon\Tag::hiddenField                hidden_field()
Phalcon\Tag::fileField                  file_field()
Phalcon\Tag::checkField                 check_field()
Phalcon\Tag::radioField                 radio_field()
Phalcon\Tag::dateField                  date_field()
Phalcon\Tag::emailField                 email_field()
Phalcon\Tag::numberField                number_field()
Phalcon\Tag::submitButton               submit_button()
Phalcon\Tag::selectStatic               select_static()
Phalcon\Tag::select                     select()
Phalcon\Tag::textArea                   text_area()
Phalcon\Tag::form                       form()
Phalcon\Tag::endForm                    end_form()
Phalcon\Tag::getTitle                   get_title()
Phalcon\Tag::stylesheetLink             stylesheet_link()
Phalcon\Tag::javascriptInclude          javascript_include()
Phalcon\Tag::image                      image()
Phalcon\Tag::friendlyTitle              friendly_title()


{# Functions #}

{# Includes the content produced in a previous rendering stage #}
content

{# Same as ‘content’ #}
get_content

{# Dynamically loads a partial view in the current template #}
partial

{# Render the contents of the parent block #}
super

{# Calls the PHP function with the same name #}
time

{# Calls the PHP function with the same name #}
date

{# Calls the PHP function ‘var_dump’ #}
dump

{# Returns the current version of the framework #}
version

{# Reads a PHP constant #}
constant

{# Generate a URL using the ‘url’ service #}
url


{# View Integration #}

{# Simple include of a partial #}
{{ partial("partials/footer") }}

{# Passing extra variables #}
{{ partial("partials/footer", ['links': $links]) }}

{# Simple include of a partial #}
{% include "partials/footer" %}

{# Passing extra variables #}
{% include "partials/footer" with ['links': links] %}


{# Template Inheritance  #}

{# Blocks for hierarchy #}

{# templates/base.volt #}
{% block head %}
    {# Your content here #}
{% endblock %}

{# templates/index1.volt #}
{% extends "templates/base.volt" %}
{% block head %}
    {# Include this in head #}
{% endblock %}

{# Keep values from father #}
{{ super() }}


{# Autoescape mode #}

{# Autoescaped true #}
{% autoescape true %}
    {# code here #}
{% endautoescape %}

{# Autoescaped false #}
{% autoescape false %}
    {# code here #}
{% endautoescape %}

{# Caching view fragments #}

{# Cache view #}
{% cache "sidebar" %}
    
{% endcache %}

{# cache the sidebar by 1 hour #}
{% cache "sidebar" 3600 %}
    
{% endcache %}

{# Cache with expresion #}
{% cache ("article-" ~ post.id) 3600 %}
    
{% endcache %}


{# Inject service #}

{# Inject the 'flash' service #}
{{ flash.output() }}
                
            

DI/IOC

Pending contribution...

Events Management

Pending contribution...

Encryption

Pending contribution...

HTTP Request

                
// Verify if its Post or Ajax request
$request = new Phalcon\Http\Request();
if ($request->isPost()) {
    if ($request->isAjax()) {
            echo 'Request was made using POST and AJAX';
    }
}

// Gets a variable from the $_REQUEST superglobal applying filters if needed. If no parameters are given the $_REQUEST superglobal is returned

//Returns value from $_REQUEST["user_email"] without sanitizing
$userEmail = $request->get("user_email");

//Returns value from $_REQUEST["user_email"] with sanitizing
$userEmail = $request->get("user_email", "email");

// Gets a variable from the $_POST superglobal applying filters if needed If no parameters are given the $_POST superglobal is returned

//Returns value from $_POST["user_email"] without sanitizing
$userEmail = $request->getPost("user_email");

//Returns value from $_POST["user_email"] with sanitizing
$userEmail = $request->getPost("user_email", "email");

// Gets a variable from put request

$userEmail = $request->getPut("user_email");

$userEmail = $request->getPut("user_email", "email");

// Gets variable from $_GET superglobal applying filters if needed If no parameters are given the $_GET superglobal is returned

//Returns value from $_GET["id"] without sanitizing
$id = $request->getQuery("id");

//Returns value from $_GET["id"] with sanitizing
$id = $request->getQuery("id", "int");

//Returns value from $_GET["id"] with a default value
$id = $request->getQuery("id", null, 150);

// Gets HTTP header from request data

$request->getHeader('Name');

// Gets information about schema, host and port used by the request

$request->getClientAddress();

// Checks whether HTTP method is POST. if $_SERVER[‘REQUEST_METHOD’]==’POST’ || GET || PUT || PATCH || HEAD || DELETE  || OPTIONS

$request->isPost();
$request->isGet();
$request->isPut();


                
            

Response

Pending contribution...

Cookies

                
// Check if cookie exists
$this->cookies->has("session-data");

// Get cookie by name
$myCookie = $this->cookies->get("session-data");

// Get the cookie attributes
$myCookie->getValue();         //value
$myCookie->getPath();          //site path
$myCookie->getName();          //cookie name
$myCookie->getExpiration();    //expire time (unix timestamp) int
$myCookie->getDomain();        //cookie domain
$myCookie->getHttpOnly();      //is http only
$myCookie->getSecure();        //is secured


/*
 * Set the cookie
 * Full set of params:
 * set(
 *      mixed $name,
 *      [mixed $value],
 *      [mixed $expire],
 *      [mixed $path],
 *      [mixed $secure],
 *      [mixed $domain],
 *      [mixed $httpOnly]
 * )
 */
$this->cookies->set(
    "session-data",
    "some value",
    time() + 3600
);

// Delete the cookie
$this->cookies->get("session-data")->delete();


// By default cookies are encrypted automatically

// Disable encryption
use Phalcon\Http\Response\Cookies;

$di->set(
    "cookies",
    function () {
        $cookies = new Cookies();

        $cookies->useEncryption(false);

        return $cookies;
    }
);

// Use encryption with own key in Crypt service
use Phalcon\Crypt;

$di->set(
    "crypt",
    function () {
        $crypt = new Crypt();

        $crypt->setKey('@2sdj8%%dp?.to/..j123D$'); // Use your own key!

        return $crypt;
    }
);

                
            

Escaping

                
use Phalcon\Escaper;

// Create an escaper
$escaper = new Escaper();

/*
 * Settings
 */

// Set the encoding to be used by the escaper
$escaper->setEncoding('utf-8');

// Set the HTML quoting type for htmlspecialchars
$escaper->setHtmlQuoteType(ENT_XHTML);

// Set the double_encode to be used by the escaper
$escaper->setDoubleEncode(false);

/*
 * Escaping examples
 */

$maliciousData = $_GET['data'];

// Escaping HTML
$secureData = $escaper->escapeHtml($maliciousParam);

// Escaping HTML Attributes
$secureData = $escaper->escapeHtmlAttr($maliciousParam);

// Escaping CSS
$secureData = $escaper->escapeCss($maliciousParam);

// Escaping JavaScript
$secureData = $escaper->escapeJs($maliciousParam);

// Escaping URLs
$secureData = $escaper->escapeUrl($maliciousParam);

/*
 * Useful functionality
 */

// Get the internal encoding used by the escaper
$escaper->getEncoding();

// Detect the character encoding of a string to be handled by an encoder Special-handling for chr(172) and chr(128) to chr(159) which fail to be detected by mb_detect_encoding()
$escaper->detectEncoding($maliciousParam)

// Utility to normalize a string’s encoding to UTF-32
$escaper->normalizeEncoding($maliciousParam)

                
            

Filtering

Pending contribution...

Forms Builder

Pending contribution...

Validation

Pending contribution...

Flash Messages

Pending contribution...

Cache

Pending contribution...

Pagination

                
// Current page from request
$currentPage = $this->request->getQuery('page', 'int', 1);


/*
 * Pagination for model
 */
...
use Phalcon\Paginator\Adapter\Model as PaginatorModel;
...
// The data from database to paginate
$articles = Articles::find();

$paginator = new PaginatorModel(
    [
        "data"  => $articles,
        "limit" => 3,
        "page"  => $currentPage
    ]
);



/*
 * Pagination for arrays
 */
...
use Phalcon\Paginator\Adapter\NativeArray as PaginatorArray;
...
// Passing an array as data
$paginator = new PaginatorArray(
    [
        "data"  => [
            ["id" => 1, "name" => "Article 1"],
            ["id" => 2, "name" => "Article 2"],
            ["id" => 3, "name" => "Article 3"]
        ],
        "limit" => 2,
        "page"  => $currentPage,
    ]
);



/*
 * Pagination for QueryBuilder
 */
...
use Phalcon\Paginator\Adapter\QueryBuilder as PaginatorQueryBuilder;
...
$builder = $this->modelsManager->createBuilder()
    ->columns("id, name")
    ->from("Articles")
    ->orderBy("name");

// Passing a QueryBuilder object as data
$paginator = new PaginatorQueryBuilder(
    [
        "builder" => $builder,
        "limit"   => 20,
        "page"    => $currentPage,
    ]
);


// Get the result for current page
$pageData = $paginator->getPaginate();

/*
 * $pageData has the following attributes:
 *
 * $pageData->items - your items from model per page (as much as %limit%)
 * $pageData->before - previous page
 * $pageData->next - next page
 * $pageData->last - last page
 * $pageData->current - current page
 * $pageData->total_pages - total number of pages
 * $pageData->total_items - total number of items
 *
 */
		        
            

Annotations

                
/**
 * Simple Annotation
 *
 * @SomeAnnotation
 */

/**
 * Annotation with parameters
 *
 * @SomeAnnotation("hello", "world", 1, 2, 3, false, true)
 */

/**
 * Annotation with named parameters
 *
 * @SomeAnnotation(first="hello", second="world", third=1)
 * @SomeAnnotation(first: "hello", second: "world", third: 1)
 */

/**
 * Passing an array
 *
 * @SomeAnnotation([1, 2, 3, 4])
 * @SomeAnnotation({1, 2, 3, 4})
 */

/**
 * Passing a hash as parameter
 *
 * @SomeAnnotation({first=1, second=2, third=3})
 * @SomeAnnotation({'first'=1, 'second'=2, 'third'=3})
 * @SomeAnnotation({'first': 1, 'second': 2, 'third': 3})
 * @SomeAnnotation(['first': 1, 'second': 2, 'third': 3])
 */

/**
 * Nested arrays/hashes
 *
 * @SomeAnnotation({"name"="SomeName", "other"={
 *      "foo1": "bar1", "foo2": "bar2", {1, 2, 3},
 * }})
 */

/**
 * Nested Annotations
 *
 * @SomeAnnotation(first=@AnotherAnnotation(1, 2, 3))
 */

// A simple example of reading annotations

$reader = new \Phalcon\Annotations\Adapter\Memory();
$reflector = $reader->get('Example');
$annotations = $reflector->getClassAnnotations();

foreach ($annotations as $annotation) {
    echo $annotation->getName(), PHP_EOL;
    echo $annotation->numberArguments(), PHP_EOL;
    print_r($annotation->getArguments());
}
                
                

Security

                
// Storing a hased password
use Phalcon\Mvc\Controller;

$user = new Users();

$username = $this->request->getPost('username');
$password = $this->request->getPost('password');

$user->username = $username;
$user->password = $this->security->hash($password);

$user->save();


// A basic example of validating a login attempt
use Phalcon\Mvc\Controller;

$username = $this->request->getPost('username');
$password = $this->request->getPost('password');

$user = Users::findFirst([
    conditions => "username = ?1",
    bind => [1 => $username]
]);

if ($user) {
    if ($this->security->checkHash($password, $user->password)) {
        // The password is valid
    }
}


// Setting a csrf token in a form
<input type="hidden" name="<?=$this->security->getTokenKey()?>" value="<?=$this->security->getToken()?>"/>


// Checking a csrf token after a form submit
use Phalcon\Mvc\Controller;

if ($this->request->isPost()) {
    if ($this->security->checkToken()) {
        // The token is valid
    }
}

                
            

Translations

Pending contribution...

Assets Management

Pending contribution...

Universal Auto-Loader

                
// Setting namespaces
$loader->registerNamespaces(
    array(
       'Store\Admin\Controllers'    => "../bundles/admin/controllers/",
       'Store\Admin\Models'    => "../bundles/admin/models/",
    )
);
                
            

Logging

Pending contribution...

CLI

Pending contribution...