Dependency Injection / Service Location Phalcon

Contoh berikut agak panjang, tapi menjelaskan mengapa penggunaan Dependency Injection dan Service Location. Pertama, mari kita beranggapan sedang mengembangkan sebuah komponen yang disebut SomeComponent. Komponen ini melakukan tugas yang tidak penting sekarang. Komponen tsb memiliki beberapa ketergantungan/Dependency yang berupa koneksi ke database.

Dalam contoh pertama ini, koneksi dibuat di dalam komponen. Pendekatan/cara ini tidak praktis; karena hal ini kita tidak dapat mengubah parameter koneksi atau jenis sistem database karena komponen hanya bekerja sebagaimana dibuat.

<?php

class SomeComponent
{

    /**
     * The instantiation of the connection is hardcoded inside
     * the component, therefore it's difficult replace it externally
     * or change its behavior
     */
    public function someDbTask()
    {
        $connection = new Connection(array(
            "host" => "localhost",
            "username" => "root",
            "password" => "secret",
            "dbname" => "invo"
        ));

        // ...
    }

}

$some = new SomeComponent();
$some->someDbTask();

Untuk mengatasi hal ini, kami telah membuat setter yang menyuntikkan ketergantungan eksternal sebelum menggunakannya. Untuk saat ini, ini tampaknya menjadi solusi yang baik:

<?php

class SomeComponent
{

    protected $_connection;

    /**
     * Sets the connection externally
     */
    public function setConnection($connection)
    {
        $this->_connection = $connection;
    }

    public function someDbTask()
    {
        $connection = $this->_connection;

        // ...
    }

}

$some = new SomeComponent();

//Create the connection
$connection = new Connection(array(
    "host" => "localhost",
    "username" => "root",
    "password" => "secret",
    "dbname" => "invo"
));

//Inject the connection in the component
$some->setConnection($connection);

$some->someDbTask();

Sekarang perhatikan bahwa kita menggunakan komponen ini di berbagai bagian dari aplikasi dan kemudian kita akan perlu untuk membuat koneksi beberapa kali sebelum diteruskan ke komponen. Menggunakan semacam registrasi global di mana kita bisa memperoleh instance koneksi dan tidak perlu membuat lagi seterusnya bisa memecahkan masalah ini:

<?php

class Registry
{

    /**
     * Returns the connection
     */
    public static function getConnection()
    {
       return new Connection(array(
            "host" => "localhost",
            "username" => "root",
            "password" => "secret",
            "dbname" => "invo"
        ));
    }

}

class SomeComponent
{

    protected $_connection;

    /**
     * Sets the connection externally
     */
    public function setConnection($connection)
    {
        $this->_connection = $connection;
    }

    public function someDbTask()
    {
        $connection = $this->_connection;

        // ...
    }

}

$some = new SomeComponent();

//Pass the connection defined in the registry
$some->setConnection(Registry::getConnection());

$some->someDbTask();

Sekarang, mari kita bayangkan bahwa kita harus menerapkan dua metode dalam komponen, yang pertama selalu perlu untuk membuat koneksi baru dan yang kedua selalu harus menggunakan koneksi bersama:

<?php

class Registry
{

    protected static $_connection;

    /**
     * Creates a connection
     */
    protected static function _createConnection()
    {
        return new Connection(array(
            "host" => "localhost",
            "username" => "root",
            "password" => "secret",
            "dbname" => "invo"
        ));
    }

    /**
     * Creates a connection only once and returns it
     */
    public static function getSharedConnection()
    {
        if (self::$_connection===null){
            $connection = self::_createConnection();
            self::$_connection = $connection;
        }
        return self::$_connection;
    }

    /**
     * Always returns a new connection
     */
    public static function getNewConnection()
    {
        return self::_createConnection();
    }

}

class SomeComponent
{

    protected $_connection;

    /**
     * Sets the connection externally
     */
    public function setConnection($connection)
    {
        $this->_connection = $connection;
    }

    /**
     * This method always needs the shared connection
     */
    public function someDbTask()
    {
        $connection = $this->_connection;

        // ...
    }

    /**
     * This method always needs a new connection
     */
    public function someOtherDbTask($connection)
    {

    }

}

$some = new SomeComponent();

//This injects the shared connection
$some->setConnection(Registry::getSharedConnection());

$some->someDbTask();

//Here, we always pass a new connection as parameter
$some->someOtherDbTask(Registry::getNewConnection());

Sejauh ini kita telah melihat bagaimana Dependency Injection memecahkan masalah kita. Memberikan dependensi sebagai argumen daripada menciptakan mereka secara internal dalam kode membuat aplikasi kita lebih maintainable dan saling-lepas /decoupled. Namun, dalam jangka panjang, bentuk dependency injection memiliki beberapa kelemahan.

Misalnya, jika komponen memiliki banyak dependensi, kita perlu membuat beberapa argumen setter untuk memberikan dependensi atau membuat konstruktor yang dengan banyak argumen yg harus diberikan, selain itu jg harus menciptakan dependensi sebelum menggunakan komponen, setiap kali, membuat kode tidak maintainable seperti yang diharapkan:

<?php

//Create the dependencies or retrieve them from the registry
$connection = new Connection();
$session = new Session();
$fileSystem = new FileSystem();
$filter = new Filter();
$selector = new Selector();

//Pass them as constructor parameters
$some = new SomeComponent($connection, $session, $fileSystem, $filter, $selector);

// ... or using setters

$some->setConnection($connection);
$some->setSession($session);
$some->setFileSystem($fileSystem);
$some->setFilter($filter);
$some->setSelector($selector);

Bayangkan bila kita harus membuat objek ini di banyak bagian aplikasi kita. Jika tidak lagi memerlukan dependensi, kita harus kemana-mana untuk menghapus parameter dalam constructor atau setter di mana kita menyuntikan kode. Untuk mengatasi hal ini, kita kembali lagi ke registri global untuk membuat komponen. Namun, registri ini menambahkan lapisan abstraksi baru sebelum membuat objek:

<?php

class SomeComponent
{

    // ...

    /**
     * Define a factory method to create SomeComponent instances injecting its dependencies
     */
    public static function factory()
    {

        $connection = new Connection();
        $session = new Session();
        $fileSystem = new FileSystem();
        $filter = new Filter();
        $selector = new Selector();

        return new self($connection, $session, $fileSystem, $filter, $selector);
    }

}

Suatu saat, kami kembali ke awal, kita membangun lagi dependensi dalam komponen! Kita bisa move-on dan mencari tahu cara untuk memecahkan masalah ini setiap kali. Tapi tampaknya saat itu dan lagi kita jatuh kembali ke dalam cara yg buruk.

Sebuah cara yang praktis dan elegan untuk memecahkan masalah ini adalah dengan menggunakan wadah untuk dependensi. Wadah bertindak sebagai registri global yang kita lihat sebelumnya. Menggunakan wadah tsb untuk dependensi sebagai jembatan untuk mendapatkan dependensi memungkinkan kita untuk mengurangi kompleksitas komponen:

<?php

class SomeComponent
{

    protected $_di;

    public function __construct($di)
    {
        $this->_di = $di;
    }

    public function someDbTask()
    {

        // Get the connection service
        // Always returns a new connection
        $connection = $this->_di->get('db');

    }

    public function someOtherDbTask()
    {

        // Get a shared connection service,
        // this will return the same connection everytime
        $connection = $this->_di->getShared('db');

        //This method also requires an input filtering service
        $filter = $this->_di->get('filter');

    }

}

$di = new Phalcon\DI();

//Register a "db" service in the container
$di->set('db', function() {
    return new Connection(array(
        "host" => "localhost",
        "username" => "root",
        "password" => "secret",
        "dbname" => "invo"
    ));
});

//Register a "filter" service in the container
$di->set('filter', function() {
    return new Filter();
});

//Register a "session" service in the container
$di->set('session', function() {
    return new Session();
});

//Pass the service container as unique parameter
$some = new SomeComponent($di);

$some->someTask();

Komponen ini sekarang hanya mengakses layanan ketika membutuhkannya, jika tidak maka akan menghemat resource. Komponen ini sekarang sangat dipisahkan. Sebagai contoh, kita bisa mengganti bagaimana koneksi dibuat, perilakunya atau aspek lainnya dan bahwa tidak akan mempengaruhi komponen.

Pendekatan Kami Untuk  Dependency Injection 

Phalcon\DI adalah komponen yg menerapkan Dependency Injection dan Location of services. Dan menjadi wadah bagi keduanya.

Karena Phalcon sangat decoupled, Phalcon\DI sangat penting untuk mengintegrasikan berbagai komponen framework. Pengembang juga dapat menggunakan komponen ini untuk menyuntikkan dependensi dan mengelola instance global pada class yang berbeda dalam aplikasi.

Pada dasarnya, komponen ini menerapkan pola Inversion of Contro. Menerapkan ini, objek tidak menerima dependensi menggunakan setter atau konstruktor, tapi meminta service dependency injector. Ini mengurangi kompleksitas keseluruhan karena hanya ada satu cara untuk mendapatkan dependensi yang diperlukan dalam komponen.

Selain itu, pola ini meningkatkan testability kode, sehingga mengurangi kerentanan error.

Mendaftarkan Service di Container 

Framework atau pengembang dapat mendaftarkan service. Ketika komponen A memerlukan komponen B (atau sebuah instance dari class tsb) untuk beroperasi, dapat meminta komponen B dari kontainer, daripada menciptakan instance baru B.

Cara kerja ini memberi kita banyak keuntungan:

  • Kita dapat dengan mudah mengganti komponen dengan buatan diri kita sendiri atau pihak ketiga.
  • Kita memiliki kontrol penuh inisialisasi obyek, memungkinkan kita untuk mengatur obyek ini, yang diperlukan sebelum memberikannya ke komponen.
  • Kita bisa mendapatkan instance global komponen dalam cara yang terstruktur dan terpadu

Service bisa didaftarkan dengan menggunakan beberapa jenis definisi:

<?php

//Create the Dependency Injector Container
$di = new Phalcon\DI();

//By its class name
$di->set("request", 'Phalcon\Http\Request');

//Using an anonymous function, the instance will be lazy loaded
$di->set("request", function() {
    return new Phalcon\Http\Request();
});

//Registering an instance directly
$di->set("request", new Phalcon\Http\Request());

//Using an array definition
$di->set("request", array(
    "className" => 'Phalcon\Http\Request'
));

Sintaks array juga diperbolehkan untuk mendaftar service:

<?php

//Create the Dependency Injector Container
$di = new Phalcon\DI();

//By its class name
$di["request"] = 'Phalcon\Http\Request';

//Using an anonymous function, the instance will be lazy loaded
$di["request"] = function() {
    return new Phalcon\Http\Request();
};

//Registering an instance directly
$di["request"] = new Phalcon\Http\Request();

//Using an array definition
$di["request"] = array(
    "className" => 'Phalcon\Http\Request'
);

Dalam contoh di atas, ketika framework ingin mengakses data request, ia akan meminta service yg bernama ‘request’ dalam kontainer. Kontainer pada gilirannya akan mengembalikan instance dari service yang diperlukan. Pengembang juga bisa menggantikan komponen tsb bila dibutuhkan.

Setiap metode (ditunjukkan dalam contoh di atas) digunakan untuk mengatur / mendaftar service memiliki kelebihan dan kekurangan. Terserah pengembang dan kebutuhan mana yang hendak digunakan.

Pengaturan service dengan string sangat sederhana, tetapi tidak memiliki fleksibilitas. Mengatur service menggunakan array menawarkan lebih banyak fleksibilitas, tetapi membuat kode yang lebih rumit. Fungsi lambda adalah keseimbangan yang baik antara keduanya, tetapi bisa menyebabkan perawatan lebih dari yg diperkirakan.

Phalcon\DI menawarkan lazy loading untuk setiap service yg disimpan. Kecuali pengembang memilih untuk membuat instance obyek secara langsung dan menyimpannya dalam wadah, obyek yang tersimpan di dalamnya (melalui array, string, dll) akan lazy loaded yaitu dipakai hanya saat diminta.

Registrasi Sederhana 

Seperti yang terlihat sebelumnya, ada beberapa cara untuk mendaftar layanan. Ini yg kita sebut sederhana:

String 

Tipe ini menerima nama class yang valid, mengembalikan sebuah objek dari class tertentu, jika class belum dimuat akan dibuat instance menggunakan auto-loader. Cara definisi ini tidak memungkinkan untuk memberikan argumen untuk konstruktor class ataupun parameter:

<?php

// return new Phalcon\Http\Request();
$di->set('request', 'Phalcon\Http\Request');

Obyek 

Tipe ini menerima suatu objek. Karena kenyataan bahwa objek tidak perlu diterjemahkan karena sudah berupa objek, bisa dikatakan bahwa itu tidak benar-benar dependency injection, namun hal ini berguna jika Anda ingin memaksa dependency untuk selalu mengembalikan objek/value yang sama:

<?php

// return new Phalcon\Http\Request();
$di->set('request', new Phalcon\Http\Request());

Closures/ fungsi Anonymous 

Metode ini menawarkan kebebasan yang lebih besar untuk membangun dependency seperti yang diinginkan, namun, sulit untuk mengubah beberapa parameter eksternal tanpa harus benar-benar mengubah definisi ketergantungan:

<?php

$di->set("db", function() {
    return new \Phalcon\Db\Adapter\Pdo\Mysql(array(
         "host" => "localhost",
         "username" => "root",
         "password" => "secret",
         "dbname" => "blog"
    ));
});

Beberapa keterbatasan dapat diatasi dengan melewatkan variabel tambahan untuk lingkungan penutupan ini:

<?php

//Using the $config variable in the current scope
$di->set("db", function() use ($config) {
    return new \Phalcon\Db\Adapter\Pdo\Mysql(array(
         "host" => $config->host,
         "username" => $config->username,
         "password" => $config->password,
         "dbname" => $config->name
    ));
});

Registrasi Kompleks 

Jika diperlukan untuk mengubah definisi layanan tanpa membuat instance / menerjemahkan service, maka, kita perlu mendefinisikan service menggunakan sintaks array. Tentukan layanan menggunakan definisi array dapat menjadi sedikit lebih lengkap (verbose):

<?php

//Register a service 'logger' with a class name and its parameters
$di->set('logger', array(
    'className' => 'Phalcon\Logger\Adapter\File',
    'arguments' => array(
        array(
            'type' => 'parameter',
            'value' => '../apps/logs/error.log'
        )
    )
));

//Using an anonymous function
$di->set('logger', function() {
    return new \Phalcon\Logger\Adapter\File('../apps/logs/error.log');
});

Kedua registrasi service di atas menghasilkan objek yang sama. Namun Definisi Array , memungkinkan untuk perubahan parameter layanan jika diperlukan:

<?php

//Change the service class name
$di->getService('logger')->setClassName('MyCustomLogger');

//Change the first parameter without instantiating the logger
$di->getService('logger')->setParameter(0, array(
    'type' => 'parameter',
    'value' => '../apps/logs/error.log'
));

Selain dengan menggunakan sintaks array Anda dapat menggunakan tiga jenis depedency injector:

Constructor Injection 

Jenis injeksi ini memberikan dependensi / argumen ke konstruktor class. Mari kita beranggapan kita memiliki komponen berikut:

<?php

namespace SomeApp;

use Phalcon\Http\Response;

class SomeComponent
{

    protected $_response;

    protected $_someFlag;

    public function __construct(Response $response, $someFlag)
    {
        $this->_response = $response;
        $this->_someFlag = $someFlag;
    }

}

Layanan ini dapat didaftarkan dengan cara ini:

<?php

$di->set('response', array(
    'className' => 'Phalcon\Http\Response'
));

$di->set('someComponent', array(
    'className' => 'SomeApp\SomeComponent',
    'arguments' => array(
        array('type' => 'service', 'name' => 'response'),
        array('type' => 'parameter', 'value' => true)
    )
));

Service “response” (Phalcon\Http\Response) diterjemahkan untuk diteruskan sebagai argumen pertama dari konstruktor, sedangkan yang kedua adalah nilai boolean (true) yang diberikan sebagaimana adanya.

Injection Setter 

Class mungkin memiliki setter untuk menyuntikkan dependensi opsional, class sebelumnya dapat diubah untuk menerima dependensi dengan setter:

<?php

namespace SomeApp;

use Phalcon\Http\Response;

class SomeComponent
{

    protected $_response;

    protected $_someFlag;

    public function setResponse(Response $response)
    {
        $this->_response = $response;
    }

    public function setFlag($someFlag)
    {
        $this->_someFlag = $someFlag;
    }

}

Sebuah service dengan injeksi setter dapat terdaftar sebagai berikut:

<?php

$di->set('response', array(
    'className' => 'Phalcon\Http\Response'
));

$di->set('someComponent', array(
    'className' => 'SomeApp\SomeComponent',
    'calls' => array(
        array(
            'method' => 'setResponse',
            'arguments' => array(
                array('type' => 'service', 'name' => 'response'),
            )
        ),
        array(
            'method' => 'setFlag',
            'arguments' => array(
                array('type' => 'parameter', 'value' => true)
            )
        )
    )
));

Properti Injection 

Strategi yg jarang digunakan adalah dgn menyuntikkan dependensi atau parameter langsung ke atribut umum class:

<?php

namespace SomeApp;

use Phalcon\Http\Response;

class SomeComponent
{

    public $response;

    public $someFlag;

}

Sebuah service dengan injeksi properti dapat diregistrasikan sebagai berikut:

<?php

$di->set('response', array(
    'className' => 'Phalcon\Http\Response'
));

$di->set('someComponent', array(
    'className' => 'SomeApp\SomeComponent',
    'properties' => array(
        array(
            'name' => 'response',
            'value' => array('type' => 'service', 'name' => 'response')
        ),
        array(
            'name' => 'someFlag',
            'value' => array('type' => 'parameter', 'value' => true)
        )
    )
));

Jenis parameter yang didukung meliputi:

Jenis Deskripsi Contoh
parameter Merupakan nilai literal untuk diteruskan sebagai parameter array (‘type’ => ‘parameter’, ‘value’ => 1234)
service Merupakan service lain dalam wadah service array (‘type’ => ‘service’, ‘name’ => ‘request’)
instance Merupakan suatu objek yang harus dibangun secara dinamis array (‘type’ => ‘instance’, ‘className’ => ‘DateTime’, ‘argumens’ => array (‘now’))

Menerjemahkan/resolve service yang definisinya yg kompleks mungkin sedikit lebih lambat dari definisi sederhana sebagaimana diperlihatkan sebelumnya. Namun, ini memberikan pendekatan yang lebih kuat untuk mendefinisikan dan service injector.

Pencampuran berbagai jenis definisi diperbolehkan, semua orang dapat memutuskan apa yang cara yang paling tepat untuk mendaftarkan layanan sesuai dengan kebutuhan aplikasi.

Resolving Service 

Mendapatkan service dari wadah adalah semudah menyebutkan perintah “get”. Sebuah instance baru dari service akan dikembalikan:

<?php $request = $di->get("request");

Atau dengan memanggil melalui metode magic:

<?php

$request = $di->getRequest();

Atau menggunakan sintaks array-akses:

<?php

$request = $di['request'];

Argumen dapat diberikan ke konstruktor dengan menambahkan parameter array ke metode “get”:

<?php

// new MyComponent("some-parameter", "other")
$component = $di->get("MyComponent", array("some-parameter", "other"));

Shared service 

Layanan dapat terdaftar sebagai “shared” service ini berarti mereka akan selalu bertindak sebagai singletons . Setelah service ini diterjemahkan/resolved untuk pertama kalinya, instance yang sama itu dikembalikan setiap kali pengguna mengambil layanan dari wadah:

<?php

//Register the session service as "always shared"
$di->setShared('session', function() {
    $session = new Phalcon\Session\Adapter\Files();
    $session->start();
    return $session;
});

$session = $di->get('session'); // Locates the service for the first time
$session = $di->getSession(); // Returns the first instantiated object

Cara alternatif untuk mendaftar layanan bersama adalah untuk memberikan “true” sebagai parameter ketiga “set”:

<?php

//Register the session service as "always shared"
$di->set('session', function() {
    //...
}, true);

Jika layanan tidak terdaftar sebagai shared dan Anda ingin memastikan bahwa contoh bersama akan diakses setiap kali layanan ini diperoleh dari DI, Anda dapat menggunakan metode ‘getShared’:

<?php

$request = $di->getShared("request");

Memanipulasi Service Secara Individual 

Setelah layanan terdaftar dalam wadah layanan, Anda dapat mengambilnya untuk memanipulasi secara individu:

<?php

//Register the "register" service
$di->set('request', 'Phalcon\Http\Request');

//Get the service
$requestService = $di->getService('request');

//Change its definition
$requestService->setDefinition(function() {
    return new Phalcon\Http\Request();
});

//Change it to shared
$requestService->setShared(true);

//Resolve the service (return a Phalcon\Http\Request instance)
$request = $requestService->resolve();

Membuat Instance class via Service Container 

Bila Anda meminta layanan dr wadah layanan, jika tidak dapat menemukan layanan dengan nama yang sama, maka akan dicoba untuk memuat sebuah kelas dengan nama yang sama. Dengan perilaku ini kita dapat mengganti setiap class dgn yg lain hanya dengan mendaftar layanan dengan namanya:

<?php

//Register a controller as a service
$di->set('IndexController', function() {
    $component = new Component();
    return $component;
}, true);

//Register a controller as a service
$di->set('MyOtherComponent', function() {
    //Actually returns another component
    $component = new AnotherComponent();
    return $component;
});

//Create an instance via the service container
$myComponent = $di->get('MyOtherComponent');

Anda dapat mengambil keuntungan dari hal ini, selalu buat instance class Anda melalui wadah layanan (bahkan jika mereka tidak terdaftar sebagai layanan). DI akan mundur ke autoloader valid untuk akhirnya memuat class. Dengan melakukan ini, Anda dapat dengan mudah mengganti setiap class di masa depan dengan menerapkan definisi untuk itu.

Menyuntikan DI Otomatis  

Jika class atau komponen memerlukan DI untuk mencari service, DI dapat menyuntikkan dirinya otomatis ke dalam instance yg dibuatnya sendiri, untuk melakukan hal ini, Anda perlu untuk mengimplementasikan Phalcon\DI\InjectionAwareInterface di class Anda:

<?php

class MyClass implements \Phalcon\DI\InjectionAwareInterface
{

    protected $_di;

    public function setDi($di)
    {
        $this->_di = $di;
    }

    public function getDi()
    {
        return $this->_di;
    }

}

Kemudian setelah layanan ini di-resolved, $di akan diberikan ke setDi otomatis:

<?php

//Register the service
$di->set('myClass', 'MyClass');

//Resolve the service (NOTE: $myClass->setDi($di) is automatically called)
$myClass = $di->get('myClass');

Menghindari resolusi layanan 

Beberapa layanan yang digunakan dalam setiap request yang dibuat untuk aplikasi, menghilangkan proses resolving/menerjemahkan layanan sedikit menambahkan performa.

<?php

//Resolve the object externally instead of using a definition for it:
$router = new MyRouter();

//Pass the resolved object to the service registration
$di->set('router', $router);

Pengorganisasian Service Dalam File 

Anda dapat lebih baik mengatur aplikasi Anda dengan memindahkan registrasi service pada file terpisah bukannya melakukan segala sesuatu di bootstrap aplikasi:

<?php

$di->set('router', function() {
    return include "../app/config/routes.php";
});

Kemudian pada file (“../App/config/routes.php”) mengembalikan objek yg dimaksud:

<?php

$router = new MyRouter();

$router->post('/login');

return $router;

Mengakses DI secara statis 

Jika diperlukan Anda dapat mengakses DI yg terakhir dibuat dalam fungsi statis dengan cara sebagai berikut:

<?php

class SomeComponent
{

    public static function someMethod()
    {
        //Get the session service
        $session = Phalcon\DI::getDefault()->getSession();
    }

}

Default DI Bawaan 

Meskipun bersifat decoupled Phalcon menawarkan kita kebebasan dan fleksibilitas, mungkin kita hanya hanya ingin menggunakannya sebagai framework full-stack. Untuk itu, framework menyediakan varian Phalcon\DI disebut Phalcon\DI\FactoryDefault. Class ini otomatis mendaftarkan layanan yang sesuai dibundel dengan framework untuk bertindak sebagai full-stack.

<?php $di = new Phalcon\DI\FactoryDefault();

Kaidah Nama Layanan  

Meskipun Anda dapat mendaftarkan layanan dengan nama yang Anda inginkan, Phalcon memiliki beberapa kaidah penamaan yang memungkinkan untuk mendapatkan layanan yang benar (built-in) ketika Anda membutuhkannya.

Layanan Nama Deskripsi Kegagalan Dibagi
dispatcher Layanan Controllers Dispatching Phalcon\MVC\Dispatcher Ya
router Layanan Routing Phalcon\MVC\Router Ya
url URL Generator Layanan Phalcon\MVC\Url Ya
request Layanan Permintaan Lingkungan HTTP Phalcon\Http\Request Ya
response HTTP Response Layanan Lingkungan Phalcon\Http\Response Ya
cookies Manajemen HTTP Cookies Layanan Phalcon\Http\Response\Cookies Ya
filter Layanan masukan Filtering Phalcon\Filter Ya
flash Flash Messaging Layanan Phalcon\flash\Direct Ya
flashSession Flash Sesi Messaging Service Phalcon\flash\Session Ya
session Layanan Session Phalcon\Session\Adapter\Files Ya
eventsManager Manajemen Kejadian Layanan Phalcon\Events\Manajer Ya
db Low-Level Database Connection Layanan Phalcon\Db Ya
security Pembantu Keamanan Phalcon\Security Ya
crypt Data Encrypt / Decrypt Phalcon\Crypt Ya
tag Pembantu generasi HTML Phalcon\Tag Ya
escaper Kontekstual Escaping Phalcon\Escaper Ya
annotations Penjelasan Parser Phalcon\Anotasi\Adapter\Memory Ya
modelsManager Manajemen Model Layanan Phalcon\MVC\Model\Manajer Ya
modelsMetadata Model Meta-Data Layanan Phalcon\MVC\Model\metadata\Memory Ya
TransactionManager Layanan Model Transaksi Manager Phalcon\MVC\Model\Transaksi\Manajer Ya
modelsCache Cache backend untuk model tembolok None
viewsCache Cache backend untuk dilihat fragmen None

Menerapkan DI Anda sendiri 

Antarmuka Phalcon\DiInterface harus diimplementasikan untuk menciptakan DI sendiri menggantikan yang disediakan oleh Phalcon atau memperpanjang yang sekarang.