Cod­e­Ig­ni­ter gilt als Web-Ap­pli­ca­ti­on-Framework für Ent­wick­ler, die Ge­schwin­dig­keit einem üppigen Funk­ti­ons­um­fang vorziehen. Zentrales Design-Ziel des quell­of­fe­nen PHP-Frame­works ist es der of­fi­zi­el­len Pro­jekt­sei­te zufolge, ein Maximum an Per­for­mance und Fle­xi­bi­li­tät im kleinst­mög­li­chen Pro­gramm­ge­rüst un­ter­zu­brin­gen.

Was ist Cod­e­Ig­ni­ter?

Bei Cod­e­Ig­ni­ter handelt es sich um ein in PHP ge­schrie­be­nes Web­frame­work, das sich damit rühmt, die Ent­wick­lung von Web­an­wen­dun­gen durch ein kompaktes Software-Design schneller und ef­fi­zi­en­ter zu gestalten. Schöpfer von Cod­e­Ig­ni­ter ist die US-ame­ri­ka­ni­sche Software-Firma EllisLab, die im Februar 2006 die erste öf­fent­li­che Version herausgab. Am 9. Juli 2013 kündigte EllisLab an, die nötigen Res­sour­cen für eine Wei­ter­ent­wick­lung der Software allein nicht mehr auf­brin­gen zu können. Ein Jahr später erfolgte die Übernahme des Projekts durch das British Columbia Institute of Tech­no­lo­gy (BCIT). Der Quellcode des Frame­works steht unter der MIT-Lizenz und kann über den On­line­dienst GitHub bezogen werden. Als letzte stabile Version wird Cod­e­Ig­ni­ter 3.1.2 seit Oktober 2016 auf der of­fi­zi­el­len Pro­jekt­sei­te kostenlos zum Download angeboten.

Aufbau und Struktur des Frame­works

Das Per­for­mance-ori­en­tier­te Design von Cod­e­Ig­ni­ter zeigt sich im schlanken Aufbau des PHP-Frame­works. Dieses ori­en­tiert sich am Software-Ar­chi­tek­tur­mus­ter Model-View-Con­trol­ler (MVC). Das Grund­prin­zip hinter MVC ist die strikte Trennung von Pro­gramm­code und Prä­sen­ta­ti­on. Diese wird durch einen modularen Software-Aufbau und die Aus­la­gereng von PHP-Code rea­li­siert. Man un­ter­schei­det drei zentrale Kom­po­nen­ten: das Da­ten­mo­dell (Model), die Prä­sen­ta­ti­on (View) und die Steuerung (Con­trol­ler).

  • Das Da­ten­mo­dell (Model) re­prä­sen­tiert die Da­ten­struk­tur einer auf Basis von Cod­e­Ig­ni­ter ent­wi­ckel­ten Web­an­wen­dung. Dazu werden im Quellcode so­ge­nann­te Mo­dell­klas­sen („model classes“) definiert. Diese be­inhal­ten spezielle Funk­tio­nen, mit denen In­for­ma­tio­nen aus einer Datenbank abgerufen, in dieser hin­ter­legt oder ak­tua­li­siert werden können.
  • Die Prä­sen­ta­ti­on (View) ist der Teil einer Anwendung, der dem Endnutzer prä­sen­tiert wird. In der Regel handelt es sich dabei um ein HTML-Dokument, in das Inhalte via PHP dynamisch ein­ge­bun­den werden. Ein View ist somit eine Art Template. Cod­e­Ig­ni­ter bietet zudem die Mög­lich­keit, Webpage-Fragmente wie Header und Footer oder RSS-Seiten als View zu de­fi­nie­ren. In der Regel nutzen Web­an­wen­dun­gen mehrere Views, die Ihre Inhalte über dasselbe Da­ten­mo­dell beziehen. So lassen sich un­ter­schied­li­che Programm-Features in ver­schie­de­nen Ansichten prä­sen­tie­ren.
  • Die Steuerung (Con­trol­ler) dient als ver­mit­teln­de Instanz zwischen Model, View und jeder anderen Ressource, die benötigt wird, um eine HTTP-Anfrage zu be­ar­bei­ten oder eine Webpage dynamisch zu erzeugen. Diese Kom­po­nen­te nimmt ein­ge­hen­de Anfragen entgegen, validiert den Input, sucht den ge­wünsch­ten View heraus und reicht Inhalte, die das Da­ten­mo­dell aus einer Datenbank geladen hat, an diesen weiter.

Folgende Grafik zeigt das Zu­sam­men­spiel der MVC-Kom­po­nen­ten in einer sche­ma­ti­schen Dar­stel­lung:

Die MVC-Struktur er­mög­licht ein flexibles Software-Design, bei dem einzelne Programm-Module mit minimalem Aufwand aus­ge­tauscht, über­ar­bei­tet und wie­der­ver­wen­det werden können. Än­de­run­gen an einer Kom­po­nen­te haben in der Regel keine Aus­wir­kung auf den Quellcode anderer Kom­po­nen­ten (vor­aus­ge­setzt es werden keine Än­de­run­gen an den Schnitt­stel­len vor­ge­nom­men).

Die strikte Trennung zwischen Pro­gramm­lo­gik und Prä­sen­ta­ti­on sorgt für einen über­sicht­li­chen, gut struk­tu­rier­ten Pro­gramm­code. Web­ap­pli­ka­tio­nen auf MVC-Basis gelten als war­tungs­freund­lich. Im Feh­ler­fall be­schränkt sich die Suche nach der Feh­ler­quel­le meist auf eine der Kom­po­nen­ten.

Darüber hinaus bietet das MVC-Ar­chi­tek­tur­mus­ter die Mög­lich­keit, Logik und Layout einer Web­an­wen­dung separat zu ent­wi­ckelt. Arbeiten Back-End- und Front-End-Ent­wick­ler dabei parallel, lassen sich An­wen­dun­gen deutlich schneller fer­tig­stel­len.

Cod­e­Ig­ni­ter macht sich MVC zunutze, bindet Anwender jedoch nicht komplett an dieses Ar­chi­tek­tur­mus­ter. Während es sich bei den Kom­po­nen­ten Con­trol­ler und View um ob­li­ga­to­ri­sche Be­stand­tei­le handelt, sind Ver­bin­dun­gen zu Da­ten­ban­ken via Model optional. Darüber hinaus lässt sich eine Anwendung auf Basis von Cod­e­Ig­ni­ter auch mit einer Hier­ar­chi­cal-MVC-Ar­chi­tek­tur (HMVC) rea­li­sie­ren, die das klas­si­sche MVC-Muster um eine hier­ar­chi­sche Logik erweitert.

Der An­wen­dungs­fluss des PHP-Frame­works

Cod­e­Ig­ni­ter basiert auf einem URL-Konzept. Das bedeutet, der Con­trol­ler als zentrale Steu­er­ein­heit zwischen View und Model wird durch die Eingabe einer URL in die Such­leis­te des Web­brow­sers an­ge­spro­chen. Ent­wick­ler erstellen dazu so­ge­nann­te Con­trol­ler-Klassen (classes). Dabei handelt es sich um PHP-Dateien, die diverse Funk­tio­nen be­inhal­ten, um Bi­blio­the­ken (libraries), Er­wei­te­run­gen (plugins) oder Helfer-Klassen (helper) zu laden, Ver­bin­dun­gen zu Da­ten­ban­ken her­zu­stel­len, ein Da­ten­mo­dell ein­zu­bin­den oder einen be­stimm­ten View her­aus­zu­su­chen.

Der An­wen­dungs­fluss von Cod­e­Ig­ni­ter basiert dabei auf folgendem URL-Grund­sche­ma:

example.com/class/function/parameter

Auf die Domain (example.com) folgt eine Con­trol­ler-Klasse, die an­ge­spro­chen werden soll, sowie eine bestimmte Con­trol­ler-Funktion. Den Abschluss bilden optionale Parameter. Diese dienen dazu, dem aus­ge­wähl­ten Con­trol­ler IDs oder Variablen zu übergeben.

In der Praxis könnte eine Cod­e­Ig­ni­ter-URL wie folgt aussehen:

example.com/news/article/511

Eine solche URL spricht den Con­trol­ler news auf der Domain example.com an und ver­an­lasst diesen, die Funktion article aus­zu­füh­ren (bei­spiels­wei­se, um einen gleich­na­mi­gen View für die Ar­ti­kel­an­sicht zu laden). Welche Inhalte über das Da­ten­mo­dell aus der Datenbank abgerufen werden sollen, geben optionale Parameter an, die dem Con­trol­ler mit der URL übergeben werden – in diesem Beispiel ein Artikel mit der ID 511.

In der Aus­gangs­kon­fi­gu­ra­ti­on führt Cod­e­Ig­ni­ter die index.php in jeder An­wen­dungs-URL auf:

example.com/index.php/news/article/511

Diese PHP-Datei be­inhal­tet In­for­ma­tio­nen darüber, wo sich die Core-Dateien des Frame­works sowie ein­ge­bun­de­ne Bi­blio­the­ken, Er­wei­te­run­gen oder Helfer-Klassen befinden und in welchem Ver­zeich­nis die Ap­pli­ka­ti­ons­da­tei­en liegen. Die index.php dient somit der In­itia­li­sie­rung sämt­li­cher Ba­sis­res­sour­cen.

Läuft Cod­e­Ig­ni­ter auf einem Apache HTTP Server, lässt sich die index.php via mod_rewrite aus den An­wen­dungs-URLs entfernen, um End­nut­zern und Such­ma­schi­nen-Crawlern „saubere“ Web­adres­sen zur Verfügung zu stellen. Ent­wick­ler fügen dazu folgenden Codeblock in die .htaccess-Datei des Web­ser­vers ein:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

Die Grund­struk­tur des PHP-Frame­works stützt sich in erster Linie auf Con­trol­ler-Klassen, Modell-Klassen und View-Templates.

Con­trol­ler-Klassen

Cod­e­Ig­ni­ter bietet Ent­wick­lern die Mög­lich­keit, in­di­vi­du­el­le Con­trol­ler als be­nut­zer­de­fi­nier­te Klassen zu pro­gram­mie­ren. Dazu legen Web­ent­wick­ler für jeden Con­trol­ler eine separate PHP-Datei im Ver­zeich­nis ap­pli­ca­ti­on/con­trol­lers/ an. Con­trol­ler enthalten die Pro­gramm­lo­gik einer mit Cod­e­Ig­ni­ter ent­wi­ckel­ten Web­an­wen­dung und werden als Un­ter­klas­sen der CI_Con­trol­ler class erstellt. Im Quellcode rea­li­sie­ren Pro­gram­mie­rer dies mithilfe des Schlüs­sel­worts extends.

class News extends CI_Controller {
}

Als un­ter­ge­ord­ne­te Klasse erbt News von der El­tern­klas­se CI_Con­trol­ler sämtliche Funk­tio­nen der Sicht­bar­keit public und protected.

Tipp

Die Schlüs­sel­wör­ter public, protected oder private dienen in PHP dazu, die Sicht­bar­keit einer Ei­gen­schaft oder Funktion zu de­fi­nie­ren. Wird ein Element als public de­kla­riert, haben alle Klassen einer Software Zugriff auf das Element. Soll dieser Zugriff auf El­tern­klas­sen und ab­ge­lei­te­te Klassen be­schränkt werden, verwenden Pro­gram­mie­rer das Schlüs­sel­wort protected. Ein Element, das als private de­kla­riert wurde, steht lediglich der Klasse zur Verfügung, die das Element definiert.

Jede be­nut­zer­de­fi­nier­te Con­trol­ler-Klasse muss zudem eine Kon­struk­tor-Funktion enthalten, mit der sich Bi­blio­the­ken, ein Da­ten­mo­dell, Da­ten­ban­ken oder Helfer-Klassen einbinden lassen. Ab PHP5 wird __construct() als stan­dar­di­sier­te Kon­struk­tor-Funktion verwendet.

<?php
class News extends CI_Controller {
    public function __construct() {        //definiert den Konstruktor 
        parent::__construct();        //ruft den Konstruktor der übergeordneten Klasse ab 
        $this->load->helper('url');        //lädt eine Helfer-Klasse für die Arbeit mit URLs
        $this->load->helper('file');        //lädt eine Helfer-Klasse für die Arbeit mit Dateien
        $this->load->database();        //lädt eine Datenbank
        $this->load->model('News_model');    //lädt ein Model mit dem Namen „News_model“ 
}
?>

Das Beispiel zeigt die Klasse News als Un­ter­klas­se von CI_Con­trol­ler. Die Kon­struk­tor-Funktion __construct() bindet zwei Helfer-Klassen, eine Datenbank und das Da­ten­mo­dell News_model ein. Die einzelnen Code­zei­len sind im Quelltext aus­kom­men­tiert.

Hinweis

Alle Con­trol­ler-Klassen, die in PHP für Cod­e­Ig­ni­ter definiert werden, müssen mit einem Groß­buch­sta­ben beginnen (News statt news). In der URL schreibt man sie hingegen klein.

Con­trol­ler-Funk­tio­nen

Steht das Grund­ge­rüst des be­nut­zer­de­fi­nier­ten Con­trol­lers, folgt die ei­gent­li­che Pro­gramm­lo­gik in Form von Con­trol­ler-Funk­tio­nen, mit denen sich Views abrufen oder In­ter­ak­tio­nen mit einem ein­ge­bun­de­nen Da­ten­mo­dell rea­li­sie­ren lassen.

Damit der Con­trol­ler einen View laden kann, muss das zu­grun­de­lie­gen­de HTML-Dokument als PHP-Datei im Ver­zeich­nis ap­pli­ca­ti­on/views/ abgelegt werden. Ein einfacher View für eine Ar­ti­kel­an­sicht könnte bei­spiels­wei­se so aussehen:

<!DOCTYPE html>
<html lang="de">
  <head>
    <meta charset="utf-8">
    <title><?php echo $title; ?></title>
 </head>
 <body >
    <h1><?php echo $headline ?></h1>
    <p><?php echo  $content_body ?></p>
 </body>
</html>
Tipp

HTML-Dokumente, die PHP-Code enthalten, müssen als PHP-Dateien ge­spei­chert werden (.php). Nur so lässt sich si­cher­stel­len, dass der PHP-In­ter­pre­ter des Web­ser­vers Skripts ausführt und den PHP-Code nicht lediglich als Text ausgibt.

Um einen View in den Con­trol­ler zu laden, wird eine be­nut­zer­de­fi­nier­te Funktion benötigt. Im nach­fol­gen­den Code­bei­spiel kommt die Funktion article() zum Einsatz, um den View article.php zu laden.

public function article() {
    if (!file_exists(application/views/article.php)) {
        show_404();
    }
$this->load->view('article');
}

Der Pro­gramm­code liest sich wie folgt: Zunächst prüft Cod­e­Ig­ni­ter, ob das Ver­zeich­nis ap­pli­ca­ti­on/views/ eine Datei mit dem Namen article.php enthält. Diese Abfrage wird durch das Sprach­kon­strukt if und die verneinte (!) Bedingung file exists() rea­li­siert.

Trifft die Bedingung zu und es findet sich keine gleich­na­mi­ge Datei im ent­spre­chen­den Ver­zeich­nis, gibt if den Wert TRUE zurück, und Cod­e­Ig­ni­ter führt die unter if auf­ge­führ­te Funktion show_404() aus. Ein Anwender bekäme in diesem Fall den Hinweis, dass die an­ge­frag­te Datei nicht existiert. Ist die if-Bedingung jedoch nicht erfüllt und wird !file_exists als FALSE evaluiert, führt Cod­e­Ig­ni­ter die Funktion $this->load->view('article') aus. Diese dient dazu, die ent­spre­chen­de Datei als View in die Anwendung zu laden.

Sofern es sich um das Format PHP handelt, kann die ge­wünsch­te Datei in der Funktion view() ohne Suffix auf­ge­führt werden. Sollen andere Formate geladen werden, ist das jeweilige Da­tei­suf­fix ob­li­ga­to­risch.

Cod­e­Ig­ni­ter kommt in der Regel im Rahmen dy­na­mi­scher Web­an­wen­dun­gen zum Einsatz. Diese spielen Anwendern statt sta­ti­scher HTML-Seiten dynamisch erzeugte Webpages aus. Dies lässt sich rea­li­sie­ren, indem man den View mit Daten füllt, die den Pa­ra­me­tern ent­spre­chen, die Cod­e­Ig­ni­ter mit der URL übergeben bekommt.

example.com/news/article/511

Bisher wurde mit der Funktion $this->load->view('article') lediglich eine Ansicht für die Ar­ti­kel­dar­stel­lung geladen. Nun gilt es, speziell die Inhalte ein­zu­bin­den, die mit dem Parameter 511 verknüpft sind. Wir gehen davon aus, dass sich dabei um eine ID handelt, die mithilfe eines Datenbank-Ma­nage­ment-Systems mit einem be­stimm­ten News­ar­ti­kel verbunden ist. Um diesen aus der Datenbank ins Programm zu laden, muss das oben­ste­hen­de Beispiel so ergänzt werden, dass das im Kon­struk­tor ein­ge­bun­de­ne Da­ten­mo­dell an­ge­spro­chen wird.

public function article($id) {
    if (!file_exists(application/views/article.php)) {
        show_404();
    }
    $data = $this->News_model->get_data($id);
    $this->load->view('article', $data);}

Das über­ge­be­ne Funk­ti­ons­ar­gu­ment (hier unter dem Va­ria­blen­na­men $id) ent­spricht dem ID-Teil der URL – bei­spiels­wei­se 511. Die noch zu schrei­ben­de Modell-Funktion get_data() dient dazu, den mit der ID ver­knüpf­ten Ar­ti­kel­in­halt aus der Datenbank zu laden. Die view()-Methode ruft den article-View auf und übergibt ihm diese Daten in Form eines as­so­zia­ti­ven Arrays ($data). Das Da­ten­mo­dell News_model übergibt also die aus­ge­le­se­nen Daten dem Con­trol­ler News, der diese an den View wei­ter­reicht.

Alle mit dem Da­ten­ab­ruf ver­bun­de­nen Ope­ra­tio­nen werden an das ein­ge­bun­de­ne Da­ten­mo­dell aus­ge­la­gert.

Modell-Klassen

Da­ten­mo­del­le kommen bei Cod­e­Ig­ni­ter zum Einsatz, um Funk­tio­nen be­reit­zu­stel­len, mit denen sich bestimmte Datenbank-Ope­ra­tio­nen durch­füh­ren lassen. Genau wie Con­trol­ler-Klassen lassen sich auch Modell-Klassen mit dem PHP-Framework be­nut­zer­de­fi­niert pro­gram­mie­ren.

Um eine Modell-Klasse anzulegen, wird zunächst ein Klas­sen­na­me vergeben – in diesem Fall News_model. Analog zu Con­trol­ler-Klassen sind alle be­nut­zer­de­fi­nier­ten Modell-Klassen Un­ter­klas­sen der El­tern­klas­se CI_Model. Die Vererbung wird durch das Schlüs­sel­wort extends rea­li­siert. Auch Modell-Klassen binden Da­ten­ban­ken und andere Res­sour­cen über die Kon­struk­tor-Funktion ein.

class News_model extends CI_Model {
    public function __construct() {
        parent::__construct();
        $this->load->database(); 
    }
}

Auf diese Grund­struk­tur folgen so­ge­nann­te Modell-Funk­tio­nen, in denen Ent­wick­ler alle Datenbank-Ope­ra­tio­nen de­fi­nie­ren, die dem Con­trol­ler über das jeweilige Da­ten­mo­dell zur Verfügung stehen sollen.

Modell-Funk­tio­nen

Modell-Klassen er­mög­li­chen es Ent­wick­lern, in­di­vi­du­el­le Funk­tio­nen für Datenbank-Ope­ra­tio­nen zu de­fi­nie­ren. In einem vor­her­ge­hen­den Beispiel haben wir in der Con­trol­ler-Klasse News die be­nut­zer­de­fi­nier­te Funktion get_data() verwendet, um Ar­ti­kel­in­hal­te aus der Datenbank in den View zu laden. Im Modell de­fi­nie­ren wir nun, welche Datenbank-Ope­ra­tio­nen sich hinter dieser Funktion verbergen.

class News_model extends CI_Model {
    public function __construct() {
        parent::__construct();
        $this->load->database(); 
    }
public function get_data($id) {
     $this->db->select('content');
     $this->db->from('example_table');
     $this->db->where('id', $id);
    $query = $this->db->get();
    return $query->result();
}

In der Mo­dell­klas­se News_model wird die oben benutzte Funktion get_data() als Datenbank-Operation definiert, die die unter select() an­ge­ge­be­ne Spalte des Da­ten­sat­zes mit der über­ge­be­nen ID-Nummer ($id) aus der unter from() an­ge­ge­be­nen Da­ten­bank­ta­bel­le via get() abfragt und mithilfe der Funktion result() als Array zu­rück­gibt. Ein Da­ten­mo­dell stellt in der Regel eine Vielzahl an Modell-Funk­tio­nen bereit. Ent­wick­ler können dabei auf die Klasse Query Builder zu­rück­grei­fen, die eine Reihe vor­de­fi­nier­ter Funk­tio­nen für klas­si­sche Datenbank-Ope­ra­tio­nen umfasst. Einen Überblick finden Sie in der of­fi­zi­el­len Do­ku­men­ta­ti­on des Cod­e­Ig­ni­ter Frame­works.

Routing mit Cod­e­Ig­ni­ter

Welche Con­trol­ler-Klasse und -Funktion an­ge­spro­chen werden sollen, wird Cod­e­Ig­ni­ter mit einer URL vor­ge­ge­ben. Das Web­frame­work nutzt dafür die URL-Struktur Klasse/Funktion/Parameter. Dieses Grund­sche­ma lässt sich bei Bedarf anpassen. Cod­e­Ig­ni­ter stellt dazu die Datei routes.php im Ver­zeich­nis ap­pli­ca­ti­on/config/ zur Verfügung. Diese enthält ein Array namens $route, das es Ent­wick­lern er­mög­licht, eigene Routing-Kriterien zu de­fi­nie­ren.

In der Aus­gangs­kon­fi­gu­ra­ti­on finden sich im Array $route drei Default-Einträge: der Standard-Con­trol­ler, eine Routing-Regel für das 404-Override sowie eine Regel für das au­to­ma­ti­sche Ersetzen von Bin­de­stri­chen (-) durch Un­ter­stri­che (_).

$route['default_controller'] = 'home/welcome';
$route['404_override'] = 'home/welcome';
$route['translate_uri_dashes'] = FALSE;

Der erste Default-Eintrag bestimmt den Standard-Con­trol­ler der Anwendung. Dieser wird von Cod­e­Ig­ni­ter immer dann geladen, wenn eine URL außer der Domain keine weiteren Routing-In­for­ma­tio­nen enthält. Im aktuellen Beispiel definiert die Routing-Regel die Con­trol­ler-Klasse home als Standard-Con­trol­ler. Besucher, die in der URL keine Angaben zur Ziel-Webpage machen, werden somit auf home um­ge­lei­tet und bekommen den View welcome prä­sen­tiert. Üblich ist eine Umleitung auf die Start­sei­te. Wurde kein Con­trol­ler als Standard definiert, zeigt Cod­e­Ig­ni­ter beim Aufruf der Start­sei­te eine 404-Feh­ler­sei­te an.

Der zweite Default-Eintrag im $route-Array definiert einen Con­trol­ler, der immer dann auf­ge­ru­fen wird, wenn der durch die URL an­ge­spro­che­ne Con­trol­ler in den Ap­pli­ka­ti­ons­da­tei­en nicht gefunden wurde. Die Routing-Regel $route['404_override'] = 'home' über­schreibt die 404-Feh­ler­sei­te, die in einem solchen Fall nor­ma­ler­wei­se aus­ge­spielt wird, und leitet statt­des­sen auf die Con­trol­ler-Klasse home um.

Der dritte Default-Eintrag im $route-Array ver­hin­dert Routing-Fehler aufgrund von Bin­de­stri­chen. Der Bin­de­strich ist kein valides Zeichen für Klassen- oder Funk­ti­ons­na­men und wird daher bereits in der Stan­dard­e­i­stel­lung in URLs au­to­ma­tisch ersetzt.

Soll eine be­nut­zer­de­fi­nier­te Routing-Regel für eine dy­na­mi­sche URL erstellt werden, stehen Web­ent­wick­lern mit Cod­e­Ig­ni­ter zwei Mög­lich­kei­ten zur Verfügung: Routing-Einträge für dy­na­mi­sche URLs lassen sich mit Wildcards (Platz­hal­ter) oder mit regulären Aus­drü­cken de­fi­nie­ren.

Die routes.php un­ter­stützt zwei Arten von Platz­hal­tern:

Hinweis

Webseiten mit einer großen Anzahl an 404-Feh­ler­sei­ten sind schlecht zu crawlen und er­schwe­ren Such­ma­schi­nen den Zugriff auf relevante Inhalte. Dies kann – neben den Aus­wir­kun­gen auf die User-Ex­pe­ri­ence – einen negativen Einfluss auf das Ranking in der Such­ma­schi­ne haben. In der Regel sind Web­ent­wick­ler daher bemüht, 404-Feh­ler­sei­ten zu vermeiden.

Wildcards der routes.php Be­schrei­bung
:num Fungiert als Platz­hal­ter für Integer (Ganz­zah­len)
:any Fungiert als Platz­hal­ter für einen String (Zei­chen­ket­te)

Folgendes Bespiel zeigt einen Eintrag in der routes.php, der es er­mög­licht, die Funktion (article) aus der URL zu streichen:

$route['news/article/(:num)'] = 'news/$1';

Durch den Platz­hal­ter :num wird der Parameter einer dy­na­mi­schen URL aus­ge­le­sen und in der Variablen $1 ge­spei­chert. Sofern Sie Routing-Regeln mit :num oder :any de­fi­nie­ren, müssen Sie diese in der routes.php in einfache Klammern setzen.

Die routes.php ak­zep­tiert zudem Routing-Regeln in Form von regulären Aus­drü­cken. Die beiden Platz­hal­ter-Typen lassen sich somit auch fol­gen­der­ma­ßen notieren:

:num entspricht \d+
:any entspricht [^/]+

Eine Al­ter­na­ti­ve zum oben­ste­hen­den Beispiel wäre somit folgende Schreib­wei­se:

$route['news/article/(\d+ )'] = 'news/$1';

Auch reguläre Ausdrücke werden in der routes.php ein­ge­klam­mert.

Der An­wen­dungs­fluss im Überblick

Folgende Grafik fasst den Ap­pli­ca­ti­on Flow einer Anwendung auf Basis von Cod­e­Ig­ni­ter in sieben Schritten zusammen:

1. Die index.php dient Cod­e­Ig­ni­ter als Front-Con­trol­ler für ein­ge­hen­de HTTP-Requests. Hier werden alle Ba­sis­res­sour­cen in­itia­li­siert, die benötigt werden, um die Anwendung aus­zu­füh­ren.

2. Im Rahmen des Routings prüft Cod­e­Ig­ni­ter, welche Aktion aus­ge­führt werden soll. Dazu gleicht die Anwendung die URL in der Anfrage mit den in der routes.php de­fi­nier­ten Routing-Regeln ab.

3. Auf das Routing folgt das Caching. Findet sich eine zum Request passende Antwort im Cache der Anwendung, wird diese direkt an den an­fra­gen­den Web­brow­ser aus­ge­lie­fert. An­dern­falls wird der während des Routings er­mit­tel­te Con­trol­ler mit vor­ge­schal­te­ter Fil­ter­funk­ti­on aus­ge­führt.

4. Das Cod­e­Ig­ni­ter-Framework be­inhal­tet einen in­te­grier­ten Filter, der schäd­li­che Anfragen abfängt. Bevor die Anwendung einen zur Anfrage passenden Con­trol­ler lädt, wird jeder HTTP-Request einem Si­cher­heits­check un­ter­zo­gen.

5. Passiert die Anfrage den Filter, wird der Con­trol­ler aus­ge­führt. Dieser wählt einen passenden View aus und lädt das Da­ten­mo­dell sowie alle Bi­blio­the­ken, Helfer-Klassen, Er­wei­te­run­gen und Skripte, die benötigt werden, um die Anfrage zu be­ant­wor­ten.

6. Sobald dem View alle re­le­van­ten Daten übergeben wurden, kann dieser an den Web­brow­ser aus­ge­lie­fert werden.

7. Ist ein Caching aktiviert, hält Cod­e­Ig­ni­ter aus­ge­hen­de Daten temporär vor, um sich wie­der­ho­len­de Abfragen direkt be­ant­wor­ten zu können.

Vorteile des Cod­e­Ig­ni­ter Frame­works

Mit mehr als 13.000 Sternen ist Cod­e­Ig­ni­ter ein viel be­ach­te­tes GitHub-Ent­wick­lungs­pro­jekt und auf Platz 3 der be­lieb­tes­ten PHP-Frame­works. Doch wie jede Software hat Cod­e­Ig­ni­ter sowohl Vor- als auch Nachteile. Diese gilt es ge­gen­ein­an­der abzuwägen, bevor Sie sich als Web­ent­wick­ler für das schlanke PHP-Framework ent­schei­den. Dies sind die Vorteile der Anwendung:

  • Geringer Kon­fi­gu­ra­ti­ons­auf­wand: Cod­e­Ig­ni­ter bietet einen schnellen Einstieg. Nutzer brauchen sich nicht lange mit der Kon­fi­gu­ra­ti­on des Frame­works aufhalten, sondern können nahezu un­mit­tel­bar nach der In­stal­la­ti­on mit der Ent­wick­lung der geplanten Anwendung beginnen. Der Kon­fi­gu­ra­ti­ons­auf­wand be­schränkt sich im We­sent­li­chen auf die Ein­stel­lun­gen in der config.php im Ver­zeich­nis ap­pli­ca­ti­on/config/. Anwender de­fi­nie­ren hier einen Stan­dard­pfad für den Zugriff per Web­brow­ser, einen Schlüssel für die Ver­schlüs­se­lung, einen Namen für den Session-Cookie und Ein­stel­lun­gen zum Cross-Site-Scripting (XSS). Zudem empfiehlt es sich, eine .htaccess-Datei anzulegen, um die index.php via Re­wri­te­Rule aus dem Pfad der An­wen­dungs-URLs zu entfernen. Darüber hinaus ist eine Kon­fi­gu­ra­tio­nen der Datenbank-Ver­bin­dung notwendig, die Sie in die Datei database.php eintragen.
  • Small Footprint: Cod­e­Ig­ni­ter hin­ter­lässt nur einen kleinen Fuß­ab­druck im System. Das Download-Paket des Frame­works umfasst rund 11 MB. Mehr als 9 MB entfallen dabei auf die aus­führ­li­che Do­ku­men­ta­ti­on der Software. Der geringe Co­de­um­fang kommt dadurch zustande, dass das Cod­e­Ig­ni­ter-Ba­sis­sys­tem lediglich ein paar kleine Bi­blio­the­ken umfasst. Zu­sätz­li­che Res­sour­cen lassen sich bei Bedarf laden.
  • Sehr gute Per­for­mance: Das schlanke Ba­sis­sys­tem führt dazu, dass Cod­e­Ig­ni­ter im Vergleich zu anderen PHP-Frame­works mit einer hohen Ge­schwin­dig­keit punkten kann. Gelobt wurde diese u. a. vom PHP-Erfinder Rasmus Lerdorf. Dieser ver­kün­de­te 2008 auf der Free and Open Source Con­fe­rence (FrOSCon), dass ihm Cod­e­Ig­ni­ter gefalle, da es schneller, leicht­ge­wich­ti­ger und weniger wie ein Framework sei („because it is faster, lighter and the least like a framework“).
  • „Saubere“ URLs: Cod­e­Ig­ni­ter generiert au­to­ma­tisch nut­zer­freund­li­che, such­ma­schi­nen­ge­eig­ne­teURLs. Statt den Zugriff auf dy­na­mi­sche Web­in­hal­te wie andere PHP-Frame­works durch Query Strings zu rea­li­sie­ren, setzt Cod­e­Ig­ni­ter auf einen seg­ment­ba­sier­ten Ansatz.
    URL mit Query String: example.com?con­trol­ler=news&function=article&id=511
    Seg­ment­ba­sier­te URL: example.com/news/article/511.
  • Freier Pro­gram­mier­stil: Cod­e­Ig­ni­ter basiert auf einer freien In­ter­pre­ta­ti­on des MVC-Ar­chi­tek­tur­mus­ters. Ent­wick­lern ist somit kein Pro­gram­mier­stil vor­ge­ge­ben.
  • Um­fang­rei­che Do­ku­men­ta­ti­on: Cod­e­Ig­ni­ter verfügt über eine aus­führ­li­che Do­ku­men­ta­ti­on in eng­li­scher Sprache inklusive Ein­stei­ger-Tutorial. Zudem ist der Quellcode über­sicht­lich und gut kom­men­tiert. Die Cod­e­Ig­ni­ter-Do­ku­men­ta­ti­on steht auf der Projekt-Website als On­lin­egui­de und Download-Version zur Verfügung.
  • Community-Support: Ent­wick­ler, die An­wen­dun­gen auf Basis von Cod­e­Ig­ni­ter ent­wi­ckeln, können sich auf die Hilfe anderer Nutzer stützen. Das Projekt wird von einer aktiven Community begleitet. Ein öf­fent­li­ches Forum wird unter https://forum.cod­e­ig­ni­ter.com angeboten. Aktuell tauschen sich dort mehr als 7.300 Anwender in rund 65.000 Threads über den Einsatz und die Wei­ter­ent­wick­lung des Frame­works aus.

Nachteile des Cod­e­Ig­ni­ter-Frame­works

Da die Ent­wick­lung des Cod­e­Ig­ni­ter-Frame­works vor der Übernahme durch das BCIT zeitweise sta­gnier­te, suchen Ent­wick­ler einige tech­no­lo­gi­sche Ent­wick­lun­gen, die von ver­gleich­ba­ren Frame­works in den ver­gan­ge­nen Jahren adaptiert wurden, bei Cod­e­Ig­ni­ter ver­geb­lich.

  • ORM nur über Dritt­an­bie­ter: Unter ob­jekt­re­la­tio­na­ler Abbildung („object-re­la­tio­nal mapping“, ORM) versteht man eine Technik der Software-Ent­wick­lung, die es An­wen­dun­gen er­mög­licht, in einer ob­jekt­ori­en­tier­ten Pro­gram­mier­spra­che wie PHP ge­schrie­be­ne Objekte in einer re­la­tio­na­len Datenbank abzulegen. Cod­e­Ig­ni­ter un­ter­stützt ORM nicht nativ. Die Technik kann jedoch durch Dritt­an­bie­ter ein­ge­bun­den werden.
  • Keine Template-Engine: Cod­e­Ig­ni­ter rühmt sich damit, ohne Template-Engine aus­zu­kom­men. Statt­des­sen stellt das Framework optional einen einfachen Template-Parser zur Verfügung. Dies kann als Vorteil angesehen werden. Der Einsatz einer Template-Engine ist in der Regel mit einem Per­for­mance-Overhead (Zu­satz­auf­wand zur Laufzeit) verbunden. Darüber hinaus muss zu­sätz­lich zum Framework auch der Gebrauch der Template-Sprache erlernt werden. An­de­rer­seits erlaubt es eine Template-Engine, die Da­ten­ge­ne­rie­rung vom Code für die Prä­sen­ta­ti­on zu se­pa­rie­ren, und führt so in der Regel zu einem über­sicht­lich struk­tu­rier­ten Quellcode. Kommt eine Template-Engine mit schlanker Syntax zum Einsatz, kann dies den Ge­samt­um­fang des Ap­pli­ca­ti­on-Codes deutlich re­du­zie­ren.
  • Kein Name­spa­cing: Mit Name­spaces bietet PHP die Mög­lich­keit, Code ver­schie­de­ner An­wen­dungs­grup­pen zu trennen. PHP-Ent­wick­ler machen sich dieses Feature zunutze, um Konflikte zu vermeiden, die bei der Benennung von Klassen und Funk­tio­nen auftreten. Gängig sind bei­spiels­wei­se Na­mens­kol­li­sio­nen mit internen PHP-Klassen, -Funk­tio­nen, -Kon­stan­ten oder -Elementen, die von Dritt­an­bie­tern ein­ge­bun­den werden. Cod­e­Ig­ni­ter nutzt dieses PHP-Feature bislang nicht.
  • Kein PHP-Auto-Loading: Seit Version 5 bietet PHP mit __autoload() und spl_autoload_register() zwei Funk­tio­nen, die es er­mög­li­chen, Klas­sen­de­fi­ni­tio­nen bei Bedarf au­to­ma­tisch zu laden. Im Cod­e­Ig­ni­ter-Framework steht dieses Feature nicht zur Verfügung.
  • Weniger Built-in-Bi­blio­the­ken als andere PHP-Frame­works: Aufgrund des schlanken Software-Designs bietet Cod­e­Ig­ni­ter in der Aus­gangs­kon­fi­gu­ra­ti­on deutlich weniger Bi­blio­the­ken als andere PHP-Frame­works. Diese umfassen in erste Linie die wich­tigs­ten Aufgaben der Web­ent­wick­lung wie Da­ten­bank­zu­grif­fe, E-Mail-Versand, die Va­li­die­rung von For­mu­lar­da­ten, das Auf­recht­erhal­ten von Sessions oder die Arbeit mit XML-RPC. Für Aufgaben, die über die Basis-Features hin­aus­ge­hen, müssen eigene Bi­blio­the­ken oder Res­sour­cen von Dritt­an­bie­tern ein­ge­bun­den werden. Ein Punkt, den Ent­wick­lern, die ein auf das Minimum re­du­zier­tes Framework suchen, auch als Vorteil in­ter­pre­tie­ren können.

Cod­e­Ig­ni­ter für den eiligen Leser

Nach­ste­hen­de Tabelle zeigt die Eckdaten des Cod­e­Ig­ni­ter-Frame­works in der Übersicht:

Cod­e­Ig­ni­ter
Ent­wick­ler British Columbia Institute of Tech­no­lo­gy (BCIT)
Aktuelles Release Version 3.1.2
Design-Muster MVC/HMVC, Active Record, Chain of Re­spon­si­bi­li­ty
Benötigte Kennt­nis­se PHP, Ob­jekt­ori­en­tier­te Pro­gram­mie­rung (OOP)
Pro­gram­mier­spra­che PHP 5.6 oder höher
Lizenz MIT-Lizenz
Da­ten­bank­un­ter­stüt­zung MySQL (5.1+), Oracle, Post­greS­QL, MS SQL, SQLite, CUBRID, Interbase/Firebird, ODBC
ORM Nur über Dritt­an­bie­ter
Caching ja
Template-Engine nein
Name­spaces nein
PHP-Auto-Loading nein
Such­ma­schi­nen­freund­li­che URLs nein
Si­cher­heits-Features Cross-Site-Request-Forgery (XSRF), Cross-Site-Scripting (XSS), SQL-Injection
Testing-Library PHP Unit
Fazit

Mit seinem kompakten Design und der ein­steig­er­freund­li­chen Syntax eignet sich Cod­e­Ig­ni­ter vor allem für angehende Pro­gram­mie­rer. Wer bereits erste Er­fah­run­gen mit der dy­na­mi­schen Web­ent­wick­lung auf Basis von PHP gemacht hat, wird sich auch in das PHP-basierte Light­weight-Framework in kürzester Zeit ein­ar­bei­ten. Und auch er­fah­ren­de Web­ent­wick­ler schätzen die Fle­xi­bi­li­tät, die ihnen ein auf Grund­funk­tio­na­li­tä­ten re­du­zier­tes PHP-Framework einräumt.

Wer Cod­e­Ig­ni­ter nutzen möchte, sollte sich jedoch mit dem MVC-Ar­chi­tek­tur­mus­ter an­freun­den und auf eine Template-Engine sowie natives ORM ver­zich­ten können. Trotz minimalem Co­de­um­fang eignet sich Cod­e­Ig­ni­ter glei­cher­ma­ßen für kleine und große Web­pro­jek­te.

Zum Hauptmenü