Przegląd

Używanie kontrolerów

Akcje to metody w kontrolerze, które obsługują żądania. Domyślnie wszystkie publiczne metody w kontrolerze mapują do akcji i są dostępne za pomocą adresu URL. Akcje są odpowiedzialne za interpretację żądania i utworzenie odpowiedzi. Zwykle odpowiedzi są w formie renderowanego widoku, chociaż są również inne sposoby ich tworzenia.

Na przykład, kiedy wchodzisz na adres URL jak ten: http://localhost/blog/posts/show/2015/the-post-title Phalcon domyślnie rozłoży każdą część adresu w następujący sposób:

Opis Fragment URL
Katalog Phalcona blog
Kontroler posts
Akcja show
Parametr 2015
Parametr the-post-title

W takim przypadku PostsController obsłuży to żądanie. Nie istnieje specjalna lokalizacja w której należy umieszczać kontrolery aplikacji, mogą być one załadowane za pomocą Phalcon\Loader, więc możesz organizować Twoje kontrolery tak, jak potrzebujesz.

Controllers must have the suffix Controller while actions the suffix Action. A sample of a controller is as follows:

<?php

use Phalcon\Mvc\Controller;

class PostsController extends Controller
{
    public function indexAction()
    {

    }

    public function showAction($year, $postTitle)
    {

    }
}

Dodatkowe parametry URI są zdefiniowane jako parametry akcji, więc mogą być łatwo dostępne poprzez użycie lokalnych zmiennych. Kontroler może opcjonalnie rozszerzać Phalcon\Mvc\Controller. W ten sposób kontroler może mieć łatwy dostęp do aplikacyjnych serwisów.

Parameters without a default value are handled as required. Setting optional values for parameters is done as usual in PHP:

<?php

use Phalcon\Mvc\Controller;

class PostsController extends Controller
{
    public function indexAction()
    {

    }

    public function showAction($year = 2015, $postTitle = 'przykładowy tytuł')
    {

    }
}

Parameters are assigned in the same order as they were passed in the route. You can get an arbitrary parameter from its name in the following way:

<?php

use Phalcon\Mvc\Controller;

class PostsController extends Controller
{
    public function indexAction()
    {

    }

    public function showAction()
    {
        $year      = $this->dispatcher->getParam('year');
        $postTitle = $this->dispatcher->getParam('postTitle');
    }
}

Pętla Komunikacyjna (ang. Dispatch Loop)

Pętla Komunikacyjna (ang. Dispatch Loop) będzie realizowana w ramach Dyspozytora, dopóki nie będzie już żadnych akcji do wykonania. W poprzednim przykładzie wykonano tylko jedną akcję. Teraz zobaczmy jak metoda forward()może dostarczyć bardziej złożony przepływ operacji w Pętli Komunikacyjnej, poprzez przekierowanie wykonania do innego kontrolera/akcji.

<?php

use Phalcon\Mvc\Controller;

class PostsController extends Controller
{
    public function indexAction()
    {

    }

    public function showAction($year, $postTitle)
    {
        $this->flash->error(
            "Nie masz dostępu do tego zasobu"
        );

        // Przekazanie przepływu operacji do innej akcji
        $this->dispatcher->forward(
            [
                'controller' => 'users',
                'action'     => 'signin',
            ]
        );
    }
}

Jeżeli użytkownicy nie mają pozwolenia na dostęp do pewnej akcji, to zostaną przekierowani do akcji signin w UsersController.

<?php

use Phalcon\Mvc\Controller;

class UsersController extends Controller
{
    public function indexAction()
    {

    }

    public function signinAction()
    {

    }
}

W Twojej aplikacji nie ma limitu dla przekazywań tak długo, jak nie prowadzą do odwołań cyklicznych, co skutkuje zatrzymaniem programu. Jeżeli nie ma więcej akcji do wyekspediowania poprzez Pętle Komunikacyjną (ang. Dispatch Loop), Dyspozytor automatycznie wywoła warstwę widoku MVC, która jest zarządzana przez Phalcon\Mvc\View.

Inicjowanie kontrolerów

Phalcon\Mvc\Controller oferuje metodę initialize(), która jest wykonywana jako pierwsza, przed realizowaniem każdej innej akcji kontrolera. Używanie metody __construct() nie jest zalecane.

<?php

use Phalcon\Mvc\Controller;

class PostsController extends Controller
{
    public $settings;

    public function initialize()
    {
        $this->settings = [
            'mySetting' => 'value',
        ];
    }

    public function saveAction()
    {
        if ($this->settings['mySetting'] === 'value') {
            // ...
        }
    }
}

Jeżeli chcesz wykonać jakąś logikę podczas inicjowania, zaraz po utworzeniu obiektu kontrolera, możesz zaimplementować metodę onConstruct():

<?php

use Phalcon\Mvc\Controller;

class PostsController extends Controller
{
    public function onConstruct()
    {
        // ...
    }
}

Wstrzykiwanie serwisów

If a controller extends Phalcon\Mvc\Controller then it has easy access to the service container in application. For example, if we have registered a service like this:

<?php

use Phalcon\Di;

$di = new Di();

$di->set(
    'storage',
    function () {
        return new Storage(
            '/some/directory'
        );
    },
    true
);

Wtedy mamy dostęp do tego serwisu na kilka różnych sposobów:

<?php

use Phalcon\Mvc\Controller;

class FilesController extends Controller
{
    public function saveAction()
    {
        // Wstrzyknięcie serwisu poprzez dostęp do zmiennej o takiej samej nazwie
        $this->storage->save('/some/file');

        // Dostęp do serwisu z Kontenera Zależności
        $this->di->get('storage')->save('/some/file');

        // Kolejny sposób na dostęp do serwisu używając magicznego Akcesora
        $this->di->getStorage()->save('/some/file');

        // I jeszcze inny sposób na dostęp do serwisu używając magicznego Akcesora
        $this->getDi()->getStorage()->save('/some/file');

        // Użycie tablicowej składni
        $this->di['storage']->save('/some/file');
    }
}

Jeżeli używasz Phalcona jako pełnowartościowego frameworka, możesz odczytywać serwisy dostarczone domyślnie w jego ramach.

Żądanie i Odpowiedź

Przy założeniu, że framework dostarcza zestaw wstępnie zarejestrowanych serwisów, wyjaśnimy jak przeprowadzać interakcję ze środowiskiem HTTP. Usługa request zawiera instancję Phalcon\Http\Request oraz response zawiera Phalcon\Http\Response reprezentującą to, co jest do wysłania z powrotem do klienta.

<?php

use Phalcon\Mvc\Controller;

class PostsController extends Controller
{
    public function indexAction()
    {

    }

    public function saveAction()
    {
        // Sprawdź czy żądanie zostało wykonane za pomocą metody POST
        if ($this->request->isPost()) {
            // Dostęp do danych z POST
            $customerName = $this->request->getPost('name');
            $customerBorn = $this->request->getPost('born');
        }
    }
}

Zwracany obiekt nie jest zazwyczaj używany bezpośrednio, ale jest zbudowany przed wykonaniem akcji, niekiedy jednak, jak w zdarzeniu afterDispatch - dostęp do bezpośredniej odpowiedzi może być użyteczny:

<?php

use Phalcon\Mvc\Controller;

class PostsController extends Controller
{
    public function indexAction()
    {

    }

    public function notFoundAction()
    {
        // Wyślij nagłówek odpowiedzi HTTP 404
        $this->response->setStatusCode(404, 'Not Found');
    }
}

Dowiedz się więcej na temat środowiska HTTP w ich dedykowanych artykułach request i response.

Dane Sesji

Sessions help us maintain persistent data between requests. You can access a Phalcon\Session\Bag from any controller to encapsulate data that needs to be persistent:

<?php

use Phalcon\Mvc\Controller;

class UserController extends Controller
{
    public function indexAction()
    {
        $this->persistent->name = 'Michael';
    }

    public function welcomeAction()
    {
        echo 'Welcome, ', $this->persistent->name;
    }
}

Korzystanie z Serwisów jako Kontrolerów

Services may act as controllers, controllers classes are always requested from the services container. Accordingly, any other class registered with its name can easily replace a controller:

<?php

// Zarejestruj kontroler jako serwis
$di->set(
    'IndexController',
    function () {
        $component = new Component();

        return $component;
    }
);

// Zarejestruj kontroler z przestrzenią nazw jako serwis
$di->set(
    'Backend\Controllers\IndexController',
    function () {
        $component = new Component();

        return $component;
    }
);

Zdarzenia w Kontrolerach

Controllers automatically act as listeners for dispatcher events, implementing methods with those event names allow you to implement hook points before/after the actions are executed:

<?php

use Phalcon\Mvc\Controller;

class PostsController extends Controller
{
    public function beforeExecuteRoute($dispatcher)
    {
        // Wykonywane przed każdą znalezioną akcją
        if ($dispatcher->getActionName() === 'save') {
            $this->flash->error(
                "Nie posiadasz uprawnień do zapisywania postów"
            );

            $this->dispatcher->forward(
                [
                    'controller' => 'home',
                    'action'     => 'index',
                ]
            );

            return false;
        }
    }

    public function afterExecuteRoute($dispatcher)
    {
        // Wykonywane po każdej znalezionej akcji
    }
}