Falls jemand mal die Breite eines HTML-Elements auslesen möchte und diese Wert jedoch in Prozent umgerechnet haben möchte – so geht es!
$(selector).width() / $(selector).parent().width() * 100;
Links:
http://api.jquery.com/width/
Falls jemand mal die Breite eines HTML-Elements auslesen möchte und diese Wert jedoch in Prozent umgerechnet haben möchte – so geht es!
$(selector).width() / $(selector).parent().width() * 100;
Links:
http://api.jquery.com/width/
Neue Webseiten werden heutzutage oft via SASS erstellt, aber was macht man mit alten Projekten? Kann man auch hier SASS einsetzten? – Ja! Das schöne an “SCSS”-Dateien ist das diese 100% mit CSS kompatibel sind, so dass man die entsprechende Dateiendung umbenennen kann und neue / kleine Anpassungen in der SASS-Syntax schreiben kann. Wer jedoch eine ganze CSS-Datei auf den SCSS-Style anpassen möchte kann z.B. den “sass-convert”-Befehl auf der Kommandozeile verwenden.
See the Pen tqJvn by Lars Moelleken (@voku) on CodePen.
CSS > SCSS
Mit dem folgendem Befehl kann man die CSS-Datei in eine SCSS-Datei umwandeln lassen.
sass-convert --from css --to scss test.css test.scss
See the Pen Arxuv by Lars Moelleken (@voku) on CodePen.
Es folgt eine kleine manuelle Optimierung, dabei gilt: Umso besser die ursprüngliche CSS-Datei aufgebaut war, desto besser kann diese konvertiert werden.
See the Pen eFdlJ by Lars Moelleken (@voku) on CodePen.
SCSS > CSS
Nun erstellen wir aus der neuen SCSS-Datei wieder eine CSS-Datei + Sourcemap
scss --sourcemap --line-comments --style expanded test.scss test_new.css
See the Pen pErjB by Lars Moelleken (@voku) on CodePen.
PS: mithilfe der Source Map kann Chrome automatisch die entsprechenden Code-Stellen in der entsprechenden SCSS-Datei anzeigen :)
Links:
http://sassmeister.com/
http://css-tricks.com/sass-style-guide/
Quellen:
http://sass-lang.com/documentation/file.SASS_REFERENCE.html#output_style
In diesem Blog-Post möchte ich erklären, was technisch hinter einer Variable in PHP steckt und wann PHP den Speicher dieser Variablen wieder freigibt.
Im Alltag schaut man doch ehr selten (nie) in den eigentlichen Quellcode von PHP. Dies sollten wir an dieser Stelle nachholen. -> https://github.com/php/php-src/tree/PHP-5.5
Info: Auf der folgenden Seite kann man den PHP Quelltext einfach nach bestimmten z.B.: Funktionen durchsuchen: http://lxr.php.net
Ich habe mich hier für den Quelltext von PHP 5.5 entschieden, da diese Version auf meinen lokalen PC läuft und ich die folgenden Tests mit dieser Version durchführen werde.
PHP Quellcode – Struktur: Hier gibt es zwei Hautbestandteile von PHP, mit welchen wir uns weiter beschädigen werden. Aufgeteilt sind diese in den folgende zwei Verzeichnissen.
– Zend: (www.php.net/manual/en/langref.php) Die Zend Engine, stellt die Laufzeitumgebung für PHP zur Verfügung. In diesem Verzeichnis werden somit alle “language level”-Funktionen von PHP bereitgestellt wie z.B. Variablen, Syntax-Analyse, Code-Ausführung und Fehlerbehandlung.
– ext: (www.php.net/manual/en/funcref.php) Extensions, stellt alle einzel Funktionen von PHP bereit. (z.B. strpos, substr, PDO, SplFixedArray etc.)
Intern stellt PHP jeder Variable als sogenannte “ZVALs” da. Dies ist unter anderen nötig, da der PHP-Kern in C geschrieben ist, C jedoch keine dynamische Typisierung wie in PHP zulässt. Somit bedient man sich einer Art Wrapper, welcher verschiedene Werte beinhalten kann.
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};
value: http://lxr.php.net/xref/PHP_5_5/Zend/zend.h#321
typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { char *val; int len; } str; HashTable *ht; /* hash table value */ zend_object_value obj; } zvalue_value;
Wir sehen, dass der “value” in einer PHP-Variable (zval) mehrere Variablentpyen (Zustände) beinhaltet. Daher kann eine PHP-Variable sowohl einen int-Wert, als auch ein Array beinhalten.
z.B.:
$foo = (int) 3;
$foo = array(3);
C |
PHP |
long |
int, boolean, resource |
double |
float |
str |
string |
hashtable |
array |
zend_object_value |
object |
type: http://lxr.php.net/xref/PHP_5_5/Zend/zend.h#578
/* data types */ /* All data types <= IS_BOOL have their constructor/destructors skipped */ #define IS_NULL 0 #define IS_LONG 1 #define IS_DOUBLE 2 #define IS_BOOL 3 #define IS_ARRAY 4 #define IS_OBJECT 5 #define IS_STRING 6 #define IS_RESOURCE 7 #define IS_CONSTANT 8 #define IS_CONSTANT_ARRAY 9 #define IS_CALLABLE 10 /* Ugly hack to support constants as static array indices */ #define IS_CONSTANT_TYPE_MASK 0x00f #define IS_CONSTANT_UNQUALIFIED 0x010 #define IS_CONSTANT_INDEX 0x080 #define IS_LEXICAL_VAR 0x020 #define IS_LEXICAL_REF 0x040 #define IS_CONSTANT_IN_NAMESPACE 0x100
Da wir sovor gesehen haben, dass das “value”-Feld verschiedene Typen von Variablen beinhalten kann, wird hier festgelegt um welchen Type es sich hier handelt. z.B.: zval.type = IS_LONG
is_ref: 0 || 1 http://www.phpinsider.com/download/PHP5RefsExplained.pdf
Dieses Feld wird auf “1” gesetzt falls es sich bei der Variable um eine Referenz (z.B.: &$foo) handelt.
refcount: http://www.php.net/manual/en/features.gc.refcounting-basics.php
Dieses Feld ist ein Zähler für die Anzahl von PHP-Variablen, welche zu dem internen zval referenzieren, so kann der PHP Garbage Collector entscheiden, wann die entsprechende Variable nicht mehr benötigt wird.
z.B.:
$a= new A; // 1 Referenz
$b = $a; // 2 Referenzen
unset( $a ); // 1 Referenz
unset( $b); // 0 Referenzen
Auf folgender Webseite wurden bereits mit PHP 5.3 getestet, wie viel Speicher für 100000 Integer-Werten in einem Array benötigt werden. -> http://nikic.github.io/2011/12/12/How-big-are-PHP-arrays-really-Hint-BIG.html
| 64 bit | 32 bit
zval | 24 bytes | 16 bytes
+ cyclic GC info | 8 bytes | 4 bytes
+ allocation header | 16 bytes | 8 bytes
===================================================
zval (value) total | 48 bytes | 28 bytes
===================================================
bucket | 72 bytes | 36 bytes
+ allocation header | 16 bytes | 8 bytes
+ pointer | 8 bytes | 4 bytes
===================================================
bucket (array element) total | 96 bytes | 48 bytes
===================================================
total total | 144 bytes | 76 bytes
144 bytes * 100000 = 13.73 MB
$int = 0;
Speichergröße: 176 bytes
(refcount=1, is_ref=0),int 0
$null = null;
Speichergröße: 184 bytes
(refcount=1, is_ref=0),null
Da es für “null” keinen Eintrag im zvalue_value gibt, wird dieser Wert seperat gespeichert und benötigt somit inital mehr Speicher als 0.
$string = ”;
Speichergröße: 200 bytes
(refcount=1, is_ref=0),string '' (length=0)
$string = ‘1234567’;
Speichergröße: 200 bytes
(refcount=1, is_ref=0),string '1234567' (length=7)
$string = ‘12345678’;
Speichergröße: 208 bytes
(refcount=1, is_ref=0),string '1234567' (length=8)
$string = ‘0123456789’;
Speichergröße: 208 bytes
(refcount=1, is_ref=0),string '1234567' (length=10)
Wir sehen, dass PHP jeweills 1 byte (8 bit) benötigt, um ein Zeichen für einen String zu Speichern und diese zu jeweills 8 bytes zusammenfasst. So bleiden im letzten Beispiel 192 (208 – 16) bytes übrig, welche PHP benötigt um die entsprechende Variable anzulegen.
$array = range(1, 100000);
Speichergröße: 8524576 bytes => 8.12966919 megabytes
(refcount=1, is_ref=0), array (size=100000)
0 => (refcount=1, is_ref=0),int 1
1 => (refcount=1, is_ref=0),int 2
2 => (refcount=1, is_ref=0),int 3
3 => (refcount=1, is_ref=0),int 4
[...]
Quellcode für den Test: test4.php
start: 88 bytes
array: 8524592 bytes
function1-begin: 8524608 bytes
function1-end: 17049016 bytes
array-test4: 8524536 bytes
function2-begin: 8524552 bytes
function2-end: 8524616 bytes
array-test4_ref: 8524552 bytes
end: 8524552 bytes
Wir sehen, dass PHP bei der ersten Funktion mit Parameterübergabe (ohne Referenz) das entsprechende Array kopiert, da es sich hier um eine neue Variable handelt, welche in der Funktion verarbeite wird und zurückgegeben wird. Zusätzlich können wir hier beobachten wann PHP die Variable kopiert und zwar erst wenn diese Verändert wird (copy-on-write).
Ich glaube es ist Zeit für eine erste Zusammenfassung von dem was wir bisher aus den PHP Quelltext und den ersten kleinen Tests sehen konnten.
1.) PHP behandelt Variablen intern als Struktur von Variablen (zval_struct -> zval).
2.) Diese Struktur beinhaltet nicht nur den aktuellem Wert und den Type, sondern auch die Anzahl wie oft diese Variable verwendet wird und ob es sich dabei um eine Referenz (&) handelt.
3.) PHPs Garbage Collector kann somit nicht mehr benötigte Variablen selbständig aus dem Speicher löschen.
Quellen:
http://www.php.net/manual/en/internals2.variables.intro.php
http://www.php.net/manual/en/features.gc.refcounting-basics.php
http://www.php.net/manual/en/function.debug-zval-dump.php
http://code.stephenmorley.org/php/references-tutorial/
http://www.developerknowhow.com/inside-the-php-engine-integers-and-their-zval/
http://webandphp.com/how-php-manages-variables
http://wiki.selfhtml.org/wiki/Artikel:PHP/
http://www.sitepoint.com/better-understanding-phps-garbage-collection/
An dieser Stelle wollte ich einmal notieren wie ich in der täglichen Arbeit mit z.B. “grep” oder “find” etc. umgehe, um möglichst schnell in Verzeichnissen und Dateien zu suchen oder Text zu ersetzten.
Ich werde hier nicht alle Möglichkeiten der entsprechenden Befehle nennen können, daher beschränke ich mich auf das, was ich wirklich verwende. Falls du dich weiter in der Thematik einlesen möchtest, empfehle ich gerne den “man”-Befehl oder wie andere es ausdrücken RTFM!
Falls dir die Begriffe tail, cat, less nicht viel sagen, dann klick hier!!!
global regular expression print -> durchsucht Dateien und Verzeichnisse via RegEx bzw. nach Strings
Kurzform | Langform | Beschreibung |
-H |
--with-filename |
gibt den Dateinamen vor jedem Treffer aus. |
-i |
--ignore-case |
unterscheide nicht zwischen Groß- und Kleinschreibung. |
-n |
--line-number |
gibt die Zeilennummer vor jedem Treffer aus. |
-R -r |
--recursive |
liest alle Dateien unter jedem Verzeichnis rekursiv. |
-v |
--invert-match |
Invertiert die Suche und liefert alle Zeilen die nicht auf das gesuchte Muster passen. |
z.B.:
grep -rHn test ~/php/
-> sucht im Verzeichnis “php”, welches sich wiederum im Home-Verzeichnis [~] befindet nach dem String “test”
PS: hier der selbe Befehl, jedoch eingeschränkt auf php-Dateien
grep -Hn test ~/php/**/*.php
Info: wenn man “git” im Einsatz hat, sollte man “git grep” verwenden ;)
Ack hat die selbe Aufgabe wie “grep” ist jedoch auf Entwickler zugeschnitten, so sucht “ack” im Standardmäßig rekursiv, ignoriert Binärdaten und Verzeichnisse von Versionkontrollsystemen (.svn, .git, etc.)
PS: unter Debian / Ubuntu findet man das entsprechende Paket unter “ack-grep”
ist bei der Suche nach Dateien behilflich (“Alles ist eine Datei”)
Suchkriterien für find | |
Kriterium | Beschreibung |
-name Datei |
Es wird nach Dateien mit dem Namen “Datei” gesucht. Sollen bei der Suche Platzhalter Verwendung finden, so muss der ganze Ausdruck in Anführungszeichen gestellt werden, zum Beispiel
-name "*.txt" |
-iname Datei |
Es wird nach Dateien mit dem Namen “Datei” – ohne Beachtung der Groß und Kleinschreibung – gesucht. |
-type f |
Es wird nur nach regulären Dateien gesucht. |
-type d |
Es wird nur nach Verzeichnissen gesucht. |
find -size +10M -20M -exec ls -lah {} \;
-> sucht alle Dateien welche eine Dateigröße zwischen 10 – 20 MB haben und zeigt diese an
WARNING: der “exec”-Parameter kann auch für jeden anderen Befehl auf die Ergebnismenge von “find” ausführen, dabei sollte man jedoch bei dem “rm”-Befehl besonders vorsichtig sein. Und ggf. kann man sich safe-rm anschauen. ;)
PS: hier sind noch ein paar Beispiel
“sudo updatedb” nicht vergessen und schon kann man sehr schnell nach Dateien suchen, da die Dateien nicht im Filesystem, sondern in einer Datenbank (updatedb) gesucht werden.
z.B.:
locate Download | grep home
Es handelt sich hier um einen “nicht-interaktiver Texteditor” was eigentlich nur bedeutet, dass man damit String verarbeite kann. Zum Bespiel kann man ein bestimmtes Wort in einer Datei durch ein anderes ersetzten.
https://github.com/voku/dotfiles/blob/master/.functions
# WARNING -> replace: changes multiple files at once replace() { if [ $3 ]; then find $1 -type f -exec sed -i 's/$2/$3/g' {} \; else echo "Missing argument" fi }
replace *.php alt neu
-> dieser Befehl such im aktuellen (+ Unterverzeichnisse) nach Dateien, welche auf “.php” enden und ersetzt darin “alt” gegen “neu”
PS: hier findet man ein paar nützliche Beispiele
Dabei ist besonders praktisch, dass man diese Funktionalität auch im “vim” verwenden kann indem man z.B. folgendes eingibt …
:%s/alt/neu/g
Wie der Name schon vermuten lässt, kann man hiermit Dateien vergleichen. z.B.:
diff -u --ignore-all-space -r old/ new/
-> vergleicht alle Dateien rekursiv (-r) vom Verzeichnis “old/” und “new/” und ignoriert dabei Änderungen vom Leerräumen z.B. Leerzeichen oder Zeilenumbrüche (\r <-> \r\n)
Info: wenn man “git” im Einsatz hat, sollte man “git diff” verwenden ;)
word count kann Wörtern, Zeichen und Bytes (man ahnt es bereits) zählen. z.B.:
cat /proc/cpuinfo | grep processor | wc -l
-> zählt die Anzahl der CPU-Kerne
Quellen:
http://beyondgrep.com/ – ack
http://wiki.ubuntuusers.de/grep
http://wiki.ubuntuusers.de/find
http://wiki.ubuntuusers.de/locate
http://wiki.ubuntuusers.de/wc
http://suckup.de/linux/find-linux/
http://suckup.de/linux/streameditor-sed/
Habe soeben einen älteren Blog-Post aktualisiert und einen kleinen Tipp hinzugefügt, welchen ich hier an zwei Beispielen zeigen möchte: suckup.de/linux/ubuntu/aptitude-dpkg/
sudo aptitude search "^php5-[a-cA-C]+"
-> sucht alle Pakete welche mit “php5-” anfangen und darauf “a”, “b oder “c” in beliebiger Häufigkeit folgen
sudo aptitude search "(^bash|^git).*completion"
-> sucht Pakete welche entweder mit “bash” oder mit “git” anfangen gefolgt von beliebigen (auch beliebige Anzahl) von Zeichen, gefolgt von dem String “completion”
Die RegEx-Funktionalität funktioniert sowohl bei “apt-cache”, “apt-get” als auch bei “aptitude” und auch bei anderen Befehlen wie z.B.: “remove”, “install”, “search”, “purge” etc. Bei meinen Tests hat dies jedoch mit “aptitude” am besten funktioniert, da hier nur nach den Paketnamen gesucht wird, falls man jedoch nicht genau weiß wonach man eigentlich sucht, dann sollte man es wohl mit “apt-cache” versuchen.
PS: wer sich RegEx noch nicht angeschaut hat, der sollte auch mal die Links in den Quellen anklicken, da man dies z.B. in so gut wie jeder Programmiersprache, in der Shell oder ansatzweise selbst bei der Google-Suche nutzen kann. Wer mehr über Tricks in der Google-Suche erfahren möchte, klickt hier! ;)
Quellen:
https://www.debian.org/doc/manuals/debian-reference/ch02.de.html#_browsing_with_the_regex_matching
http://regex101.com/
http://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck
Habe meine dotfiles (Dateien im Home-Verzeichnis, welche mit einem “.” beginnen) mit anderen Quellen angereichert und diese auf github veröffentlicht. Wer möchte kann diese Einstellungen, Aliase, Funktionen für die “Linux-Shell” verwenden oder auch verbessern, indem man einen entsprechenden Fork von dem Projekt erstellt.
https://github.com/voku/dotfiles
cd ~ && git clone https://github.com/voku/dotfiles.git && cd dotfiles && ./bootstrap.sh
… wenn gewünscht kann man mit diesem kleinen Skript entsprechende ggf. benötigte Pakete nachinstallieren:
./firstInstall.sh
./bootstrap.sh
Die Datei “~/.config_dotfiles” beinhaltet einige Einstellungen für die entsprechenden dotfiles. Wenn diese Datei nicht existiert wird diese automatisch beim ausführen der “bootstrap.sh”-Datei erzeugt.
z.B.: “cat ~/.extra”
CONFIG_DEFAULT_USER="lars" CONFIG_TMUX=false CONFIG_ZSH_PLUGINS="(git bower composer ruby bundler gem)" CONFIG_ZSH_THEME="voku" CONFIG_BASH_THEME="voku" CONFIG_CHARSET_UTF8=true CONFIG_LANG="en_US"
Die Plugins sind von “bash-it“, “oh-my-zsh” und eigenen eigenen Anpassungen zusammengefügt. Außerdem wurden Plugins welche allgemeingültig sind in die globalen “.aliases” und “.functions” ausgelagert.
ZSH (Z-SHELL): https://github.com/revans/bash-it/tree/master/plugins/
BASH: https://github.com/revans/bash-it/tree/master/plugins/available
Wenn die Datei “~/.extra” existiert, wird diese zusammen mit den anderen Dateien verarbeitet. Man kann diese nutzen, um benutzerdefinierte Befehle ausführen zu lassen.
z.B.: “cat ~/.extra”
GIT_AUTHOR_NAME="Lars Moelleken" GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME" git config --global user.name "$GIT_AUTHOR_NAME" GIT_AUTHOR_EMAIL="lars@moelleken.org" GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL" git config --global user.email "$GIT_AUTHOR_EMAIL" git config --global push.default simple
http://suckup.de/linux/bashrc/
http://wiki.ubuntuusers.de/Bash/bashrc
http://suckup.de/linux/vi-howto/
http://vim.wikia.com/wiki/Example_vimrc
http://dotfiles.org/
Wer die entsprechenden Tools aus der Überschrift noch nicht installiert hat, der sollte zur folgenden Post lesen: -> Toolchain für Webentwickler <-
Slides: https://speakerdeck.com/thorsten/modern-frontend-development
International PHP Conference: Thorsten Rinne (@ThorstenRinne) zeigt die Möglichkeiten von Tools wie Bower, Grunt und Yeoman, mit denen man den kompletten Entwicklungsworkflow im Frontend-Bereich abdecken kann. (auf deutsch)
Slides: https://speakerdeck.com/chriscoyier/a-modern-web-designers-workflow
CSS-Tricks: Chris Coyier (@Real_CSS_Tricks) Screencast where Chris Coyier explains his workflow.
Slides: http://dl.dropboxusercontent.com/u/39519/talks/fluent/index.html#/
Fluent 2012: Paul Irish (@paul_irish) Learn what a modern development workflow looks like, from editors and plugins, to authoring abstractions, testing and DVCS integration.
Slides: http://dl.dropboxusercontent.com/u/39519/talks/html5dc-workflow/index.html#1
HTML5DevConf: Paul Irish (@paul_irish) Iterating faster, avoiding bugs through tools, and improved automated testing are great ideas, but in this talk Google’s Paul Irish will show how to really incorporate them into a functional and realistic developer workflow.
… und zum Schluss noch ein Beispiel, wie man mit “Yeoman” & “Grunt” & “Bower” & “AngularJS” eine modere Web-App baut: http://yeoman.io/codelab.html
Wir können die Aspekte von guten Code mit folgenden drei Leitlinien zusammenfassen: Lesbarkeit, Erweiterbarkeit, Effizienz. Dabei hängt es ganz von dem Projekt / Projektphase ab, in welcher Reihenfolge diese Leitlinien stehen. In diesem Artikel werde ich mich mit der „Lesbarkeit“ (Syntax, Stil, Standards) von PHP-Code, Kommentaren und git-commits beschäftigen.
Übersicht:
1. Namensgebung
2. Kommentare
3. Code-Standards
4. Refactoring
5. Debug
6. Versionskontrollsystem (git)
7. CI – Server
8. Empfehlung
Zur Lesbarkeit von Quellcode gehört insbesondere die Benennung von Variablen, Funktionen, Methoden, Klassen, Konstanten usw. Ich versuche dies an ein paar simplen Beispielen zu erklären:
FALSCH | RICHTIG | Erklärung |
str2clean | string | die lokalen Variablen wurde vereinfacht, so dass man den Quelltext besser lesen kann |
margin2Set | margin | |
naviPageEdit_innavi[$value] | naviPageEdit[‘inNavi’][$pageID] | ‘value’ wurde durch ‘pageID’ ersetzt |
naviPageEdit_offline[$value] | naviPageEdit[‘offline’][$pageID] | ‘_offine’ wurde durch eine weitere Array-Stufe ersetzt |
startTimerGlobal | GLOBALS[‘startTimerGlobal’] | die globale Variable ist nun auch als solche erkennbar |
dontRewriteFileName = false | rewriteFileName = true | keine Verneinung in Variablennamen verwenden!!! |
pageContentPriorities[$i], pageContentPriorityArray[$i], page->contentPriorities[$i] |
page->contentPriority[$i] | wenn möglich kein Plural für Variablen verwenden ; keine Angabe vom Variablentype im Variablennamen |
length,delay | length_in_mm,delay_seconds | wenn eine bestimmte Information sehr Wichtig für eine Variable ist, dann sollte man diese Information auch mit im Namen aufnehmen |
Gute Namen beschreiben was der Sinn dieser Variable ist und Funktionen sollten beschreiben was diese tun und nicht wie dies programmiert sind.
FALSCH | RICHTIG | Erklärung |
left_column, right_column | navi_column, content_column | Der Sinn der Variable ist es, die Navigation oder den Inhalt zu beinhalten. |
setHeadlineFontColorToRed() | setHeadlineFontColor(‘red’) | Wir beschreiben im Funktionsnamen nicht wie wir die Überschrift hervorheben, sondern dass wir dies überhaupt machen. |
renderBackgroundBlack() | renderBackgroundColor(‘black’) |
Es folgenden einfache, aussagekräftige Beispiele für Variablennamen: carColor, imageWidth, pageTemplate, daysDateRange, errorCounter, startDateTime, …
Allgemein sollten / dürfen Variablen keine Sonderzeichen (außer dem Unterstrich) enthalten und dürfen in den meisten Programmiersprachen nicht mit Zahlen oder Unterstrich anfangen. Zudem sollte diese in englisch ausgeschrieben werden. Einige Namen sollte man einfach aus seinem Wortschatz streichen: value, key, equals, data, lall, foo, bar, temp, tmp, x, xx, xxx, variable, var, arr, thing, stuff, bla, this, that, something, whatever, dummy, one, two, tree … Wenn man länger über den Namen für z.B. eine Methode nachdenken muss, ist dies ein Indiz dafür, dass man den Zweck dieser Methode noch nicht korrekt durchdacht hat und dass man diese Methode ggf. noch weiter aufteilen kann / sollte.
Beispiel für Wörter, welch man nicht verwenden sollte:
FALSCH | RICHTIG | Erklärung |
foreach ($pages as $key => $value) | foreach ($pages as $pageID => $page) | Variablen müssen immer Aussagekräftig sein! |
Bei Programmen mit Datenspeicherung sieht man im Quelltext häufig folgende Namensgebung: “fetch”, “get”, “retrieve”, “search”, “pull”, “pop”, “read”, usw. um Daten zu erhalten und so etwas wie “put”, “persist”, “set”, “push”, “add”, “insert”, “update”, “write”, usw. um Daten abzuspeichern. Einige Projekte halten sich an der Namensgebung „CRUD“ (Create, Read, Update, Delete) dabei ergibt sich aus dem Zusammenhang, was abgespeichert oder geändert wird, so dass man den entsprechenden Methodennamen auf das wesentliche beschränken und entsprechende Interface definieren kann: z.B.: $user->create(), $car->delete(), $page->update()
Ausnahmen bei gängigen Abkürzungen:
Abkürzung | Ausgeschrieben |
num | numberOf |
pos | position |
len | length |
max | maximum |
min | minimum |
temp || tmp | temporary |
val | value |
ret | return |
fp | filePointer |
Man sollte lieber dreimal über einen Namen nachdenken als einmal zu wenig. Und falls einem gerade kein passender Name einfällt, dann sollte man besser einen Aussagekräftigen, wenn auch längeren Namen verwenden. z.B.: cleanFilenameAfterFileupload()
– 1 Zeichen für Schleifenzähler ist gebräuchlich (z.B.: $i, $x, $y)
– 1 Wort für Zustands- / Schleifenvariablen (z.B.: $active, $hidden, $flag)
– 1-3 Wörter für lokale Variablen in Methoden / Funktionen (z.B.: $string, $linkText, $teaserTextType)
– 1-2 Wörter für Methoden (z.B.: isActive(), isHidden(), isTrue(), send())
– 1-2 Wörter für Klassen [wenn Namespaces verwendet werden] (Cache, CacheChain, AdaperApc)
– 1-2 Wörter für Interface [wenn Namespaces verwendet werden] (iCache, iAdapter)
– 2-4 Wörter für Globales [sollte man am besten gar nicht verwenden, dazu gleich mehr]
Halte dich an den Code-Style in einem Projekt, auch wenn dieser dir nicht zusagt. Wenn zum Beispiel einmal festgelegt wurde, dass Datenfelder aus der Datenbank in einer Klasse genauso heißen wie das entsprechende Datenbankfeld, dann muss man dies in dem Projekt auch konsequent durchziehen, ansonsten ist das Refactoring wirklich anstrengend. Man sollte sich für alle Projekte in einem Team / Firma auf einen Code-Style festlegen und diesen auch irgendwo niederschreiben (z.B. in einem Wiki), so dass neue Teammitglieder / Mitarbeiter wissen nach welchem Schema man den Quellcode lesen & schreiben sollte.
Es folgt eine kleine Auflistung von Variablen um zu verdeutlichen, welche Möglichkeiten man hat und dass es im Verlauf eines Projektes nicht mehr ganz so einfach ist diese mithilfe von Suchen- / Ersetzen-Tools in Einklang zu bringen:
userName, UserName, USER_NAME, s_userName, user_name, username, name, user->name
Allgemeine-Regel:
– Camel Case (Upper Camel Case) für Klassen → z.B.: AdaperApc
– Lower Case für namespaces / packages → z.B.: voku\cms\cache
– Mixed Case (Lower Camel Case) für Variablen → z.B.: cacheIsReady
– Upper Case für Konstanten → z.B.: SECONDS_IN_A_HOUR
– Unterstriche sollten nur für Konstanten verwendet werden
– SQL-Befehle sollten große geschrieben werden → SELECT id, username FROM user
Konsequente Temporäre Variablennamen:
Variable | Kontext |
$i | Schleifenzähler |
$j | verschachtelte Schleifenzähler |
$k | weiter verschachtelte Schleifenzähler |
$return | Rückgabewert |
$query | SQL-Query String |
$result | SQL-Query Ergebnis |
$fp | File-Pointer |
Auch wenn ich dies irgendwann mal in der Schule gelernt habe, solle man Namen nicht mit Tags / Suffixes versehen.
FALSCH | RICHTIG | Erklärung |
gintKundenID | $customer->getID() | global Integer “KundenID” |
$this->mintBenutzerName | $this->getName() | privat (modular) Integer “BenutzerName” |
Zum einen unterstützen uns heute moderne IDEs (z.B.: PhpStorm, Netbeans, Eclipse), so dass man selbst bei schwach typisierten Programmiersprachen wie PHP viele Informationen zu seinen Variablen / Funktionen / Klassen erhält, zum anderen sollte man anstatt eine globale ID für einen Kunden besser eine „Customer“-Klasse anlegen, welche eine Methode mit dem Namen „getID()“ beinhalten könnte.
Klassen: Man sollte vermeiden denselben Namen innerhalb von einer Klasse in unterschiedlichen Zusammenhängen (z.B.: in einer Methode, Konstruktor oder Attribut) zu verwenden, um die Verständlichkeit und Wartbarkeit zu erhöhen.
Methoden / Funktionen: Zudem sollte man nicht dieselbe Variable für verschiedene Zwecke innerhalb einer Funktion verwenden. Man sollte besser eine neue Variable anlegen anstatt eine alte Variabel zu „recyclen“. Ansonsten erschwert dies ebenfalls die Wartbarkeit und Lesbarkeit des Quellcodes.
Zuerst sollte geklärt werden, was Global heißt. Innerhalb von PHP kann jede Variable welche nicht innerhalb einer Funktion oder Klasse ausgelagert ist „global“ gesetzt / genutzt werden. Benötigt man diese Variablen in einem anderen Kontext (z.B. innerhalb einer Methode) kann man (sollte man jedoch nicht machen) dies mit dem Befehl „global $lall“ zugänglich machen. In den meisten Fällen tut man sich damit jedoch keinen Gefallen, da jemand anderes (oder man selbst) ggf. nicht weiß dass die Variable „$lall“ nun nicht mehr verwendet werden darf, da man diese nun in irgendeiner Methode global setzt hat. Zudem sieht man im Quellcode einer Variable nicht an, dass diese global ist und dass man diese nicht einfach verwenden / verändern darf.
Superglobale Variablen in PHP:
$GLOBALS | alle Variablen im globalen Gültigkeitsbereich |
$_POST | alle Variablen welche via HTTP-POST empfangen wurden |
$_GET | alle Variabel welche via HTTP-GET empfangen wurden |
$_REQUEST | alle Variablen welche via HTTP-POST / GET oder via COOKIE empfangen wurden |
$_SESSION | alle Session-Variablen (wir per User auf den Server gespeichert) |
$_COOKIE | alle Cookie-Variablen (werden per User auf dem PC des Users gespeichert) |
$_FILES | alle Datei-Uploads welche via HTTP-POST empfangen wurden |
$_SERVER | alle Variablen vom Server / Ausführungsumgebung |
$_ENV | alle Umgebungsvariablen welche z.B. im Betriebssystem gesetzt wurden |
PHP-Test mit globalen Variablen:
$thisIsGlobal= 1; echo $GLOBALS['thisIsGlobal']; $GLOBALS['thisIsGlobal'] = 2; echo $GLOBALS['thisIsGlobal']; globalTestNr1(); echo $GLOBALS['thisIsGlobal']; globalTestNr2(); echo $GLOBALS['thisIsGlobal']; globalTestNr3($thisIsGlobal); echo $GLOBALS['thisIsGlobal']; function globalTestNr1() { global $thisIsGlobal; $thisIsGlobal= 3; } function globalTestNr2() { $GLOBALS['thisIsGlobal'] = 4; } function globalTestNr3(&$input) { $input = 5; }
// output: 12345
Man sieht bereits bei wenigen Zeilen Code, dass dies nicht zur Wartbarkeit oder Lesbarkeit beiträgt. Zudem habe ich bisher keine Anforderung gesehen, welche man nicht ohne Globale-Variablen lösen könnte: z.B. via Übergabeparameter, Vererbung von Klassen, Singleton-Klassen, ausgelagerte „Konfiguration“ in einer separaten Datei und vieles mehr.
Kommentare sollten, wie die bisher erwähnten allgemeine Namensgebung in englisch geschrieben werden, da der Quelltext einerseits länger in Gebrauch sein kann als man denkt, andere (externe) Mitarbeiter daran irgendwann weiterarbeiten und ggf. auch den Weg in andere Projekte findet. Wenn man einmal den Fall hatte, dass man z.B.: eine „SHA-256“ Implementation für ältere PHP-Installationen benötigt und diese Bibliothek nur in Französisch („mais si un char necessite 16bits, on passe tout sur 16 …“ → aha?!) auf „github.com“ zu finden ist, dann weiß man warum man in der Programmierung Konsequent arbeiten sollte / muss.
In PHP sollte man zu jeder Methode / Funktion / Klasse einen Kommentar schreiben. Zudem sollte man wichtigen Attributen von Klassen mit einem Kommentar versehen, dabei sollten Mehrzeilige Kommentare vor dem zu beschreibenden Codeabschnitt stehen. Inline-Kommentare sollten nicht das wiedergeben, was man im Quelltext sowieso schon lesen kann, sondern einen Mehrwert bieten. Ein zusätzliches Problem welches entsteht, wenn man in Kommentaren beschreibt, dass der Code exakt macht und nicht was es allgemein machen sollte ist, dass man den Kommentar bei jeder Anpassung des Quellcodes theoretisch auch den Kommentar anpassen müsste, was jedoch nur sehr selten geschieht und somit ist der Kommentar nun ggf. Falsch!!! Mehrzeilige Kommentare sollten einen größeren Code-Abschnitt zusammenfassend beschreiben, dies deutet jedoch wiederum an, dass dieses Code-Abschnitt ggf. auch in eine neue Methode ausgelagert werden kann.
Beispiel:
FALSCH | RICHTIG | Erklärung |
// salutation can be Herr/Frau or 1/2 | // set the salutation | (ggf. kann man diesen Kommentar auch ganz entfernen) |
// get country out of DB depending on PLZ/City | // get the country from db | Wenn man hier irgendwann auch „Monsieur“ oder „Madame“ übergeben kann, ist dieser Kommentar Fehlerhaft und kann zu echten Problemen führen. |
if ($winner) { // JUST GET NEW WINNERS IF A NUMBER IS PASSED | // get the new winner from db if ($winner) { |
Der Kommentar sollte immer über einem Codeabschnitt stehen und nicht beschreiben, was sowieso im Code steht. |
„TODO“-Kommentare sollten immer mit „TODO“ anfangen und vor dem Nächten Release beseitigt werden. Moderne IDEs zeigen diese Kommentare in einer extra Übersicht / Fenster an, so dass jeder im Projekt weiß, dass hier noch etwas zu tun ist. Es kann zudem sehr hilfreich sein, wenn man Namenskürzel zu den TODOs hinzufügt, so dass man die Zuständigkeit für den Quellcode und für die Lösung des Problems direkt festhält.
Quellcode sollte nicht einfach nur auskommentiert werden, wenn dieser nicht mehr benötigt wird, sondern direkt gelöscht werden, da das Versionskontrollsystem sowieso jeder Version des Projektes beinhaltet und der Quellcode somit nicht verloren gehen kann.
Moderne IDEs bieten die Möglichkeit Kommentare automatisch zu erstellen, indem man z.B. vor der entsprechenden Funktion „/**“ + [Enter] eingibt. PhpStorm erkennt in vielen Fällen bereits welchen Type die Übergabeparameter und der „Return“-Wert haben, sodass man diese Information nicht in Inline-Kommentaren oder gar in der Variable speichern muss. Zudem kann man z.B. via phpDocumentor eine entsprechende Code-Dokumentation aus diesen Angaben und der Struktur des Projektes erstellen lassen.
Zusätzliche zu den bereits erwähnten PHPDoc (@param, @return) gibt es noch weitere sehr hilfreiche Information welche man zumindest für Klassen / Funktionen / Methoden hinzufügen sollte: @param, @return, @since, @package
Tag |
Inhalt |
Beschreibung |
---|---|---|
@abstract | Dokumentiert Abstrakte Klasse / Methoden | |
@access | public, private oder protected | Beschreibt die Sichtbarkeit von Variablen / Methoden |
@author | Autor <name@email> | Dokumentiert den Autor der z.B.: Klasse |
@copyright | Name / Datum | Dokumentiert Copyright Informationen |
@deprecated | version | Dokumentiert seit wann z.B. eine Funktion als veraltet gilt |
@deprec | @deprecated | |
@example | /path/to/example | Dokumentiert den Pfad zu einem Beispiel |
@exception | Dokumentiert eine „Exception“ welche von einer Methode geworfen wird → @throws. | |
@global | type $globalvarname | Dokumentiert eine globale Variable |
@ignore | Das Element wird in der Dokumentiert ignoriert | |
@internal | private Information für andere Entwickler | |
@link | URL | Eine URL zur eigentlichen Dokumentation |
@name | global variable name | Alias-Name für eine Variablen z.B.: $GLOBALS[‘myvariable’] → $myvariable |
@package | Namespaces | Dokumentiert den entsprechenden Namespace |
@param | type [$varname] description | Dokumentiert Funktions-Parameter |
@return | type description | Dokumentiert den Rückgabewert, wenn die Funktion einen Rückgabewert beinhaltet, falls dies nicht der Fall ist sollte man diese Angabe in PHP weglassen. |
@see | element | Dokumentiert die Verbindung zu anderen Elementen (global variable, include, page, class, function, define, method, variable). |
@since | version | Dokumentiert seit welcher Version der Software die entsprechende z.B.: Klasse / Methode hinzufügt wurde |
@static | Dokumentiert statische Klassen oder Methoden | |
@staticvar | type | Dokumentiert statische Variablen in einer Funktion oder Klasse |
@subpackage | Spezifiziert sub-package von Gruppen aus Klassen und Funktionen. | benötigt das Tag @package | |
@throws | Dokumentiert Exceptions von Methoden | |
@todo | Dokumentiert was an dieser Stelle noch gemacht werden muss | |
@var | type | Datentype für Klassenattribute |
@version | Dokumentiert die Version einer Klasse, Funktion |
Info: Zudem kann man HTML in PHPDoc schreiben, um z.B. bestimmte <strong>Dinge</strong> hervorzuheben!
Beispiel:
Besser als jeder Kommentar bleiben jedoch eindeutige Namen und die Aufteilung des Quelltextes in kleine einzelnen Modulen (Klassen + Namespaces), sodass man sich mehr mit dem Programmieren und nicht dem Verstehen des Codes und dem lesen von Kommentaren beschäftigen muss.
Zum Schluss noch ein Link mit vielen Beispielen wie man es nicht machen sollte: ;)
Man sollte nicht unterschätzen, wie sich die Quellcodeformatierung & Code-Standards auf die Programmierung im Team auswirkt. Einerseits hat jeder seine Vorlieben, andererseits muss man sich auf einen Standard einigen, da man ansonsten z.B. ständig Merge-Konflikte hervorruft und das Refactoring unmöglich gemacht wird. Nachdem man sich auf einen Standard geeinigt hat sollte man die Änderungen der Formatierung automatisch per IDE ausführen lassen. Zudem sollte man die automatische Codeformatierung in einem eigenen „commit“ in das Versionskontrollsystem einchecken. Ich empfehle an dieser Stelle einfach mal bereits bestehende PHP-Standards → PHP Framework Interoperability Group
Tipp: Minimale IDE übergreifende Programmierstandards kann man relativ einfach pro Projekt via „editorconfig.org“ festlegen.
github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
– Ein komplett ausgeschriebener Namespace mit Klasse muss die folgende Struktur einhalten \<Anbieter Name>\(<Namespace>\)*<Name der Klasse>
– Jeder Namespace muss den übergeordneten Namespace (“Anbieter Namen”) besitzen.
– Jeder Namespace kann beliebig viele Unter-Namespaces besitzen.
– Jeder Trenner (“\”) für Namespaces wird beim Laden vom Dateisystem zu einem DIRECTORY_SEPARATOR konvertiert.
– Jedes “_” Zeichen im KLASSENNAMEN wird zu einem DIRECTORY_SEPARATOR konvertiert. Das Zeichen _ hat keine besondere Bedeutung in einem Namespace.
– Der komplette Namespace wird mit dem Namen der Klasse und dem Suffix .php kombiniert, wenn dieser vom Dateisystem geladen wird.
– Alphabetische Zeichen in Anbieternamen, Namespaces und Klassennamen können in beliebiger Kombination aus Groß- und Kleinschreibung bestehen.
Zusammenfassung:
Jede Klasse muss (seit PHP 5.3) einen eigenen Namespace (mit Angabe des Anbieters) enthalten, so dass man sich sowohl bei Klassennamen also auch bei Namspaces nicht in die Quere kommt.
Beispiele:
Namespace + Klasse | Dateipfad |
\Doctrine\Common\IsolatedClassLoader | /path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php |
\Symfony\Core\Request | /path/to/project/lib/vendor/Symfony/Core/Request.php |
\Zend\Acl | /path/to/project/lib/vendor/Zend/Acl.php |
Zend\Mail\Message | /path/to/project/lib/vendor/Zend/Mail/Message.php |
Beispiele: Unterstriche in Namespaces & Klassennamen
Namespace + Klasse | Dateipfad |
\namespace\package\Class_Name | /path/to/project/lib/vendor/namespace/package/Class/Name.php |
\namespace\package_name\Class_Name | /path/to/project/lib/vendor/namespace/package_name/Class/Name.php |
Der Standard, welcher hier gesetzt wird, repräsentiert die minimale Anforderung, um eine Kompatibilität hinsichtlich Autoloader zu gewährleisten. Mit der Nutzung der Beispielimplementation des SplClassLoaders [https://gist.github.com/jwage/221634] (verfügbar ab PHP 5.3) kann man somit dynamisch und ohne weiteren Aufwand z.B. externe Bibliotheken nutzen.
github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md
– PHP-Dateien dürfen nur <?php und <?= Tags verwenden.
– PHP-Dateien dürfen nur UTF-8 ohne BOM verwenden.
– PHP-Dateien sollten entweder Klassen, Funktionen, Konstanten, etc. enthalten oder diese ausführen. Somit sollten die HTML-Navi z.B. in der Klasse „Navi“ entstehen jedoch nicht von dieser ausgegeben werden. Oder sollte die Klasse „Logger“ zwar die Funktionalität zum Loggen bereitstellen, diese jedoch nicht selber triggern.
– Namensräume und-Klassen müssen PSR-0 folgen.
– Klassennamen müssen in StudlyCaps deklariert werden.
– Klassen Konstanten müssen in Großbuchstaben geschrieben und ggf. mit dem Unterstrich getrennt)
– Methodennamen müssen in camelCase geschrieben werden.
github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
– Code muss dem “coding style guide” PSR [PSR-1] befolgen.
– PHP-Dateien müssen als Zeilenende Unix LF [\n] haben, Windows CRLF [\r\n]
– PHP-Dateien müssen mit einer leeren Zeile enden
– PHP-Dateien haben kein ?> tag am Ende der Datei
– Code muss 4 Leerzeilen pro Einzug verwenden. Tabs werden nicht verwendet.
– Es gibt keine Längenbegrenzung pro Codezeile; jedoch sollten die 120 Zeichen nicht überschritten werden (80 Zeichen oder weniger seien noch besser)
– PHP-Keywörter (z.B.: include, require, use etc.) müssen immer klein geschrieben werden
– PHP-Konstanten (z.B.: true, false, null) müssen ebenfalls klein geschrieben werden
– Es muss eine Leerzeile nach der Deklaration des Namespaces und ebenso nach den Nutzungserklärungen geben.
– Klammern für Klassen & Methoden müssen in der nächsten Zeile, nach dem Klassennamen geöffnet und dürfen erst eine Zeile unter der geöffneten Klammer geschlossen werden.
– Die Sichtbarkeit (public, private, protected) muss zu allen Eigenschaften und Methoden deklariert werden ; „abstract“ und „final“ muss vor der endgültigen Sichtbarkeit deklariert werden ; „static“ muss nach der Sichtbarkeit deklariert werden.
– Kontrollstrukturen (if, elseif, else, switch …) müssen nachfolgend ein Leerzeichen haben (z.B.: if ($lall === true)) ; Methoden und Funktionen benötigen kein extra Leerzeichen (z.B.: echo(‘lall’);)
– Geöffnete Klammern von Kontrollstrukturen müssen auf der gleichen Linienebene geschlossen werden ; Öffnende und Schließende Klammerpaare dürfen nicht in einer Zeile stehen.
– Geöffnete Klammern von Kontrollstrukturen dürfen nachfolgend keine Leerzeichen besitzen und schließenden Klammern dürfen zuvor keine unnötigen Leerzeichen haben.
Am besten schaut man sich mal ein paar Beispiele auf der angegebenen Webseite an, da ich hier nicht alle Regeln notiert habe. Dies sollte nur eine kleine Übersicht von Überlegungen sein, welche bereits andere Leute für uns übernommen haben, sodass wir und auf wichtigere Dinge wie z.B. dem Implementieren neuer Features konzentrieren können.
Vorweg: Ohne moderne IDE mit „Refoctoring“-Funktion (nicht Suchen- & Ersetzten) oder ohne Versionskontrollsystem (z.B. git) sollte man gar nicht mit dem Refactoring anfangen. Zudem sollten für Klassen, welche geändert werden sollen vor und nach den Änderungen entsprechende PHPUnit-Tests durchgeführt bzw. erstellt werden. Es folgt ein etwas längeres Video über das Refactoring via PhpStorm.
Wie beim Refactoring ist es auch hier sehr Sinnvoll, dass man ein Versionskontrollsystem nutzt, um einerseits zu einem früheren Programmzustand zurückzukehren und andererseits, um seine Änderungen im Nachhinein nachvollziehen zu können.
Bei komplexeren Problemen ist es immer hilfreich, dass Problem im kleinen Nachzustellen. Ggf. kann man die Funktion / Klasse, welche das Problem verursacht außerhalb des gesamten Projektes betrachten und testen.
Wer einmal an einem größerem Open-Source-Projekt mitgearbeitet hat, wo User Bugs melden, der weiß wie wichtig die Beschreibung von Fehlermeldungen ist. Ich habe dazu extra eine Webseite eingerichtet, nachdem wir viele Meldung bekommen haben, dass etwas nicht funktioniert. → dorimanx.suckup.de/dorimanx-kernel-for-sg2-i9100/howto-report-bugs/
Zusammenfassung:
Minimaler Bug-Report: Was hast du getan (mit welcher Version der Software), was hast du erwartet was passieren sollte und was passiert momentan.
Xdebug ist ein Debugger und Profiler für PHP. Dabei ist der Profiler besonders hilfreich, wenn eine Anwendung Performance Probleme hat, welche man nur schwer lokalisieren kann. Zudem ersetzt Xdebug die eigentlichen Debug-Funktionen von PHP und reichert diese z.B. mit einem Trace des Problems an. Zusätzlich bietet die Erweiterung neue Funktionen z.B.: xdebug_debug_zval(), xdebug_memory_usage(), xdebug_get_function_stack(),
Installation: suckup.de/allgemein/toolchain-fuer-webentwickler
HowTo: code.tutsplus.com/tutorials/xdebug-professional-php-debugging–net-34396
Gerade bei PHP sollte man die Warnungen während der Programmierung aktivieren und beseitigen, so dass man Programmierfehler bereits bei der Entwicklung sieht und nicht dem Nutzer später auffallen. Ähnlich wie die Ölstand Warnanzeige im Auto sich zu einem wirklichen Problem entwickeln kann, wenn man sich nicht um dessen Behebung kümmert. Außerdem sollte es in jedem PHP-Projekt eine Logging-Klasse (z.B.: monolog, log4php) geben, welche bestimmte definierte Ereignisse aufzeichnet.
An dieser Stelle möchte ich noch ein paar Worte zu „git“ verlieren. Erstens gibt es bereits viele praktische Programme und Integrationen in allen modernen IDEs, zweitens benötigt man im Standardfall nur wenige einfach Befehle auf der Kommandozeile, um git zu bedienen:
git Task |
Notiz |
Kommando |
---|---|---|
Erstellen eines neuen lokalen Repositories |
git init
|
|
Klone ein existierendes Repository | Erstelle eine Kopie eines lokalen Repositories |
git clone /path/to/repository
|
Erstelle eine Kopie eines externen Repositories |
git clone username@host:/path/to/repository
|
|
Datei hinzufügen | Füge eine oder mehrere Dateien zum index |
git add <Dateiname|*.php> git add --all |
Einchecken [commit] (wird noch nicht zum Server hochgeladen) | Änderungen lokal einchecken |
git commit -m "Nachricht"
|
Neue Dateien (git add) und Änderungen lokal einchecken |
git commit -am „Nachricht“
|
|
Hochladen [push] von commits | Sendet Änderungen zum „master“-Zweig vom Server |
git push origin master
|
Status | Zeigt eine Liste von geänderten, neuen und eingecheckten Daten an |
git status
|
Verbindung zu einem externen Server hinzufügen | Lokales Repository mit einem Server-Repository verbinden (um anschließend Commit zum Server senen zu können) |
git remote add origin <server>
|
Zeige alle momentan Verbundenen externen Server an |
git remote -v
|
|
Entwicklungszweig [branche] |
Erstelle einen neuen lokalen Entwicklungszweig |
git checkout -b <branchname>
|
Wechseln zwischen lokalen Entwicklungszweigen |
git checkout <branchname>
|
|
Zeigt alle Entwicklungszweige an |
git branch
|
|
Löscht ein lokalen Entwicklungszweig |
git branch -d <branchname>
|
|
Sendet den aktuellen lokalen Entwicklungszweig zum Server |
git push origin <branchname>
|
|
Sendet alle aktuellen Entwicklungszweige an den Server |
git push --all origin
|
|
Löscht einen Entwicklungszweig auf dem Server |
git push origin :<branchname> [git push origin --delete <branchname>] |
|
Updates vom externen (Server) Repository | Ziehe und vereinige (merge) alle Änderungen vom externen Repository in dein lokales Repository |
git pull
|
Merge einen lokalen Entwicklungszeig in den aktuellen lokalen Entwicklungszeig |
git merge <branchname>
|
|
Zeige alle Änderungen an:Zeigt alle Änderungen (bis auf Zeilenumbrüche an ; funktioniert auch beim normalen „diff“)Zeigt Unterschiede von verschiedenen Branches an: | git diff
git diff -u --ignore-all-space
git diff <sourcebranch> <targetbranch> |
|
Tags | Man kann Tags für Release-Versionen der Software vergeben |
git tag 1.0.0 <commitID>
|
CommitId ist eine eindeutige ID zu jedem Commit und kann z.B. folgendermaßen angeigt werden … |
git log
|
|
Sende alle Tags zum Server |
git push --tags origin
|
|
lokale Änderungen Rückgängig machen | Um eine Datei auf den Stand vom letzten Commit zurück zu drehen: |
git checkout -- <filename>
|
WARNUNG: hier werden auch lokale Commits gelöscht und sowohl die Dateien als auch der Index geändert |
git fetch origin git reset --hard <commitID> |
|
Suchen | Sucht im aktuellen Verzeichnis | git grep “foo()” |
Commit-Style | Erklärung | Beispiel |
[+] | Ein neues Feature wurde hinzugefügt (auch kleine neue Funktionen oder Tests). | [+]: added new SwiftmailerWrapper Class |
[-] | Feature wurde entfernt z.B. ein „revert“ eines [+] – Commits. | [-]: revert some changes from <commitID> |
[~] | Ein Refactoring Änderung, wobei weder Fehler behebt noch Funktion hinzugefügt wurden | [~]: refactored SwiftmailerWrapper Class |
[!] | Ein Fix für einen Bug. [fixes <issueID>] | [!]: fixed embedding images in the SwiftmailerWrapper Class |
[!#] | Visualisiert, dass eine Änderung ein Sicherheitsproblem behebt. | [!#]: fixed send() methode in the SwiftmailerWrapper Class |
[!!!] | Eine Änderung, welche Grundlegende Änderungen mit sich bringt und sich auch auf die Programmierung anderer Programmierung auswirkt. | [!!!]: changed SwiftmailerWrapper constructor-parameter |
[*] | Alles was nicht zu den bisher definierten Fällen passt, z.B. Code-Style Änderungen, hinzufügen von Dokumentation oder Ändern von Build-Skripten | [*]: fixed code-style from the SwiftmailerWrapper Class |
Interaktive Tutorials, welche man einmal in ein paar freien Minuten durchführen sollte.
– try.github.io (englisch)
– pcottle.github.io/learnGitBranching (deutsch)
Wer „git“ im privaten Umfeld einsetzten möchte, seine Projekte jedoch nicht öffentlich auf github.com stellen möchte, der kann z.B. www.gitlab.com/gitlab-com nutzen und für Firmen empfiehlt es sich einen eignen „gitlab“-Server (github.com/gitlabhq/gitlabhq) zu installieren.
Wer prüfen möchte, ob man sich in einem Projekt auch an gewisse PHP-Standards hält, der kann z.B. seinen CI-Server (Jenkins) für PHP optimieren und einige Tests automatisch ausführen / auswerten lassen:
– PHP_CodeSniffer → github.com/squizlabs/PHP_CodeSniffer
– PHPUnit → phpunit.de/manual/current/en/index.html
– phpCPD → github.com/EHER/phpunit-all-in-one/tree/master/src/phpcpd
– PHP_Depends → pdepend.org
– phpLOC → github.com/sebastianbergmann/phploc
– phpMD → phpmd.org
– phpdox → phpdox.de
Die entsprechenden Code-Standards kann man anschließend in einer „xml“-Datei (phpcs.xml) im Projekt hinterlegen und auch für andere Projekte verwenden.
Zum Schluss möchte ich zu diesem Thema noch ein gutes Buch empfehlen → „Weniger schlecht programmieren“ ← . Auch wenn sich das Buch an vielen Stellen direkt an Programmieranfänger richtet, findend man doch einige Beispiele welche man direkt in der täglichen Arbeit umsetzten kann. PS: Am besten kauft man solche Bücher direkt beim Verlag und nicht bei z.B. Amazon. Für dich ist es der selben Preis, der Autor jedoch verdient dabei mehr Geld, da nicht noch ein Händler daran mit verdient.
Quellen:
– „Weniger schlecht programmieren“ ISBN: 978-3-89721-567-2 → http://www.oreilly.de/catalog/wenschleprogger/
– PHP: Was ist guter Code? → http://www.sitepoint.com/practical-refactoring-1/
– Lesbaren Quellcode schreiben → http://code.tutsplus.com/tutorials/top-15-best-practices-for-writing-super-readable-code–net-8118
– Test Code Coverage → http://code.tutsplus.com/articles/test-code-coverage-from-myth-to-reality–cms-20442
– PSR? → http://code.tutsplus.com/tutorials/psr-huh–net-29314
– PHP Standards Recommendation → https://github.com/php-fig/fig-standards
– Reddick-Namenskonvention: http://de.wikipedia.org/wiki/Reddick-Namenskonvention#Beispiele
– Refactoring PHP-Code + Beispiel → http://code.tutsplus.com/tutorials/refactoring-legacy-code-part-1-the-golden-master–cms-20331
– Refactoring mit PHPStorm → http://code.tutsplus.com/tutorials/phpstorm-when-the-ide-really-matters–cms-20787
– PHPDocs → http://phpdoc.org/
– PHPDocs – Wiki → http://en.wikipedia.org/wiki/PHPDoc
– Professional PHP Debugging → http://code.tutsplus.com/tutorials/xdebug-professional-php-debugging–net-34396
– xDebug → http://xdebug.org/docs/
– git Befehle → https://confluence.atlassian.com/display/STASH/Basic+Git+commands
– Commit Message rules for TYPO3 Flow → http://docs.typo3.org/flow/TYPO3FlowDocumentation/stable/TheDefinitiveGuide/PartV/CodingGuideLines/PHP.html#commit-messages
– Commit Message Format from AngularJS → https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit
– Template for Jenkins Jobs for PHP Projects → http://jenkins-php.org/installation.html
– HowTo für PHP + Jenkins → http://systemsarchitect.net/continuous-integration-for-php-with-jenkins/
– HowTo (Video) für PHP + Jenkins → https://www.youtube.com/watch?v=PklYO2vYIfc
if (-1 == true) { echo "aha ..."; } // output: aha ... $tmpArray = array(0, 'foo2'); if (in_array("foo", $tmpArray)) { echo "aha v2 ..."; } // output: aha v2 ... $tmpArray = array(0, 'foo2'); if (in_array("foo", $tmpArray, true)) { echo "aha v3 ..."; } // output:
Das Beispiel mit in Array hab ich auf Twitter gesehen und hat mich im ersten Momentan doch ein wenig verwirrt.
Wenn man den dritten Parameter ($strict = null) von der Funktion “in_array” nicht auf “true” setzt, werden die Werte mit dem “==” Operator verglichen und daher ist ein nicht definierter String == null == 0 -> daher wieder “true” ;)
Also, sollte man in den meisten Fällen $strict auf “true” setzten und somit einen Typenvergleich mit dem “===” Operator durchführen lassen.
<- Übersicht ->
== | true | false | 1 | 0 | -1 | “1” | “0” | “-1” | null | array() | array(1) | array(“php”) | “php” | “” | NAN |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
true | true | false | true | false | true | true | false | true | false | false | true | true | true | false | true |
false | false | true | false | true | false | false | true | false | true | true | false | false | false | true | false |
1 | true | false | true | false | false | true | false | false | false | false | false | false | false | false | false |
0 | false | true | false | true | false | false | true | false | true | false | false | false | true | true | false |
-1 | true | false | false | false | true | false | false | true | false | false | false | false | false | false | false |
“1” | true | false | true | false | false | true | false | false | false | false | false | false | false | false | false |
“0” | false | true | false | true | false | false | true | false | false | false | false | false | false | false | false |
“-1” | true | false | false | false | true | false | false | true | false | false | false | false | false | false | false |
null | false | true | false | true | false | false | false | false | true | true | false | false | false | true | false |
array() | false | true | false | false | false | false | false | false | true | true | false | false | false | false | false |
array(1) | true | false | false | false | false | false | false | false | false | false | true | false | false | false | false |
array(“php”) | true | false | false | false | false | false | false | false | false | false | false | true | false | false | false |
“php” | true | false | false | true | false | false | false | false | false | false | false | false | true | false | false |
“” | false | true | false | true | false | false | false | false | true | false | false | false | false | true | false |
NAN | true | false | false | false | false | false | false | false | false | false | false | false | false | false | false |
source: http://habnab.it/php-table.html
PHP 5 und frühere Versionen haben keine nativen Unicode-Unterstützung, dass heißt im Ernstfall muss man seine Applikation via “mbstring”-, “iconv-” und “intl”-Funktionen nachbessern. Daher habe ich eine kleine PHP-Bibliothek zusammengestellt, welche via composer installiert werden kann.
Beispiel:
echo strlen($string) . "\n<br />"; echo UTF8::strlen($string) . "\n<br />"; // output: // 70 // 67 $string_test1 = strip_tags($string); $string_test2 = UTF8::strip_tags($string); echo strlen($string_test1) . "\n<br />"; echo UTF8::strlen($string_test2) . "\n<br />"; // output: // 53 // 50
Erklärung:
Trotz seines Namens zählt “strlen()” nicht Zeichen sondern Bytes, bei UTF-8 kann ein Charakter jedoch bis zu vier Bytes [rfc3629] lang sein.
Installation:
https://packagist.org/packages/voku/portable-utf8
Dokumentation:
https://github.com/voku/portable-utf8/master/doc/classes/voku.helper.UTF8.html
Based on Hamid Sarfraz’s work: http://pageconfig.com/attachments/portable-utf8.php