Tutorial - Vökuró


Vökuró is a sammple application, showcasing a typical web application written in Phalcon. This application focuses on: - User Login (security) - User Signup (security) - User Permissions - User management

You can use Vökuró as a starting point for your application and enhance it further to meet your needs. By no means this is a perfect application and it does not fit all needs.

This tutorial assumes that you are familiar with the concepts of the Model View Controller design pattern.



In order to install the application, you can either clone or download it from GitHub. You can visit the GitHub page, download the application and then unzip it to a directory on your machine. Alternatively you can use git clone:

git clone


There are some prerequisites for the Vökuró to run. You will need to have PHP >= 7.2 installed on your machine and the following extensions: - ctype - curl - dom - json - iconv - igbinary - mbstring - memcached - opcache - openssl - pdo - pdo_mysql - psr - session - simplexml - tokenizer - xml - xmlwriter - zip

Phalcon needs to be installed. Head over to the if you need help with installing Phalcon. Note that Phalcon v4 requires the PSR extension to be installed and loaded **before** Phalcon. To install PSR you can check the [php-psr]( GitHub page.

Finally, you will also need to ensure that you have updated the composer packages (see section below).


If all the above requirements are satisfied, you can run the application using PHP’s built in web server by issuing the following command on a terminal:

php -S localhost:8080 -t public/

The above command will start serving the site for localhost at the port 8080. You can change those settings to suit your needs. Alternatively you can set up your site in Apache or nginX using a virtual host. Please consult the relevant documentation on how to set up a virtual host for these web servers.


In the resopurces folder you will find a Dockerfile which allows you to quickly set up the environment and run the application.

add how


In the resources folder you will also find a boxfile.yml file that allows you to use nanobox in order to set up the environment quickly. All you have to do is copy the file to the root of your directory and run nanobox run php-server. Once the application is set up for the first time, you will be able to navigate to the IP address presented on screen and work with the application.

For more information on how to set up nanobox, check our [Environments Nanobox][environments-nanobox] page as well as the Nanobox Guides page

In this tutorial, we assume that your application has been downloaded or cloned in a directory called vokuro.


Looking at the structure of the application we have the following:

Directory Описание
.ci Files necessary for setting services for the CI
configs Configuration files
db Holds the migrations for the databsae
public Entry point for the application, css, js, images
resources Docker/nanobox files for setting the application
src Where the application lives (controllers, forms etc.)
src/Controllers Controllers
src/Forms Forms
src/Models Database Models
src/Plugins Plugins
src/Providers Providers: setting services in the DI container
tests Tests
themes Themes/views for easy customization
themes/vokuro Default theme for the application
var Various supporting files
var/cache Cache files
var/logs Logs
vendor Vendor/composer based libraries



Vökuró uses the popular Dotenv library by Vance Lucas. The library utilizes a .env file located in your root folder, which holds configuration parameters such as the database server host, username, password etc. There is a .env.example file that comes with Vökuró that you can copy and rename to .env and then edit it to match your environment. You need to do this first so that your application can run properly.

The available options are:

Параметр Описание
APP_CRYPT_SALT Random and long string that is used by the Phalcon\Crypt component to produce passwords and any additional security features
APP_BASE_URI Usually / if your web server points directly to the Vökuró directory. If you have installed Vökuró in a sub directory, you can adjust the base URI
APP_PUBLIC_URL The public URL of the application. This is used for the emails.
DB_ADAPTER The database adapter. The available adapters are: mysql, pgsql, sqlite. Please ensure that the relevant extensions for the database are installed in your system.
DB_HOST The database host
DB_PORT The database port
DB_USERNAME The database username
DB_PASSWORD The database password
DB_NAME The database name
MAIL_FROM_NAME The FROM name when sending emails
MAIL_FROM_EMAIL The FROM email when sending emails
MAIL_SMTP_SECURITY The SMTP security (e.g. tls)
CODECEPTION_URL The Codeception server for tests. If you run the tests locally this should be
CODECEPTION_PORT The Codeception port

Once the configuration file is in place, visiting the IP address will present a screen similar to this:


You also need to initialize the database. Vökuró uses the popular library Phinx by Rob Morgan (now the Cake Foundation). The library uses its own configuration file (phinx.php), but for Vökuró you don’t need to adjust any settings since phinx.php reads the .env file to retrieve the configuration settings. This allows you to set your configuration parameters in one place.

We will now need to run the migrations. To check the status of our database:

/app $ ./vendor/bin/phinx status

You will see the following screen:

To initialize the database we need to run the migrations:

/app $ ./vendor/bin/phinx migrate

The screen will show the operation:

And the status command will now show all green:


Looking at the config/ folder, you will notice four files. There is no need for you to change these files to start the application but if you wish to customize it, this is the place to visit. The acl.php file returns an array of routes that controls which routes are visible to only logged in users.

The current setup will require a user to be logged in, if they visit these routes:

  • users/index
  • users/search
  • users/edit
  • users/create
  • users/delete
  • users/changePassword
  • profiles/index
  • profiles/search
  • profiles/edit
  • profiles/create
  • profiles/delete
  • permissions/index

If you use Vökuró as a starting point for your own application, you will need to modify this file to add or remove routes so as to ensure that your protected routes are behind the login mechanism.

Keeping the private routes in an array is efficient and easy to maintain for a small to medium application. Once your application starts growing, you might need to consider a different technique to keep your private routes such as the database with a caching mechanism.


This file holds all configuration parameters that Vökuró needs. Usually you will not need to change this file, since the elements of the array are set by the .env file and Dotenv. However, you might want to change the location of your logs or other paths, should you decide to change the directory structure.

One of the elements you might want to consider when working with Vökuró on your local machine is the useMail and set it to false. This will instruct Vökuró not to try to connect to a mail server and send an email when a user registers on the site.


This file contains all the providers that Vökuró needs. This is a list of classes in the application, that registers the particular class in the DI container. If you need to register new components to your DI container, you can add them to the array of this file.


This file contains the routes that Vökuró understands. The router already registers the default routes, so any routes defined in routes.php are specific ones. You can add any non standard routes you need, when customizing Vökuró, in this file. As a reminder, the default routes are:



As mentioned above, Vökuró uses classes called Providers in order to register services in the DI container. This is just one way to register services in the DI container, nothing stops you from putting all these registrations in a single file.

For Vökuró we decided to use one file per service as well as a providers.php (see above) as the registration configuration array for these services. This allows us to have much smaller chunks of code, organized in a separate file per service, as well as an array that allows us to register or unregister/disable a service without removing files. All we need to do is change the providers.php array.

The provider classes are located in src/Providers. Each of the provider classes implements the Phalcon\Di\ServiceProviderInterface interface. For more information, see the bootstrapping section below.


Vökuró uses composer to download and install supplemental PHP libraries. The libraries used are:

Looking at composer.json the required packages are:

"require": {
    "php": ">=7.2",
    "ext-openssl": "*",
    "ext-phalcon": "~4.0.0-beta.2",
    "robmorgan/phinx": "^0.11.1",
    "swiftmailer/swiftmailer": "^5.4",
    "vlucas/phpdotenv": "^3.4"

If this is a fresh installation you can run

composer install

of if you want to upgrade the existing installations of the above packages:

composer update

For more information about composer, you can visit their documentation page.



The entry point of our application is public/index.php. This file contains the necessary code that bootstraps the application and runs it. It also serves as a single point of entry to our application, making things much easier for us when we want to trap errors, protect files etc.

Let’s look at the code:


use Vokuro\Application as VokuroApplication;

$rootPath = dirname(__DIR__);

try {
    require_once $rootPath . '/vendor/autoload.php';

     * Load .env configurations

     * Run Vökuró!
    echo (new VokuroApplication($rootPath))->run();
} catch (Exception $e) {
    echo $e->getMessage(), '<br>';
    echo nl2br(htmlentities($e->getTraceAsString()));

First of all we ensure that we have full error reporting. You can of course change this if you wish, or rework the code where error reporting is controlled by an entry in your .env file.

A try/catch block wraps all operations. This ensures that all errors are caught and displayed on screen.

NOTE You will need to rework the code to enhance security. Currently, if an error happens with the database, the catch code will echo on screen the database credentials with the exception. This code is intended as a tutorial not a full scale production application

We ensure that we have access to all the supporting libraries by loading composer’s autoloader. In the composer.json we have also defined the autoload entry, directing the autoloader to load any Vokuro namespaced classes from the src folder.

"autoload": {
    "psr-4": {
        "Vokuro\\": "app/"
    "files": [

Then we load the environment variables as defined in our .env file by calling the


Finally, we run our application.


All the application logic is wrapped in the Vokuro\Application class. Let’s see how this is done:


namespace Vokuro;

use Exception;
use Phalcon\Application\AbstractApplication;
use Phalcon\Di\DiInterface;
use Phalcon\Di\FactoryDefault;
use Phalcon\Di\ServiceProviderInterface;
use Phalcon\Mvc\Application as MvcApplication;

 * Vökuró Application
class Application
    const APPLICATION_PROVIDER = 'bootstrap';

     * @var AbstractApplication
    protected $app;

     * @var DiInterface
    protected $di;

     * Project root path
     * @var string
    protected $rootPath;

     * @param string $rootPath
     * @throws Exception
    public function __construct(string $rootPath)
        $this->di       = new FactoryDefault();
        $this->app      = $this->createApplication();
        $this->rootPath = $rootPath;

        $this->di->setShared(self::APPLICATION_PROVIDER, $this);


     * Run Vökuró Application
     * @return string
     * @throws Exception
    public function run(): string
        return (string) $this

     * Get Project root path
     * @return string
    public function getRootPath(): string
        return $this->rootPath;

     * @return AbstractApplication
    protected function createApplication(): AbstractApplication
        return new MvcApplication($this->di);

     * @throws Exception
    protected function initializeProviders(): void
        $filename = $this->rootPath 
                 . '/configs/providers.php';
        if (!file_exists($filename) || !is_readable($filename)) {
            throw new Exception(
                'File providers.php does not exist or is not readable.'

        $providers = include_once $filename;
        foreach ($providers as $providerClass) {
            /** @var ServiceProviderInterface $provider */
            $provider = new $providerClass;

The constructor of the class first creates a new DI container and store it in a local property. We are using the Phalcon\Di\FactoryDefault one, which has a lot of services already registered for us.

We then create a new Phalcon\Mvc\Application and store it in a property also. We also store the root path because it is useful throughout the application.

We then register this class (the Vokuro\Application) in the Di container using the name bootstrap. This allows us to have access to this class from any part of our application through the Di container.

The last thing we do is to register all the providers. Although the Phalcon\Di\FactoryDefault object has a lot of services already registered for us, we still need to register providers that suit the needs of our application. As mentioned above, each provider class implements the Phalcon\Di\ServiceProviderInterface interface, so we can load each class and call the register() method with the Di container to register each service. We therefore first load the configuration array config/providers.php and then loop through the entries and register each provider in turn.

The available providers are:

Provider Описание
AclProvider Permissons
AuthProvider Authentication
ConfigProvider Configuration values
CryptProvider Encryption
DbProvider Database access
DispatcherProvider Dispatcher - what controller to call for what URL
FlashProvider Flash messages for feedback to the user
LoggerProvider Logger for errors and other information
MailProvider Mail support
ModelsMetadataProvider Metadata for models
RouterProvider Routes
SecurityProvider Security
SessionBagProvider Session data
SessionProvider Session data
UrlProvider URL handling
ViewProvider Views and view engine

run() will now handle the REQUEST_URI, handle it and return the content back. Internally the application will calculate the route based on the request, and dispatch the relevant controller and view before returning the result of this operation back to the user as a response.









Load Classes and Dependencies

This project uses Phalcon\Loader to load controllers, models, forms, etc. within the project and composer to load the project’s dependencies. So, the first thing you have to do before execute Vökuró is install its dependencies via composer. Assuming you have it correctly installed, type the following command in the console:

cd vokuro
composer install

Vökuró sends emails to confirm the sign up of registered users using Swift, the composer.json looks like:

    "require" : {
        "php": ">=5.5.0",
        "ext-phalcon": ">=3.0.0",
        "swiftmailer/swiftmailer": "^5.4",
        "amazonwebservices/aws-sdk-for-php": "~1.0"

Now, there is a file called app/config/loader.php where all the auto-loading stuff is set up. At the end of this file you can see that the composer autoloader is included enabling the application to autoload any of the classes in the downloaded dependencies:


// ...

// Use composer autoloader to load vendor classes
require_once BASE_PATH . '/vendor/autoload.php';

Moreover, Vökuró, unlike the INVO, utilizes namespaces for controllers and models which is the recommended practice to structure a project. This way the autoloader looks slightly different than the one we saw before (app/config/loader.php):


use Phalcon\Loader;

$loader = new Loader();

        'Vokuro\Models'      => $config->application->modelsDir,
        'Vokuro\Controllers' => $config->application->controllersDir,
        'Vokuro\Forms'       => $config->application->formsDir,
        'Vokuro'             => $config->application->libraryDir,


// ...

Instead of using registerDirectories(), we use registerNamespaces(). Every namespace points to a directory defined in the configuration file (app/config/config.php). For instance the namespace Vokuro\Controllers points to app/controllers so all the classes required by the application within this namespace requires it in its definition:


namespace Vokuro\Controllers;

class AboutController extends ControllerBase
    // ...

Sign Up

First, let’s check how users are registered in Vökuró. When a user clicks the Create an Account button, the controller SessionController is invoked and the action signup is executed:


namespace Vokuro\Controllers;

use Vokuro\Forms\SignUpForm;

class SessionController extends ControllerBase
    public function signupAction()
        $form = new SignUpForm();

        // ...

        $this->view->form = $form;

This action simply pass a form instance of SignUpForm to the view, which itself is rendered to allow the user enter the login details:

{{ form('class': 'form-search') }}

        Sign Up

    <p>{{ form.label('name') }}</p>
        {{ form.render('name') }}
        {{ form.messages('name') }}

    <p>{{ form.label('email') }}</p>
        {{ form.render('email') }}
        {{ form.messages('email') }}

    <p>{{ form.label('password') }}</p>
        {{ form.render('password') }}
        {{ form.messages('password') }}

    <p>{{ form.label('confirmPassword') }}</p>
        {{ form.render('confirmPassword') }}
        {{ form.messages('confirmPassword') }}

        {{ form.render('terms') }} {{ form.label('terms') }}
        {{ form.messages('terms') }}

    <p>{{ form.render('Sign Up') }}</p>

    {{ form.render('csrf', ['value': security.getToken()]) }}
    {{ form.messages('csrf') }}


{{ endForm() }}