SlideShare ist ein Scribd-Unternehmen logo
1 von 90
Downloaden Sie, um offline zu lesen
Professionelle Webentwicklung mit PHP

Inhaltsverzeichnis
Professionelle Webentwicklung mit PHP ..................................................................................................1
Kleines Vorwort..........................................................................................................................................3
   Voraussetzung........................................................................................................................................3
Wie funktioniert ein Webrequest:...............................................................................................................4
Entwicklung am Beispiel einer Datenbankklasse...................................................................................... 5
   So nicht..................................................................................................................................................5
   IDE........................................................................................................................................................ 5
   Erste Klasse in php................................................................................................................................ 6
      Der Quellcode der Klasse................................................................................................................. 6
phpDoc....................................................................................................................................................... 9
Codevervollständigung.............................................................................................................................11
Unittesting................................................................................................................................................ 12
   phpUnit................................................................................................................................................12
Integrationstesting.................................................................................................................................... 13
Exceptions................................................................................................................................................ 13
Revision Control System......................................................................................................................... 15
Vererbung in Klassen............................................................................................................................... 17
Code Refactoring..................................................................................................................................... 20
CodeConventions..................................................................................................................................... 20
   Teamarbeit........................................................................................................................................... 21
   Variable Naming Conventions ............................................................................................................21
   Constant Naming Conventions ...........................................................................................................22
   Method Naming Conventions ............................................................................................................ 22
   Parameter Naming Conventions .........................................................................................................22
   Struktur im Projekt.............................................................................................................................. 23
Wie schnell ist mein php-Script............................................................................................................... 24
Logfiles / Was passiert im Programm...................................................................................................... 25
   Loglevel...............................................................................................................................................26
      Vorgriff zu Nagios / Hobbit / xymon.............................................................................................. 27
Templating................................................................................................................................................27
i18n / Internationalisierung...................................................................................................................... 30
   Translation........................................................................................................................................... 31
Continous Integration 1............................................................................................................................31
Kleiner Ausflug zurück zu Git................................................................................................................. 32
SSH Keygen............................................................................................................................................. 34
Continous Integration 2............................................................................................................................35
   Unser Projekt hinzufügen....................................................................................................................36
      Git Repository initialisieren............................................................................................................36
      Verzeichnisproblem mit Git und CruiseControl............................................................................. 37
Selenium...................................................................................................................................................46


© Günther Haslbeck 2011 – V 0.2
Logfile + Systemüberwachung................................................................................................................ 49
   Nagios..................................................................................................................................................49
Komplette automatisch überwachte Entwicklung und Liveseite............................................................. 51
MRTG...................................................................................................................................................... 51
MemcacheD............................................................................................................................................. 51
Geschwindigkeit der Seite erhöhen..........................................................................................................52
   Geschwindigkeit der Elemente in der Seite messen............................................................................53
PHP -Entwicklung auf Linux................................................................................................................... 53
   Ubuntu basiert auf Debian-Linux........................................................................................................54
   Die wichtigsten Dateien und Befehle für uns......................................................................................54
      Wo sind wir (aktuelles Verzeichnis anzeigen)................................................................................ 54
      Verzeichnisinhalt anzeigen............................................................................................................. 55
      Ausgabe weiterverarbeiten............................................................................................................. 55
      Verzeichnisse ................................................................................................................................. 55
      Dateien suchen................................................................................................................................56
      TAB ................................................................................................................................................56
      Programme installieren...................................................................................................................57
      Textdatei erstellen / bearbeiten mit vi.............................................................................................58
      Das erste PHP-Script...................................................................................................................... 59
      Apache und Co (neu) starten.......................................................................................................... 59
      Hat unser Programm Fehler?.......................................................................................................... 59
Logfiles auswerten................................................................................................................................... 59
Welche Programme laufen und diese beenden.........................................................................................60
PHP Entwicklung mit Frameworks..........................................................................................................61
   Wieso................................................................................................................................................... 61
   Code nur einmal verwenden................................................................................................................61
Outsourcing.............................................................................................................................................. 65
Sessions und Rechte.................................................................................................................................65
Versionierung mit GIT............................................................................................................................. 66
Netbeans zeigt php-docs nicht an.............................................................................................................66
Error-Reporting........................................................................................................................................ 68
Eigenen Errorhandler............................................................................................................................... 69
Undefinierte Variablen in PHP anzeigen..................................................................................................69
Gitweb – neues Projekt erstellen..............................................................................................................76
Gitweb installieren in ubuntu.................................................................................................................. 76
Branching in Git.......................................................................................................................................85




© Günther Haslbeck 2011 – V 0.2
Kleines Vorwort

Das folgende Dokument wurde erstellt um eine klare Struktur in den Entwicklungsprozess zu bringen,
insbesondere in php.



Voraussetzung
Diese Anleitung setzt voraus, dass php 5.3 oder höher, ein Apache Webserver installiert ist, eine lokale
MySql-Instanz sowie java und phpmyamin sowie git unter Ubuntu 10/11


apt-get update
apt-get install git-core
apt-get install apache2
apt-get install mysql-server
apt-get install phpmyadmin

Java: java.sun.com:
SDK:
JDK 6 .. i586.bin




runterladen,

chmod u+x jdk-6u26-linux-i586.bin;
./jdk-6u26-linux-i586.bin

Dann

sudo /etc/init.d/mysql restart
sudo /etc/init.d/apache2 restart

unter http://localhost/ zeigt der Apache den Inhalt aus /var/www/
unter http://localhost/phpmyadmin/ zeigt phpmyadmin den Inhalt der MySQL Datenbank




© Günther Haslbeck 2011 – V 0.2
Erst einmal ein kleiner Ausflug:

Wie funktioniert ein Webrequest:




Das Ausführen des php-Scripts darf also nicht länger als ca 1 Sek (besser 0,7) dauern sonst dauert das
laden der Graphiken zu lange um die 1,5 Sekunden zu schaffen.
(obiges Beispiel != mod_php)

© Günther Haslbeck 2011 – V 0.2
Zurück zu php

Entwicklung am Beispiel einer Datenbankklasse

So nicht
Leider wird Code wie der folgende durch jedes neue php-Programm immer wieder kopiert weil der
Code nicht wiederverwendbar ist. Er ist Teil des eigentlichen Programms.
Das führt unter anderem dazu, das a) DB-Passwörter überall stehen und b) diese sich nicht mehr ändern




lassen weil keiner weiß wo diese stehen.
Und natürlich hauptsächlich: Führt es zu hunderten Kopien immer gleichen Codes mit immer den
gleichen Fehlern.
Und ganz nebenbei: Wir verwenden NIE die() in einem Programm


IDE
Als Entwicklungsumgebung wird im folgenden Netbeans verwendet.




Genau so könnte natürlich auch Eclipse verwendet werden




© Günther Haslbeck 2011 – V 0.2
Für beide IDEs (integrated development environment) muss evtl in Linux die JAVA_HOME gesetzt
sein. Java runterladen und das java-Hauptverzeichnis setzen:

export JAVA_HOME=/home/user/java/jdk1.6.0_24;export PATH=$JAVA_HOME/bin:$PATH


Erste Klasse in php

Wir starten Netbeans, erstellen ein neues PHP Projekt.
Wir erstellen ein Unterverzeichnis und nennen es classes.
Dort legen wir eine Daten namens Database.php ab

Diese sieht zB so aus




Der Quellcode der Klasse

class Database {

  //put your code here

  private $connection;
  private $servername = "localhost";
  private $mysqluser = "root";
  private $mysqlpasswd = "passwd";

  /**
   * connect
   *
   * connect to database
   *
   * @param string $databasename null or ro for readonly
   * @param string $mode null or ro for readonly


© Günther Haslbeck 2011 – V 0.2
*/
    public function connect($databasename = null, $mode = null) {

        //mode is for readonly - later on


        if ($this->connection) {
            //still connected!
        } else {
            $this->connection = mysql_connect($this->servername, $this->mysqluser, $this->mysqlpasswd);
        }

        if (!$this->connection) {
            echo “db-connect-error”;
        }
        if ($databasename) {
            $db_select = mysql_select_db($databasename);


            if ($db_select) {
                //echo 'database $databasename selected';
            } else {
                echo $databasename . " could not be selected" . mysql_error();
            }
        }
    }

    /**
     * disconnect
     *
     * disconnect fom database
     *
     */
    public function disconnect() {
        mysql_close($this->connection);
    }

    /**
     * query
     *
     * querycall to database
     *
     * @param string $query the querytext
     */
    public function query($query) {
        $result = mysql_query($query);

        if (!$result) {
            echo “cant query”;
        }

        return $result;
    }

}



Eingerückt wird der Code übrigens mit TAB, nicht mit Leerzeichen.

Man sieht, dass die Passwörter usw als private deklariert sind, die Methoden wie Connect als public.


© Günther Haslbeck 2011 – V 0.2
Damit sind nur die Methoden der Klasse nach außen sichtbar.
Passwörter usw muss und kann keiner sehen und keiner ändern.
Generell sollten Membervariablen (also Variablen die nur die Klasse verwendet) nicht sichtbar sein
sondern – wenn überhaupt nur per Getter/Setter also zB getServername(); oder
setServername(“newServer”); modifizierbar sein.

Die Klasse merkt sich auch die $connection intern, wir brauchen uns also nicht darum zu kümmern.

Halte Klassen klein: In jeder Klasse nur den exakten Usecase abbilden.
Beachte auch: Bei jedem Aufruf muss das komplette Script neu compiliert werden – viel drin, viel
Compilezeit!

Unser Programm das die Klasse benutzt sieht dann so aus:




bei folgender Datenbankstruktur




Keine Passwörter mehr, kein doppelter Code.

Bei Netbeans oder Eclipse erkennt die IDE nun auch welche Methoden es gibt und zeigt Informationen
an wenn man nur zB $db eingibt. Welche Methoden es gibt, welche Parameter diese haben usw(später
dazu mehr).


Die Info erhält Netbeans vom Kommentar über der Methode (phpDoc-Kommentar):

© Günther Haslbeck 2011 – V 0.2
Damit weiß die IDE was wie gemeint ist. Zudem kann man daraus einfach Doku generieren.
Dazu müssen wir erst einmal phpdoc installieren:


phpDoc

apt-cache search php-doc
apt-get install php-doc

und evtl PhpDocumentator
  apt-get install php-pear
  pear config-set data_dir /var/www/
  pear install --alldeps PhpDocumentor
  mkdir /var/www/PhpDocumentor-output
  chown www-data /var/www/PhpDocumentor-output
unter http://localhost/PhpDocumentor/ findet sich nun eine Config-Oberfläche




© Günther Haslbeck 2011 – V 0.2
Danach generieren wir die Doku zu dieser Klasse in unser Webserver-Verzeichnis:

phpdoc -d Quellverzeichnis -t Zielverzeichnis

phpdoc -d /home/user/NetBeansProjects/PhpProject1 -t /var/www/phpdocu




Code wird somit wiederverwendbar und von jedem verstanden.

Mehr:

http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.qui
ckstart.pkg.html

Zu beachten:
für die einzelnen Projekte ist in der Doku das Tag package zu verwenden da phpDoc sonst alles in eine
Ebene wirft




© Günther Haslbeck 2011 – V 0.2
Codevervollständigung
Wie schon erwähnt erkennt Netbeans/Eclipse welche Klassen vorhanden sind.
Erstellen wir eine Klasse




vervollständigt die IDE den Code und hilft schnell und einfach Software zu erstellen:




(Anzeigen auch durch STRG+Shift möglich, STRG + Klick springt zur Deklaration wenn im Projekt

© Günther Haslbeck 2011 – V 0.2
die entsprechenden Klassenpfade eingebunden sind , STRG + B entspricht STRG + Klick– Alle
Keyboardshortcuts unter
http://usersguide.netbeans.org/shortcuts.pdf )




Unittesting

Aber was, wenn jeder darin rumspielt? Funktioniert dann noch alles?
1. Sollten diese Basisklassen von keinem verändert werden und wenn doch sollten generell alle Klassen
per
2. Unit-Tests getestet werden.

Wir installieren phpunit:

apt-get install phpunit


phpUnit
ruft eine Klasse auf und vergleicht das Ergebnis mit einem festgelegten Ergebnis.
In unserem Falle testen wir indirekt gleich mit ob die Datenbank und der Inhalt ok sind:




© Günther Haslbeck 2011 – V 0.2
Das Script baut eine Datenbankverbindung über unsere Klasse auf, sucht einen User und vergleicht das
Ergebnis (assertSame) mit einem festgelegten Wert.

Dies kann nun alle x Minuten gemacht werden. Solange das Ergebnis stimmt ist der Test erfolgreich
und unser Code macht immer genau das was man von ihm erwartet.

> phpunit DatabaseTest.php
PHPUnit 3.4.13 by Sebastian Bergmann.
OK (1 test, 1 assertion)

Also alles ok.


Integrationstesting
Was hier vorher als Unittest dargestellt wurde ist eigentlich ein Integrationstest.
Der Unterschied besteht darin, dass ein Unit-Test nur ganz kleine Schritte (Methoden usw) testet, ein
Integrationstest aber aus mehreren Unittests bzw kompletten Programmabläufen besteht

Exceptions

Nun kann zB während der DB-Verbindung ein Problem auftreten. Dies fangen wir auf gar keinen Fall
mit die() ab da die() das Programm sofort beendet, sondern wir werfen eine Exception.
Da php als Default nur den Typ Exception kennt, wir aber ein bisschen genauer unterscheiden wollen
erstellen wir unsere eigenen Exception zB am besten in der Klasse selbst




© Günther Haslbeck 2011 – V 0.2
Tritt ein Fehler auf, werfen wir eine DatabaseException nach „oben“:




und fangen diese in unserem Programm außen wieder:




© Günther Haslbeck 2011 – V 0.2
Somit kann auf jeder Problem angemessen reagiert werden und nicht einfach das Programm
abgebrochen.

Wir haben nun obigen Code geändert. Durch einen erneuten Test durch phpUnit können wir sicher sein,
dass noch alles tut.
Aber was haben wir geändert?

Revision Control System
Im weiteren wird GIT verwendet. Git ist wie CVS oder SVN eine Freie Software zur
Versionsverwaltung von Dateien und Verzeichnissen.
Im Gegensatz zu CVS und dessen Nachfolger SVN (SubVersioN) setzt Git allerdings keinen zentralen
Server voraus.




© Günther Haslbeck 2011 – V 0.2
Um also zu sehen was wir geändert haben, erstellen wir ein git Repository im Code-Verzeichnis

> git init
> git add PhpProject1
> git commit -a -m "first strike"

Git erstellt nun ein .git Verzeichnis und merkt sich den aktuellen Stand dort.
„first strike“ ist dabei ein frei festzulegender Kommentar der aussagekräftig gesetzt werden sollte.




Wir verändern nun eine Datei (fügen eine Kommentarzeile ein) und speichern und committen erneut.
(der Parameter -m ist um den Kommentar direkt in der Kommandozeile einzugeben)

> git commit -a -m "added comment"
und sehen:
 1 files changed, 1 insertions(+)




© Günther Haslbeck 2011 – V 0.2
Was ist passiert:
> git log PhpProject1/index.php

und wir sehen




und was wurde geändert?
Wir lassen uns den Unterschied zw 2 Commits anzeigen:

> git diff --color 652189eaa529e44.... 069627823fc52a8b44937....




Aha, eine Kommentarzeile wurde eingefügt.
Tipp: git als Cron laufen lassen und Code einfach alle 60 min automatisch einchecken.

Vererbung in Klassen

Klassen sollten aber nicht verändert werden sondern abgeleitet/vererbt:
Dabei “erbt” die neue Klasse die Eigenschaften (Methoden) der alten Klasse und wird durch die
zusätzlichen Methoden erweitert.
Das kann zB auch dafür genutzt werden aus einer “Basis”Klasse “Fahrzeug” jeweils ein “Auto” einen
“Lieferwagen” zu erzeugen. Beide basieren damit auf einer Klasse die die Grundeigenschaften abbildet
(Motor, 4 Reifen) aber zusätzlich die Klasse um eine Ladefläche (Lieferwagen) oder ein Schiebedach
(Auto) erweitert.

© Günther Haslbeck 2011 – V 0.2
© Günther Haslbeck 2011 – V 0.2
Weitere Möglichkeiten der Vererbung in PHP 5




© Günther Haslbeck 2011 – V 0.2
Code Refactoring

Oft merkt man während des entwickeln des Codes dass man gerne die eine oder andere Klasse oder
Methode umbenennen möchte. Auch hier helfen die IDEs und können alle Stellen an den der Code
verwendet wird in allen Files umbenennen. Diese Funktion findet sich in Eclipse und Netbeans unter
„Rechte Maustaste → Refactoring“




CodeConventions

Methoden wie bla() oder Variablen wie
$i = “vorname” sind schlecht zu lesen und teilweise irreführend zB wenn $i wiederverwendet wird
$i = 17;
Was ist also $i?

Deswegen Variablen eindeutig und ausschreiben und in camelCase Form.
Um den Entwicklungsstil überall gleich zu halten wurden in Java CodeConventions erstellt und diese
haben sich mittlerweile fast überall durchgesetzt:
http://www.oracle.com/technetwork/java/codeconvtoc-136057.html

Alterntive: PEAR PHP Conventions
http://pear.php.net/manual/en/standards.funcdef.php




© Günther Haslbeck 2011 – V 0.2
Teamarbeit
Ist man alleine ist es wichtig Codeconventions einzuhalten denn es sind in jedem Projekt Zeiten in
denen man nicht daran arbeitet. Trotzdem möchte man später auch wieder schnell weitermachen und
gleich verstehen was man damals meinte.
Im Team ist es sehr wichtig Absprachen einzuhalten denn jeder im Team muss jederzeit verstehen was
das Programm macht und wieso was wie geschrieben wurde.

Einrücken des Codes
Schon beim einrücken des Codes sollte man sich vorher absprechen und dann auch einhalten:
Rückt man im Team per Leerzeichen ein oder per Tabulator. Und wenn per Tabulator ist darauf zu
achten keine Texteditoren zu verwenden die beim Speichern die Tabs in Leerzeichen umwandeln.
So bleibt der Code gut eingerückt und lesebar.

Tools wie Netbeans oder Eclipse können Code auch selbständig einrücken:




Variable Naming Conventions

Choose meaningful names that describe what the variable is being used for. Avoid generic names like
number or temp whose purpose is unclear.

Compose variable names using mixed case letters starting with a lower case letter. For example, use
salesOrder rather than SalesOrder or sales_order.

Use plural names for arrays. For example, use testScores instead of testScore.

Exception: for loop counter variables are often named simply i, j, or k, and declared local to the for
loop whenever possible.




© Günther Haslbeck 2011 – V 0.2
Constant Naming Conventions

   * Use ALL_UPPER_CASE for your named constants, separating words with the underscore
character. For example, use TAX_RATE rather than taxRate or TAXRATE.
   * Avoid using magic numbers in the code. Magic numbers are actual numbers like 27 that appear in
the code that require the reader to figure out what 27 is being used for. Consider using named constants
for any number other than 0 and 1.




Method Naming Conventions

Try to come up with meaningful method names that succinctly describe the purpose of the method,
making your code self-documenting and reducing the need for additional comments.

Compose method names using mixed case letters, beginning with a lower case letter and starting each
subsequent word with an upper case letter.

Begin method names with a strong action verb (for example, deposit). If the verb is not descriptive
enough by itself, include a noun (for example, addInterest). Add adjectives if necessary to clarify the
noun (for example, convertToEuroDollars).

Use the prefixes get and set for getter and setter methods. Getter methods merely return the value of a
instance variable; setter methods change the value of a instance variable. For example, use the method
names getBalance and setBalance to access or change the instance variable balance.

If the method returns a boolean value, use is or has as the prefix for the method name. For example, use
isOverdrawn or hasCreditLeft for methods that return true or false values. Avoid the use of the word
not in the boolean method name, use the ! operator instead.
For example, use !isOverdrawn instead of isNotOverdrawn.


Parameter Naming Conventions

With formal parameter names, follow the same naming conventions as with variables, i.e. use mixed
case, begin with a lower case letter, and begin each subsequent word with an upper-case letter

Consider using the prefix a or an with parameter names. This helps make the parameter distinguishable
from local and instance variables.

Occasionally, with very general purpose methods, the names chosen may be rather generic (for
example, aNumber). However, most of the time the parameter names should succinctly describe the
type of value being passed into the method.



© Günther Haslbeck 2011 – V 0.2
Struktur im Projekt
Nicht nur über die Methoden- und Variblennamen sollte man sich Gedanken machen, auch über die
Struktur des Codes selbst.
Je nach Projekt sollte die Struktur vorher festgelegt und dann auch über Projekte hinweg eingehalten
werden.




© Günther Haslbeck 2011 – V 0.2
Wie schnell ist mein php-Script

Millisekunden messen. Ist Laufzeit > 1 Sek (=0,001) dann warne




© Günther Haslbeck 2011 – V 0.2
Logfiles / Was passiert im Programm

Vorweg: Um zu sehen wieso ein php-Programm gar nichts macht greifen wir auf die Log-Ausgaben
von Apache zurück
> tail -f /var/log/apache2/error.log
[Sun Jun 12 11:33:01 2011] [error] [client 127.0.0.1] PHP Warning: fopen(/var/lo...

Aber:
Während des normalen Betriebs möchte man ab und an, dass ein Programm Logausgaben macht.
Um das zu ermöglichen sollte eine Logklasse nicht fehlen.




Diese erstellt dann ein Logfile mit Datum.
Vorteil: Morgen wir automatisch ein neues File erstellt.
Der Name des Logfiles wir aus __FILE__ ermittelt. Das ist der komplette Pfad+Scriptname.

> cat /var/log/20110613-PhpProject1.log
13.06.2011 14:48:49 WARN           ups, to slow: 0.00045585632324219
13.06.2011 14:50:11 WARN           ups, to slow: 0.0039768218994141
13.06.2011 14:50:11 WARN           ups, to slow: 0.0064089298248291

Damit sehen wir also wenn ein Script zu lange gebraucht hat.



© Günther Haslbeck 2011 – V 0.2
Es gibt übrigends noch mehr Konstanten:
echo __LINE__."<br>";
hilft zB beim Debugging


Loglevel
Wir erweitern die Logmethode um einen Loglevel:




Mit $currentloglevel wird definiert welcher Loglevel geschrieben werden soll.




Man kann also im Programm überall DEBUG Log-Ausgaben einbauen. Diese werden aber nicht
geschrieben.
Geschrieben werden nur Meldungen die > Debug sind. Ändert man die Variable auf dem Livesystem
auf 1 ab wird auch alles was als Debug eingetragen ist geschrieben. So lassen sich im Livebetrieb
schnell Logging ein und auschalten.
Logfiles sind wichtig um zu erkennen was im Programm passiert ist. ZB sollten alle kritischen
Vorgänge auf INFO geloggt werden.
WARN, ERROR und FATAL sollten zB geschrieben werden von Exceptions.




© Günther Haslbeck 2011 – V 0.2
Vorgriff zu Nagios / Hobbit / xymon
Nagios wird später kurz angeschrieben. Nagios wertet Logfiles aus. Dort können Schwellen pro
Logfiles + Loglevel festgelegt werden.
Tritt zB in der Stunde in einem Logfile 1 FATAL oder 10 ERROR order 100 WARN auf, so schaltet
Nagios die Überwachung auf rot und versendet eine Email an den Admin.

Fällt also zB die Datenbank aus und werden Verbindungsexceptions als FATAL geschrieben geht sofort
beim Admin eine Email ein.


Templating
Code zu mischen mit HTML in php widerspricht dem MVC Pattern. (Dazu später mehr)
Kurz: HTML nicht mit Code mischen.
Generell gilt: Erstelle kein HTML im Code wie zB

echo “<b>Hallo Welt</b>”;

Nutze eine Templateengine wie zB smarty (oder twig).
Weiterer Vorteil: Die Entwickler und Webdesigner-Tätigkeit lässt trennen (Personal / Outsourcing!)
Im Template gibt man Platzhalter an, im Programm definiert man dann den Inhalt für diese Platzhalter
lädt und gibt dann das Template aus.
So können Seiten oder Teile der Seiten immer wieder verwendet werden.




© Günther Haslbeck 2011 – V 0.2
Und das Template:




die Ausgaben sieht dann so aus

Hallo Welt
Das hier ist die erste TemplateSeite

Templating macht aber nur Sinn, wenn wir Teile der Seite wie zB Header und Footer auslagern.
Das geht so:




© Günther Haslbeck 2011 – V 0.2
und in template/page_header.tpl steht




© Günther Haslbeck 2011 – V 0.2
Seite aufrufen (hier mal der HTML-Code der erzeugt wird)




i18n / Internationalisierung
Internationalisierung (engl. internationalization) wird gerne mit I18N abgekürzt (im englischen Wort
befinden sich 18 Buchstaben zwischen I und N).

Man möchte eine Seite in mehreren Sprachen ausgeben.
Das beeinflusst den Text den man an das Template schickt, das Template (falls es Text oder Bilder mit
Text enthält) und natürlich auch Felder wie Datum usw (24.12.2011 vs 12/24/11) usw.

Da Smarty mit Internationalisierung nicht ohne weiteres umgehen kann hier obiges Beispiel nochmal
mit TWIG:

Installation:
1. PEAR installieren ( > apt-get install php-pear )
2. > pear channel-discover pear.twig-project.org
    3. > pear install twig/Twig
    4. > apt-get install php-gettext

wir erstellen ein Template unter /var/www/PhpProject1/twig/index.html




© Günther Haslbeck 2011 – V 0.2
und den entsprechenden php-Code:




Fertig. Seite wird ausgegeben.


Translation
(siehe Twig I18n Implementation / Translation – How it works weiter hinten in diesem Dokument)


Continous Integration 1
Unit-Tests machen keinen Sinn wenn diese nicht dauernd ausgeführt werden
Tools dafür sind CruiseControl und dessen PHPPlugin phpUnderControl oder auch Hudson/Jenkins

Diese Tools checken dauernd den Stand des Quellcodes aus Git aus, compilieren diesen und starten die
Unit-Tests.
Hat jemand einen Fehler eingecheckt so wird dies hier sichtbar.




© Günther Haslbeck 2011 – V 0.2
Kleiner Ausflug zurück zu Git

Links (braun) unser Rechner = Client, rechts (schwarz) neuer (leerer) GIT-Server

Auf dem Server erstellen wir ein Verzeichnis und legen eine leeres Repository an

Das linke Fenster (unser Rechner) fügt ein Repository names Origin in seine config hinzu und pusht
dann den Master (Trunk – also den Hauptzweig) in das Remote-Repo.




Jetzt wollen wir mal aufm Server das Repo lokal auschecken.
Das machen wir per clone:




alles da.
Wir ändern hier ein File und pushen wieder zurück (lokal)


© Günther Haslbeck 2011 – V 0.2
und holen es dann auch wieder auf unseren Rechner/Client:



"git pull" does a "git fetch" followed by a "git merge".

So lässt sich also Code per Git hin und her kopieren.

Mehr unter http://www.jedi.be/blog/2009/05/06/8-ways-to-share-your-git-repository/

Überblick:




© Günther Haslbeck 2011 – V 0.2
SSH Keygen

Da wir das Repo per SSH hin und her kopieren müssen wir jedes mal ein Passwort eingeben.
Das kann man sich sparen in dem man auf dem Rechner von dem man sich auf einen anderen
Verbinden will einen public Key erzeugt.
ssh-keygen -t dsa

Kein Passwort eingeben wenn danach gefragt wird!

Den Inhalt des erzeugten Files (/home/user/.ssh/id_dsa.pub) fügt man auf dem Zielrechner in das
File /home/usermitdemannsicheinloggt/.ssh/authorized_keys hinzu.
Es darf kein Zeilenumbruch in der Zeile sein die eingefügt wird.

Bei einem erneuten SSH Login wird nicht mehr nach dem Passwort gefragt und deshalb auch nicht
mehr bei Git.




© Günther Haslbeck 2011 – V 0.2
Continous Integration 2

Wir installieren CruiseControl und phpUnderControl
(weitere quellen: http://pear.phpundercontrol.org/)

pear channel-discover components.ez.no
pear channel-discover pear.phpundercontrol.org
pear install --alldeps phpuc/phpUnderControl-beta
apt-get install php5-xdebug
pear upgrade --force pear
cd /tmp
wget http://freefr.dl.sourceforge.net/sourceforge/cruisecontrol/cruisecontrol-bin-2.8.3.zip
unzip cruisecontrol-bin-2.8.3.zip -d /opt
cd /opt
ln -s cruisecontrol-bin-2.8.3 cruisecontrol
phpuc install /opt/cruisecontrol

wir müssen auch noch runterladen

 pear channel-discover pear.phpmd.org
 pear channel-discover pear.pdepend.org
 pear install --alldeps phpmd/PHP_PMD
 pear channel-discover pear.phpunit.de
 pear install phpunit/phpcpd

und starten

cd /opt/cruisecontrol
export JAVA_HOME=/home/user/java/jdk1.6.0_24;export PATH=$JAVA_HOME/bin:$PATH
./cruisecontrol.sh

Im Browser sehen wir nun unter http://localhost:8080/cruisecontrol/ die Oberfläche von CC:




© Günther Haslbeck 2011 – V 0.2
Beenden geht übrigens mit : kill `cat /opt/cruisecontrol/cc.pid`


Unser Projekt hinzufügen

wir erstellen in /opt/cruisecontrol/projects ein neues Projekt
> mkdir PhpProject1
> mkdir -p PhpProject1/{source,build}
> mkdir -p PhpProject1/build/{api,logs,log,coverage}

Dort legen wir ein build.xml ab (siehe später)
Dort geben wir den Namen des Projekt an
<project name="PhpProject1" default="build" basedir=".">
und legen in den ensprechenden Verzeichnissen die Sourcen ab

Zudem muss
die vi /opt/cruisecontrol/config.xml
angepasst werden so dass das Projekt gebaut wird


Git Repository initialisieren
Damit das Git-Plugin auch weiß von wo es pullen soll, muss der source-Ordner einmal mit git
initialisiert werden:
cd PhpProject1/source/
git clone example.com/projectrepository.git .

Oder von lokal:

dazu muss vorher ein lokales repository angelegt werden
> mkdir /home/gitrepo
> cd /home/gitrepo/

© Günther Haslbeck 2011 – V 0.2
> git - - bare init
Initialized empty Git repository in /home/gitrepo/
> sudo git push /home/gitrepo/ master
Counting objects: 31, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (22/22), done.
Writing objects: 100% (31/31), 4.04 KiB, done.
Total 31 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (31/31), done.
To /home/gitrepo/
 * [new branch]      master -> master

> cd PhpProject1/source/
> git clone /home/gitrepo/
Initialized empty Git repository in /opt/cruisecontrol-bin-2.8.3/projects/PhpProject1/source/gitrepo/.git/


Verzeichnisproblem mit Git und CruiseControl
Das „git clone“ muss so plaziert werden, dass die config.xml von CruiseControl und der Bereich der
den Checkout von Git definiert genau auf das .git Verzeichnis trifft.
Hat man (wie ich) nicht ein Projekt sondern den Ordner wo alle Projekte sind global in git, so klappt
das nicht.
Deswegen habe ich das „git clone“ im Projects-Ordner ausgeführt. Es entsteht ein Unterverzeichnis
namens repo und darin sind dann die Projekte incl dem .git Verzeichnis.
Mein Config.xml zeigt dann auf




und von dort habe ich dann per


ln -s gitrepo/PhpProject1 .
Verlinkt und dann darin das „build.xml“ abgelegt und die Verzeichnisse (von oben) angelegt




© Günther Haslbeck 2011 – V 0.2
Damit kann ich nun in meinem Homeornder eine Datei ändern, ein Git commiten,
mit git push /home/gitrepo/ master in das lokale repository pushen und von da holt es dann
Cruisecontrol ab da es über die config.xml in gitrepo guckt, dort im gitfile steht, das es neues aus
/home/gitrepo/ holen soll.
Das Ergebnis sieht dann so aus:




© Günther Haslbeck 2011 – V 0.2
Evtl muss auch Testscript angepasst und woanders abgelegt werden




Jetzt cruisecontrol erneut starten:
Projekt erscheint unter

http://localhost:8080/cruisecontrol/




http://techportal.ibuildings.com/2009/03/03/getting-started-with-phpundercontrol/

phpUnderControl benutzt nun
PhpDocumentor (zum erzeugen der Doku)
PHPUnit (um die Unittests auszuführen)
PhpCodeSniffer (detects violations of a defined set of coding standards)
PhpMessDetector (checks for: Possible bugs, Suboptimal code, Overcomplicated expressions, Unused
parameters, methods, properties)
phpcpd (copy paste detector )

um den Code zu prüfen.

http://skaverat.net/howto/installation-und-einrichtung-von-phpundercontrol-auf-linux.html


Hier die beiden Files:
/opt/cruisecontrol/projects/PhpProject1/build.xml

<project name="PhpProject1" default="build" basedir=".">



© Günther Haslbeck 2011 – V 0.2
<property name="builddir" value="${basedir}/build" />

 <target name="prepare" depends="clean,init" />

 <target name="init">
    <mkdir dir="${builddir}" />
    <mkdir dir="${builddir}/api" />
    <mkdir dir="${builddir}/log" />
    <mkdir dir="${builddir}/coverage" />
    <mkdir dir="${builddir}/phpcb" />
 </target>

  <!--
     Removes all temporary build artifacts
  -->
  <target name="clean">
     <delete dir="${builddir}" />
  </target>

 <target name="checkout">
  <exec dir="${basedir}/source" executable="git">
    <arg line="pull"> </arg>
  </exec>
 </target>

  <target name="phpunit">
   <exec executable="phpunit" dir="${basedir}/source" failonerror="on">
     <arg line="--log-junit ${builddir}/log/junit.xml --coverage-clover ${builddir}/log/phpunit.coverage.xml
--coverage-html ${builddir}/coverage phpucAllTests ${basedir}/testsuite/all_tests.php" />
   </exec>
  </target>

<target name="pdepend">
 <exec dir="${basedir}"
     executable="pdepend"
     failonerror="false">
  <arg line="--jdepend-xml=${basedir}/build/logs/jdepend.xml ."/>
 </exec>
</target>



 <target name="phpcpd" depends="init">
  <exec executable="phpcpd" failonerror="false">
    <arg line="--log-pmd ${builddir}/log/pmd-cpd.xml ${basedir}/source " />
    </exec>
 </target>




© Günther Haslbeck 2011 – V 0.2
<target name="php-documentor2" depends="init">
   <exec executable="phpdoc" dir="${basedir}/source">
    <arg line=" -o HTML:Smarty:default -t ${basedir}/build/api -ct type -ue on -tb
/usr/share/php/data/phpUnderControl/data/phpdoc/ -d ${basedir}/source "/>
   </exec>
 </target>

 <target name="php-documentor">
  <exec executable="phpdoc" dir="${basedir}/source">
    <arg line=" -t ${builddir}/api -o HTML:Smarty:default . -ct type -ue on --filename **/*.php"/>
  </exec>
 </target>

 <target name="php-codesniffer">
   <exec executable="phpcs" dir="${basedir}/source" output="${builddir}/logs/checkstyle.xml"
error="/tmp/checkstyle.error.log">
    <arg line="--report=checkstyle --standard=PEAR ."/>
   </exec>
 </target>

 <target name="phpmd">
  <exec executable="phpmd" dir="${basedir}/source">
    <arg line=". xml codesize,unusedcode,naming --reportfile ${basedir}/build/logs/pmd.xml"/>
  </exec>
 </target>

 <target name="build" depends="checkout,php-documentor,php-codesniffer,phpmd,phpcpd,phpunit,pdepend"/>
</project>




UND-----------------


/opt/cruisecontrol/config.xml

<cruisecontrol>
<project name="PhpProject1" buildafterfailed="false">
<modificationset>
<alwaysbuild/>
</modificationset>



<!-- Git Bootstrapping auf den source-ordner -->
<bootstrappers>
<gitbootstrapper localWorkingCopy="projects/${project.name}/source" />
</bootstrappers>


© Günther Haslbeck 2011 – V 0.2
<schedule interval="60">
 <ant anthome="apache-ant-1.7.0" buildfile="projects/${project.name}/build.xml"/>
 </schedule>

 <listeners>
 <currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
 </listeners>

 <log dir="logs/${project.name}">
 <merge dir="projects/${project.name}/build/logs/"/>
 </log>

<publishers>
<artifactspublisher dir="projects/${project.name}/build/api"
    dest="artifacts/${project.name}"
    subdirectory="api"/>
<artifactspublisher dir="projects/${project.name}/build/coverage"
    dest="artifacts/${project.name}"
    subdirectory="coverage"/>
<execute command="phpuc graph logs/${project.name}
    artifacts/${project.name}"/>
</publishers>
</project>
</cruisecontrol>



Anfangs gabs Probleme mit phpdoc und den Output-Convertern.
Welche installier sind finden man unter:
/usr/share/php/PhpDocumentor/phpDocumentor/Converters/HTML$ dir
frames Smarty

So siehts dann unter anderem aus:




© Günther Haslbeck 2011 – V 0.2
Man sieht zB auch die Testabdeckung der Unittests




und welche Codezeilen getestet wurden




© Günther Haslbeck 2011 – V 0.2
erweitern wir das /opt/subversion/config.xml um unsere Emailadresse so erhalten wir eine Email




wir ergänzen nun das build.xml im Projekt um alles zu zippen:




© Günther Haslbeck 2011 – V 0.2
als nächstes lassen wir im Erfolgsfall (via /opt/cruisecontrol/config.xml) das zip kopieren




und schon da:




Dieses File könnten wir nun auf einen Staging-Webserver kopieren und dort entpacken.
Damit liegt dort dann eine sauber durchgetestete Version der aktuellen Software.


Selenium
Mit phpunit haben wir aber bisher nur Backendmethoden getestet. Was wird aus dem Frontend?
Dazu nutzen wir Selenium.
Selenium setzt “leider” einen Desktop-PC voraus den es startet einen richtigen Browser und testet mit
diesem.

So funktionierts:
Unter http://seleniumhq.org/download/ laden wir die aktuelle Version der Selenium-IDE für Firefox
herunter.
Nach dem Neustart von Firefox starten wir über Tools die Selenium IDE. Dort klicken wir auf den
roten Aufnahmeknopf und machen dann im Browser genau das was wir testen wollen: zB eine Suche
auf Google.de nach „selenium“
Auf der nächsten Seite markieren wir einen Text der und beweisst, das das was wir gemacht haben
erfolgreich war zB




© Günther Haslbeck 2011 – V 0.2
Das kann aber natürlich auch ein Willkommenstext nach einem Login sein usw usw..
In Selenium ist nun zu sehen was wir gemacht haben. Wir beenden dort die Aufnahme.




Durch File → Save Testcase kann dieser nun gespeichert und über die IDE auch wieder geladen und
ausgeführt werden.
Aber wir möchten ja automatisch und nicht jedes mal selbst Hand anlegen.
Deswegen klicken wir auf File → Export-Test-Case und als PHP Testing_Selenium.




© Günther Haslbeck 2011 – V 0.2
Das Ergebnis sieht sehr nach unseren Unit-Tests aus:
(ich musste die require_once Zeile selbst nachbessern?!)




Als nächstes laden wir den Selenium Server runter von
http://seleniumhq.org/download/


und starten das .jar file direkt




und wir starten per phpunit das script



Es wird ein Browser gestartet und genau da ausgeführt was im Script steht.
Wunderbar.

Damit hätten wir (wenn genug Tests erstellt sind) auch das Frontend durchgetestet und können diese

© Günther Haslbeck 2011 – V 0.2
Tests auch immer automatisch fahren.

MockObjekte
tbd


Logfile + Systemüberwachung
Wie wir im Logfilekapitel vorher erfahren haben ist es wichtig Logfiles zu schreiben und auszuwerten
Wir wollen überwachen was unsere Anwendungen machen.
Dazu nehmen wir viele Nagios oder Xymon (früher Hobbit früher Big Brother)

Hobbit
apt-get install xymon
Nun sollte schon alles funktionieren. Die Oberfläche findet sich unter
http://localhost/hobbit/index.html

Ist ein Zugriff nicht erlaubt evt in:
/etc/apache2/conf.d/hobbit
         alle
   #Allow from localhost ::1/128
         ändern nach
   Allow from all
/etc/init.d/apache2 restart

und die Oberfläche ist da




Nagios
Nur kurz erwähnt

© Günther Haslbeck 2011 – V 0.2
apt-get install nagios3 (passwort bei der inst merken)
/etc/init.d/nagios3 start

und zugreifen via
http://localhost/nagios3

benutzername: nagiosadmin, passwort wie vorher festgelegt

und wir sehen wie es der Maschine geht




jetzt muss nur noch eine Überwachung der Logs eingebaut werden.




© Günther Haslbeck 2011 – V 0.2
Komplette automatisch überwachte Entwicklung und Liveseite




MRTG


MemcacheD
http://www.debian-administration.org/article/Speeding_up_dynamic_websites_with_caching

Gut: Ist der MCD ausgefallen funtioniert die Seite trotzdem




© Günther Haslbeck 2011 – V 0.2
Geschwindigkeit der Seite erhöhen
Baue zu Beginn der Seite nur eine DB-Connection auf und übergebe diese an alle Methoden / Klassen.
Die Klassen selbst müssen keine eigenen DB-Connections aufbauen
Vermeide schreiben in Dateien (Logfiles, Schreiben nach STDERR usw)
Lade nur so wenig Klassen wie nötig (sinnlose Ladezeit der Scripte + Compilezeit der Scripte)


CSS/Bilder:
Nutze optimierte Bilder, Javascripts usw (mehr erklärt Google in Pagespeed)

Geschwindigkeit der Seite selbst messen
Nutze Firebug
https://addons.mozilla.org/en-US/firefox/addon/firebug/

Firebug auf Seite anklicken
Net (oder Netzwerk) aktivieren
Shift+F5 und sehen was passiert.

Am Beispiel GMX ist zu sehen: Ladezeit der Hauptseite (also zB php-Script) dauert 0,163 Sekunden.
Super! - Allerdings dauert die ganze Seite dann Gesamt: 4,94 Sekunden. Katastrophe!




© Günther Haslbeck 2011 – V 0.2
Geschwindigkeit der Elemente in der Seite messen
Google Pagespeed zeigt was zu verbessern ist und wie http://pagespeed.googlelabs.com




Screenshots in diesem File erstellt mit “shutter” für Ubuntu



PHP -Entwicklung auf Linux

1. Ubuntu installieren
Auf der Homepage von Ubuntu die aktuelle (am besten 64bit) Version runterladen
http://www.ubuntu.com/download/ubuntu/download
und auf CD brennen.

Diese installieren wir auf einer alten externen Platte. Einfach von CD booten, dann installieren. Beim
Installieren darauf achten, dass die externe Platte verwendet wird (das ist dann zB sdf1...) und (sehr
wichtig) dass auch der Bootsektor dann auf sdf installiert wird (NICHT sda!).



Dann beim Start des PCs statt CD das angeschlossene Festplattenlaufwerk auswählen. Ubuntu sollte
normal starten


© Günther Haslbeck 2011 – V 0.2
Ubuntu basiert auf Debian-Linux
Daher benutzt Ubuntu die gleichen Programme und Verzeichnisse


Die wichtigsten Dateien und Befehle für uns

Apache Logfiles:
/var/log/apache2/access.log
/var/log/apache2/error.log

html-Startverzeichnis:
/var/www/


Einstellungen des Apache Webservers:
/etc/apache2/sites-enabled/000-default


Wo sind wir (aktuelles Verzeichnis anzeigen)
Wir starten erst einmal das Terminal (Anwendungen > Zubehör > Terminal) und geben ein:

pwd



pwd = print work directory

Hilfe zu jedem Befehl anzeigen (zb pwd)
man pwd



© Günther Haslbeck 2011 – V 0.2
Dort kommt man wie in vielen Linuxprogrammen mit q, strg+c oder manchmal alt+q wieder raus.
Scrollen mit den Cursortasten


Verzeichnisinhalt anzeigen
ls

Viele Programme haben Paramter die man meisst mit -paramter anhängt. Das können auch mehrere
sein die dann direkt aneinandergereit werden

ls -al zeigt alle Dateien ausführlich an
ls -alt (gut zu merken für deutsche) zeigt sortiert nach Datum (Parameter l)
ls -als zeigt nach Dateigrösse sortiert (Parameter s)

man ls hilft weiter was was bedeutet


Ausgabe weiterverarbeiten
Ist die Ausgabe nun sehr lange wäre es schön, wenn man diese Seitenweise angezeigen könnte.
Das ist mit ls nicht möglich. Allerdings können wir mit | die Ausgabe von ls an ein anderes Programm
senden das genau das macht was wir gerne hätten.
Wir nutzen das Program more

ls -al | more

mit Cursor oder Space können wir nun Zeilen oder Seitenweise durch die Ausgabe scrollen.

Man kann die Ausgabe auch in eine Datei schreiben mit >
Dabei bedeutet > immer neue Datei anlegen, >> an bestehende Datei anhängen.

ls -al > datei.txt

Eine Datei ausgeben kann man mit cat

cat datei.txt

und Seitenweise dann eben wieder mit

cat datei.txt | more


Verzeichnisse
Verzeichnis anlegen

mkdir verzeichnisname


© Günther Haslbeck 2011 – V 0.2
Datei oder Verzeichnis löschen
rm verzeichnisname bzw rm dateiname

Sind im Verzeichnis Dateien können die mi
rm -rf verzeichnisname gelöscht werden. Aber Vorsicht: Es wird ohne zu fragen ALLES was in dem
Verzeichnis war gelöscht. Weg ist weg. Nix Papierkorb

Interessant ist auch das Programm grep. Damit können wir filtern.
ls -al | grep „bla“

hier werden nur Dateien oder Verzeichnisse ausgegeben die „bla“ im Dateinamen haben.


Dateien suchen
find . -name „bla*.pdf“
find sucht ab . (das Verzeichnis wo wir uns gerade befinden) alle Dateien die bla*.pdf heissen.

Verzeichnis wechseln
In Linux gibt es keine Laufwerke, deswegen auch kein c: und die Verzeichnisnamen sind mit / getrennt
und nicht mit  wie in Windows
Die Wurzel ist also / und nicht c:

cd ~ wechselt ins heimant (eigene User) verzeichnis
cd / wechselt ins root-Verzeichnis
cd /tmp un das /tmp Verzeichni
cd – wechselt in das letzte Verzeichnis in dem wir gerade vorher noch waren


TAB
benutze die Tab-Taste um beim tippen von Verzeichnissen die Namen automatisch zu vervollstädnigen.
Bringt Tab keine Antwort dann gibt es das Verzeichnis nicht. Hört Tab mitten im Namen auf so sind
mehrere Verzeichnisse vorhanden mit ab hier verschiedenen Namen. Nochmal Tab zeigt die
Möglichkeiten

Datei kopieren
cp datei1.txt datei2.txt

Verzeichiss mit kompletten Inhalt kopieren
cp -r verzeichnis1 verzeichnis2

Datei / Verzeichnis verschieben
mv datei1.txt datei2.txt




© Günther Haslbeck 2011 – V 0.2
Programme installieren
kurzes Vorwort: In Ubuntu sind wir immer ein Nutzer, kein Admin
whoami
zeigt den Usernamen an. Der Adminuser heisst in Linux root.
Dieser darf alles.
Um Admin zu werden müssen wir mit
sudo su
root werden.
Allerdings ist sudo das Kommando um Programme als root auszuführen wenn man nicht root ist.
Deswegen reicht es eigentlich immer
sudo kommando
aufzurufen statt tatsächlich root zu sein

Programm installieren 2
Ubuntu holt sich die Programme von Listen die bei Ubuntu selbst verwaltet werden. Um sicher zu sein
immer die neusten Infos zu haben machen wir erst einmal ein Update
sudo apt-get update

apt ist hier das Installationstool
Die Infos liegen nun im cache von apt und können nun nach Programmen durchsucht werden
sudo apt-cache search apache2
Durchsucht den Cache nach allen Programmen in denen apache2 vorkommt (hier ist grep von vorher
dein Freund)

Die Ausgabe ist dann
Paketname – Beschreibung:
….
apache2 - Apache HTTP Server
….

Wir installieren also
sudo apt-get install apache2

sudo apt-get install mysql-server

sowie
sudo apt-get install phpmyadmin

Während der Installation von mysql und phpmyadmin wird nach Passwörtern gefragt. Am besten
immer das gleiche eingeben. Phpmyadmin fragt auch nach dem Webserver – hier nur Apache
auswählen.

Dann installieren wir noch vi (Texteditor)
sudo apt-get install vim




© Günther Haslbeck 2011 – V 0.2
Textdatei erstellen / bearbeiten mit vi
Wir machen das mit vi

vi datei.txt
 (Dateiname schon zum start angeben wenns die Datei noch nicht gibt)
vi datei.txt +15 öffnet eine Datei und springt gleich in Zeile 15 (ganz praktisch bei Fehlermeldungen im
Programm)

Achtung: Vi hat 3 Modis die alle per Tastaturkürzel bedient werden. Vi hat keine Oberfläche.
vi datei.txt
eingeben und genau schaun was untem am Rand steht.
Mit ESC kommen wir immer in den Kommandomodus. Dann steht unten im Eck nichts.
Durch drücken eines Selbstlautes (zb i) kommen wir in den TexteingabeModus. Dann steht unten zB
INSERT

Also mal i drücken, Text eingeben, ESC drücken

Kommandos wie zB speichern gibt man nun per :Befehl ein (aber nur wenn man im Kommandomodus
(vorher ESC) ist)
Dabei bedeutet
q = quit
w = write
q! = quit ohne nachfragen

:w schreibt also die Date
:q beendet vi
:wq schreibt und beendet vi

Wir speichern also mit :wq und befinden uns wieder ausserhalb von vi

Wir öffnen die Datei wieder:
vi datei.txt

Im Kommandomodus können wir auch text bearbeiten. Dabei gilt normalerweise immer
BEFEHLanzahlBEFEHL

so löscht dd die Zeile in der der Cursor steht, d2d löscht 2 Zeilen aber der Zeile in der der Cursor steht.
x löscht ein zeichen
yy kopiert eine Zeile in die Zwischenablage,
p fügt die Zeile darunter wieder ein.

Ein bischen einfacher wird das mit v.
V öffnet den -Visual- Modus (siehe wieder links unten). Man kann dann mit den Cursortasten
markieren, mit y kopieren und mit p wieder einfügen. Mit ESC kommt man wieder aus dem Visual-
Modus raus.



© Günther Haslbeck 2011 – V 0.2
:wq speichert und beendet die Bearbeitung der Datei.
Ja, der Umgang mit vi will gelernt sein und erfordert Übung. Es gibt sehr viele Kommandos wie zB :
%s/vorher/nachher/g um zu suchen/ersetzen.
Dazu am besten eine ausführliche Anleitung lesen.


Das erste PHP-Script
vi /var/www/index.php

Wir drücken i und geben ein

<?
echo('hallo welt');
?>

ESC und :wq

und öffnen dann im Browser
http://localhost/index.php
und wir sollten Hello World sehen


Apache und Co (neu) starten
läuft apache nicht, so starten wir ihn per
/etc/init.d/apache2 start
bzw
etc/init.d/apache2 restart
oder
etc/init.d/apache2 stop

gleiches mit mysql
/etc/init.d/mysql start/restart/stop


Hat unser Programm Fehler?
so gucken wir einfach was das Fehlerlog schreibt:
Wir öffnen ein neues Terminal und geben ein:
tail -f /var/log/apache2/error.log
und drücken dann im Browser F5 / Seite neu laden

Tail lassen wir laufen. Es zeigt wenn sich eine Datei verändert und gibt das dann aus. Optimal für uns.


Logfiles auswerten
guckt man die Logfiles von Apache so würde man gerne wissen was die User so gucken.

© Günther Haslbeck 2011 – V 0.2
Hier hilft uns awk. Awk hat eigentlich nichts mit Logfiles zu tun aber man kann mit awk auf Teile einer
Zeile der Logfiles zugreifen.
Eine Zeile Logfile sieht so aus
12.34.56.78 - - [04/Sep/2011:06:52:07 +0200] "GET /alle-titel/ HTTP/1.0" 200 26206 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;
 +http://www.google.com/bot.html )"
Man sieht hinter dem GET welche Datei abgerufen wurde.
Awk splittet nun die Zeilen am leerzeichen und kann das entsprechende Element ausgeben.
cat /var/log/apache2/access.log |awk '{print $7}'
schickt das Log an awk, das splittet und gibt „Spalte“ 7 aus.

….
/uploads/RTEmagicC_ca.jpg.jpg
/uploads/pics/nl_01.gif
….

und wenn man nun diese ausgaben zählt und nach Anzahl sortiert:


….
    14 /uploads/pics/tttp.jpeg
    15 /fileadmin/templates_studinfo/css/info.css?1305011933
    16 /ntpagetag.js
….


Welche Programme laufen und diese beenden
mit
top
lassen sich alle laufenden Programme anzeigen.
Mit Shift+M oder Shift+P lassen sich die Angaben nach zB Memory oder cPu-Last sortieren.

Gleiches zeigt auch
ps waufx

Beide Programm zeigen die PID (Processid) eines Programms..
USER      PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root     2 0.0 0.0  0 0?         S Sep01 0:00 [kthreadd]

Programme beenden geht per kill $pid also zB
kill 2384

dabei wird das Programm aber nicht abgeschossen sondern dem Programm mitgeteilt dass es sich
beenden soll.
Tut es das nicht kann per
kill -9 2348



© Günther Haslbeck 2011 – V 0.2
das Programm hart abgeschossen werden



PHP Entwicklung mit Frameworks

Wieso
Bei Softwareentwicklung tritt fast immer das gleiche Problem auf:
Die Entwickler sind zu faul zu dokumentieren und kopieren lieber als Software anzupassen. Das führt
zu unübersichtlichen und xmal vorhandenen Code.
Deswegen bietet Frameworks einen gewissen Rahmen. Nun kann man CakePhp oder Symphonie
verwenden aber diese sind doch etwas schwer für unsere Bedürfnisse.
Es reicht eigentlich ein einfaches PHP Programm das Parameter entgegen nimmt, etwas damit macht
und dann ausgibt.
Fängt man mit der Ausgabe an so stellt man fest: HTML komplett auszugeben ist nicht sinnvoll da das
Webdesign im php-Code stattfindet. Man kann die Tätigkeiten „Entwickeln“ und „Webdisign“ nicht
trennen. Deswegen ist es sinnvoll ein Templatesystem wie Twig zu verwenden.
In Twig werden im HTML Platzhalter definiert die dann in php mit Werten gefüllt werden und dann
alles ausgegeben.
Des weiteren ist es sinnvoll die Businesslogik im Programm von der Datenspeicherung zu trennen.
Insgesamt nennt sich das dann Model (DB-Logik), Controller ( Businesslogik), View = Ausgabe bzw
„offiziell“ MVC (Model View Controller)
Aber auch im Model möchten wir nicht jedesmal eine DB-Verbindung komplett neu programmieren.
Deswegen die obig genannten Frameworks. Es geht aber auch sehr einfach.
Unser Programm würde ungefähr so aussehen:

<?
Übergabeparamter aus der URL/Form einlesen
Datenbankverbindung aufbauen
In Datenbank schreiben oder daraus lesen
Datenbankverbinung abbauen
Twig Template laden
Werte in Twig setzen
Template ausgeben
?>

Betrachtet man das genauer so ist das Programm selbst der Controller,
Der von der Datenbank eingeschlossene Bereich das Model
und danach die Befüllung des Views (also des html-Templates)


Code nur einmal verwenden

Um das nicht alles immer neu zu machen erstellen zerlegen wir obiges File in 3 Files:



© Günther Haslbeck 2011 – V 0.2
controller.php
<?
Übergabeparamter aus der URL/Form einlesen
Modelaufruf
Viewaufruf
?>

Model
<?
Datenbankverbindung aufbauen
In Datenbank schreiben oder daraus lesen
Datenbankverbindung abbauen
?>

View
<?
Twig Template laden
Werte in Twig setzen
Template ausgeben
?>

Wenn wir uns nun die Programme ansehen ist immer noch vieles was später immer wieder kopiert
werden würde. Zudem ist mit View eigentlich die HTML-Seite (Also das Template gemeint), nicht die
Logik dieses zu befüllen....

Wir müssen also das ganze Programm nochmal etwas drehen.
Aber wie?

Nun, erst einmal fassen wir alles was wir immer wieder brauchen aber nichts mit dem Programmablauf
zu tun hat zusammen in eigene Dateien zB Datenbank Auf/Abbau usw.
Damit ist schon mal viel Code so vorhanden das wir diesen in jedem unserer Projekte verwenden
können. Gleiches gilt für den Code um Twig zu nutzen.
Bleibt also nur die Businesslogik und das Datenmodell selbst das jedesmal anders ist.
Wir schreiben dazu eine Klasse die die Rahmenbedingungen enthält aber kein Datenstuktur und keine
Businesslogik.
Würde man das in einem File darstellen wollen (was wir aber oben ja wegen der wiederverwendbarkeit
des Codes nicht wollen, so würde diese wieder so aussehen:

<?
Controllerplatzhalter

Datenbankverbindung aufbauen

Modelplatzhalter

Datenbankverbinung abbauen

© Günther Haslbeck 2011 – V 0.2
Templateplatzhalter

Twig Template laden
Werte in Twig setzen
Template ausgeben
?>

Von dieser Klasse leiten wir dann ab (extends) und füllen nur noch den Code den wir brauchen:

<?
class neu extends vorherigesbeispiel{

Controllerplatzhalter = { unser code }

Modelplatzhalter = {unser code}

Templateplatzhalter = { unser html code)

}
?>

Diese 3 „lokalen“ Codeblöcke lagern wir aus in 3 Files. Die 3 Files benennen wir jeweils gleich und
legen diese jeweils in das Verzeichnis
/controller/gleichername.php
/model/gleichername.php
/view/gleichername.html

So, schon mal sehr schön.
Jetzt bräuchten wir nur noch etwas was erkennt welche Files zusammengehören.
Wir brauchen ein kleines Programm, das die Steuerung übernimmt.

Hier kommt der nächst Trick:
wir definieren, dass die URLs unserer Webseite so aussehen:
http://www.wir.de/appname/name

und legen eine .htaccess in das Verzeichnis appname die sagt:
Nimm, was hinter appname/ steht und baue damit ein Programm zusammen, das aus dem Rahmen
besteht und aus dem model/view/controller Dateien die mit Name. beginnen.

Im Verzeichnis appname erstellen wir eine Datei die sich darum kümmert.
Diese bekommt den Namen von der htaccess übergeben, baut sich ein php-Script aus eben diesen
Teilen zusammen und führt das Programm aus.

Wichtig noch: Wir wollen auch die Bilder zum Projekt im gleichen Verzeichnis ablegen (hier in res),
deswegen darf hier die Regel nicht greifen.
Die .htaccess

© Günther Haslbeck 2011 – V 0.2
----------------------
RewriteEngine on

RewriteCond %{REQUEST_URI} ^/appname/res/(.*) [NC]
RewriteRule (.*) /appname/view/img/%1 [L]

RewriteCond %{REQUEST_URI} !^/appname/view/(.*) [NC]
RewriteCond %{REQUEST_URI} !^/appname/index.php [NC]
RewriteRule (.*) /appname/index.php/$1 [L]

die index.php ist unser Framework und baut dann unser Programm zusammen und führt es aus.

Für jedes neue Seite in unserer Applikation müssen wir also nur noch unseren Controller, das Model
und die HTML-Seite kopieren und gleich benennen und ausprogrammieren. Für die Startseite der
Applikation nennen wir alle 3 Files „index...“ und fertig.

Das funktioniert übrigens deshalb da in php wir dynamisch eine Klasse instanzieren können
$object = new $class();

und per überschreiben der __autoload und den namen der Klasse definieren könne wo diese liegen

….
      function __autoload($class_name) {
        $pos = stripos($class_name, "global");

         if ($pos === false){
               include './classes/' . $class_name . '.php';
….

Aber das nur als kleiner Einschub...

Voila, unser eigenes Framework ist fertig und sauber in MVC aufgeteilt das dann so aussieht

.htaccess
index.php
/model/seite.php
/view/seite.html
/controller/seite.php
/helper/framework.php
/helper/database.php

sowie

/design/css
/design/js
/design/images/seite/


© Günther Haslbeck 2011 – V 0.2
Um helper aber nicht x mal zu kopieren erstellen wir auf dem Server ein Verzeichnis in dem diese Files
liegen und verlinken diese nur in das Projekt.


Outsourcing
Als nächstes möchten wir, das andere externe Firmen an unserem Code mitentwickeln.
Dazu setzen wir einen funktionierenden Server auf. Unsere Applikationen benutzen dort die normale
Datenbank usw.
Wie können aber externe entwickeln ohne dass diese Zugriff auf unsere Daten haben?
Nun, wir erweitern unser Framework um den Ordner
/local/

Dort legen wir Klassen ab, die die Datenbankverbindung usw simulieren. Unsere normale database.php
entfernen wir. Nun muss das Framework nur noch so angepasst werden dass auch in lokal nach einer
database.php gesucht wird und zwar vor der in helper und dann diese genommen wird. Damit läuft die
App ohne echte Datenbankverbindung. (Stichwort Mock-Objekte)

Den Code kopieren wir und richten wir vollständig ein. Dann checken wir diese leere App in github ein
und richten unseren externen Kollegen einen Zugang ein.
Diese können nun bei sich lokal entwickeln und testen. Immer mal wieder checken die Jungs dann den
Code wieder ein.
Auf unserem Testserver guckt ein Cronjob alle 5 min bei github nach ob sich dort etwas neues befindet.
Wenn ja so wird die Änderung von github heruntergeladen und dann die richtige Stelle auf dem dev-
Server kopiert. Zudem die Mockobjekte entfernt und damit greift dort nun wieder der normale
Database Code.
Damit kann der externe Entwickler also auf die Applikation praktisch in der zukünftigen Umgebung
testen OHNE darauf Zugriff zu haben.


Sessions und Rechte
Unsere Framework-Klasse muss sich zusätzlich darum kümmern, das der User eingeloggt ist oder
nicht. Das kann jeder implementieren wie er will.
Möchte man nur einige Seiten der App sperren so ist die Abfrage statt im Framework im Controller
auszuführen.
Nun ist es auch günstig wenn zur Session eine Rechtetabelle verwaltet wird. Dort kann dann hinterlegt
werden ob der User wenn er eingeloggt ist den Seite sehen darf oder nicht.
Über einen Zeitstempel kann das dann auch zeitgesteuert funktionieren.

So ist damit denkbar dass zB bei der Registrierung ein solches Recht zB für 14 Tage eingetragen wird.
Sind die 14 Tage abgelaufen so muss sich der User das Recht kaufen. Vorher kann der User testen.

Mit Hilfe dieser Rechtetabelle kann also jeder Bereich in der Applikation gegen Gebühr ein und
ausgeschaltet werden.



© Günther Haslbeck 2011 – V 0.2
Versionierung mit GIT

Der aktuelle Stand in GIT ist ok? - Dann einen Tag erzeugen mit Versionsnummer:




Jetzt kann auf den Zielrechner mit
-l“ist“ (list)




geguckt werden welche Versionen es gibt und die ensprechende dann ausgecheckt werden.

Anmerkung:
Eigentlich wird nicht ausgecheckt sondern der Stand zu diesem Tag hergestellt.

Es könnte also sein, dass ein „git clone .. „ schon weiter ist. Durch git checkout „version“ wird dann
rein „rollback“ auf einen älteren Stand gemacht.


Netbeans zeigt php-docs nicht an

Netbeans hat je nach Code etwas Schwierigkeiten den Code zu erkennen und den Code Completion
Assistant anzuzeigen.
Je nachdem zeigt Netbeans entweder




oder
Netbeans zeigt eine Auswahl aller Files die eine Variable mit gleichen Namen enthalten




© Günther Haslbeck 2011 – V 0.2
Um Netbeans zu unterstützen kann man direkt direkt über den Variablen definieren welchen Typ (oder
Klasse) diese Variablen repräsentieren:




oder direkt




und schon klappts




© Günther Haslbeck 2011 – V 0.2
Wenns nicht geht: Ist phpdoc installiert? Sind die anderen Klassen im Include-Pfad?

Mehr unter http://blogs.oracle.com/netbeansphp/entry/code_completion_for_a_class


Error-Reporting

sollte immer auf Vollanschlag sein denn Code der Warnungen erzeugt.. dem kann man nicht trauen.
Wo keine Warnungen sind sind auch keine Fehler

Das Fehlerreporting kann am Anfang oder in der php.ini gesetzt werden:

// Melde alle PHP Fehler (auch wenn in spät. PHP-Versionen neue hinzu kommen)
error_reporting(-1);

// Error Reporting komplett abschalten
error_reporting(0);

// Nur bestimmte Fehler melden
error_reporting(E_ERROR | E_WARNING | E_PARSE);

Mehr:


© Günther Haslbeck 2011 – V 0.2
http://php.net/manual/de/function.error-reporting.php


Eigenen Errorhandler




Undefinierte Variablen in PHP anzeigen

Da hilft Netbeans gerne aus:

Warnungen in Netbeans für PHP aktivieren:




© Günther Haslbeck 2011 – V 0.2
Definieren wie was angezeigt werden soll (Achtung, gilt für alle Sprachen)




Voila:




© Günther Haslbeck 2011 – V 0.2
Twig I18n Implementation / Translation – How it works



The Twig Docu is very good but this (important) Part ist not very clear
How to use the i18n Support.
First of all, just read the Docu at
http://twig.sensiolabs.org/doc/extensions/i18n.html
but they is a little “short”… i would say
The missing Part:
First: Checkout the Extension Repository:
git clone https://github.com/fabpot/Twig-extensions.git
and install gettext
apt-get install php-gettext
Then (for testing) i copied the I18n.php and the Parser.php from to
…/Twig-extensions/lib/Twig/Extensions/Extension cp -r I18n.php
/usr/share/php/Twig/Extension/
…/Twig-extensions/lib/Twig/Extensions/# cp -r
TokenParser /usr/share/php/Twig/Extension/
…/Twig-extensions/lib/Twig/Extensions/# cp -r Node /usr/share/php/Twig/Extension/
but nothing happens bec this directory seams to be not directly included so if you add the
Files directly like:
     $twig = new Twig_Environment($loader, $env_options);
     // Set language to german
     putenv(‘LC_ALL=de_DE.utf8′);
     setlocale(LC_ALL, ‘de_DE.utf8′);
     // Specify the location of the translation tables
     bindtextdomain(‘myAppPhp’, ‘/usr/share/locale’);
     bind_textdomain_codeset(‘myAppPhp’, ‘UTF-8′);
     // Choose domain
     textdomain(‘myAppPhp’);
     require_once(‘/usr/share/php/Twig/Extension/I18n.php’);
     require_once(‘/usr/share/php/Twig/Extension/TokenParser/Trans.php’);
     require_once(‘/usr/share/php/Twig/Extension/Node/Trans.php’);
     $twig->addExtension(new Twig_Extensions_Extension_I18n());
everything works…
the de_DE.utf8 is for german and /usr/share/locale is where normally the .mo files are for the
linux system (you can use every other directory)
to get the language exactly use
     locale -a | grep DE

© Günther Haslbeck 2011 – V 0.2
and you will get
     de_DE.utf8
so this is where the system will translate your english default text to. This means you have to
set LC_ALL to the target language
But: This was only the first Step.
Now add a
{% trans “Hello World!” %}
somewhere in one of your templates and lets see if the “Hello World” is on your site…
If so, good!
Ok,
as next turn the Twig-Cache on if not still done
     $env_options = array(
     ‘cache’ => ‘/var/www/vhost081/twig_cache’,
     );
     $twig = new Twig_Environment($loader, $env_options);
Youll find php files like 4b/c6/189025b9af97f63de69cce1f5cb2.php
in the twigcache and if you look into the files youll see the “Hello World” there:
….
// line 8
echo gettext(“Hello World!”);
// line 9
…
bec Twig translates all the templates into php code (this is also mentioned at the End of the
Twig i18n docu) and what you see is how gettext in php works.
So now we have to extract all these calls and create a file for translation
but first we need to install xgettext:
apt-get install gettext
then create the po-file from the php cache file:
     /var/www/vhost081/twig_cache# xgettext –default-domain=myAppPhp -p
     /tmp –from-code=UTF-8 -n –omit-header -L PHP
     4b/c6/189025b9af97f63de69cce1f5cb2.php
I write it to /tmp with the name myAppPhp (which was set before in the php code)
if you look at it youll see something like
     #: 4b/c6/189025b9af97f63de69cce1f5cb2.php:25
     msgid “Hello World!”
     msgstr “”
so use poedit or just a normal texteditor and change msgstr to the translated version
     #: 4b/c6/189025b9af97f63de69cce1f5cb2.php:25
     msgid “Hello World!”
     msgstr “Hallo Welt!”


© Günther Haslbeck 2011 – V 0.2
now convert the file into a machine readable format (from .po to .mo)
      msgfmt -v -o /tmp/myAppPhp.mo /tmp/myAppPhp.po
and copy the file to the given directory
      cp /tmp/myAppPhp.mo /usr/share/locale/de/LC_MESSAGES/
If you use a different directory dont forget the LC_MESSAGES and that the file has to be
readable and accessable for apache/php
If you want to check whats in the file:
      strings /tmp/myAppPhp.mo
and youll see “Hallo Welt” on the Website
My Sources for this Article
http://oriya.sarovar.org/docs/gettext_single.html
and
http://stackoverflow.com/questions/2425562/php-gettext-function-only-
returns-orignal-untranslated-string
Still unclear:
How to use different translations on different sites ?!

Webdesign
Woher bekommt man eigentlich coole Webdesigns?
Eigentlich relativ einfach. Wenn man kein Künstler ist, dann kauf man sich ein fertiges Design. Da wir
dieses dann sowieso etwas anpassen müssen ist es egal für welches System das Design/Template
eigentlich gemacht ist. Deswegen: Webseiten wie Templatemonster.com verkaufen 1000de von Designs
für ca 50€. Die Hauptarbeit ist eher das stöbern nach dem richtigen Design

Fotos für die Seite
Gibts bei Fotolia oder Stockphotos im Netz. Evtl die Lizenzbedingungen beachten.


Logo für die Seite
Da gibts die Möglichkeit fertige Logos zu kaufen
http://www.logotion.com/logodesign/logos-1.html
http://www.logomarket.com/
für 100-200-1000 Euro
oder sich 25 bis 70 Logos vorschlagen zu lassen ab 700 Euro
http://de.wilogo.com/
aber woher weiss ich ob was dabei ist?
Trifft es meinen Geschmack?
Ich habs deshalb jetzt umgekehrt gemacht.
Ich hab mir auf
http://de.wilogo.com/nos-references-en-logos.html

© Günther Haslbeck 2011 – V 0.2
die Logos ausgeguckt die mir am besten gefallen haben und mir dann weitere von dem
Designer (diesmal aus .de) angeguckt.
Den hab ich nun angeschrieben und ihm die, die mir am besten gefallen genannt und das ich
so eins gerne hätte.
Der macht mir nun am Wochenende Vorschläge für mich und dann schau ma mal ob da was
rauskommt.
Wenns passt hätt er gerne 250 Euro.


PHP Beschleunigen

Ganz einfach mit Xcache für Apache (oder alternativ gleich NGINX verwenden).
http://arnowelzel.de/wiki/de/web/xcache

und so gehts:
apt-get install php5-xcache


apache restart, fertig.
In /etc/php5/apache2/conf.d/xcache.ini ist insbesondere der Wert für xcache.size wichtig.
Einfach ein bissl höher drehen ;)

durch kopieren des Admininterfaces in das Webverzeichnis (wird unter ubuntu gleich mit auf
die Platte kopiert)

 cp -a /usr/share/xcache/admin /var/www/vhost008/html/xcache-admin
 vi /etc/php5/conf.d/xcache.ini


entfernen der admin/passwort kommentare und setzen eines MD5 Passworts


[xcache.admin]
xcache.admin.enable_auth = On
xcache.admin.user = "bla"
xcache.admin.pass = "8f87e10869299a5fe80b315695296b88"
(einfach durch einen md5 online generator generieren)


erhält man ein sehr schönes Webinterface




© Günther Haslbeck 2011 – V 0.2
Apache Status Modul

Da PHP als Modul im Speicher läuft sollte kann nicht einfach geprüft werden was gerade im
System los ist. Einfach mit
http://httpd.apache.org/docs/2.0/mod/mod_status.html
den Status des Servers überwachen
Dort ist deutlich zu sehen welche Prozesse gerade laufen usw




© Günther Haslbeck 2011 – V 0.2
Gitweb – neues Projekt erstellen
(installation wird im nächsten Abschnitt erklärt, hier erst mal der schnelle weg)
Ins Projektroot von gitweb wechseln, dann repostory erstellen.
Die meissten nennen diese am Ende .git – Ich mache viel mit Windows und ich mag es nicht wenn
Verzeichnisse eine „Extension“ haben deswegen bei mir ohne:




in description eine einfache Beschreibung eingeben
Dann config-File einstellen (geht direkt im File oder:)




Fertig.



Gitweb installieren in ubuntu


          1. ganz normal via apt-get installieren

   2. Pfad wo die reps liegen in /etc/gitweb.conf definieren




darin legen wir nun ein Verzeichnis an und darin legen wir nun ein git repository an




und editieren darin die description des projects



© Günther Haslbeck 2011 – V 0.2
und wir sehen dann im Browser




und wenn wir darauf klicken ist auch alles da




was aber noch fehlt ist die Anzeige der URL des repositories.
Das macht das Auschecken etwas leichter

das geschieht am Ende von /etc/gitweb.
Dort können 1 oder mehrere URLs angegeben werden




diese erscheinen dann auch in gitweb




© Günther Haslbeck 2011 – V 0.2
Jetzt checken wir mal das repository aus

Dazu lokal ein Verzeichnis anlegen in dem dann das repository erscheinen soll
darin per git clone auschecken (Für alle die SSH auf einem anderen port laufen lassen: Einfach
ssh://xxx:PORT/bla )
reinwechseln
Datei anlegen,
committen




dann pushen




© Günther Haslbeck 2011 – V 0.2
und file ist da




und natürlich hat git vorher wieder gewarnt:




© Günther Haslbeck 2011 – V 0.2
und deswegen sollten wir die Werte wie angegeben auch setzen




einmal git pull und git push
und die Welt ist wieder in Ordnung




File ändern und commiten und pushen:




alles brav, alles funktioniert



© Günther Haslbeck 2011 – V 0.2
GIT in Eclipse installieren
Egit unter HELP > INSTALL NEW SOFTWARE hinzufügen
http://eclipse.org/egit/download/




© Günther Haslbeck 2011 – V 0.2
Ein bestehendes Projekt für Eclipse aus GIT auschecken

Projekt anlegen via
Import → GIT → Projects from GIT




© Günther Haslbeck 2011 – V 0.2
und dann CLONE und dort




wieder hier mit Extra-Port Angabe (:32 – normalerweise nicht nötig).
Den Rest füllt EGIT selbst aus

Unten noch Benutzername + PW angeben.

Dann Importieren


------------
Neues Projekt
Erst einmal mit TEAM → Share ein neues Repository lokal erstellen.


© Günther Haslbeck 2011 – V 0.2
Dann über die Console (anders hab ichs nicht geschaft)




Dann klappts mit TEAM > PUSH TO UPSTREAM

und fertig ;)

Push geht allerdings nur oben beim „Projekt“ selbst




© Günther Haslbeck 2011 – V 0.2
Branching in Git

Einen neuen Branch (hier mal mit testnamen „newbranch“)erzeugen und dann mal anzeigen welche
Branches es gibt




Das * vor master zeigt, das wir im Master-Branch sind
Wir wechseln mal in unseren „newbranch“



und pushen diesen auch gleich mal in unser gitrepository




und er erscheint auch in unserem gitweb




© Günther Haslbeck 2011 – V 0.2
Wir bearbeiten ein File und committen und pushen




Man sieht auch in gitweb die Änderungen am File und in welchem Branch




Wechseln wir nun zurück zum Masterbranch




so ist im File wieder der alte Stand.

Nun mergen wir den Master mit dem Stand aus „newbranch“




© Günther Haslbeck 2011 – V 0.2
und das File passt wieder.
Wir pushen alles noch, dann ists auch wieder im repository ok




und auch in gitweb sieht man dass das File nun in beiden Branches aktuell ist:




Wenns Probleme gab beim mergen:

git diff zeigt die Probleme
git commit -a um die Files dann zu committen

git branch -d newbranch löscht einen Branch der in einem normalen Status ist
git branch -D newbranch löscht den Branch egal in welchen Status er ist

Deployment mit Git
wäre damit zB so möglich: Der Sync auf die Server kann dann einfach per rsync erfolgen




© Günther Haslbeck 2011 – V 0.2
Wir haben also aktuell unseren Quellcode zB so organisiert:

                                   Remote Master
                                     Repository
 Netbeans


      Lokales Master                             Remote Master
                                                                         dev-webserver
        Repository                                  clone


                                                                 rsync

und so hätten wirs gerne




© Günther Haslbeck 2011 – V 0.2
Remote Master
                                  Repository
   Netbeans
                                                                rsync
      Lokales Master                            Remote Master
                                                                   dev-webserver
        Repository                                 clone


                                     Switch from Master (dev) to Stage
                                     Merge to Stage and sync
                                     Switch back to Master (Dev)
                                            Remote Stage
                                                                  stage-webserver
                                            Branch clone

                                       Switch from Stage to Live
                                       Merge to Live and sync
                                       Switch back to Stage
                                                Remote Live
                                                                   live-webserver
                                                Branch clone


Wir legen also erst einmal 2 neue Branches an
$ git branch stage
$ git branch live

und pushen diese
$ git push origin stage
$ git push origin live

was haben wir, wo sind wir:

$ git branch

© Günther Haslbeck 2011 – V 0.2
live
* master
 stage

und wechseln dann in den Stage-Branch
$ git checkout stage
Switched to branch 'stage'

und prüfen:

$ git branch
 live
 master
* stage

Perfect. Nun mergen wir alles von master nach stage, vergeben just for fun ein (versions) Tag (nicht
nötig) und pushen alles wieder zurück

$ git merge master
$ git push
$ git tag -a v0.1 -m "neue Version"
$ git push origin v0.1
$ git checkout master
Switched to branch 'master'

Alle Änderungen vom Masterbranch sind nun auch im Stagebranch.

Das sehen wir auch in Gitweb




Jetzt muss nur noch der Repository-Clone vom Stagesverzeichnis dass dann mit dem Stage-Server
syncht auf eben diesen Branch umgeschaltet werden damit nur Änderungen aus dem Stage-Branch
gesyncht werden

wir wechseln also in das Verzeichnis in dem das Stagesystem geclonet ist und sehen uns die
vorhandenen Branches an

$ git branch
    • master

Es gibt nur Master. Wir wollen aber einen anderen. Welche es gibt zeigt -a :

$ git branch -a
* master
 remotes/origin/HEAD -> origin/master

© Günther Haslbeck 2011 – V 0.2
remotes/origin/live
 remotes/origin/master
 remotes/origin/stage

(Mehr http://stackoverflow.com/questions/67699/how-do-i-clone-all-remote-branches-with-git )

um in den stage-branch zu kommen müssen wir diesen hier einmalig auschecken:

$ git checkout -b stage remotes/origin/stage
Branch stage set up to track remote branch stage from origin.
Switched to a new branch 'stage'

wir sind nun in
$ git branch
 master
* stage

und holen uns nun zur Sicherheit nochmal den neusten stand

$ git pull

Von diesem Verzeichnis werden also nur Änderungen gesyncht die im Branch Stage sind.

Ändert man nun in Netbeans etwas ab und commit/pullt diese Änderungen in den Masterbranch so
erscheint diese Änderung nur auf dem Devserver.

Um die Änderung auch auf dem Stageserver zu sehen muss eben der Stagebrach mit dem Masterbranch
gemerget werden.

$ git merge master
$ git tag -a v0.2 -m "neue Version"
$ git push origin v0.2
$ git push
$ git checkout master

und schon erscheint die Änderung auf auf dem Stageserver.
Auch in gitweb ist schön zu sehen auf welchem Stand die Systeme sind




und durch die Tags könnten wir auch später auf eine ältere Version zurückspringen.




© Günther Haslbeck 2011 – V 0.2

Weitere ähnliche Inhalte

Was ist angesagt?

Agorum core-entwickler-dokumentation-6 4-0
Agorum core-entwickler-dokumentation-6 4-0Agorum core-entwickler-dokumentation-6 4-0
Agorum core-entwickler-dokumentation-6 4-0agorum Software GmbH
 
Team Oldenburger Robo-Fußball – Abschlussbericht der Projektgruppe 2010
Team Oldenburger Robo-Fußball – Abschlussbericht  der Projektgruppe  2010Team Oldenburger Robo-Fußball – Abschlussbericht  der Projektgruppe  2010
Team Oldenburger Robo-Fußball – Abschlussbericht der Projektgruppe 2010Johannes Diemke
 
382726314 X Php5 In 14 Tagen (Ddt)
382726314 X Php5 In 14 Tagen (Ddt)382726314 X Php5 In 14 Tagen (Ddt)
382726314 X Php5 In 14 Tagen (Ddt)guest943d41
 
LeitlinienküHlwasser
LeitlinienküHlwasserLeitlinienküHlwasser
LeitlinienküHlwasserguestcfc74b3
 
Dreamweaver cs5 hilfe
Dreamweaver cs5 hilfeDreamweaver cs5 hilfe
Dreamweaver cs5 hilfefersel2015
 
Technikerarbeit: Technische Dokumentation in der Ersatzteillogistik
Technikerarbeit: Technische Dokumentation in der ErsatzteillogistikTechnikerarbeit: Technische Dokumentation in der Ersatzteillogistik
Technikerarbeit: Technische Dokumentation in der ErsatzteillogistikTheRealWolf
 
Vrtcl gamercharts free2play_report_2012
Vrtcl gamercharts free2play_report_2012Vrtcl gamercharts free2play_report_2012
Vrtcl gamercharts free2play_report_2012Eric Hegmann
 
Hacking in german
Hacking in germanHacking in german
Hacking in germanCr CRays
 
Bedienungsanleitung Schlüsselverwaltung TSObjektkey 2008
Bedienungsanleitung Schlüsselverwaltung TSObjektkey 2008Bedienungsanleitung Schlüsselverwaltung TSObjektkey 2008
Bedienungsanleitung Schlüsselverwaltung TSObjektkey 2008Thomas Schoessow
 
Machbarkeitsanalyse und prototypische Entwicklung eines eMagazines für das A...
Machbarkeitsanalyse und prototypische Entwicklung eines eMagazines für das A...Machbarkeitsanalyse und prototypische Entwicklung eines eMagazines für das A...
Machbarkeitsanalyse und prototypische Entwicklung eines eMagazines für das A...Jonathan Keller
 
1 pdfsam unlock-buchauszug
1 pdfsam unlock-buchauszug1 pdfsam unlock-buchauszug
1 pdfsam unlock-buchauszugdavetsbass
 
backy - Image-basiertes Backup für virtuelle Maschinen
backy - Image-basiertes Backup für virtuelle Maschinenbacky - Image-basiertes Backup für virtuelle Maschinen
backy - Image-basiertes Backup für virtuelle MaschinenChristian Kauhaus
 
Sappress Sap Controlling2
Sappress Sap Controlling2Sappress Sap Controlling2
Sappress Sap Controlling2caradha
 
ABAP Test & Troubleshooting @SITMuc 2013
ABAP Test & Troubleshooting @SITMuc 2013ABAP Test & Troubleshooting @SITMuc 2013
ABAP Test & Troubleshooting @SITMuc 2013SbgMartin
 
Zotero Tutorial
Zotero TutorialZotero Tutorial
Zotero Tutorialheiko.vogl
 
SITEFORUM Tutorial v7
SITEFORUM Tutorial v7SITEFORUM Tutorial v7
SITEFORUM Tutorial v7anuvito
 

Was ist angesagt? (20)

Agorum core-entwickler-dokumentation-6 4-0
Agorum core-entwickler-dokumentation-6 4-0Agorum core-entwickler-dokumentation-6 4-0
Agorum core-entwickler-dokumentation-6 4-0
 
Team Oldenburger Robo-Fußball – Abschlussbericht der Projektgruppe 2010
Team Oldenburger Robo-Fußball – Abschlussbericht  der Projektgruppe  2010Team Oldenburger Robo-Fußball – Abschlussbericht  der Projektgruppe  2010
Team Oldenburger Robo-Fußball – Abschlussbericht der Projektgruppe 2010
 
382726314 X Php5 In 14 Tagen (Ddt)
382726314 X Php5 In 14 Tagen (Ddt)382726314 X Php5 In 14 Tagen (Ddt)
382726314 X Php5 In 14 Tagen (Ddt)
 
LeitlinienküHlwasser
LeitlinienküHlwasserLeitlinienküHlwasser
LeitlinienküHlwasser
 
Handbuch
HandbuchHandbuch
Handbuch
 
Dreamweaver cs5 hilfe
Dreamweaver cs5 hilfeDreamweaver cs5 hilfe
Dreamweaver cs5 hilfe
 
Technikerarbeit: Technische Dokumentation in der Ersatzteillogistik
Technikerarbeit: Technische Dokumentation in der ErsatzteillogistikTechnikerarbeit: Technische Dokumentation in der Ersatzteillogistik
Technikerarbeit: Technische Dokumentation in der Ersatzteillogistik
 
Vrtcl gamercharts free2play_report_2012
Vrtcl gamercharts free2play_report_2012Vrtcl gamercharts free2play_report_2012
Vrtcl gamercharts free2play_report_2012
 
Hacking in german
Hacking in germanHacking in german
Hacking in german
 
Bedienungsanleitung Schlüsselverwaltung TSObjektkey 2008
Bedienungsanleitung Schlüsselverwaltung TSObjektkey 2008Bedienungsanleitung Schlüsselverwaltung TSObjektkey 2008
Bedienungsanleitung Schlüsselverwaltung TSObjektkey 2008
 
Machbarkeitsanalyse und prototypische Entwicklung eines eMagazines für das A...
Machbarkeitsanalyse und prototypische Entwicklung eines eMagazines für das A...Machbarkeitsanalyse und prototypische Entwicklung eines eMagazines für das A...
Machbarkeitsanalyse und prototypische Entwicklung eines eMagazines für das A...
 
B8 Handbuch
B8 HandbuchB8 Handbuch
B8 Handbuch
 
1 pdfsam unlock-buchauszug
1 pdfsam unlock-buchauszug1 pdfsam unlock-buchauszug
1 pdfsam unlock-buchauszug
 
backy - Image-basiertes Backup für virtuelle Maschinen
backy - Image-basiertes Backup für virtuelle Maschinenbacky - Image-basiertes Backup für virtuelle Maschinen
backy - Image-basiertes Backup für virtuelle Maschinen
 
Sappress Sap Controlling2
Sappress Sap Controlling2Sappress Sap Controlling2
Sappress Sap Controlling2
 
ABAP Test & Troubleshooting @SITMuc 2013
ABAP Test & Troubleshooting @SITMuc 2013ABAP Test & Troubleshooting @SITMuc 2013
ABAP Test & Troubleshooting @SITMuc 2013
 
[DE] Dr. Ulrich Kampffmeyer - Artikel auf Wikipedia | 2015
[DE] Dr. Ulrich Kampffmeyer - Artikel auf Wikipedia | 2015[DE] Dr. Ulrich Kampffmeyer - Artikel auf Wikipedia | 2015
[DE] Dr. Ulrich Kampffmeyer - Artikel auf Wikipedia | 2015
 
Erfolgsgedaechtnis 1
Erfolgsgedaechtnis 1Erfolgsgedaechtnis 1
Erfolgsgedaechtnis 1
 
Zotero Tutorial
Zotero TutorialZotero Tutorial
Zotero Tutorial
 
SITEFORUM Tutorial v7
SITEFORUM Tutorial v7SITEFORUM Tutorial v7
SITEFORUM Tutorial v7
 

Andere mochten auch

Knockout.js
Knockout.jsKnockout.js
Knockout.jsdevtyr
 
IDEAS FOR SCULPTURES
IDEAS FOR SCULPTURESIDEAS FOR SCULPTURES
IDEAS FOR SCULPTURESsaujanya94
 
Bad Neuenahr Gesundheitstag 2011: Begrüßung
Bad Neuenahr Gesundheitstag 2011: BegrüßungBad Neuenahr Gesundheitstag 2011: Begrüßung
Bad Neuenahr Gesundheitstag 2011: BegrüßungNatur_und_Medizin
 
Innovation 18 innov
Innovation 18 innovInnovation 18 innov
Innovation 18 innovseouler
 
Skript wie erstelle ich eine wissenschaftliches Arbeiten
Skript wie erstelle ich eine wissenschaftliches ArbeitenSkript wie erstelle ich eine wissenschaftliches Arbeiten
Skript wie erstelle ich eine wissenschaftliches Arbeitenmarrrci
 
Helga und freitag der 13 te
Helga und freitag der 13 teHelga und freitag der 13 te
Helga und freitag der 13 teGeorg Montsch
 
Citizen journalismus
Citizen journalismusCitizen journalismus
Citizen journalismusMartina197
 
Live session 24_04_13_1
Live session 24_04_13_1Live session 24_04_13_1
Live session 24_04_13_1Andrea Lißner
 
Begrüßung am Barcamp Kirche und Social Media
Begrüßung am Barcamp Kirche und Social Media Begrüßung am Barcamp Kirche und Social Media
Begrüßung am Barcamp Kirche und Social Media Kirche 2.0
 
WIssenschaftsjahr 2013 - Planspiel-Ausschreibung
WIssenschaftsjahr 2013 - Planspiel-AusschreibungWIssenschaftsjahr 2013 - Planspiel-Ausschreibung
WIssenschaftsjahr 2013 - Planspiel-AusschreibungMalte Paw
 
Social Media Monitoring & Analyse (Präsentation Infopaq beim 5. Twittwoch Rhe...
Social Media Monitoring & Analyse (Präsentation Infopaq beim 5. Twittwoch Rhe...Social Media Monitoring & Analyse (Präsentation Infopaq beim 5. Twittwoch Rhe...
Social Media Monitoring & Analyse (Präsentation Infopaq beim 5. Twittwoch Rhe...Infopaq Deutschland
 

Andere mochten auch (20)

Knockout.js
Knockout.jsKnockout.js
Knockout.js
 
IDEAS FOR SCULPTURES
IDEAS FOR SCULPTURESIDEAS FOR SCULPTURES
IDEAS FOR SCULPTURES
 
Bad Neuenahr Gesundheitstag 2011: Begrüßung
Bad Neuenahr Gesundheitstag 2011: BegrüßungBad Neuenahr Gesundheitstag 2011: Begrüßung
Bad Neuenahr Gesundheitstag 2011: Begrüßung
 
Innovation 18 innov
Innovation 18 innovInnovation 18 innov
Innovation 18 innov
 
Skript wie erstelle ich eine wissenschaftliches Arbeiten
Skript wie erstelle ich eine wissenschaftliches ArbeitenSkript wie erstelle ich eine wissenschaftliches Arbeiten
Skript wie erstelle ich eine wissenschaftliches Arbeiten
 
QR Code erstellen
QR Code erstellenQR Code erstellen
QR Code erstellen
 
Helga und freitag der 13 te
Helga und freitag der 13 teHelga und freitag der 13 te
Helga und freitag der 13 te
 
Citizen journalismus
Citizen journalismusCitizen journalismus
Citizen journalismus
 
Outline
OutlineOutline
Outline
 
Fu
FuFu
Fu
 
BDG
BDGBDG
BDG
 
Standard
StandardStandard
Standard
 
05 videos para llevar
05 videos para llevar05 videos para llevar
05 videos para llevar
 
Els ànecs
Els ànecsEls ànecs
Els ànecs
 
Live session 24_04_13_1
Live session 24_04_13_1Live session 24_04_13_1
Live session 24_04_13_1
 
Begrüßung am Barcamp Kirche und Social Media
Begrüßung am Barcamp Kirche und Social Media Begrüßung am Barcamp Kirche und Social Media
Begrüßung am Barcamp Kirche und Social Media
 
WIssenschaftsjahr 2013 - Planspiel-Ausschreibung
WIssenschaftsjahr 2013 - Planspiel-AusschreibungWIssenschaftsjahr 2013 - Planspiel-Ausschreibung
WIssenschaftsjahr 2013 - Planspiel-Ausschreibung
 
Social Media Monitoring & Analyse (Präsentation Infopaq beim 5. Twittwoch Rhe...
Social Media Monitoring & Analyse (Präsentation Infopaq beim 5. Twittwoch Rhe...Social Media Monitoring & Analyse (Präsentation Infopaq beim 5. Twittwoch Rhe...
Social Media Monitoring & Analyse (Präsentation Infopaq beim 5. Twittwoch Rhe...
 
MANUALIDADES
MANUALIDADESMANUALIDADES
MANUALIDADES
 
óSsos
óSsosóSsos
óSsos
 

Ähnlich wie Besser php programmieren - Von der Klasse über Unittests, Cruisecontrol, Selinum bis auf den Server

Final Opentrans 2.0 Rfq
Final Opentrans 2.0   RfqFinal Opentrans 2.0   Rfq
Final Opentrans 2.0 Rfqguest6f1fb4
 
Evaluierungsmodell
EvaluierungsmodellEvaluierungsmodell
Evaluierungsmodelloneduphine
 
Evaluierungsmodell
EvaluierungsmodellEvaluierungsmodell
Evaluierungsmodelloneduphine
 
Sappres Netweaver Identity Management
Sappres Netweaver Identity ManagementSappres Netweaver Identity Management
Sappres Netweaver Identity Managementgueste2a899
 
Der Linux Schulserver
Der Linux Schulserver Der Linux Schulserver
Der Linux Schulserver heiko.vogl
 
Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10
Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10
Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10Hoempagecms
 
Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10
Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10
Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10Websitecms
 
Homepage erstellen Benutzerhandbuch
Homepage erstellen BenutzerhandbuchHomepage erstellen Benutzerhandbuch
Homepage erstellen BenutzerhandbuchHomepageErstellen
 
Whitepaper: Indoor Positionsbestimmung in Büros & intelligenten Gebäuden
Whitepaper: Indoor Positionsbestimmung in Büros & intelligenten GebäudenWhitepaper: Indoor Positionsbestimmung in Büros & intelligenten Gebäuden
Whitepaper: Indoor Positionsbestimmung in Büros & intelligenten Gebäudeninfsoft GmbH
 
Benutzerhandbuch Zeta Producer 9 CMS
Benutzerhandbuch Zeta Producer 9 CMSBenutzerhandbuch Zeta Producer 9 CMS
Benutzerhandbuch Zeta Producer 9 CMSUwe Keim
 
53045 ba dpt 3000 v6.17
53045 ba dpt 3000 v6.1753045 ba dpt 3000 v6.17
53045 ba dpt 3000 v6.17Teo Dor
 
Creation ii v0.93 vorläufig
Creation ii v0.93 vorläufigCreation ii v0.93 vorläufig
Creation ii v0.93 vorläufigmarkktoo
 
Best Practice Guide
Best Practice GuideBest Practice Guide
Best Practice Guideguestc141a6
 

Ähnlich wie Besser php programmieren - Von der Klasse über Unittests, Cruisecontrol, Selinum bis auf den Server (20)

Final Opentrans 2.0 Rfq
Final Opentrans 2.0   RfqFinal Opentrans 2.0   Rfq
Final Opentrans 2.0 Rfq
 
JAX B
JAX BJAX B
JAX B
 
Evaluierungsmodell
EvaluierungsmodellEvaluierungsmodell
Evaluierungsmodell
 
Evaluierungsmodell
EvaluierungsmodellEvaluierungsmodell
Evaluierungsmodell
 
Sappres Netweaver Identity Management
Sappres Netweaver Identity ManagementSappres Netweaver Identity Management
Sappres Netweaver Identity Management
 
Solution Guide
Solution GuideSolution Guide
Solution Guide
 
Der Linux Schulserver
Der Linux Schulserver Der Linux Schulserver
Der Linux Schulserver
 
User manual
User manualUser manual
User manual
 
Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10
Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10
Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10
 
Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10
Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10
Website erstellen-mit-desktop-cms-benutzerhandbuch-zeta-producer-10
 
Homepage erstellen Benutzerhandbuch
Homepage erstellen BenutzerhandbuchHomepage erstellen Benutzerhandbuch
Homepage erstellen Benutzerhandbuch
 
Whitepaper: Indoor Positionsbestimmung in Büros & intelligenten Gebäuden
Whitepaper: Indoor Positionsbestimmung in Büros & intelligenten GebäudenWhitepaper: Indoor Positionsbestimmung in Büros & intelligenten Gebäuden
Whitepaper: Indoor Positionsbestimmung in Büros & intelligenten Gebäuden
 
Benutzerhandbuch Zeta Producer 9 CMS
Benutzerhandbuch Zeta Producer 9 CMSBenutzerhandbuch Zeta Producer 9 CMS
Benutzerhandbuch Zeta Producer 9 CMS
 
Web Analytics
Web AnalyticsWeb Analytics
Web Analytics
 
Diplomarbeit
DiplomarbeitDiplomarbeit
Diplomarbeit
 
German Original
German OriginalGerman Original
German Original
 
53045 ba dpt 3000 v6.17
53045 ba dpt 3000 v6.1753045 ba dpt 3000 v6.17
53045 ba dpt 3000 v6.17
 
Creation ii v0.93 vorläufig
Creation ii v0.93 vorläufigCreation ii v0.93 vorläufig
Creation ii v0.93 vorläufig
 
BSI Audit
BSI AuditBSI Audit
BSI Audit
 
Best Practice Guide
Best Practice GuideBest Practice Guide
Best Practice Guide
 

Besser php programmieren - Von der Klasse über Unittests, Cruisecontrol, Selinum bis auf den Server

  • 1. Professionelle Webentwicklung mit PHP Inhaltsverzeichnis Professionelle Webentwicklung mit PHP ..................................................................................................1 Kleines Vorwort..........................................................................................................................................3 Voraussetzung........................................................................................................................................3 Wie funktioniert ein Webrequest:...............................................................................................................4 Entwicklung am Beispiel einer Datenbankklasse...................................................................................... 5 So nicht..................................................................................................................................................5 IDE........................................................................................................................................................ 5 Erste Klasse in php................................................................................................................................ 6 Der Quellcode der Klasse................................................................................................................. 6 phpDoc....................................................................................................................................................... 9 Codevervollständigung.............................................................................................................................11 Unittesting................................................................................................................................................ 12 phpUnit................................................................................................................................................12 Integrationstesting.................................................................................................................................... 13 Exceptions................................................................................................................................................ 13 Revision Control System......................................................................................................................... 15 Vererbung in Klassen............................................................................................................................... 17 Code Refactoring..................................................................................................................................... 20 CodeConventions..................................................................................................................................... 20 Teamarbeit........................................................................................................................................... 21 Variable Naming Conventions ............................................................................................................21 Constant Naming Conventions ...........................................................................................................22 Method Naming Conventions ............................................................................................................ 22 Parameter Naming Conventions .........................................................................................................22 Struktur im Projekt.............................................................................................................................. 23 Wie schnell ist mein php-Script............................................................................................................... 24 Logfiles / Was passiert im Programm...................................................................................................... 25 Loglevel...............................................................................................................................................26 Vorgriff zu Nagios / Hobbit / xymon.............................................................................................. 27 Templating................................................................................................................................................27 i18n / Internationalisierung...................................................................................................................... 30 Translation........................................................................................................................................... 31 Continous Integration 1............................................................................................................................31 Kleiner Ausflug zurück zu Git................................................................................................................. 32 SSH Keygen............................................................................................................................................. 34 Continous Integration 2............................................................................................................................35 Unser Projekt hinzufügen....................................................................................................................36 Git Repository initialisieren............................................................................................................36 Verzeichnisproblem mit Git und CruiseControl............................................................................. 37 Selenium...................................................................................................................................................46 © Günther Haslbeck 2011 – V 0.2
  • 2. Logfile + Systemüberwachung................................................................................................................ 49 Nagios..................................................................................................................................................49 Komplette automatisch überwachte Entwicklung und Liveseite............................................................. 51 MRTG...................................................................................................................................................... 51 MemcacheD............................................................................................................................................. 51 Geschwindigkeit der Seite erhöhen..........................................................................................................52 Geschwindigkeit der Elemente in der Seite messen............................................................................53 PHP -Entwicklung auf Linux................................................................................................................... 53 Ubuntu basiert auf Debian-Linux........................................................................................................54 Die wichtigsten Dateien und Befehle für uns......................................................................................54 Wo sind wir (aktuelles Verzeichnis anzeigen)................................................................................ 54 Verzeichnisinhalt anzeigen............................................................................................................. 55 Ausgabe weiterverarbeiten............................................................................................................. 55 Verzeichnisse ................................................................................................................................. 55 Dateien suchen................................................................................................................................56 TAB ................................................................................................................................................56 Programme installieren...................................................................................................................57 Textdatei erstellen / bearbeiten mit vi.............................................................................................58 Das erste PHP-Script...................................................................................................................... 59 Apache und Co (neu) starten.......................................................................................................... 59 Hat unser Programm Fehler?.......................................................................................................... 59 Logfiles auswerten................................................................................................................................... 59 Welche Programme laufen und diese beenden.........................................................................................60 PHP Entwicklung mit Frameworks..........................................................................................................61 Wieso................................................................................................................................................... 61 Code nur einmal verwenden................................................................................................................61 Outsourcing.............................................................................................................................................. 65 Sessions und Rechte.................................................................................................................................65 Versionierung mit GIT............................................................................................................................. 66 Netbeans zeigt php-docs nicht an.............................................................................................................66 Error-Reporting........................................................................................................................................ 68 Eigenen Errorhandler............................................................................................................................... 69 Undefinierte Variablen in PHP anzeigen..................................................................................................69 Gitweb – neues Projekt erstellen..............................................................................................................76 Gitweb installieren in ubuntu.................................................................................................................. 76 Branching in Git.......................................................................................................................................85 © Günther Haslbeck 2011 – V 0.2
  • 3. Kleines Vorwort Das folgende Dokument wurde erstellt um eine klare Struktur in den Entwicklungsprozess zu bringen, insbesondere in php. Voraussetzung Diese Anleitung setzt voraus, dass php 5.3 oder höher, ein Apache Webserver installiert ist, eine lokale MySql-Instanz sowie java und phpmyamin sowie git unter Ubuntu 10/11 apt-get update apt-get install git-core apt-get install apache2 apt-get install mysql-server apt-get install phpmyadmin Java: java.sun.com: SDK: JDK 6 .. i586.bin runterladen, chmod u+x jdk-6u26-linux-i586.bin; ./jdk-6u26-linux-i586.bin Dann sudo /etc/init.d/mysql restart sudo /etc/init.d/apache2 restart unter http://localhost/ zeigt der Apache den Inhalt aus /var/www/ unter http://localhost/phpmyadmin/ zeigt phpmyadmin den Inhalt der MySQL Datenbank © Günther Haslbeck 2011 – V 0.2
  • 4. Erst einmal ein kleiner Ausflug: Wie funktioniert ein Webrequest: Das Ausführen des php-Scripts darf also nicht länger als ca 1 Sek (besser 0,7) dauern sonst dauert das laden der Graphiken zu lange um die 1,5 Sekunden zu schaffen. (obiges Beispiel != mod_php) © Günther Haslbeck 2011 – V 0.2
  • 5. Zurück zu php Entwicklung am Beispiel einer Datenbankklasse So nicht Leider wird Code wie der folgende durch jedes neue php-Programm immer wieder kopiert weil der Code nicht wiederverwendbar ist. Er ist Teil des eigentlichen Programms. Das führt unter anderem dazu, das a) DB-Passwörter überall stehen und b) diese sich nicht mehr ändern lassen weil keiner weiß wo diese stehen. Und natürlich hauptsächlich: Führt es zu hunderten Kopien immer gleichen Codes mit immer den gleichen Fehlern. Und ganz nebenbei: Wir verwenden NIE die() in einem Programm IDE Als Entwicklungsumgebung wird im folgenden Netbeans verwendet. Genau so könnte natürlich auch Eclipse verwendet werden © Günther Haslbeck 2011 – V 0.2
  • 6. Für beide IDEs (integrated development environment) muss evtl in Linux die JAVA_HOME gesetzt sein. Java runterladen und das java-Hauptverzeichnis setzen: export JAVA_HOME=/home/user/java/jdk1.6.0_24;export PATH=$JAVA_HOME/bin:$PATH Erste Klasse in php Wir starten Netbeans, erstellen ein neues PHP Projekt. Wir erstellen ein Unterverzeichnis und nennen es classes. Dort legen wir eine Daten namens Database.php ab Diese sieht zB so aus Der Quellcode der Klasse class Database { //put your code here private $connection; private $servername = "localhost"; private $mysqluser = "root"; private $mysqlpasswd = "passwd"; /** * connect * * connect to database * * @param string $databasename null or ro for readonly * @param string $mode null or ro for readonly © Günther Haslbeck 2011 – V 0.2
  • 7. */ public function connect($databasename = null, $mode = null) { //mode is for readonly - later on if ($this->connection) { //still connected! } else { $this->connection = mysql_connect($this->servername, $this->mysqluser, $this->mysqlpasswd); } if (!$this->connection) { echo “db-connect-error”; } if ($databasename) { $db_select = mysql_select_db($databasename); if ($db_select) { //echo 'database $databasename selected'; } else { echo $databasename . " could not be selected" . mysql_error(); } } } /** * disconnect * * disconnect fom database * */ public function disconnect() { mysql_close($this->connection); } /** * query * * querycall to database * * @param string $query the querytext */ public function query($query) { $result = mysql_query($query); if (!$result) { echo “cant query”; } return $result; } } Eingerückt wird der Code übrigens mit TAB, nicht mit Leerzeichen. Man sieht, dass die Passwörter usw als private deklariert sind, die Methoden wie Connect als public. © Günther Haslbeck 2011 – V 0.2
  • 8. Damit sind nur die Methoden der Klasse nach außen sichtbar. Passwörter usw muss und kann keiner sehen und keiner ändern. Generell sollten Membervariablen (also Variablen die nur die Klasse verwendet) nicht sichtbar sein sondern – wenn überhaupt nur per Getter/Setter also zB getServername(); oder setServername(“newServer”); modifizierbar sein. Die Klasse merkt sich auch die $connection intern, wir brauchen uns also nicht darum zu kümmern. Halte Klassen klein: In jeder Klasse nur den exakten Usecase abbilden. Beachte auch: Bei jedem Aufruf muss das komplette Script neu compiliert werden – viel drin, viel Compilezeit! Unser Programm das die Klasse benutzt sieht dann so aus: bei folgender Datenbankstruktur Keine Passwörter mehr, kein doppelter Code. Bei Netbeans oder Eclipse erkennt die IDE nun auch welche Methoden es gibt und zeigt Informationen an wenn man nur zB $db eingibt. Welche Methoden es gibt, welche Parameter diese haben usw(später dazu mehr). Die Info erhält Netbeans vom Kommentar über der Methode (phpDoc-Kommentar): © Günther Haslbeck 2011 – V 0.2
  • 9. Damit weiß die IDE was wie gemeint ist. Zudem kann man daraus einfach Doku generieren. Dazu müssen wir erst einmal phpdoc installieren: phpDoc apt-cache search php-doc apt-get install php-doc und evtl PhpDocumentator apt-get install php-pear pear config-set data_dir /var/www/ pear install --alldeps PhpDocumentor mkdir /var/www/PhpDocumentor-output chown www-data /var/www/PhpDocumentor-output unter http://localhost/PhpDocumentor/ findet sich nun eine Config-Oberfläche © Günther Haslbeck 2011 – V 0.2
  • 10. Danach generieren wir die Doku zu dieser Klasse in unser Webserver-Verzeichnis: phpdoc -d Quellverzeichnis -t Zielverzeichnis phpdoc -d /home/user/NetBeansProjects/PhpProject1 -t /var/www/phpdocu Code wird somit wiederverwendbar und von jedem verstanden. Mehr: http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.qui ckstart.pkg.html Zu beachten: für die einzelnen Projekte ist in der Doku das Tag package zu verwenden da phpDoc sonst alles in eine Ebene wirft © Günther Haslbeck 2011 – V 0.2
  • 11. Codevervollständigung Wie schon erwähnt erkennt Netbeans/Eclipse welche Klassen vorhanden sind. Erstellen wir eine Klasse vervollständigt die IDE den Code und hilft schnell und einfach Software zu erstellen: (Anzeigen auch durch STRG+Shift möglich, STRG + Klick springt zur Deklaration wenn im Projekt © Günther Haslbeck 2011 – V 0.2
  • 12. die entsprechenden Klassenpfade eingebunden sind , STRG + B entspricht STRG + Klick– Alle Keyboardshortcuts unter http://usersguide.netbeans.org/shortcuts.pdf ) Unittesting Aber was, wenn jeder darin rumspielt? Funktioniert dann noch alles? 1. Sollten diese Basisklassen von keinem verändert werden und wenn doch sollten generell alle Klassen per 2. Unit-Tests getestet werden. Wir installieren phpunit: apt-get install phpunit phpUnit ruft eine Klasse auf und vergleicht das Ergebnis mit einem festgelegten Ergebnis. In unserem Falle testen wir indirekt gleich mit ob die Datenbank und der Inhalt ok sind: © Günther Haslbeck 2011 – V 0.2
  • 13. Das Script baut eine Datenbankverbindung über unsere Klasse auf, sucht einen User und vergleicht das Ergebnis (assertSame) mit einem festgelegten Wert. Dies kann nun alle x Minuten gemacht werden. Solange das Ergebnis stimmt ist der Test erfolgreich und unser Code macht immer genau das was man von ihm erwartet. > phpunit DatabaseTest.php PHPUnit 3.4.13 by Sebastian Bergmann. OK (1 test, 1 assertion) Also alles ok. Integrationstesting Was hier vorher als Unittest dargestellt wurde ist eigentlich ein Integrationstest. Der Unterschied besteht darin, dass ein Unit-Test nur ganz kleine Schritte (Methoden usw) testet, ein Integrationstest aber aus mehreren Unittests bzw kompletten Programmabläufen besteht Exceptions Nun kann zB während der DB-Verbindung ein Problem auftreten. Dies fangen wir auf gar keinen Fall mit die() ab da die() das Programm sofort beendet, sondern wir werfen eine Exception. Da php als Default nur den Typ Exception kennt, wir aber ein bisschen genauer unterscheiden wollen erstellen wir unsere eigenen Exception zB am besten in der Klasse selbst © Günther Haslbeck 2011 – V 0.2
  • 14. Tritt ein Fehler auf, werfen wir eine DatabaseException nach „oben“: und fangen diese in unserem Programm außen wieder: © Günther Haslbeck 2011 – V 0.2
  • 15. Somit kann auf jeder Problem angemessen reagiert werden und nicht einfach das Programm abgebrochen. Wir haben nun obigen Code geändert. Durch einen erneuten Test durch phpUnit können wir sicher sein, dass noch alles tut. Aber was haben wir geändert? Revision Control System Im weiteren wird GIT verwendet. Git ist wie CVS oder SVN eine Freie Software zur Versionsverwaltung von Dateien und Verzeichnissen. Im Gegensatz zu CVS und dessen Nachfolger SVN (SubVersioN) setzt Git allerdings keinen zentralen Server voraus. © Günther Haslbeck 2011 – V 0.2
  • 16. Um also zu sehen was wir geändert haben, erstellen wir ein git Repository im Code-Verzeichnis > git init > git add PhpProject1 > git commit -a -m "first strike" Git erstellt nun ein .git Verzeichnis und merkt sich den aktuellen Stand dort. „first strike“ ist dabei ein frei festzulegender Kommentar der aussagekräftig gesetzt werden sollte. Wir verändern nun eine Datei (fügen eine Kommentarzeile ein) und speichern und committen erneut. (der Parameter -m ist um den Kommentar direkt in der Kommandozeile einzugeben) > git commit -a -m "added comment" und sehen: 1 files changed, 1 insertions(+) © Günther Haslbeck 2011 – V 0.2
  • 17. Was ist passiert: > git log PhpProject1/index.php und wir sehen und was wurde geändert? Wir lassen uns den Unterschied zw 2 Commits anzeigen: > git diff --color 652189eaa529e44.... 069627823fc52a8b44937.... Aha, eine Kommentarzeile wurde eingefügt. Tipp: git als Cron laufen lassen und Code einfach alle 60 min automatisch einchecken. Vererbung in Klassen Klassen sollten aber nicht verändert werden sondern abgeleitet/vererbt: Dabei “erbt” die neue Klasse die Eigenschaften (Methoden) der alten Klasse und wird durch die zusätzlichen Methoden erweitert. Das kann zB auch dafür genutzt werden aus einer “Basis”Klasse “Fahrzeug” jeweils ein “Auto” einen “Lieferwagen” zu erzeugen. Beide basieren damit auf einer Klasse die die Grundeigenschaften abbildet (Motor, 4 Reifen) aber zusätzlich die Klasse um eine Ladefläche (Lieferwagen) oder ein Schiebedach (Auto) erweitert. © Günther Haslbeck 2011 – V 0.2
  • 18. © Günther Haslbeck 2011 – V 0.2
  • 19. Weitere Möglichkeiten der Vererbung in PHP 5 © Günther Haslbeck 2011 – V 0.2
  • 20. Code Refactoring Oft merkt man während des entwickeln des Codes dass man gerne die eine oder andere Klasse oder Methode umbenennen möchte. Auch hier helfen die IDEs und können alle Stellen an den der Code verwendet wird in allen Files umbenennen. Diese Funktion findet sich in Eclipse und Netbeans unter „Rechte Maustaste → Refactoring“ CodeConventions Methoden wie bla() oder Variablen wie $i = “vorname” sind schlecht zu lesen und teilweise irreführend zB wenn $i wiederverwendet wird $i = 17; Was ist also $i? Deswegen Variablen eindeutig und ausschreiben und in camelCase Form. Um den Entwicklungsstil überall gleich zu halten wurden in Java CodeConventions erstellt und diese haben sich mittlerweile fast überall durchgesetzt: http://www.oracle.com/technetwork/java/codeconvtoc-136057.html Alterntive: PEAR PHP Conventions http://pear.php.net/manual/en/standards.funcdef.php © Günther Haslbeck 2011 – V 0.2
  • 21. Teamarbeit Ist man alleine ist es wichtig Codeconventions einzuhalten denn es sind in jedem Projekt Zeiten in denen man nicht daran arbeitet. Trotzdem möchte man später auch wieder schnell weitermachen und gleich verstehen was man damals meinte. Im Team ist es sehr wichtig Absprachen einzuhalten denn jeder im Team muss jederzeit verstehen was das Programm macht und wieso was wie geschrieben wurde. Einrücken des Codes Schon beim einrücken des Codes sollte man sich vorher absprechen und dann auch einhalten: Rückt man im Team per Leerzeichen ein oder per Tabulator. Und wenn per Tabulator ist darauf zu achten keine Texteditoren zu verwenden die beim Speichern die Tabs in Leerzeichen umwandeln. So bleibt der Code gut eingerückt und lesebar. Tools wie Netbeans oder Eclipse können Code auch selbständig einrücken: Variable Naming Conventions Choose meaningful names that describe what the variable is being used for. Avoid generic names like number or temp whose purpose is unclear. Compose variable names using mixed case letters starting with a lower case letter. For example, use salesOrder rather than SalesOrder or sales_order. Use plural names for arrays. For example, use testScores instead of testScore. Exception: for loop counter variables are often named simply i, j, or k, and declared local to the for loop whenever possible. © Günther Haslbeck 2011 – V 0.2
  • 22. Constant Naming Conventions * Use ALL_UPPER_CASE for your named constants, separating words with the underscore character. For example, use TAX_RATE rather than taxRate or TAXRATE. * Avoid using magic numbers in the code. Magic numbers are actual numbers like 27 that appear in the code that require the reader to figure out what 27 is being used for. Consider using named constants for any number other than 0 and 1. Method Naming Conventions Try to come up with meaningful method names that succinctly describe the purpose of the method, making your code self-documenting and reducing the need for additional comments. Compose method names using mixed case letters, beginning with a lower case letter and starting each subsequent word with an upper case letter. Begin method names with a strong action verb (for example, deposit). If the verb is not descriptive enough by itself, include a noun (for example, addInterest). Add adjectives if necessary to clarify the noun (for example, convertToEuroDollars). Use the prefixes get and set for getter and setter methods. Getter methods merely return the value of a instance variable; setter methods change the value of a instance variable. For example, use the method names getBalance and setBalance to access or change the instance variable balance. If the method returns a boolean value, use is or has as the prefix for the method name. For example, use isOverdrawn or hasCreditLeft for methods that return true or false values. Avoid the use of the word not in the boolean method name, use the ! operator instead. For example, use !isOverdrawn instead of isNotOverdrawn. Parameter Naming Conventions With formal parameter names, follow the same naming conventions as with variables, i.e. use mixed case, begin with a lower case letter, and begin each subsequent word with an upper-case letter Consider using the prefix a or an with parameter names. This helps make the parameter distinguishable from local and instance variables. Occasionally, with very general purpose methods, the names chosen may be rather generic (for example, aNumber). However, most of the time the parameter names should succinctly describe the type of value being passed into the method. © Günther Haslbeck 2011 – V 0.2
  • 23. Struktur im Projekt Nicht nur über die Methoden- und Variblennamen sollte man sich Gedanken machen, auch über die Struktur des Codes selbst. Je nach Projekt sollte die Struktur vorher festgelegt und dann auch über Projekte hinweg eingehalten werden. © Günther Haslbeck 2011 – V 0.2
  • 24. Wie schnell ist mein php-Script Millisekunden messen. Ist Laufzeit > 1 Sek (=0,001) dann warne © Günther Haslbeck 2011 – V 0.2
  • 25. Logfiles / Was passiert im Programm Vorweg: Um zu sehen wieso ein php-Programm gar nichts macht greifen wir auf die Log-Ausgaben von Apache zurück > tail -f /var/log/apache2/error.log [Sun Jun 12 11:33:01 2011] [error] [client 127.0.0.1] PHP Warning: fopen(/var/lo... Aber: Während des normalen Betriebs möchte man ab und an, dass ein Programm Logausgaben macht. Um das zu ermöglichen sollte eine Logklasse nicht fehlen. Diese erstellt dann ein Logfile mit Datum. Vorteil: Morgen wir automatisch ein neues File erstellt. Der Name des Logfiles wir aus __FILE__ ermittelt. Das ist der komplette Pfad+Scriptname. > cat /var/log/20110613-PhpProject1.log 13.06.2011 14:48:49 WARN ups, to slow: 0.00045585632324219 13.06.2011 14:50:11 WARN ups, to slow: 0.0039768218994141 13.06.2011 14:50:11 WARN ups, to slow: 0.0064089298248291 Damit sehen wir also wenn ein Script zu lange gebraucht hat. © Günther Haslbeck 2011 – V 0.2
  • 26. Es gibt übrigends noch mehr Konstanten: echo __LINE__."<br>"; hilft zB beim Debugging Loglevel Wir erweitern die Logmethode um einen Loglevel: Mit $currentloglevel wird definiert welcher Loglevel geschrieben werden soll. Man kann also im Programm überall DEBUG Log-Ausgaben einbauen. Diese werden aber nicht geschrieben. Geschrieben werden nur Meldungen die > Debug sind. Ändert man die Variable auf dem Livesystem auf 1 ab wird auch alles was als Debug eingetragen ist geschrieben. So lassen sich im Livebetrieb schnell Logging ein und auschalten. Logfiles sind wichtig um zu erkennen was im Programm passiert ist. ZB sollten alle kritischen Vorgänge auf INFO geloggt werden. WARN, ERROR und FATAL sollten zB geschrieben werden von Exceptions. © Günther Haslbeck 2011 – V 0.2
  • 27. Vorgriff zu Nagios / Hobbit / xymon Nagios wird später kurz angeschrieben. Nagios wertet Logfiles aus. Dort können Schwellen pro Logfiles + Loglevel festgelegt werden. Tritt zB in der Stunde in einem Logfile 1 FATAL oder 10 ERROR order 100 WARN auf, so schaltet Nagios die Überwachung auf rot und versendet eine Email an den Admin. Fällt also zB die Datenbank aus und werden Verbindungsexceptions als FATAL geschrieben geht sofort beim Admin eine Email ein. Templating Code zu mischen mit HTML in php widerspricht dem MVC Pattern. (Dazu später mehr) Kurz: HTML nicht mit Code mischen. Generell gilt: Erstelle kein HTML im Code wie zB echo “<b>Hallo Welt</b>”; Nutze eine Templateengine wie zB smarty (oder twig). Weiterer Vorteil: Die Entwickler und Webdesigner-Tätigkeit lässt trennen (Personal / Outsourcing!) Im Template gibt man Platzhalter an, im Programm definiert man dann den Inhalt für diese Platzhalter lädt und gibt dann das Template aus. So können Seiten oder Teile der Seiten immer wieder verwendet werden. © Günther Haslbeck 2011 – V 0.2
  • 28. Und das Template: die Ausgaben sieht dann so aus Hallo Welt Das hier ist die erste TemplateSeite Templating macht aber nur Sinn, wenn wir Teile der Seite wie zB Header und Footer auslagern. Das geht so: © Günther Haslbeck 2011 – V 0.2
  • 29. und in template/page_header.tpl steht © Günther Haslbeck 2011 – V 0.2
  • 30. Seite aufrufen (hier mal der HTML-Code der erzeugt wird) i18n / Internationalisierung Internationalisierung (engl. internationalization) wird gerne mit I18N abgekürzt (im englischen Wort befinden sich 18 Buchstaben zwischen I und N). Man möchte eine Seite in mehreren Sprachen ausgeben. Das beeinflusst den Text den man an das Template schickt, das Template (falls es Text oder Bilder mit Text enthält) und natürlich auch Felder wie Datum usw (24.12.2011 vs 12/24/11) usw. Da Smarty mit Internationalisierung nicht ohne weiteres umgehen kann hier obiges Beispiel nochmal mit TWIG: Installation: 1. PEAR installieren ( > apt-get install php-pear ) 2. > pear channel-discover pear.twig-project.org 3. > pear install twig/Twig 4. > apt-get install php-gettext wir erstellen ein Template unter /var/www/PhpProject1/twig/index.html © Günther Haslbeck 2011 – V 0.2
  • 31. und den entsprechenden php-Code: Fertig. Seite wird ausgegeben. Translation (siehe Twig I18n Implementation / Translation – How it works weiter hinten in diesem Dokument) Continous Integration 1 Unit-Tests machen keinen Sinn wenn diese nicht dauernd ausgeführt werden Tools dafür sind CruiseControl und dessen PHPPlugin phpUnderControl oder auch Hudson/Jenkins Diese Tools checken dauernd den Stand des Quellcodes aus Git aus, compilieren diesen und starten die Unit-Tests. Hat jemand einen Fehler eingecheckt so wird dies hier sichtbar. © Günther Haslbeck 2011 – V 0.2
  • 32. Kleiner Ausflug zurück zu Git Links (braun) unser Rechner = Client, rechts (schwarz) neuer (leerer) GIT-Server Auf dem Server erstellen wir ein Verzeichnis und legen eine leeres Repository an Das linke Fenster (unser Rechner) fügt ein Repository names Origin in seine config hinzu und pusht dann den Master (Trunk – also den Hauptzweig) in das Remote-Repo. Jetzt wollen wir mal aufm Server das Repo lokal auschecken. Das machen wir per clone: alles da. Wir ändern hier ein File und pushen wieder zurück (lokal) © Günther Haslbeck 2011 – V 0.2
  • 33. und holen es dann auch wieder auf unseren Rechner/Client: "git pull" does a "git fetch" followed by a "git merge". So lässt sich also Code per Git hin und her kopieren. Mehr unter http://www.jedi.be/blog/2009/05/06/8-ways-to-share-your-git-repository/ Überblick: © Günther Haslbeck 2011 – V 0.2
  • 34. SSH Keygen Da wir das Repo per SSH hin und her kopieren müssen wir jedes mal ein Passwort eingeben. Das kann man sich sparen in dem man auf dem Rechner von dem man sich auf einen anderen Verbinden will einen public Key erzeugt. ssh-keygen -t dsa Kein Passwort eingeben wenn danach gefragt wird! Den Inhalt des erzeugten Files (/home/user/.ssh/id_dsa.pub) fügt man auf dem Zielrechner in das File /home/usermitdemannsicheinloggt/.ssh/authorized_keys hinzu. Es darf kein Zeilenumbruch in der Zeile sein die eingefügt wird. Bei einem erneuten SSH Login wird nicht mehr nach dem Passwort gefragt und deshalb auch nicht mehr bei Git. © Günther Haslbeck 2011 – V 0.2
  • 35. Continous Integration 2 Wir installieren CruiseControl und phpUnderControl (weitere quellen: http://pear.phpundercontrol.org/) pear channel-discover components.ez.no pear channel-discover pear.phpundercontrol.org pear install --alldeps phpuc/phpUnderControl-beta apt-get install php5-xdebug pear upgrade --force pear cd /tmp wget http://freefr.dl.sourceforge.net/sourceforge/cruisecontrol/cruisecontrol-bin-2.8.3.zip unzip cruisecontrol-bin-2.8.3.zip -d /opt cd /opt ln -s cruisecontrol-bin-2.8.3 cruisecontrol phpuc install /opt/cruisecontrol wir müssen auch noch runterladen pear channel-discover pear.phpmd.org pear channel-discover pear.pdepend.org pear install --alldeps phpmd/PHP_PMD pear channel-discover pear.phpunit.de pear install phpunit/phpcpd und starten cd /opt/cruisecontrol export JAVA_HOME=/home/user/java/jdk1.6.0_24;export PATH=$JAVA_HOME/bin:$PATH ./cruisecontrol.sh Im Browser sehen wir nun unter http://localhost:8080/cruisecontrol/ die Oberfläche von CC: © Günther Haslbeck 2011 – V 0.2
  • 36. Beenden geht übrigens mit : kill `cat /opt/cruisecontrol/cc.pid` Unser Projekt hinzufügen wir erstellen in /opt/cruisecontrol/projects ein neues Projekt > mkdir PhpProject1 > mkdir -p PhpProject1/{source,build} > mkdir -p PhpProject1/build/{api,logs,log,coverage} Dort legen wir ein build.xml ab (siehe später) Dort geben wir den Namen des Projekt an <project name="PhpProject1" default="build" basedir="."> und legen in den ensprechenden Verzeichnissen die Sourcen ab Zudem muss die vi /opt/cruisecontrol/config.xml angepasst werden so dass das Projekt gebaut wird Git Repository initialisieren Damit das Git-Plugin auch weiß von wo es pullen soll, muss der source-Ordner einmal mit git initialisiert werden: cd PhpProject1/source/ git clone example.com/projectrepository.git . Oder von lokal: dazu muss vorher ein lokales repository angelegt werden > mkdir /home/gitrepo > cd /home/gitrepo/ © Günther Haslbeck 2011 – V 0.2
  • 37. > git - - bare init Initialized empty Git repository in /home/gitrepo/ > sudo git push /home/gitrepo/ master Counting objects: 31, done. Delta compression using up to 4 threads. Compressing objects: 100% (22/22), done. Writing objects: 100% (31/31), 4.04 KiB, done. Total 31 (delta 6), reused 0 (delta 0) Unpacking objects: 100% (31/31), done. To /home/gitrepo/ * [new branch] master -> master > cd PhpProject1/source/ > git clone /home/gitrepo/ Initialized empty Git repository in /opt/cruisecontrol-bin-2.8.3/projects/PhpProject1/source/gitrepo/.git/ Verzeichnisproblem mit Git und CruiseControl Das „git clone“ muss so plaziert werden, dass die config.xml von CruiseControl und der Bereich der den Checkout von Git definiert genau auf das .git Verzeichnis trifft. Hat man (wie ich) nicht ein Projekt sondern den Ordner wo alle Projekte sind global in git, so klappt das nicht. Deswegen habe ich das „git clone“ im Projects-Ordner ausgeführt. Es entsteht ein Unterverzeichnis namens repo und darin sind dann die Projekte incl dem .git Verzeichnis. Mein Config.xml zeigt dann auf und von dort habe ich dann per ln -s gitrepo/PhpProject1 . Verlinkt und dann darin das „build.xml“ abgelegt und die Verzeichnisse (von oben) angelegt © Günther Haslbeck 2011 – V 0.2
  • 38. Damit kann ich nun in meinem Homeornder eine Datei ändern, ein Git commiten, mit git push /home/gitrepo/ master in das lokale repository pushen und von da holt es dann Cruisecontrol ab da es über die config.xml in gitrepo guckt, dort im gitfile steht, das es neues aus /home/gitrepo/ holen soll. Das Ergebnis sieht dann so aus: © Günther Haslbeck 2011 – V 0.2
  • 39. Evtl muss auch Testscript angepasst und woanders abgelegt werden Jetzt cruisecontrol erneut starten: Projekt erscheint unter http://localhost:8080/cruisecontrol/ http://techportal.ibuildings.com/2009/03/03/getting-started-with-phpundercontrol/ phpUnderControl benutzt nun PhpDocumentor (zum erzeugen der Doku) PHPUnit (um die Unittests auszuführen) PhpCodeSniffer (detects violations of a defined set of coding standards) PhpMessDetector (checks for: Possible bugs, Suboptimal code, Overcomplicated expressions, Unused parameters, methods, properties) phpcpd (copy paste detector ) um den Code zu prüfen. http://skaverat.net/howto/installation-und-einrichtung-von-phpundercontrol-auf-linux.html Hier die beiden Files: /opt/cruisecontrol/projects/PhpProject1/build.xml <project name="PhpProject1" default="build" basedir="."> © Günther Haslbeck 2011 – V 0.2
  • 40. <property name="builddir" value="${basedir}/build" /> <target name="prepare" depends="clean,init" /> <target name="init"> <mkdir dir="${builddir}" /> <mkdir dir="${builddir}/api" /> <mkdir dir="${builddir}/log" /> <mkdir dir="${builddir}/coverage" /> <mkdir dir="${builddir}/phpcb" /> </target> <!-- Removes all temporary build artifacts --> <target name="clean"> <delete dir="${builddir}" /> </target> <target name="checkout"> <exec dir="${basedir}/source" executable="git"> <arg line="pull"> </arg> </exec> </target> <target name="phpunit"> <exec executable="phpunit" dir="${basedir}/source" failonerror="on"> <arg line="--log-junit ${builddir}/log/junit.xml --coverage-clover ${builddir}/log/phpunit.coverage.xml --coverage-html ${builddir}/coverage phpucAllTests ${basedir}/testsuite/all_tests.php" /> </exec> </target> <target name="pdepend"> <exec dir="${basedir}" executable="pdepend" failonerror="false"> <arg line="--jdepend-xml=${basedir}/build/logs/jdepend.xml ."/> </exec> </target> <target name="phpcpd" depends="init"> <exec executable="phpcpd" failonerror="false"> <arg line="--log-pmd ${builddir}/log/pmd-cpd.xml ${basedir}/source " /> </exec> </target> © Günther Haslbeck 2011 – V 0.2
  • 41. <target name="php-documentor2" depends="init"> <exec executable="phpdoc" dir="${basedir}/source"> <arg line=" -o HTML:Smarty:default -t ${basedir}/build/api -ct type -ue on -tb /usr/share/php/data/phpUnderControl/data/phpdoc/ -d ${basedir}/source "/> </exec> </target> <target name="php-documentor"> <exec executable="phpdoc" dir="${basedir}/source"> <arg line=" -t ${builddir}/api -o HTML:Smarty:default . -ct type -ue on --filename **/*.php"/> </exec> </target> <target name="php-codesniffer"> <exec executable="phpcs" dir="${basedir}/source" output="${builddir}/logs/checkstyle.xml" error="/tmp/checkstyle.error.log"> <arg line="--report=checkstyle --standard=PEAR ."/> </exec> </target> <target name="phpmd"> <exec executable="phpmd" dir="${basedir}/source"> <arg line=". xml codesize,unusedcode,naming --reportfile ${basedir}/build/logs/pmd.xml"/> </exec> </target> <target name="build" depends="checkout,php-documentor,php-codesniffer,phpmd,phpcpd,phpunit,pdepend"/> </project> UND----------------- /opt/cruisecontrol/config.xml <cruisecontrol> <project name="PhpProject1" buildafterfailed="false"> <modificationset> <alwaysbuild/> </modificationset> <!-- Git Bootstrapping auf den source-ordner --> <bootstrappers> <gitbootstrapper localWorkingCopy="projects/${project.name}/source" /> </bootstrappers> © Günther Haslbeck 2011 – V 0.2
  • 42. <schedule interval="60"> <ant anthome="apache-ant-1.7.0" buildfile="projects/${project.name}/build.xml"/> </schedule> <listeners> <currentbuildstatuslistener file="logs/${project.name}/status.txt"/> </listeners> <log dir="logs/${project.name}"> <merge dir="projects/${project.name}/build/logs/"/> </log> <publishers> <artifactspublisher dir="projects/${project.name}/build/api" dest="artifacts/${project.name}" subdirectory="api"/> <artifactspublisher dir="projects/${project.name}/build/coverage" dest="artifacts/${project.name}" subdirectory="coverage"/> <execute command="phpuc graph logs/${project.name} artifacts/${project.name}"/> </publishers> </project> </cruisecontrol> Anfangs gabs Probleme mit phpdoc und den Output-Convertern. Welche installier sind finden man unter: /usr/share/php/PhpDocumentor/phpDocumentor/Converters/HTML$ dir frames Smarty So siehts dann unter anderem aus: © Günther Haslbeck 2011 – V 0.2
  • 43. Man sieht zB auch die Testabdeckung der Unittests und welche Codezeilen getestet wurden © Günther Haslbeck 2011 – V 0.2
  • 44. erweitern wir das /opt/subversion/config.xml um unsere Emailadresse so erhalten wir eine Email wir ergänzen nun das build.xml im Projekt um alles zu zippen: © Günther Haslbeck 2011 – V 0.2
  • 45. als nächstes lassen wir im Erfolgsfall (via /opt/cruisecontrol/config.xml) das zip kopieren und schon da: Dieses File könnten wir nun auf einen Staging-Webserver kopieren und dort entpacken. Damit liegt dort dann eine sauber durchgetestete Version der aktuellen Software. Selenium Mit phpunit haben wir aber bisher nur Backendmethoden getestet. Was wird aus dem Frontend? Dazu nutzen wir Selenium. Selenium setzt “leider” einen Desktop-PC voraus den es startet einen richtigen Browser und testet mit diesem. So funktionierts: Unter http://seleniumhq.org/download/ laden wir die aktuelle Version der Selenium-IDE für Firefox herunter. Nach dem Neustart von Firefox starten wir über Tools die Selenium IDE. Dort klicken wir auf den roten Aufnahmeknopf und machen dann im Browser genau das was wir testen wollen: zB eine Suche auf Google.de nach „selenium“ Auf der nächsten Seite markieren wir einen Text der und beweisst, das das was wir gemacht haben erfolgreich war zB © Günther Haslbeck 2011 – V 0.2
  • 46. Das kann aber natürlich auch ein Willkommenstext nach einem Login sein usw usw.. In Selenium ist nun zu sehen was wir gemacht haben. Wir beenden dort die Aufnahme. Durch File → Save Testcase kann dieser nun gespeichert und über die IDE auch wieder geladen und ausgeführt werden. Aber wir möchten ja automatisch und nicht jedes mal selbst Hand anlegen. Deswegen klicken wir auf File → Export-Test-Case und als PHP Testing_Selenium. © Günther Haslbeck 2011 – V 0.2
  • 47. Das Ergebnis sieht sehr nach unseren Unit-Tests aus: (ich musste die require_once Zeile selbst nachbessern?!) Als nächstes laden wir den Selenium Server runter von http://seleniumhq.org/download/ und starten das .jar file direkt und wir starten per phpunit das script Es wird ein Browser gestartet und genau da ausgeführt was im Script steht. Wunderbar. Damit hätten wir (wenn genug Tests erstellt sind) auch das Frontend durchgetestet und können diese © Günther Haslbeck 2011 – V 0.2
  • 48. Tests auch immer automatisch fahren. MockObjekte tbd Logfile + Systemüberwachung Wie wir im Logfilekapitel vorher erfahren haben ist es wichtig Logfiles zu schreiben und auszuwerten Wir wollen überwachen was unsere Anwendungen machen. Dazu nehmen wir viele Nagios oder Xymon (früher Hobbit früher Big Brother) Hobbit apt-get install xymon Nun sollte schon alles funktionieren. Die Oberfläche findet sich unter http://localhost/hobbit/index.html Ist ein Zugriff nicht erlaubt evt in: /etc/apache2/conf.d/hobbit alle #Allow from localhost ::1/128 ändern nach Allow from all /etc/init.d/apache2 restart und die Oberfläche ist da Nagios Nur kurz erwähnt © Günther Haslbeck 2011 – V 0.2
  • 49. apt-get install nagios3 (passwort bei der inst merken) /etc/init.d/nagios3 start und zugreifen via http://localhost/nagios3 benutzername: nagiosadmin, passwort wie vorher festgelegt und wir sehen wie es der Maschine geht jetzt muss nur noch eine Überwachung der Logs eingebaut werden. © Günther Haslbeck 2011 – V 0.2
  • 50. Komplette automatisch überwachte Entwicklung und Liveseite MRTG MemcacheD http://www.debian-administration.org/article/Speeding_up_dynamic_websites_with_caching Gut: Ist der MCD ausgefallen funtioniert die Seite trotzdem © Günther Haslbeck 2011 – V 0.2
  • 51. Geschwindigkeit der Seite erhöhen Baue zu Beginn der Seite nur eine DB-Connection auf und übergebe diese an alle Methoden / Klassen. Die Klassen selbst müssen keine eigenen DB-Connections aufbauen Vermeide schreiben in Dateien (Logfiles, Schreiben nach STDERR usw) Lade nur so wenig Klassen wie nötig (sinnlose Ladezeit der Scripte + Compilezeit der Scripte) CSS/Bilder: Nutze optimierte Bilder, Javascripts usw (mehr erklärt Google in Pagespeed) Geschwindigkeit der Seite selbst messen Nutze Firebug https://addons.mozilla.org/en-US/firefox/addon/firebug/ Firebug auf Seite anklicken Net (oder Netzwerk) aktivieren Shift+F5 und sehen was passiert. Am Beispiel GMX ist zu sehen: Ladezeit der Hauptseite (also zB php-Script) dauert 0,163 Sekunden. Super! - Allerdings dauert die ganze Seite dann Gesamt: 4,94 Sekunden. Katastrophe! © Günther Haslbeck 2011 – V 0.2
  • 52. Geschwindigkeit der Elemente in der Seite messen Google Pagespeed zeigt was zu verbessern ist und wie http://pagespeed.googlelabs.com Screenshots in diesem File erstellt mit “shutter” für Ubuntu PHP -Entwicklung auf Linux 1. Ubuntu installieren Auf der Homepage von Ubuntu die aktuelle (am besten 64bit) Version runterladen http://www.ubuntu.com/download/ubuntu/download und auf CD brennen. Diese installieren wir auf einer alten externen Platte. Einfach von CD booten, dann installieren. Beim Installieren darauf achten, dass die externe Platte verwendet wird (das ist dann zB sdf1...) und (sehr wichtig) dass auch der Bootsektor dann auf sdf installiert wird (NICHT sda!). Dann beim Start des PCs statt CD das angeschlossene Festplattenlaufwerk auswählen. Ubuntu sollte normal starten © Günther Haslbeck 2011 – V 0.2
  • 53. Ubuntu basiert auf Debian-Linux Daher benutzt Ubuntu die gleichen Programme und Verzeichnisse Die wichtigsten Dateien und Befehle für uns Apache Logfiles: /var/log/apache2/access.log /var/log/apache2/error.log html-Startverzeichnis: /var/www/ Einstellungen des Apache Webservers: /etc/apache2/sites-enabled/000-default Wo sind wir (aktuelles Verzeichnis anzeigen) Wir starten erst einmal das Terminal (Anwendungen > Zubehör > Terminal) und geben ein: pwd pwd = print work directory Hilfe zu jedem Befehl anzeigen (zb pwd) man pwd © Günther Haslbeck 2011 – V 0.2
  • 54. Dort kommt man wie in vielen Linuxprogrammen mit q, strg+c oder manchmal alt+q wieder raus. Scrollen mit den Cursortasten Verzeichnisinhalt anzeigen ls Viele Programme haben Paramter die man meisst mit -paramter anhängt. Das können auch mehrere sein die dann direkt aneinandergereit werden ls -al zeigt alle Dateien ausführlich an ls -alt (gut zu merken für deutsche) zeigt sortiert nach Datum (Parameter l) ls -als zeigt nach Dateigrösse sortiert (Parameter s) man ls hilft weiter was was bedeutet Ausgabe weiterverarbeiten Ist die Ausgabe nun sehr lange wäre es schön, wenn man diese Seitenweise angezeigen könnte. Das ist mit ls nicht möglich. Allerdings können wir mit | die Ausgabe von ls an ein anderes Programm senden das genau das macht was wir gerne hätten. Wir nutzen das Program more ls -al | more mit Cursor oder Space können wir nun Zeilen oder Seitenweise durch die Ausgabe scrollen. Man kann die Ausgabe auch in eine Datei schreiben mit > Dabei bedeutet > immer neue Datei anlegen, >> an bestehende Datei anhängen. ls -al > datei.txt Eine Datei ausgeben kann man mit cat cat datei.txt und Seitenweise dann eben wieder mit cat datei.txt | more Verzeichnisse Verzeichnis anlegen mkdir verzeichnisname © Günther Haslbeck 2011 – V 0.2
  • 55. Datei oder Verzeichnis löschen rm verzeichnisname bzw rm dateiname Sind im Verzeichnis Dateien können die mi rm -rf verzeichnisname gelöscht werden. Aber Vorsicht: Es wird ohne zu fragen ALLES was in dem Verzeichnis war gelöscht. Weg ist weg. Nix Papierkorb Interessant ist auch das Programm grep. Damit können wir filtern. ls -al | grep „bla“ hier werden nur Dateien oder Verzeichnisse ausgegeben die „bla“ im Dateinamen haben. Dateien suchen find . -name „bla*.pdf“ find sucht ab . (das Verzeichnis wo wir uns gerade befinden) alle Dateien die bla*.pdf heissen. Verzeichnis wechseln In Linux gibt es keine Laufwerke, deswegen auch kein c: und die Verzeichnisnamen sind mit / getrennt und nicht mit wie in Windows Die Wurzel ist also / und nicht c: cd ~ wechselt ins heimant (eigene User) verzeichnis cd / wechselt ins root-Verzeichnis cd /tmp un das /tmp Verzeichni cd – wechselt in das letzte Verzeichnis in dem wir gerade vorher noch waren TAB benutze die Tab-Taste um beim tippen von Verzeichnissen die Namen automatisch zu vervollstädnigen. Bringt Tab keine Antwort dann gibt es das Verzeichnis nicht. Hört Tab mitten im Namen auf so sind mehrere Verzeichnisse vorhanden mit ab hier verschiedenen Namen. Nochmal Tab zeigt die Möglichkeiten Datei kopieren cp datei1.txt datei2.txt Verzeichiss mit kompletten Inhalt kopieren cp -r verzeichnis1 verzeichnis2 Datei / Verzeichnis verschieben mv datei1.txt datei2.txt © Günther Haslbeck 2011 – V 0.2
  • 56. Programme installieren kurzes Vorwort: In Ubuntu sind wir immer ein Nutzer, kein Admin whoami zeigt den Usernamen an. Der Adminuser heisst in Linux root. Dieser darf alles. Um Admin zu werden müssen wir mit sudo su root werden. Allerdings ist sudo das Kommando um Programme als root auszuführen wenn man nicht root ist. Deswegen reicht es eigentlich immer sudo kommando aufzurufen statt tatsächlich root zu sein Programm installieren 2 Ubuntu holt sich die Programme von Listen die bei Ubuntu selbst verwaltet werden. Um sicher zu sein immer die neusten Infos zu haben machen wir erst einmal ein Update sudo apt-get update apt ist hier das Installationstool Die Infos liegen nun im cache von apt und können nun nach Programmen durchsucht werden sudo apt-cache search apache2 Durchsucht den Cache nach allen Programmen in denen apache2 vorkommt (hier ist grep von vorher dein Freund) Die Ausgabe ist dann Paketname – Beschreibung: …. apache2 - Apache HTTP Server …. Wir installieren also sudo apt-get install apache2 sudo apt-get install mysql-server sowie sudo apt-get install phpmyadmin Während der Installation von mysql und phpmyadmin wird nach Passwörtern gefragt. Am besten immer das gleiche eingeben. Phpmyadmin fragt auch nach dem Webserver – hier nur Apache auswählen. Dann installieren wir noch vi (Texteditor) sudo apt-get install vim © Günther Haslbeck 2011 – V 0.2
  • 57. Textdatei erstellen / bearbeiten mit vi Wir machen das mit vi vi datei.txt (Dateiname schon zum start angeben wenns die Datei noch nicht gibt) vi datei.txt +15 öffnet eine Datei und springt gleich in Zeile 15 (ganz praktisch bei Fehlermeldungen im Programm) Achtung: Vi hat 3 Modis die alle per Tastaturkürzel bedient werden. Vi hat keine Oberfläche. vi datei.txt eingeben und genau schaun was untem am Rand steht. Mit ESC kommen wir immer in den Kommandomodus. Dann steht unten im Eck nichts. Durch drücken eines Selbstlautes (zb i) kommen wir in den TexteingabeModus. Dann steht unten zB INSERT Also mal i drücken, Text eingeben, ESC drücken Kommandos wie zB speichern gibt man nun per :Befehl ein (aber nur wenn man im Kommandomodus (vorher ESC) ist) Dabei bedeutet q = quit w = write q! = quit ohne nachfragen :w schreibt also die Date :q beendet vi :wq schreibt und beendet vi Wir speichern also mit :wq und befinden uns wieder ausserhalb von vi Wir öffnen die Datei wieder: vi datei.txt Im Kommandomodus können wir auch text bearbeiten. Dabei gilt normalerweise immer BEFEHLanzahlBEFEHL so löscht dd die Zeile in der der Cursor steht, d2d löscht 2 Zeilen aber der Zeile in der der Cursor steht. x löscht ein zeichen yy kopiert eine Zeile in die Zwischenablage, p fügt die Zeile darunter wieder ein. Ein bischen einfacher wird das mit v. V öffnet den -Visual- Modus (siehe wieder links unten). Man kann dann mit den Cursortasten markieren, mit y kopieren und mit p wieder einfügen. Mit ESC kommt man wieder aus dem Visual- Modus raus. © Günther Haslbeck 2011 – V 0.2
  • 58. :wq speichert und beendet die Bearbeitung der Datei. Ja, der Umgang mit vi will gelernt sein und erfordert Übung. Es gibt sehr viele Kommandos wie zB : %s/vorher/nachher/g um zu suchen/ersetzen. Dazu am besten eine ausführliche Anleitung lesen. Das erste PHP-Script vi /var/www/index.php Wir drücken i und geben ein <? echo('hallo welt'); ?> ESC und :wq und öffnen dann im Browser http://localhost/index.php und wir sollten Hello World sehen Apache und Co (neu) starten läuft apache nicht, so starten wir ihn per /etc/init.d/apache2 start bzw etc/init.d/apache2 restart oder etc/init.d/apache2 stop gleiches mit mysql /etc/init.d/mysql start/restart/stop Hat unser Programm Fehler? so gucken wir einfach was das Fehlerlog schreibt: Wir öffnen ein neues Terminal und geben ein: tail -f /var/log/apache2/error.log und drücken dann im Browser F5 / Seite neu laden Tail lassen wir laufen. Es zeigt wenn sich eine Datei verändert und gibt das dann aus. Optimal für uns. Logfiles auswerten guckt man die Logfiles von Apache so würde man gerne wissen was die User so gucken. © Günther Haslbeck 2011 – V 0.2
  • 59. Hier hilft uns awk. Awk hat eigentlich nichts mit Logfiles zu tun aber man kann mit awk auf Teile einer Zeile der Logfiles zugreifen. Eine Zeile Logfile sieht so aus 12.34.56.78 - - [04/Sep/2011:06:52:07 +0200] "GET /alle-titel/ HTTP/1.0" 200 26206 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html )" Man sieht hinter dem GET welche Datei abgerufen wurde. Awk splittet nun die Zeilen am leerzeichen und kann das entsprechende Element ausgeben. cat /var/log/apache2/access.log |awk '{print $7}' schickt das Log an awk, das splittet und gibt „Spalte“ 7 aus. …. /uploads/RTEmagicC_ca.jpg.jpg /uploads/pics/nl_01.gif …. und wenn man nun diese ausgaben zählt und nach Anzahl sortiert: …. 14 /uploads/pics/tttp.jpeg 15 /fileadmin/templates_studinfo/css/info.css?1305011933 16 /ntpagetag.js …. Welche Programme laufen und diese beenden mit top lassen sich alle laufenden Programme anzeigen. Mit Shift+M oder Shift+P lassen sich die Angaben nach zB Memory oder cPu-Last sortieren. Gleiches zeigt auch ps waufx Beide Programm zeigen die PID (Processid) eines Programms.. USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 2 0.0 0.0 0 0? S Sep01 0:00 [kthreadd] Programme beenden geht per kill $pid also zB kill 2384 dabei wird das Programm aber nicht abgeschossen sondern dem Programm mitgeteilt dass es sich beenden soll. Tut es das nicht kann per kill -9 2348 © Günther Haslbeck 2011 – V 0.2
  • 60. das Programm hart abgeschossen werden PHP Entwicklung mit Frameworks Wieso Bei Softwareentwicklung tritt fast immer das gleiche Problem auf: Die Entwickler sind zu faul zu dokumentieren und kopieren lieber als Software anzupassen. Das führt zu unübersichtlichen und xmal vorhandenen Code. Deswegen bietet Frameworks einen gewissen Rahmen. Nun kann man CakePhp oder Symphonie verwenden aber diese sind doch etwas schwer für unsere Bedürfnisse. Es reicht eigentlich ein einfaches PHP Programm das Parameter entgegen nimmt, etwas damit macht und dann ausgibt. Fängt man mit der Ausgabe an so stellt man fest: HTML komplett auszugeben ist nicht sinnvoll da das Webdesign im php-Code stattfindet. Man kann die Tätigkeiten „Entwickeln“ und „Webdisign“ nicht trennen. Deswegen ist es sinnvoll ein Templatesystem wie Twig zu verwenden. In Twig werden im HTML Platzhalter definiert die dann in php mit Werten gefüllt werden und dann alles ausgegeben. Des weiteren ist es sinnvoll die Businesslogik im Programm von der Datenspeicherung zu trennen. Insgesamt nennt sich das dann Model (DB-Logik), Controller ( Businesslogik), View = Ausgabe bzw „offiziell“ MVC (Model View Controller) Aber auch im Model möchten wir nicht jedesmal eine DB-Verbindung komplett neu programmieren. Deswegen die obig genannten Frameworks. Es geht aber auch sehr einfach. Unser Programm würde ungefähr so aussehen: <? Übergabeparamter aus der URL/Form einlesen Datenbankverbindung aufbauen In Datenbank schreiben oder daraus lesen Datenbankverbinung abbauen Twig Template laden Werte in Twig setzen Template ausgeben ?> Betrachtet man das genauer so ist das Programm selbst der Controller, Der von der Datenbank eingeschlossene Bereich das Model und danach die Befüllung des Views (also des html-Templates) Code nur einmal verwenden Um das nicht alles immer neu zu machen erstellen zerlegen wir obiges File in 3 Files: © Günther Haslbeck 2011 – V 0.2
  • 61. controller.php <? Übergabeparamter aus der URL/Form einlesen Modelaufruf Viewaufruf ?> Model <? Datenbankverbindung aufbauen In Datenbank schreiben oder daraus lesen Datenbankverbindung abbauen ?> View <? Twig Template laden Werte in Twig setzen Template ausgeben ?> Wenn wir uns nun die Programme ansehen ist immer noch vieles was später immer wieder kopiert werden würde. Zudem ist mit View eigentlich die HTML-Seite (Also das Template gemeint), nicht die Logik dieses zu befüllen.... Wir müssen also das ganze Programm nochmal etwas drehen. Aber wie? Nun, erst einmal fassen wir alles was wir immer wieder brauchen aber nichts mit dem Programmablauf zu tun hat zusammen in eigene Dateien zB Datenbank Auf/Abbau usw. Damit ist schon mal viel Code so vorhanden das wir diesen in jedem unserer Projekte verwenden können. Gleiches gilt für den Code um Twig zu nutzen. Bleibt also nur die Businesslogik und das Datenmodell selbst das jedesmal anders ist. Wir schreiben dazu eine Klasse die die Rahmenbedingungen enthält aber kein Datenstuktur und keine Businesslogik. Würde man das in einem File darstellen wollen (was wir aber oben ja wegen der wiederverwendbarkeit des Codes nicht wollen, so würde diese wieder so aussehen: <? Controllerplatzhalter Datenbankverbindung aufbauen Modelplatzhalter Datenbankverbinung abbauen © Günther Haslbeck 2011 – V 0.2
  • 62. Templateplatzhalter Twig Template laden Werte in Twig setzen Template ausgeben ?> Von dieser Klasse leiten wir dann ab (extends) und füllen nur noch den Code den wir brauchen: <? class neu extends vorherigesbeispiel{ Controllerplatzhalter = { unser code } Modelplatzhalter = {unser code} Templateplatzhalter = { unser html code) } ?> Diese 3 „lokalen“ Codeblöcke lagern wir aus in 3 Files. Die 3 Files benennen wir jeweils gleich und legen diese jeweils in das Verzeichnis /controller/gleichername.php /model/gleichername.php /view/gleichername.html So, schon mal sehr schön. Jetzt bräuchten wir nur noch etwas was erkennt welche Files zusammengehören. Wir brauchen ein kleines Programm, das die Steuerung übernimmt. Hier kommt der nächst Trick: wir definieren, dass die URLs unserer Webseite so aussehen: http://www.wir.de/appname/name und legen eine .htaccess in das Verzeichnis appname die sagt: Nimm, was hinter appname/ steht und baue damit ein Programm zusammen, das aus dem Rahmen besteht und aus dem model/view/controller Dateien die mit Name. beginnen. Im Verzeichnis appname erstellen wir eine Datei die sich darum kümmert. Diese bekommt den Namen von der htaccess übergeben, baut sich ein php-Script aus eben diesen Teilen zusammen und führt das Programm aus. Wichtig noch: Wir wollen auch die Bilder zum Projekt im gleichen Verzeichnis ablegen (hier in res), deswegen darf hier die Regel nicht greifen. Die .htaccess © Günther Haslbeck 2011 – V 0.2
  • 63. ---------------------- RewriteEngine on RewriteCond %{REQUEST_URI} ^/appname/res/(.*) [NC] RewriteRule (.*) /appname/view/img/%1 [L] RewriteCond %{REQUEST_URI} !^/appname/view/(.*) [NC] RewriteCond %{REQUEST_URI} !^/appname/index.php [NC] RewriteRule (.*) /appname/index.php/$1 [L] die index.php ist unser Framework und baut dann unser Programm zusammen und führt es aus. Für jedes neue Seite in unserer Applikation müssen wir also nur noch unseren Controller, das Model und die HTML-Seite kopieren und gleich benennen und ausprogrammieren. Für die Startseite der Applikation nennen wir alle 3 Files „index...“ und fertig. Das funktioniert übrigens deshalb da in php wir dynamisch eine Klasse instanzieren können $object = new $class(); und per überschreiben der __autoload und den namen der Klasse definieren könne wo diese liegen …. function __autoload($class_name) { $pos = stripos($class_name, "global"); if ($pos === false){ include './classes/' . $class_name . '.php'; …. Aber das nur als kleiner Einschub... Voila, unser eigenes Framework ist fertig und sauber in MVC aufgeteilt das dann so aussieht .htaccess index.php /model/seite.php /view/seite.html /controller/seite.php /helper/framework.php /helper/database.php sowie /design/css /design/js /design/images/seite/ © Günther Haslbeck 2011 – V 0.2
  • 64. Um helper aber nicht x mal zu kopieren erstellen wir auf dem Server ein Verzeichnis in dem diese Files liegen und verlinken diese nur in das Projekt. Outsourcing Als nächstes möchten wir, das andere externe Firmen an unserem Code mitentwickeln. Dazu setzen wir einen funktionierenden Server auf. Unsere Applikationen benutzen dort die normale Datenbank usw. Wie können aber externe entwickeln ohne dass diese Zugriff auf unsere Daten haben? Nun, wir erweitern unser Framework um den Ordner /local/ Dort legen wir Klassen ab, die die Datenbankverbindung usw simulieren. Unsere normale database.php entfernen wir. Nun muss das Framework nur noch so angepasst werden dass auch in lokal nach einer database.php gesucht wird und zwar vor der in helper und dann diese genommen wird. Damit läuft die App ohne echte Datenbankverbindung. (Stichwort Mock-Objekte) Den Code kopieren wir und richten wir vollständig ein. Dann checken wir diese leere App in github ein und richten unseren externen Kollegen einen Zugang ein. Diese können nun bei sich lokal entwickeln und testen. Immer mal wieder checken die Jungs dann den Code wieder ein. Auf unserem Testserver guckt ein Cronjob alle 5 min bei github nach ob sich dort etwas neues befindet. Wenn ja so wird die Änderung von github heruntergeladen und dann die richtige Stelle auf dem dev- Server kopiert. Zudem die Mockobjekte entfernt und damit greift dort nun wieder der normale Database Code. Damit kann der externe Entwickler also auf die Applikation praktisch in der zukünftigen Umgebung testen OHNE darauf Zugriff zu haben. Sessions und Rechte Unsere Framework-Klasse muss sich zusätzlich darum kümmern, das der User eingeloggt ist oder nicht. Das kann jeder implementieren wie er will. Möchte man nur einige Seiten der App sperren so ist die Abfrage statt im Framework im Controller auszuführen. Nun ist es auch günstig wenn zur Session eine Rechtetabelle verwaltet wird. Dort kann dann hinterlegt werden ob der User wenn er eingeloggt ist den Seite sehen darf oder nicht. Über einen Zeitstempel kann das dann auch zeitgesteuert funktionieren. So ist damit denkbar dass zB bei der Registrierung ein solches Recht zB für 14 Tage eingetragen wird. Sind die 14 Tage abgelaufen so muss sich der User das Recht kaufen. Vorher kann der User testen. Mit Hilfe dieser Rechtetabelle kann also jeder Bereich in der Applikation gegen Gebühr ein und ausgeschaltet werden. © Günther Haslbeck 2011 – V 0.2
  • 65. Versionierung mit GIT Der aktuelle Stand in GIT ist ok? - Dann einen Tag erzeugen mit Versionsnummer: Jetzt kann auf den Zielrechner mit -l“ist“ (list) geguckt werden welche Versionen es gibt und die ensprechende dann ausgecheckt werden. Anmerkung: Eigentlich wird nicht ausgecheckt sondern der Stand zu diesem Tag hergestellt. Es könnte also sein, dass ein „git clone .. „ schon weiter ist. Durch git checkout „version“ wird dann rein „rollback“ auf einen älteren Stand gemacht. Netbeans zeigt php-docs nicht an Netbeans hat je nach Code etwas Schwierigkeiten den Code zu erkennen und den Code Completion Assistant anzuzeigen. Je nachdem zeigt Netbeans entweder oder Netbeans zeigt eine Auswahl aller Files die eine Variable mit gleichen Namen enthalten © Günther Haslbeck 2011 – V 0.2
  • 66. Um Netbeans zu unterstützen kann man direkt direkt über den Variablen definieren welchen Typ (oder Klasse) diese Variablen repräsentieren: oder direkt und schon klappts © Günther Haslbeck 2011 – V 0.2
  • 67. Wenns nicht geht: Ist phpdoc installiert? Sind die anderen Klassen im Include-Pfad? Mehr unter http://blogs.oracle.com/netbeansphp/entry/code_completion_for_a_class Error-Reporting sollte immer auf Vollanschlag sein denn Code der Warnungen erzeugt.. dem kann man nicht trauen. Wo keine Warnungen sind sind auch keine Fehler Das Fehlerreporting kann am Anfang oder in der php.ini gesetzt werden: // Melde alle PHP Fehler (auch wenn in spät. PHP-Versionen neue hinzu kommen) error_reporting(-1); // Error Reporting komplett abschalten error_reporting(0); // Nur bestimmte Fehler melden error_reporting(E_ERROR | E_WARNING | E_PARSE); Mehr: © Günther Haslbeck 2011 – V 0.2
  • 68. http://php.net/manual/de/function.error-reporting.php Eigenen Errorhandler Undefinierte Variablen in PHP anzeigen Da hilft Netbeans gerne aus: Warnungen in Netbeans für PHP aktivieren: © Günther Haslbeck 2011 – V 0.2
  • 69. Definieren wie was angezeigt werden soll (Achtung, gilt für alle Sprachen) Voila: © Günther Haslbeck 2011 – V 0.2
  • 70. Twig I18n Implementation / Translation – How it works The Twig Docu is very good but this (important) Part ist not very clear How to use the i18n Support. First of all, just read the Docu at http://twig.sensiolabs.org/doc/extensions/i18n.html but they is a little “short”… i would say The missing Part: First: Checkout the Extension Repository: git clone https://github.com/fabpot/Twig-extensions.git and install gettext apt-get install php-gettext Then (for testing) i copied the I18n.php and the Parser.php from to …/Twig-extensions/lib/Twig/Extensions/Extension cp -r I18n.php /usr/share/php/Twig/Extension/ …/Twig-extensions/lib/Twig/Extensions/# cp -r TokenParser /usr/share/php/Twig/Extension/ …/Twig-extensions/lib/Twig/Extensions/# cp -r Node /usr/share/php/Twig/Extension/ but nothing happens bec this directory seams to be not directly included so if you add the Files directly like: $twig = new Twig_Environment($loader, $env_options); // Set language to german putenv(‘LC_ALL=de_DE.utf8′); setlocale(LC_ALL, ‘de_DE.utf8′); // Specify the location of the translation tables bindtextdomain(‘myAppPhp’, ‘/usr/share/locale’); bind_textdomain_codeset(‘myAppPhp’, ‘UTF-8′); // Choose domain textdomain(‘myAppPhp’); require_once(‘/usr/share/php/Twig/Extension/I18n.php’); require_once(‘/usr/share/php/Twig/Extension/TokenParser/Trans.php’); require_once(‘/usr/share/php/Twig/Extension/Node/Trans.php’); $twig->addExtension(new Twig_Extensions_Extension_I18n()); everything works… the de_DE.utf8 is for german and /usr/share/locale is where normally the .mo files are for the linux system (you can use every other directory) to get the language exactly use locale -a | grep DE © Günther Haslbeck 2011 – V 0.2
  • 71. and you will get de_DE.utf8 so this is where the system will translate your english default text to. This means you have to set LC_ALL to the target language But: This was only the first Step. Now add a {% trans “Hello World!” %} somewhere in one of your templates and lets see if the “Hello World” is on your site… If so, good! Ok, as next turn the Twig-Cache on if not still done $env_options = array( ‘cache’ => ‘/var/www/vhost081/twig_cache’, ); $twig = new Twig_Environment($loader, $env_options); Youll find php files like 4b/c6/189025b9af97f63de69cce1f5cb2.php in the twigcache and if you look into the files youll see the “Hello World” there: …. // line 8 echo gettext(“Hello World!”); // line 9 … bec Twig translates all the templates into php code (this is also mentioned at the End of the Twig i18n docu) and what you see is how gettext in php works. So now we have to extract all these calls and create a file for translation but first we need to install xgettext: apt-get install gettext then create the po-file from the php cache file: /var/www/vhost081/twig_cache# xgettext –default-domain=myAppPhp -p /tmp –from-code=UTF-8 -n –omit-header -L PHP 4b/c6/189025b9af97f63de69cce1f5cb2.php I write it to /tmp with the name myAppPhp (which was set before in the php code) if you look at it youll see something like #: 4b/c6/189025b9af97f63de69cce1f5cb2.php:25 msgid “Hello World!” msgstr “” so use poedit or just a normal texteditor and change msgstr to the translated version #: 4b/c6/189025b9af97f63de69cce1f5cb2.php:25 msgid “Hello World!” msgstr “Hallo Welt!” © Günther Haslbeck 2011 – V 0.2
  • 72. now convert the file into a machine readable format (from .po to .mo) msgfmt -v -o /tmp/myAppPhp.mo /tmp/myAppPhp.po and copy the file to the given directory cp /tmp/myAppPhp.mo /usr/share/locale/de/LC_MESSAGES/ If you use a different directory dont forget the LC_MESSAGES and that the file has to be readable and accessable for apache/php If you want to check whats in the file: strings /tmp/myAppPhp.mo and youll see “Hallo Welt” on the Website My Sources for this Article http://oriya.sarovar.org/docs/gettext_single.html and http://stackoverflow.com/questions/2425562/php-gettext-function-only- returns-orignal-untranslated-string Still unclear: How to use different translations on different sites ?! Webdesign Woher bekommt man eigentlich coole Webdesigns? Eigentlich relativ einfach. Wenn man kein Künstler ist, dann kauf man sich ein fertiges Design. Da wir dieses dann sowieso etwas anpassen müssen ist es egal für welches System das Design/Template eigentlich gemacht ist. Deswegen: Webseiten wie Templatemonster.com verkaufen 1000de von Designs für ca 50€. Die Hauptarbeit ist eher das stöbern nach dem richtigen Design Fotos für die Seite Gibts bei Fotolia oder Stockphotos im Netz. Evtl die Lizenzbedingungen beachten. Logo für die Seite Da gibts die Möglichkeit fertige Logos zu kaufen http://www.logotion.com/logodesign/logos-1.html http://www.logomarket.com/ für 100-200-1000 Euro oder sich 25 bis 70 Logos vorschlagen zu lassen ab 700 Euro http://de.wilogo.com/ aber woher weiss ich ob was dabei ist? Trifft es meinen Geschmack? Ich habs deshalb jetzt umgekehrt gemacht. Ich hab mir auf http://de.wilogo.com/nos-references-en-logos.html © Günther Haslbeck 2011 – V 0.2
  • 73. die Logos ausgeguckt die mir am besten gefallen haben und mir dann weitere von dem Designer (diesmal aus .de) angeguckt. Den hab ich nun angeschrieben und ihm die, die mir am besten gefallen genannt und das ich so eins gerne hätte. Der macht mir nun am Wochenende Vorschläge für mich und dann schau ma mal ob da was rauskommt. Wenns passt hätt er gerne 250 Euro. PHP Beschleunigen Ganz einfach mit Xcache für Apache (oder alternativ gleich NGINX verwenden). http://arnowelzel.de/wiki/de/web/xcache und so gehts: apt-get install php5-xcache apache restart, fertig. In /etc/php5/apache2/conf.d/xcache.ini ist insbesondere der Wert für xcache.size wichtig. Einfach ein bissl höher drehen ;) durch kopieren des Admininterfaces in das Webverzeichnis (wird unter ubuntu gleich mit auf die Platte kopiert) cp -a /usr/share/xcache/admin /var/www/vhost008/html/xcache-admin vi /etc/php5/conf.d/xcache.ini entfernen der admin/passwort kommentare und setzen eines MD5 Passworts [xcache.admin] xcache.admin.enable_auth = On xcache.admin.user = "bla" xcache.admin.pass = "8f87e10869299a5fe80b315695296b88" (einfach durch einen md5 online generator generieren) erhält man ein sehr schönes Webinterface © Günther Haslbeck 2011 – V 0.2
  • 74. Apache Status Modul Da PHP als Modul im Speicher läuft sollte kann nicht einfach geprüft werden was gerade im System los ist. Einfach mit http://httpd.apache.org/docs/2.0/mod/mod_status.html den Status des Servers überwachen Dort ist deutlich zu sehen welche Prozesse gerade laufen usw © Günther Haslbeck 2011 – V 0.2
  • 75. Gitweb – neues Projekt erstellen (installation wird im nächsten Abschnitt erklärt, hier erst mal der schnelle weg) Ins Projektroot von gitweb wechseln, dann repostory erstellen. Die meissten nennen diese am Ende .git – Ich mache viel mit Windows und ich mag es nicht wenn Verzeichnisse eine „Extension“ haben deswegen bei mir ohne: in description eine einfache Beschreibung eingeben Dann config-File einstellen (geht direkt im File oder:) Fertig. Gitweb installieren in ubuntu 1. ganz normal via apt-get installieren 2. Pfad wo die reps liegen in /etc/gitweb.conf definieren darin legen wir nun ein Verzeichnis an und darin legen wir nun ein git repository an und editieren darin die description des projects © Günther Haslbeck 2011 – V 0.2
  • 76. und wir sehen dann im Browser und wenn wir darauf klicken ist auch alles da was aber noch fehlt ist die Anzeige der URL des repositories. Das macht das Auschecken etwas leichter das geschieht am Ende von /etc/gitweb. Dort können 1 oder mehrere URLs angegeben werden diese erscheinen dann auch in gitweb © Günther Haslbeck 2011 – V 0.2
  • 77. Jetzt checken wir mal das repository aus Dazu lokal ein Verzeichnis anlegen in dem dann das repository erscheinen soll darin per git clone auschecken (Für alle die SSH auf einem anderen port laufen lassen: Einfach ssh://xxx:PORT/bla ) reinwechseln Datei anlegen, committen dann pushen © Günther Haslbeck 2011 – V 0.2
  • 78. und file ist da und natürlich hat git vorher wieder gewarnt: © Günther Haslbeck 2011 – V 0.2
  • 79. und deswegen sollten wir die Werte wie angegeben auch setzen einmal git pull und git push und die Welt ist wieder in Ordnung File ändern und commiten und pushen: alles brav, alles funktioniert © Günther Haslbeck 2011 – V 0.2
  • 80. GIT in Eclipse installieren Egit unter HELP > INSTALL NEW SOFTWARE hinzufügen http://eclipse.org/egit/download/ © Günther Haslbeck 2011 – V 0.2
  • 81. Ein bestehendes Projekt für Eclipse aus GIT auschecken Projekt anlegen via Import → GIT → Projects from GIT © Günther Haslbeck 2011 – V 0.2
  • 82. und dann CLONE und dort wieder hier mit Extra-Port Angabe (:32 – normalerweise nicht nötig). Den Rest füllt EGIT selbst aus Unten noch Benutzername + PW angeben. Dann Importieren ------------ Neues Projekt Erst einmal mit TEAM → Share ein neues Repository lokal erstellen. © Günther Haslbeck 2011 – V 0.2
  • 83. Dann über die Console (anders hab ichs nicht geschaft) Dann klappts mit TEAM > PUSH TO UPSTREAM und fertig ;) Push geht allerdings nur oben beim „Projekt“ selbst © Günther Haslbeck 2011 – V 0.2
  • 84. Branching in Git Einen neuen Branch (hier mal mit testnamen „newbranch“)erzeugen und dann mal anzeigen welche Branches es gibt Das * vor master zeigt, das wir im Master-Branch sind Wir wechseln mal in unseren „newbranch“ und pushen diesen auch gleich mal in unser gitrepository und er erscheint auch in unserem gitweb © Günther Haslbeck 2011 – V 0.2
  • 85. Wir bearbeiten ein File und committen und pushen Man sieht auch in gitweb die Änderungen am File und in welchem Branch Wechseln wir nun zurück zum Masterbranch so ist im File wieder der alte Stand. Nun mergen wir den Master mit dem Stand aus „newbranch“ © Günther Haslbeck 2011 – V 0.2
  • 86. und das File passt wieder. Wir pushen alles noch, dann ists auch wieder im repository ok und auch in gitweb sieht man dass das File nun in beiden Branches aktuell ist: Wenns Probleme gab beim mergen: git diff zeigt die Probleme git commit -a um die Files dann zu committen git branch -d newbranch löscht einen Branch der in einem normalen Status ist git branch -D newbranch löscht den Branch egal in welchen Status er ist Deployment mit Git wäre damit zB so möglich: Der Sync auf die Server kann dann einfach per rsync erfolgen © Günther Haslbeck 2011 – V 0.2
  • 87. Wir haben also aktuell unseren Quellcode zB so organisiert: Remote Master Repository Netbeans Lokales Master Remote Master dev-webserver Repository clone rsync und so hätten wirs gerne © Günther Haslbeck 2011 – V 0.2
  • 88. Remote Master Repository Netbeans rsync Lokales Master Remote Master dev-webserver Repository clone Switch from Master (dev) to Stage Merge to Stage and sync Switch back to Master (Dev) Remote Stage stage-webserver Branch clone Switch from Stage to Live Merge to Live and sync Switch back to Stage Remote Live live-webserver Branch clone Wir legen also erst einmal 2 neue Branches an $ git branch stage $ git branch live und pushen diese $ git push origin stage $ git push origin live was haben wir, wo sind wir: $ git branch © Günther Haslbeck 2011 – V 0.2
  • 89. live * master stage und wechseln dann in den Stage-Branch $ git checkout stage Switched to branch 'stage' und prüfen: $ git branch live master * stage Perfect. Nun mergen wir alles von master nach stage, vergeben just for fun ein (versions) Tag (nicht nötig) und pushen alles wieder zurück $ git merge master $ git push $ git tag -a v0.1 -m "neue Version" $ git push origin v0.1 $ git checkout master Switched to branch 'master' Alle Änderungen vom Masterbranch sind nun auch im Stagebranch. Das sehen wir auch in Gitweb Jetzt muss nur noch der Repository-Clone vom Stagesverzeichnis dass dann mit dem Stage-Server syncht auf eben diesen Branch umgeschaltet werden damit nur Änderungen aus dem Stage-Branch gesyncht werden wir wechseln also in das Verzeichnis in dem das Stagesystem geclonet ist und sehen uns die vorhandenen Branches an $ git branch • master Es gibt nur Master. Wir wollen aber einen anderen. Welche es gibt zeigt -a : $ git branch -a * master remotes/origin/HEAD -> origin/master © Günther Haslbeck 2011 – V 0.2
  • 90. remotes/origin/live remotes/origin/master remotes/origin/stage (Mehr http://stackoverflow.com/questions/67699/how-do-i-clone-all-remote-branches-with-git ) um in den stage-branch zu kommen müssen wir diesen hier einmalig auschecken: $ git checkout -b stage remotes/origin/stage Branch stage set up to track remote branch stage from origin. Switched to a new branch 'stage' wir sind nun in $ git branch master * stage und holen uns nun zur Sicherheit nochmal den neusten stand $ git pull Von diesem Verzeichnis werden also nur Änderungen gesyncht die im Branch Stage sind. Ändert man nun in Netbeans etwas ab und commit/pullt diese Änderungen in den Masterbranch so erscheint diese Änderung nur auf dem Devserver. Um die Änderung auch auf dem Stageserver zu sehen muss eben der Stagebrach mit dem Masterbranch gemerget werden. $ git merge master $ git tag -a v0.2 -m "neue Version" $ git push origin v0.2 $ git push $ git checkout master und schon erscheint die Änderung auf auf dem Stageserver. Auch in gitweb ist schön zu sehen auf welchem Stand die Systeme sind und durch die Tags könnten wir auch später auf eine ältere Version zurückspringen. © Günther Haslbeck 2011 – V 0.2