Einstieg in Symfony2

In diesem Tutorial wird eine erste kleine CRUD-Anwendung mit Symfony2 erstellt.

Composer installieren

Mit Hilfe des PHP Dependency Managers Composer kann Symfony2 inklusive aller benötigten und zukünftig anfallenden Abhängigkeiten relativ leicht installiert werden. Das folgende Tutorial bezieht sich auf *nix-Artige Betriebssyteme (in meinem Fall Mac OSX).

Mit den folgenden beiden CLI-Befehlen wird Composer global installiert:

$ curl -sS https://getcomposer.org/installer | php
$ mv composer.phar /usr/local/bin/composer

Dabei muss natürlich /usr/local/bin/ in der Shell-Variable $PATH enthalten sein, was mit einem

$ echo $PATH

überprüft werden kann. Sollte dies untypischerweise nicht der Fall sein, bitte folgende Zeile in die ~/.bash_profile eintragen:

export PATH=/usr/local/bin:$PATH

Anschließend entweder das Terminal neu starten oder folgendes Kommando absetzen:

$ source ~/.bash_profile

Symfony2-Projekt erstellen

Nachdem der Composer global verfügbar ist, kann das erste Symfony2-Projekt erstellt werden.

$ composer create-project symfony/framework-standard-edition symfony2.local 2.4.*

symfony2.local ist dabei das Zielverzeichnis und 2.4.* die zu installierende Symfony-Version. Während der Installation werden bereits einige Zugangsdaten konfiguriert und in die Datei app/config/parameters.yml geschrieben. Ist die Website fertig eingerichtet, können die Parameter auch im Browser über http://DOMAIN.TLD/config.php geändert werden.

Wie auch in der offiziellen Dokumentation beschrieben, passe ich mit folgenden Zeilen die Benutzerrechte des Systems an:

$ rm -rf app/cache/*
$ rm -rf app/logs/*
$ APACHEUSER=`ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data' | grep -v root | head -1 | cut -d\  -f1`
$ sudo chmod +a "$APACHEUSER allow delete,write,append,file_inherit,directory_inherit" app/cache app/logs
$ sudo chmod +a "`whoami` allow delete,write,append,file_inherit,directory_inherit" app/cache app/logs

Per $ composer install können alle in der Datei composer.json definierten Abhängigkeiten jederzeit aktualisiert werden.

Host und Webserver konfigurieren

Ein neuer Eintrag in der /etc/hosts

127.0.0.1 symfony2.local

und folgende Ergänzung in /etc/apache2/extra/httpd-vhosts.conf

<VirtualHost *:80>
    ServerName symfony2.local
    DocumentRoot "/PFAD-ZUM-PROJEKT/symfony2.local/web"
    <Directory "/PFAD-ZUM-PROJEKT/symfony2.local/web">
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

sorgen dafür, dass das Projekt im Browser per http://symfony2.local/app_dev.php erreichtbar ist. (Bitte nicht vergessen den Apache mit sudo apachectl restart neu zu starten).

Um zu prüfen, ob der Webserver richtig konfiguriert ist, steht folgendes CLI-Kommando zur Verfügung:

$ php app/check.php

Source code management

Wie vielleicht bereits bemerkt, liegt im Root-Verzeichnis des Projekts bereits die Datei .gitignore. Einzelheiten zur Verwendung der Versionsverwaltung git im Zusammenhang mit Symfony werden unter How to Create and store a Symfony2 Project in Git beschrieben.

Bundles

Einer der entscheidenden Unterschiede zu Symfony Version 1.x ist die Einführung der Bundles:

Bundles sind voneinander gelöste Einheiten einer Webapplikation. Ein Gästebuch-Bundle enthält demnach alle Daten, die zur vollständigen Lauffähigkeit des Gästebuchs dienen. Dazu gehören nicht nur die erforderlichen Klassen, sondern auch Ressourcen (Grafiken, Scripts etc.). Entwickler können entwickelte Bundles veröffentlichen, so dass andere Nutzer von Symfony 2 diese Applikationseinheit ohne Codeänderungen implementieren können. [Wikipedia]

Wie das mit der Basis-Installation ausgelieferte Bundle AcmeDemoBundle deinstalliert werden kann, wird hier beschrieben: How to remove the AcmeDemoBundle.

Das Default-CLI von Symfony2 bietet zwar bereits einige Tools:

$ app/console

SensioGeneratorBundle

Mit Hilfe des Bundles SensioGeneratorBundle kann es aber, wie aus Symfony1 gewohnt, um zahlreiche Funktionen für das Scaffolding und Erstellen von CRUD-Skeletons erweitert werden.

Zur Installation muss "sensio/generator-bundle": "2.3.*" im Eintrag require in der Datei composer.json hinzugefügt werden (Siehe auch Packagist). Für den Download dann $ composer install ausführen.

In der Datei app/AppKernel.php ist das Bundle bereits aktiviert.

Mein erstes Bundle

Zeit für das erste eigene Bundle:

$ php app/console generate:bundle

Als Namespace (muss mit “Bundle” enden) wähle ich Mettbox\MapObjectBundle (geplant ist, diese Projekt für eine GoogleMap-Anwendung zu nutzen…). Als Konfigurationsformat gebe ich Yaml (yml), weil ich dies bereits aus Symfony 1.4 gut kenne. Bei der Frage Do you want to generate the whole directory structure [no]? ändere ich den Defaultwert auf yes, ansonsten stimme ich allen anderen Vorschlägen zu.

Ob wirklich nötig, weiß ich noch nicht, aber vorsichtshalber leere ich mal den Cache:

$ app/console cache:clear

Das Ergebnis des frisch gebackenen Bundles ist kann jetzt im Browser betrachtet werden:

http://symfony2.local/app_dev.php/hello/mettbox

Das Model erstellen

Mit Hilfe des zuvor installiertem SensioGeneratorBundle kann nun das Model per CLI erstellt werden (Generating a New Doctrine Entity Stub):

$ php app/console generate:doctrine:entity

Daraufhin meldet sich der Doctrine2 entity generator und man wird aufgefordert einen Entity shortcut name anzugeben. Passend zum neuen Bundle wähle ich hier MettboxMapObjectBundle:Object. Als Configuration format wähle ich auch hier Yaml, erstelle, wie vom Assistenten vorgeschlagen bereits ein paar Felder und beantworte die letzte Frage mit yes:

Instead of starting with a blank entity, you can add some fields now.
Note that the primary key will be added automatically (named id).

Available types: array, simple_array, json_array, object, boolean, integer, smallint, bigint, string, text, datetime, datetimetz, date, time, decimal, float, blob, guid.

New field name (press <return> to stop adding fields): title
Field type [string]: 
Field length [255]: 

New field name (press <return> to stop adding fields): latitude
Field type [string]: 
Field length [255]: 

New field name (press <return> to stop adding fields): longitude
Field type [string]: 
Field length [255]: 

Do you want to generate an empty repository class [no]? yes  

“You can now start using the generated code!”

Auch wenn der Doctrine2 entity generator mit diesen Worten endet, bin ich neugierig vorher zu sehen, wie das erstellte Model in der Datenbank abgebildet wird:

$ php app/console doctrine:database:create
$ php app/console doctrine:schema:update --force

CRUD-Controller (Create, Read, Update, Delete) für die erstellte Entity MettboxMapObjectBundle:Object erstellen:

$ php app/console generate:doctrine:crud

The Entity shortcut name: MettboxMapObjectBundle:Object    
Do you want to generate the "write" actions [no]? yes
Configuration format (yml, xml, php, or annotation) [annotation]: yml
Routes prefix [/object]: 
..
Confirm automatic update of the Routing [yes]? yes
Importing the CRUD routes: FAILED

The command was not able to configure everything automatically.
You must do the following changes manually.
- Import the bundle's routing resource in the bundle routing file (/Users/holgersimon/Sites/0_local/symfony2/symfony2.local/src/Mettbox/MapObjectBundle/Resources/config/routing.yml).
    MettboxMapObjectBundle_object:
        resource: "@MettboxMapObjectBundle/Resources/config/routing/object.yml"
        prefix:   /object

Wie in der Generator-Ausgabe angegeben (Importing the CRUD routes: FAILED) ergänze ich folgende Zeilen in src/Mettbox/MapObjectBundle/Resources/config/routing.yml:

MettboxMapObjectBundle_object:
    resource: "@MettboxMapObjectBundle/Resources/config/routing/object.yml"
    prefix:   /object 

Über die URL http://symfony2.local/app_dev.php/object/ können jetzt die generierten CRUD-Methoden getestet werden :-)

Schreibe einen Kommentar

Pflichtfelder sind mit * markiert.


+ 84 = 90