We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Whats is the best way to write a fast load bootstrap .

Hi , I want to know what the best way to write a fast project in Phalcon , I'm writing a project that should response more than 1000 request in second , consider I'll use caching but I wonder about the whole Phalcon framework , I don't know what's the best model to write a very fast bootstrap , for example useing Phalcon\DI\FactoryDefault() or not ? . How we should define our services ? with anonymous function or array style ?

any Idea ?

edited Jan '15

Common and quite good variant.

/public/index.php:

<?php

use \Phalcon\DI\FactoryDefault as PhDi;

define('DOCROOT', realpath(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR);

try {
    include DOCROOT . 'common/library/bootstrap.php';
    $di = new PhDi;
    $app = new Bootstrap($di);
    echo $app->run();

} catch (\Phalcon\Exception $e) {
    echo $e->getMessage();
} catch (PDOException $e){
    echo $e->getMessage();
}

/common/library/bootstrap.php

<?php

use Phalcon\DI\FactoryDefault         as PhDi;
use Phalcon\Exception                 as PhException;
use Phalcon\Session\Adapter\Files     as PhSession;
use Phalcon\Config                    as PhConfig;
use Phalcon\Mvc\Url                   as PhUrl;
use Phalcon\Mvc\Router                as PhRouter;
use Phalcon\Db\Adapter\Pdo\Mysql      as PhMysql;
use Phalcon\Events\Manager            as PhEvents;
use Phalcon\Logger\Adapter\File       as PhLogger;
use Phalcon\Mvc\Model\Metadata\Memory as PhMetadataMemory;
use Phalcon\Assets\Manager            as PhAssets;
use Phalcon\Mvc\View                  as PhView;
use Phalcon\Mvc\View\Engine\Volt      as PhVolt;
use Phalcon\Flash\Session             as PhFlash;
use Phalcon\Crypt                     as PhCrypt;
use Phalcon\Security                  as PhSecurity;
use Phalcon\Version                   as PhVersion;
use Phalcon\Cache\Frontend\Output     as PhCacheFront;
use Phalcon\Cache\Backend\File        as PhCacheBackFile;
use Phalcon\Cache\Backend\Apc         as PhCacheBackApc;
use Phalcon\Mvc\Application           as PhApplication;

/**
 * Bootstraps the application
 */
class Bootstrap
{
    /**
     * Standard Phalcon\Di
     * @var PhDi
     */
    private $di;

    /**
     * Bootstrap constructor
     *
     * @param PhDi $di Standard Phalcon\Di
     */
    public function __construct($di)
    {
        // Handle the request
        $this->di = $di;
    }

    /**
     * Runs the application performing all initializations
     *
     * @param array $options
     * @return mixed
     */
    public function run(array $options = [])
    {
        $loaders = [
            'environment',
            'session',
            'config',
            'loader',
            'url',
            'router',
            'database',
            'modelsMetadata',
            'logger',
            'assets',
            'view',
            'flash',
            'crypt',
            'security',
            'cache',
        ];

        try {
            foreach ($loaders as $service) {
                $function = 'init' . ucfirst($service);
                $this->$function($options);
            }

            $application = new PhApplication();
            $application->setDI($this->di);

            $config = $this->di['config'];
            $application->registerModules($config->modules->toArray());

            return $application->handle()->getContent();
        } catch (PhException $e) {
            echo $e->getMessage();
        } catch (\PDOException $e) {
            echo $e->getMessage();
        }
    }

    /**
     * Initializes the Environment
     *
     * @param array $options
     */
    protected function initEnvironment(array $options = [])
    {
        /**
         * @const APP_START_TIME The start time of the application, used for profiling
         */
        define('APP_START_TIME', microtime(TRUE));

        /**
         * @const DEV_IP Developer IP mask
         */
        define('DEV_IP', '192.168.');

        /**
         * @const APP_PRODUCTION Production stage
         */
        define('APP_PRODUCTION', 'production');

        /**
         * @const APP_DEVELOPMENT Development stage
         */
        define('APP_DEVELOPMENT', 'development');

        /**
         * @const APP_STAGING Staging stage
         */
        define('APP_STAGING', 'staging');

        /**
         * @const APP_TESTING Testing stage
         */
        define('APP_TESTING', 'testing');

        /**
         * @const DS shortcut for DIRECTORY_SEPARATOR
         */
        define('DS', DIRECTORY_SEPARATOR);

        /**
         * @const APP_START_MEMORY The memory usage at the start of the application, used for profiling
         */
        define('APP_START_MEMORY', memory_get_usage(defined('HHVM_VERSION')));

        // Set TZ (Kiyv +0200)
        date_default_timezone_set('Etc/GMT-2');  // CHANGE IT IF NECESSARY

        // Set the default locale
        setlocale(LC_ALL, 'ru_RU.utf-8'); // CHANGE IT IF NECESSARY

        // Set internal character encoding to UTF-8.
        mb_internal_encoding('UTF-8');

        // Set the mb_substitute_character to "none"
        mb_substitute_character('none');

        // Set environment variable
        if (isset($_SERVER['APP_ENV'])) {
            // Get environment variable from $_SERVER, .htaccess, apache.conf, nginx.conf, etc.
            $env = $_SERVER['APP_ENV'];
        } elseif (get_cfg_var('APP_ENV')) {
            // Get environment variable from php.ini or from ini_get('user_ini.filename')
            $env = get_cfg_var('APP_ENV');
        } else {
            $env = APP_PRODUCTION;
        }

        /**
         * @const APP_ENV Application environment
         */
        define('APP_ENV', strtolower($env));

        /**
         * @const PHALCONDEBUG Defining a debug or environment flag
         */
        defined('PHALCONDEBUG') || define('PHALCONDEBUG', APP_ENV === APP_DEVELOPMENT);

        /**
         * Include Composer autoloader
         */
        if (is_file(DOCROOT .'common' . DS . 'vendor' . DS . 'autoload.php')) {
            require_once(DOCROOT .'common' . DS . 'vendor' . DS . 'autoload.php');
        }
    }

    /**
     * Initializes the Session
     *
     * @param array $options
     */
    protected function initSession(array $options = [])
    {
        $this->di['session'] = function () {
            $session = new PhSession;
            $session->start();

            return $session;
        };
    }

    /**
     * Initializes the Config. Reads it from its location and
     * stores it in the Di container for easier access
     *
     * @param array $options
     */
    protected function initConfig($options = [])
    {
        $configFile  = require(DOCROOT . 'config/'.APP_ENV.'.php');

        // Create the new object
        $config = new PhConfig($configFile);

        // Store it in the Di container
        // Settings cones from the include
        $this->di['config'] = $config;
    }

    /**
     * Initializes the Loader
     *
     * @param array $options
     */
    protected function initLoader($options = [])
    {
        // Creates the autoloader
        $loader = require DOCROOT . 'config/loader.php';

        // Dump it in the DI to reuse it
        $this->di['loader'] = $loader;
    }

    /**
     * Initializes the Url
     *
     * @param array $options
     */
    protected function initUrl($options = [])
    {
        $config = $this->di['config'];
        $baseUrl = $config->application->baseUri;

        /**
         * The URL component is used to generate all kind of urls in the
         * application
         */
        $this->di['url'] = function () use ($baseUrl) {
            $url = new PhUrl();
            $url->setBaseUri($baseUrl);
            return $url;
        };
    }

    /**
     * Initializes the Router
     * @param array $options
     */
    protected function initRouter($options = [])
    {
        $config = $this->di['config'];
        $routes = $config['routes'];

        $this->di['router'] = function () use ($routes) {
            $router = new PhRouter(false);

            $router->notFound([
                'controller' => 'index',
                'action'     => 'route404'
            ]);

            $router->removeExtraSlashes(true);

            foreach ($routes as $route => $items) {
                $router->add($route, $items->params->toArray())
                    ->setName($items->name);
            }

            return $router;
        };
    }

    /**
     * Initializes the Database
     * @param array $options
     */
    protected function initDatabase($options = [])
    {
        $config = $this->di['config'];
        $dbConfig = $config->database->toArray();
        $logsDir = $config->application->logsDir;

        $this->di['db'] = function () use ($dbConfig, $logsDir) {
            $connection    = new PhMysql($dbConfig);
            $eventsManager = new PhEvents;
            $logger        = new PhLogger(sprintf('%s.log', $logsDir . date('Y-m-d').'-sql_debug'));
            $listener      = new \Your\Best\Listener\DbListener($logger);

            $eventsManager->attach('db', $listener);

            //Assign the eventsManager to the db adapter instance
            $connection->setEventsManager($eventsManager);

            return $connection;
        };
    }

    /**
     * Initializes the Models Metadata
     *
     * @param array $options
     */
    protected function initModelsMetadata($options = [])
    {
        $this->di['modelsMetadata'] = function () {
            return new PhMetadataMemory;
        };
    }

    /**
     * Initializes the Logger
     *
     * @param array $options
     */
    protected function initLogger($options = [])
    {
        $config = $this->di['config'];
        $logsDir = $config->application->logsDir;

        $this->di['logger'] = function() use($logsDir) {
            $logger = new PhLogger(sprintf('%s.log', $logsDir . date('Y-m-d')));

            return $logger;
        };
    }

    /**
     * Initializes the Assets
     *
     * @param array $options
     */
    protected function initAssets($options = [])
    {
        $this->di['assets'] = function() {
            $assets = new PhAssets;
            $assets
                ->addJs('js/jquery.min.js')
                ->addJs('js/bootstrap.min.js');

            $assets
                ->addCss('css/bootstrap.min.css')
                ->addCss('css/font-awesome.min.css');

            return $assets;
        };
    }

    /**
     * Initializes the View and Volt
     *
     * @param array $options
     */
    protected function initView($options = [])
    {
        $config = $this->di['config'];
        $di     = $this->di;

        $voltDir           = $config->volt->cacheDir;
        $compiledExt       = $config->volt->compiledExt;
        $compiledSeparator = $config->volt->separator;
        $debug             = $config->application->debug;

        $this->di['view'] = function () use ($voltDir, $compiledExt, $compiledSeparator, $debug, $di) {
            $view = new PhView;

            $view->registerEngines([
                '.volt' => function ($view , $di) use ($voltDir, $compiledExt, $compiledSeparator, $debug) {
                    $volt        = new PhVolt($view, $di);
                    $voltOptions = [
                        'compiledPath'      => $voltDir,
                        'compiledExtension' => $compiledExt,
                        'compiledSeparator' => $compiledSeparator
                    ];

                    if ($debug) {
                        $voltOptions['compileAlways'] = true;
                    }

                    $volt->setOptions($voltOptions);

                    $volt->getCompiler()
                        ->addFunction('strtotime', 'strtotime')
                        ->addFunction('isset', 'isset');

                    return $volt;
                },
                '.phtml' => 'Phalcon\Mvc\View\Engine\Php'
            ]);

            $view->setVar('version', PhVersion::get());

            return $view;
        };
    }

    /**
     * Initializes the Flash
     *
     * @param array $options
     */
    protected function initFlash($options = [])
    {
        $this->di['flash'] = function () {
            return new PhFlash([
                'error'   => 'alert alert-danger',
                'success' => 'alert alert-success',
                'notice'  => 'alert alert-info',
                'warning' => 'alert alert-warning'
            ]);
        };
    }

    /**
     * Initializes the Crypt
     *
     * @param array $options
     */
    protected function initCrypt($options = [])
    {
        $config = $this->di['config'];
        $key = $config->crypt->key;

        $this->di['crypt'] = function () use ($key) {
            $crypt = new PhCrypt;
            // Set a global encryption key
            $crypt->setKey($key);

            return $crypt;
        };
    }

    /**
     * Initializes the Security
     *
     * @param array $options
     */
    protected function initSecurity($options = [])
    {
        $this->di['security'] = function () {
            $security = new PhSecurity;
            // Set the password hashing factor to 12 rounds
            $security->setWorkFactor(12);

            return $security;
        };
    }

    /**
     * Initializes the Cache
     *
     * @param array $options
     */
    protected function initCache($options = [])
    {
        $config = $this->di['config'];
        $lifeTime = $config->cache->lifetime;
        $cacheDir = $config->cache->cacheDir;

        $this->di['viewCache'] = function () use ($lifeTime, $cacheDir) {
            // Get the parameters
            $frontCache = new PhCacheFront(['lifetime' => $lifeTime]);

            if (function_exists('apc_store')) {
                $cache = new PhCacheBackApc($frontCache);
            } else {
                $cache = new PhCacheBackFile($frontCache, ['cacheDir' => $cacheDir]);
            }

            return $cache;
        };
    }
}


1.7k

Thanks Serghei