Podstawy Kohany – dla wszystkich

Kilka osób prosiło mnie o napisanie jeszcze łatwiejszego przykładu niż Pierwsze starcie, tak aby było jeszcze bardziej zrozumiałe. Cofnijmy się zatem jeszcze raz do podstawy.
Po instalacji widzimy hello, world!. Stworzymy na podstawie kontrolera Welcome (odpowiedzialnego za wyświetlenie hello, world!) prostą stronę po lewej część statyczna na wszystkich stronach, po prawej część dynamiczna, zmieniająca się dla danej podstrony.

Wyjaśnijmy jak w kohanie działa routing. Po wejściu w stronę główną (domena.com albo kohana/ na localhoście) zostaje wczytany podstawowy kontroler z routingu, domyślnie welcome i uruchomiona zostanie domyślna akcja index. Aby wczytać inny kontroler należy po / wpisać jego nazwę, np. domena.com/nazwa_kontrolera albo kohana/nazwa_kontrolera. Aby uruchomić akcję index wystarczy wpisać nazwę kontrolera albo możemy z linku wywołać także kohana/nazwa_kontrolera/index, natomiast aby uruchomić inną akcję w linku wpisujemy kohana/nazwa_kontrolera/nazwa_akcji. Gdy chcemy z linku odczytać parametr to link powinien wyglądać tak: kohana/nazwa_kontrolera/nazwa_akcji/wartość_parametru1.

Kontrolery to klasy, a akcje to ich metody (funkcje). Wywołując jakąś akcję wykonujemy to co w niej się znajduje np. wykonujemy jakieś obliczenia, przypisujemy do zmiennych, przesyłamy zmienne do widoku, sprawdzamy czy formularz został wysłany czy wczytujemy widoki. Kontrolery powinny znajdować się w folderze application/classes/controller/ natomiast widoki w application/views/

Standardowy kontroler Welcome wygląda tak:

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Welcome extends Controller {

	public function action_index()
	{
		$this->response->body('hello, world!');
	}

} // End Welcome

Wg defaultowego routingu kohany najpierw zostanie wczytany ten kontroler i akcja index, a aby wczytać inny kontroler należy podać jego nazwę w linku kohana/kontroler

Aby łatwo można było wczytywać nowe widoki proponuję wykorzystać kontroler Template Kohany i tak zmodyfikować kontroler Welcome. Kontroler ten ma już w sobie zaimplementowane wywołanie więc nie musimy używać $this->response->body().

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Welcome extends Controller_Template {
    
        public $template = 'szablon';

	public function action_index()
	{
	}

}

Należy teraz stworzyć widok szablon z kodem html, gdyż kohana będzie szukać pliku o nazwie szablon.php i zwróci błąd gdyż go nie znajdzie. Oto on:

<html>
<head>
    <title>Tytuł</title>
    <style type="text/css">
        .w1000{width:1000px}
        .w50{width:50%}
        .ovh{overflow: hidden}
        .fll{float:left}
        .flr{float:right}
    </style>
</head>
<body>
    <div class="w1000 ovh">
        <div class="w50 fll">Left</div>
        <div class="w50 flr">Right</div>
    </div>
</body>
</html>

Aby można było po prawej wczytywać inne treści to należy w tym widoku zadeklarować wczytanie innego widoku:

<div class="w50 flr"><?php include Kohana::find_file('views', $content);?></div>

Spowoduje to wczytanie widoku o nazwie, która jest ukryta pod zmienną $content. Wystarczy nadpisać tą wartość. Należy jednak pamiętać, iż zmienna ta musi zostać przesłana, gdyż jej brak spowoduje wyświetlenie błędu.

Stwórzmy zatem widok o nazwie home.php, który zostanie wczytany do szablonu po wywołaniu strony głównej kohana/

<h1>Strona główna</h1>

Musimy jeszcze w kontrolerze Welcome w akcji index przesłać do zmiennej $content nazwę widoku: home, tak aby został on wczytany.

public function action_index()
	{
            $this->template->content='home';
	}

Aby wczytać widok do dynamicznej części po prawej wystarczy przypisać nazwę widoku w powyższy sposób w jakiejś akcji. Stwórzmy zatem drugi kontroler, a w nim defaultową akcję index i drugą, tak aby można przetestować zasady wczytywania.

Kontroler Article będzie rozszerzał zatem kontroler Wellcome

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Article extends Controller_Welcome {

	public function action_index()
	{
            $this->template->content='article';
	}
        public function action_show($id=NULL)
	{
            $this->template->content='article_show';

            switch ($id){
            case 1:$this->template->name='Artykuł 1'; break;
            case 2:$this->template->name='Artykuł 2'; break;
            case 3:$this->template->name='Artykuł 3'; break;
            default: $this->template->content='article_default';
            }
	}
}

Po wpisaniu w link kohana/article co jest równoznaczne z kohana/article/index zostanie wywołana akcja index, w której zostanie wysłany do dynamicznej części widok o nazwie article.php, natomiast w akcji show mamy parametr, który może wystąpić, bądź nie (=NULL). Jeśli nie ma parametru kohana/article/show, bądź ma inną wartość zostanie wczytany widok article_default, jeśli wystąpi parametr o wartościach 1,2,3 kohana/article/show/1 zostanie wczytany widok article_show, dodatkowo do tego widoku zostanie przesłana zmienna $name. Musi ona wystąpić w widoku article_show, ponieważ jej brak spowoduje błąd ew. w tym widoku można dodać warunek if(isset($name)).

Widok article:

<h1>Artykuły</h1>
<p><a href="/article/show">Pokaż artykuły</a></p>

Widok article_default:

<h1>Wybierz artykuł</h1>
<p><a href="/article/show/1">Artykuł 1</a></p>
<p><a href="/article/show/2">Artykuł 2</a></p>
<p><a href="/article/show/3">Artykuł 3</a></p>

Widok article_show:

<h1>Treść artykułu</h1>
<p><?php echo $name;?></p>

Dodajmy jeszcze link w szablonie po lewej stronie do strony z widokiem article i strony głównej.

<div class="w50 fll"><a href="/">Główna</a><br /><a href="/article">Atrykuły</a></div>

Zmodyfikowaliśmy zatem kontroler Welcome i dodaliśmy drugi kontroler Article z akcjami. Stworzyliśmy prosty szablon i kilka widoków.

Kontroler Welcome ostatecznie wygląda tak:

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Welcome extends Controller_Template {

        public $template = 'szablon';

	public function action_index()
	{
            $this->template->content='home';
	}

}

A widok szablon tak:

<html>
<head>
    <title>Tytuł</title>
    <style type="text/css">
        .w1000{width:1000px}
        .w50{width:50%}
        .ovh{overflow: hidden}
        .fll{float:left}
        .flr{float:right}
    </style>
</head>
<body>
    <div class="w1000 ovh">
        <div class="w50 fll"><a href="/">Główna</a><br /><a href="/article">Atrykuły</a></div>
        <div class="w50 flr"><?php include Kohana::find_file('views', $content);?></div>
    </div>
</body>
</html>

Polecam w ramach ćwiczeń dodać samodzielnie kolejny kontroler i kilka akcji, tak aby oswoić się z odwołaniami z linku do akcji.

Pliki można pobrać: Podstawy kohany (711)

25 Odpowiedzi :“Podstawy Kohany – dla wszystkich”

  1. Najlepszy tutorial Kohana 3 w polskim internecie! W jednym kod nie działa nawet po skopiowaniu, w innym wszystko działa, ale nie wiadomo jak i dlaczego. A tutaj wszystko pięknie wytłumaczone, tak że nawet nie trzeba zaglądać do Kohana Wiki. Brawo, oby tak dalej!
    PS. może zamiast normalnych linków w widokach użyłbyś html::anchor(), bardziej uniwersalne ;)

  2. Mariusz napisał:

    Dzięki za pochlebne słowa :)
    Oczywiście można używać html::anchor(), html::image() czy innych helperów. Chciałem pokazać, że w widokach używamy zwykły html.

  3. Mariusz napisał:

    Czy w pliku /application/bootstrap.php wyłączyłeś wyświetlanie index.php?

    Kohana::init(array(
    	'base_url'   => '/',
            'index_file' => FALSE,
    ));
    

    Jeśli jest false to wtedy nie trzeba w linku podawać tego index.php. Domyślnie jest wyświetlany, stąd zapewne problemy.

  4. vell napisał:

    Zacząłem uczyć się kohany i już na początku mam problem.
    Cały kod jest ok, problem w tym że wywołując kontroler article linkiem http://localhost/article dostaję błąd 404. Wywołując http://localhost/index.php/article wszystko jest ok.
    modrewrite na apache jest włączony, w .htaccess są wpisy
    Options FollowSymLinks
    RewriteEngine On

    strona standardowo jest w /srv/www/htdocs
    Dlaczego tak się dzieje?

  5. vell napisał:

    Tak, jest wyłączone. Plik w linku się nie wyświetla ale dostaję wtedy 404, dopiero kiedy ręcznie wpisze adres do kontrolera z index.php działa

    • Mariusz napisał:

      Sprawdziłem. Dokładnie te objawy występują jak nie ma włączonego RewriteEngine On. Upewnij się, że moduł apache rewrite jest włączony na serwerze, a w głównym folderze znajduje się plik .htaccess z tym wpisem, problem nie leży w Kohanie.

  6. vell napisał:

    No właśnie moduł jest załadowany, potweirdzone w yascie i phpinfo.
    Mój .htaccess

    Options FollowSymLinks
    RewriteEngine On
    RewriteBase /
    
    
    	Order Deny,Allow
    	Deny From All
    
    
    RewriteRule ^(?:application|modules|system)\b.* index.php/$0 [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule .* index.php/$0 [PT]
    
    • Mariusz napisał:

      Trzeba w pliku konfiguracyjnym apache (w suse: /etc/apache2/default-server.conf) zezwolić na nadpisywanie: AllowOverride All dla katalogu głównego apache i zrestartować /etc/init.d/apache2 restart. Po tych czynnościach powinno grać. Jeśli chcesz mieć kilka projektów na domenach jak localhost, kohana to polecam zrobić vhosty, jest gdzieś na blogu o tym :)

  7. vell napisał:

    Poz zmianie na AllowOverride All w konfigu Apache wszystko jest w porządku.
    Dzięki

  8. white napisał:

    Witam,

    podany w poscie kod źródłowy nie działa prawidłowo dla wyświetlania poszczególnych artykułów
    bez względu na to jaki paramatert podany jest /article/show/1 .. 2 .. 3
    zawsze pokazuje article_default

  9. Mariusz napisał:

    Na jakiej wersji kohany? W najnowszej 3.2 należy w inny sposób odwoływać się do parametrów akcji:

    public function action_show()
    	{
                $id = $this->request->param('id');
                $this->template->content='article_show';
     
                switch ($id){
                case 1:$this->template->name='Artykuł 1'; break;
                case 2:$this->template->name='Artykuł 2'; break;
                case 3:$this->template->name='Artykuł 3'; break;
                default: $this->template->content='article_default';
                }
    	}
    
  10. white napisał:

    nie trzeba już podawać parametrów w deklaracji metody ?
    tylko $id = $this->request->param(‘id’);

    jak wtedy jest z kolejnością ?

    btw. na prawdę dobry blog do nauki kohany ;)

  11. Mariusz napisał:

    We wcześniejszych wersjach też nie trzeba było. Podawanie w akcji może było prostsze, ale już nie można tak więc należy odwoływać się przez $this->request->param(). Co do kolejności i nazw parametrów to definiuje je routing (w pliku bootstrap.php) i domyślnie:

    Route::set('default', '(<controller>(/<action>(/<id>)))')
    	->defaults(array(
    		'controller' => 'welcome',
    		'action'     => 'index',
    	));
    

    Dodając np. id2 umożliwiamy przesłanie drugiego parametru:

    Route::set('default', '(<controller>(/<action>(/<id>(/<id2>))))')
    

    Kolejność będzie następująca /kontroler/akcja/id1/id2, więc aby się odwołać wykonujemy:

    $param1 = $this->request->param('id');
    $param2 = $this->request->param('id2');
    
  12. tajger napisał:

    Witam!
    mam mały problemik.. dlaczego niechce się wyświetlić dana zawartość artykułu jak klikam na 1 2 albo 3.. linki nie dzialaja..

    wydaje mi sie ze trzeba zmienic id nie na NULL ale na cos innego.. dawalem 1,2 lub 3 to sie wysiwetla dana zawartosc artykulu.. jak jest null to nie mozna wejsc w odsylacz
    public function action_show($id=NULL)

  13. Mariusz napisał:

    @White kilka komentarzy wyżej pytał o to. Należy odwołać się poprzez param(), ponieważ w Ko3.2 zrezygnowano z przekazywania parametrów bezpośrednio w akcji.

    $id = $this->request->param('id');
    
  14. white napisał:

    Witam,

    czy jak rozszerzasz kontroler Template, to następne kontrolery należy rozszerzać już (tak jak w tym przypadku) o Controler_Welcome ?
    Bo zauważyłem, że gdy tak rozszerzam ‚kolejne o kolejny’ to gdy chcę użyć metody before() wywoływane są wszystkie nadrzędne, a to trochę nie chciany efekt,

    natomiast gdy tworze nowy controller oparty o Template, jest gorzej z przesyłaniem danych pomiędzy sobą,

    i tak jeszcze na koniec, w czym tak na prawdę funkcje before i after odgrywają role, za co odpowiadają ?

    • Mariusz napisał:

      Zależy, czy potomny będzie coś dziedziczył, jeśli nie to można rozszerzać tylko Template i wtedy nie odziedziczymy z Welcome, jeśli będziemy z czegoś korzystać to rozszerzamy Welcome czy jakiś inny szablonowy i wtedy mamy to co w rodzicu, możemy to nadpisać, aczkolwiek jeśli w szablonowym kontrolerze w before znajduje się zbyt wiele rzeczy to wszystkie one będą dziedziczone.

      Before() i after() są wykonywane odpowiednio przed i po ładowaniu danej akcji kontrolera. Nie jest ściśle określone co ma w nich być, bez nich też działa. Ja do nich ładuje to co się pojawia wszędzie w szablonie (także w potomnych kontrolerach), czyli deklaracje title, description, style, js, tak abym nie musiał w każdej akcji wysyłać ich do widoku.

      Możesz ew. zamiast:

      parent::before();
      

      spróbować:

      Controller_Template::before();
      
  15. white napisał:

    dzięki za szybką odpowiedź,

    jeśli będę kontrolery rozszerzał zawsze o Controller_Template, to w kazdym bede musial na nowo wywolywac wszystkie dane szalobnu, to troche boli

    // zdaję trochę dziwne/błahe pytania, bo spodobała mi się bardzo kohana, i wszystkie takie zagadnienia które są drobne staram się wyjaśniać aby nie robić jakiś błędów

  16. Beginner napisał:

    Witam!
    Postępuje zgodnie z poleceniami, jednak po kliknięciu linku Artykuły następuje wyświetlenie strony startowej programu WebServ, mimo, że wchodzi w adres: http://localhost/~Kohhana/article.

    Wpis dodałem edytujac szablon.php.

    Podaję część mojego pliku httpd.conf

        AllowOverride All
        Order allow,deny
        Allow from all
    
        Include "C:/Program Files/WebServ/apache2/conf/ban.conf"
    
        AllowOverride All
        Options MultiViews Indexes SymLinksIfOwnerMatch Includes ExecCGI
        
            Order allow,deny
            Allow from all
        
            Order deny,allow
            Deny from all
    
        Include "C:/Program Files/WebServ/apache2/conf/ban.conf"
    

    Plik .htaccess

    # Turn on URL rewriting
    RewriteEngine On
    
    # Installation directory
    RewriteBase /
    
    # Protect hidden files from being viewed
    
    	Order Deny,Allow
    	Deny From All
    
    # Protect application and system files from being viewed
    RewriteRule ^(?:application|modules|system)\b.* index.php/$0 [L]
    
    # Allow any files or directories that exist to be displayed directly
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    
    # Rewrite all other URLs to index.php/URL
    RewriteRule .* index.php/$0 [PT]
    

    Proszę o poradę.
    Kohana 3.2
    Webserv 2.0.

    • Mariusz napisał:

      Spróbuj dodać w pierwszej linii .htaccess

      Options FollowSymLinks
      

      Popatrz też na RewriteBase w .htaccess i base_url w bootstrap.php

      Ja używam linuxa, nie wiem jak ten webserv oznacza główny katalog, ale z linku co podałeś wydaje się, że w tych 2 plikach powinno być /~Kohhana

      PS. W ko3.2 należy inaczej niż w tym wpisie odwoływać się do parametrów:

      $id = $this->request->param('id');
      
  17. Beginner napisał:

    Pomogło!
    Jednak, żeby działały wszędzie podlinki, musiałem dodać „http://localhost/~Kohhana/”

    Dziękuję za szybką odpowiedź!

    Szacunek dla Twojej wiedzy ;)

  18. Witam, posiadam z zakupionym skryptem postawionym na kohanie, otóż skrypt wyświetla się poprawnie w czystej formie po instalacji i tylko pod FF, natomiast po dodaniu jakiegokolwiek kodu, np statystyk w pliku layout_main.php to strona się rozjeżdża, pod samym FF nie ma tragedii natomiast pod IE to totalna porażka…Adres strony to http://www.nabazarze.pl, czytam coś o kohanie powoli, ale nie ogarniam tego za bardzo jeszcze i nie wiem które pliki edytować :P , może ktoś z was pomoże :)

    • Mariusz napisał:

      Za układ i rozmieszczenie nie odpowiada Kohana, tylko HTML i style CSS. Na różnych przeglądarkach może inaczej wyświetlać, nieraz trzeba się namęczyć aby na większości wyglądało OK (na ie zawsze są problemy, zobacz na nowszej wersji). Style masz w /media/css/main.css, więc tam coś ew. poprawiaj.

Dodaj komentarz

Dodając kod PHP używaj tagów: [php][/php]

*