Grundsätzliche Frage: Wie professionell PHP programmieren?

deostift

Erfahrenes Mitglied
Ich grüße Euch,

zu meinem Background: Ich war die letzten zwei Jahre in einer Internet-Agentur das "Mädchen für alles": Ich hab Layouts für Web-Portale erstellt, habe die HTML Templates für die CMS-Systeme geschnitzt und schließlich die CMS Systeme konfiguriert bzw. neue php-Modue erstellt oder vorhandene modifiziert.

Vor kurzen habe ich nun eine neue Arbeitsstelle angetreten bei der die Web-Entwicklung in PHP im Vordergrund steht.

Meine bisherige Programmierung war eher davon geprägt: Es muss funktionieren und eben schnell umgesetzt sein. Für saubere Schichtenmodelle bzw. OOP blieb keine Zeit.

Deshalb meine Frage an Euch: Wie kann man in seine Art zu Coden (speziell PHP5) mehr Struktur einfließen lassen. Bisher teste ich immer aus und hangle mich von einer Hürde zur anderem, suche im Netz nach Beispiel-Skripten und habe zum Schluss jede Menge Code der später sehr mies für ein "Refactoring" wäre.

OOP, Klassendiagramme, Datenbank-Modelle, Schichten-Trennungen habe ich in der Hochschule theoretisch mit ein wenig Code in Java erlernt. Aber wenn man frisch vor einer neuen Aufgabenstellung sitz, sieht die Welt wieder ganz anders aus.

Gibt es hier eine Herangehensweise wie man sich z.B. mit Patterns oder Frameworks vertraut machen kann. Wie schon oben genannt, suche ich oft nach Beispielen im Netz, aber eigne mir keinen eigenen sauberen Stil an.

Eine Erklärung was Variablen etc. sind oder wie OOP prinzipiell durchführt brauche ich sicher nicht. Was ich such wäre eher wie ich an neue Aufgaben herangehe, welche Schritte zuerst umgesetzt werden sollen. Leider habe ich keinen Guru der mir alles geduldig erklärt bzw. dem ich über die Schulter schauen kann ... deswegen meine Bitte an Euch :)

Viele Grüße, Deo
 
Also das ist eine recht komplexe Frage und jeder wird dir eine andere Herangehensweise empfehlen.

Und eine universelle Lösung wird es auch nicht geben.
Aber hier mal meine "allgemeinen" Tipps zum rangehen an neue Aufgaben.

1. Mindmaps erstellen (oder zumindest durchdenken)
http://de.wikipedia.org/wiki/Mindmap
Hierbei wird das Thema mittig auf Papier (oder Bildschirm) gebracht und man lässt einfach mal den Gedanken freien Lauf und schreibt alles dazu, was einem einfällt.
In unserem Fall: "Was muss es alles können? Was brauch ich?"

2. Aus den Mindmaps Todo-Listen erstellen, was alles zu tun ist.
dabei schön Gruppieren und Unterkategorien bilden.

3. Mit Klassen und Funktionen arbeiten / Modular arbeiten
Muss man z.B. auf eine Datenbank zugreiffen und hat beim letzten Projekt schon eine Datenbankklasse entwickelt (bzw. eine Fremde verwendet) kann man diese direkt wieder verwenden und in der Todo-Liste abhaken

4. Todo-Liste von unten nach oben abarbeiten und dabei immer darauf achten, dass man aus allem was man irgendwann wieder gebrauchen kann entweder in eine Klasse oder Funktion packt.

5. Alles zusammenfügen und zum Laufen bringen


Noch ein paar "persönliche" Tipps, auch wenn einige User anderer Meinung sind:

PHP:
// 1. Immer alles schön dokumentieren
2. Für jede Klasse ne kleine Textfile in der die Befehle aufgelistet sind und mit Beispielen

3. Einige Jungs in meinem Team sind richtige Code-Jongleure. wofür ich 5 Zeilen brauche, brauchen die nur 2. aber mit einem Unterschied: Wenn ich mal meinen Quelli jemanden Zeige, dann ist alles direkt verständlich und man frägt sich nicht "Was ist das denn?"
Also: Übersichtlich Coden, damit andere oder du nach einiger Zeit schnell sehen können was da passieren soll. (Kann man nach dem Debuggen immernoch shrinken)

4. Mit einem Templatesystem arbeiten, um HTML und PHP voneinander zu trennen, um z.B. dem Designer/Grafiker die Arbeit zu vereinfachen und im schneller das Design zu integrieren

5. Immer noch Hintertürchen offen halten. Jetzt nicht zum Hacken sondern bei der Umsetzung schon berücksichtigen, dass vielleicht noch neue Features hinzukommen sollen.

EDIT: (das Wichtigste vergessen)
6. Kompatibel programmieren. Klar ist es sinnvoll alles auf PHP 5 auszulegen, aber meiner Meinung nach ist es besser so weit wie möglich auf PHP4 zu arbeiten. Man weis ja nie wo das Skript mal eingesetzt werden soll.Und es gibt nichts peinlicheres als das Skript dem Kunden auf seinem Server vorführen zu wollen um dann festzustellen, dass es dort nicht läuft. Besser ist natürlich vorher zu checken welche Voraussetzungen gegeben sind, bzw.klarzustellen welche Voraussetzungen du benötigst. Wenn du aber was universelles programmieren musst, immer auf Kompatibilität achten.

So, mehr fällt mir zum Thema: "Wie gehe ich an ein neues Projekt ran?" nicht ein.
Vielleicht ist ja was für dich dabei
 
Zuletzt bearbeitet:
Hi,

ich kann mich dem MiNiMaG da so ziemlich komplett anschließen. Das ist eine gute Vorgehensweise. Ich mache es ähnlich

1. Alles aufschreiben, was mir zu meinem Problem so einfällt
--> Was muss das Programm können
--> Hat es ein bestimmtes design
--> muss es schnell zu implementieren sein
--> usw.

2. Ich arbeite immer Objektorientiert, wenn die Programmiersprache es zulässt. Das heißt:
--> überlegen, welche Klassen ich benötige
--> überlegen, was die Klassen für Eigenschaften und Methoden benötigen.

3. Überlegen, welche Klassen kann ich ableiten, und welche nehme ich als Templates (abstract)

4. Ich programmiere immer Bottom Up. Andere programmieren Top Down. Bottom Up ist in sofern besser, als dass man schneller Testen kann und die einzelnen Klassen schon implementieren kann, auch wenn sie eigentlich noch gar nichts machen.

5. DAS GANZE TESTEN. WICHTIG. Vergessen viele. Blackbox und Whitebox test. (Gibt noch viele andere Verfahren)

6. Fehler beseiten.

7. NOCHMAL TESTEN.


So würde ich es angehen. Und wie MiNiMaG schon gesagt hat, immer schön Dokumentieren. Das sollte man nicht vergessen, auch wenn man wenig Zeit hat. Die Zeit spart man hinterher wieder, wenn man sich da noch mal reinarbeiten muss oder wenn sich dort wer anders reinarbeiten muss.
Außerdem bin ich auch eher ein Fan davon nicht 20 Funktionen in eine Zeile zu verschachteln. Lieber Stückweise programmieren und gut lesbaren Code erzeugen.

Gruß
 
Ich empfehle zur Darstellung des Programmauf-/und ablauf MS Visio oder die weit aus günstigere Variante Visustin. Natürlich ist das nicht unbedingt MUSS, es dient einfach zur Übersichtlichkeit, vor allem wenn man im Team arbeitet.
 
Ich empfehle zur Darstellung des Programmauf-/und ablauf MS Visio oder die weit aus günstigere Variante Visustin. Natürlich ist das nicht unbedingt MUSS, es dient einfach zur Übersichtlichkeit, vor allem wenn man im Team arbeitet.
Und fuer Linux-User (und auch User aehnlicher Betriebssysteme) gibt es da als Alternative Kivio, welches Teil von KOffice ist.

Beim Rest des Themas kann ich mich im Grunde nur anschliessen.
Code einruecken, nicht alles in eine Zeile klatschen und ordentlich testen.
Vor allem bei PHP gilt es im Auge zu behalten woher Daten kommen (koennen) und diese entsprechend zu behandeln um den gaengigen Risiken (SQL-Injections, Code-Injections, Cross-Site-Scripting) gleich im Ansatz vorzubeugen.
Dazu kann ich auf jeden Fall nur einen Blick in den Thread Sicherheit in PHP empfehlen, wo sich bereits einige interessante Links zusammengetragen haben.
In dem Thread, oder evtl. einem seperaten, wollte ich demnaechst auch mal 2 verschiedene php.inis vorstellen und ein paar Hinweise mitliefern worauf zu achten ist, dass Scripts mit beiden laufen und auch einigermassen abgesichert sind. Aber das wird noch etwas Zeit in Anspruch nehmen da ich sowas nicht einfach nur mal eben aus der Hand schuetteln will.

Auch wenn es natuerlich schoen ist wenn man mit der aktuellsten PHP-Version mit allem Schnickschnack arbeiten kann (daheim und auf der Arbeit nutze ich PHP 5.2 inklusive Suhosin-Patch und -Extension) so ist es immer wichtig kompatibel zu bleiben. Vor allem da offensichtlich noch sehr viele Hoster auf PHP4 zu setzen scheinen.
Zum Beispiel entwickle ich all meine Klassen erst fuer PHP5, portiere sie dann aber auch fuer PHP4. Fuer meine Website nutze ich z.B. auch die PHP4-Versionen der Klassen.
 
Ich bin mir bewusst, dass dies eine sehr komplexe Fragestellung war. Um so dankbarer bin ich für Eure ausführlichen Beiträge :)

Kennt ihr zufällige OpenSource-Beispiele von denen man noch einiges "abschauen" könnte. Also wie diese Ihr System aufgebaut haben bzw. wie sie ihre Schichten definiert haben und die Trennung realisierten und als Sahnehäubchen noch eine gute Dokumentation beinhaltet :)

Ein Projekt, das ich sehr interessant finde und bei dem sich ein Blick in den Source-Code lohnt ist "Sugar CRM" >> http://www.sugarcrm.com/crm/

Kennt ihr noch weitere Projekte, die Euch inspiriert haben. Oder Links auf Webseiten, die einem mehr vermitteln als "Was sind Funktionen" .. "Mein erstes 'Hello World'". Oder eben Bücher die sich mit professioneller Projektdurchführung mit PHP(5) befassen.

Mein Prof. rümpfte immer die Nase wenn PHP zur Sprache kam. Er vertrat die Meinung, dass dies keine ernstzunehmende Sprache sei zumindest nicht für professionelle Anwendungen ... einfach weil sich zu viele chaotische Stile gebildet haben. Der eine codet alles prozedural, der andere nimmt Funktionen und ein Dritter erschlägt einen mit Referenzen oder globalen Variablen etc.


Vielen Dank ;) .. need mooore ^^
 
Mein Prof. rümpfte immer die Nase wenn PHP zur Sprache kam. Er vertrat die Meinung, dass dies keine ernstzunehmende Sprache sei zumindest nicht für professionelle Anwendungen ... einfach weil sich zu viele chaotische Stile gebildet haben. Der eine codet alles prozedural, der andere nimmt Funktionen und ein Dritter erschlägt einen mit Referenzen oder globalen Variablen etc.
Dein Professor hat da nicht ganz unrecht: PHP? Bitte nicht!

Ich würde zusätzlich noch den Einsatz eines Framework in Erwägung ziehen.
 
Mein Prof. rümpfte immer die Nase wenn PHP zur Sprache kam. Er vertrat die Meinung, dass dies keine ernstzunehmende Sprache sei zumindest nicht für professionelle Anwendungen ... einfach weil sich zu viele chaotische Stile gebildet haben. Der eine codet alles prozedural, der andere nimmt Funktionen und ein Dritter erschlägt einen mit Referenzen oder globalen Variablen etc.
Dein Prof. hat damit nicht ganz unrecht. Eben aus den genannten Gruenden. PHP ist im Grunde dafuer ausgelegt eine einfach zu lernende und zu nutzende Sprache zu sein, und einem eben nicht irgendwelche Stolpersteine in den Weg zu legen. Die Auswirkungen dessen sind zum Teil halt recht katastrophale Scripts die dann z.B. nur mit bestimmten Einstellungen laufen oder riesige Sicherheitsluecken in's System reissen.
Das Problem liegt dabei aber nicht unbedingt bei PHP selbst, auch wenn PHP natuerlich durch seine Struktur ordentlich Hilfestellung leistet, sondern bei Usern die unerfahren sind und aus schlechten oder veralteten Quellen lernen. Oder aber auch User die meinen, dass jeder der seine kleine Website besucht auch wirklich nur auf die Links klickt und nicht mal probiert was passiert wenn man eine Anfrage etwas abaendert, also Usern die sich mit Sicherheit kein Stueck auseinandersetzen.
Das Hauptproblem findet man also, wie so oft zwischen Tastatur und Stuhl aufzufinden. Mit jeder Programmiersprache kann man Schrott schreiben, aber PHP verleitet zum Teil halt dazu, weil eben Einstellungen wie z.B. register_globals oder allow_url_fopen einiges vereinfachen koennen. Und wenn ein User es nicht von Anfang an richtig lernt, dann wird er wohl frueher oder spaeter Probleme mit seinen Scripts haben und dann umlernen muessen. Und wir wissen ja alle dass der Mensch ein Gewohnheitstier ist, nicht? ;)
Ich kenn das ja selbst. Meine ersten Erfahrungen mit PHP hab ich mit PHP3 gemacht, und da war noch vieles anders. Und auch ich hab mich damals auf register_globals verlassen und Code geschrieben wovor ich heute wild kreischend weglaufen wuerde.
Und im Grunde hauptsaechlich dadurch, dass ich mich in den letzten Jahren viel mit Security befasst habe hab ich meinen kompletten Programmierstil in PHP geaendert. Und es fallen mir immer wieder neue Kleinigkeiten ein die man noch besser machen koennte.

Es ist einfach ein lauffaehiges Script zu schreiben, aber es ist was anderes ein Script gegen alle Eventualitaeten abzudichten.
Mal ein einfaches Beispiel in ein paar Evulotionsstufen. Ich will dabei nicht alle Einzelschritte aufzeigen, dass wuerde etwas den Rahmen sprengen, aber mal ein paar Schritte wie so ein Script ein gutes Stueck sicherer wird.
PHP:
$galleries=mysql_query("select * from galleries where id='".$gallery."'");
$gallery=mysql_fetch_assoc($galleries);
echo 'Galerie: '.$gallery['gallery'];
$images=mysql_query("select * from images where id='".$gallery."'");
while ($image=mysql_fetch_assoc($image))
{
 //Ausgabe
}
Dies ist wohl die schreckliste aller moeglichen Varianten. $gallery kommt per GET, wird in keinster Weise geprueft ob es ueberhaupt uebergeben wird oder numerisch und es wird auch davon ausgegangen, dass die gewuenschte Galerie existiert. Weiterhin werden hier 2 Moeglichkeiten zur SQL-Injection geboten.
PHP:
if ($_GET['gallery'])
{
 $galleries=mysql_query("select * from galleries where id='".$_GET['gallery']."'");
 $gallery=mysql_fetch_assoc($galleries);
 echo 'Galerie: '.$gallery['gallery'];
 $images=mysql_query("select * from images where id='".$_GET['gallery']."'");
 while ($image=mysql_fetch_assoc($image))
 {
  //Ausgabe
 }
}
Hier wird zumindest mit $_GET gearbeitet und auch geprueft ob der Wert gallery auch uebergeben wurde. Ein Schritt in die richtige Richtung, aber nur ein kleiner, denn alle anderen Probleme bestehen weiterhin.
PHP:
if ((!empty($_GET['gallery'])) && (is_numeric($_GET['gallery'])))
{
 $galleries=mysql_query("select * from galleries where id='".$_GET['gallery']."'");
 $gallery=mysql_fetch_assoc($galleries);
 echo 'Galerie: '.$gallery['gallery'];
 $images=mysql_query("select * from images where id='".$gallery['id']."'");
 while ($image=mysql_fetch_assoc($image))
 {
  //Ausgabe
 }
}
Hier wird nun geprueft ob $_GET['gallery'] nun auch wirklich einen Wert beinhaltet, und dieser muss zudem numerisch sein. Dadurch faellt auch das Problem der SQL-Injections flach, denn diese sind ueber eine einfache Zahl nicht moeglich. Weiterhin wird in der 2. Query nun die GalleryID aus der ersten Query genutzt. Dies macht zwar hier keinen wirklichen Unterschied, jedoch kann dies bei anderen Werten als bei Zahlen zu ein klein wenig mehr Sicherheit fuehren da ein Angriffspunkt wegfaellt.
PHP:
if ((!empty($_GET['gallery'])) && (is_numeric($_GET['gallery'])))
{
 $galleries=mysql_query("select * from galleries where id='".$_GET['gallery']."'");
 if (mysql_num_rows($galleries)==1)
 {
  $gallery=mysql_fetch_assoc($galleries);
  echo 'Galerie: '.$gallery['gallery'];
  $images=mysql_query("select * from images where id='".$gallery['id']."'");
  while ($image=mysql_fetch_assoc($image))
  {
   //Ausgabe
  }
 }
}
Hier wird dann zusaetzlich auch noch geprueft ob die gewuenschte Galerie ueberhaupt existiert.
Zusaetzlich koennte man nun noch die Feld- und Tabellennamen in der Query entsprechend kennzeichnen, das saehe dann so aus:
PHP:
if ((!empty($_GET['gallery'])) && (is_numeric($_GET['gallery'])))
{
 $galleries=mysql_query("select * from `galleries` where `id`='".$_GET['gallery']."'");
 if (mysql_num_rows($galleries)==1)
 {
  $gallery=mysql_fetch_assoc($galleries);
  echo 'Galerie: '.$gallery['gallery'];
  $images=mysql_query("select * from `images` where `id`='".$gallery['id']."'");
  while ($image=mysql_fetch_assoc($image))
  {
   //Ausgabe
  }
 }
}
Einen wirklichen Unterschied macht dies aber nicht. Damit verhindert man nur, dass evtl. ein Tabellen-/Feldname mit einem Schluesselwort kollidiert. Man kann ja durchaus ein Feld mit dem Namen select haben.
Die Query
SQL:
select * from my_table where select='lala'
wird aber fehlschlagen da select als Schluesselwort angesehen wird.
SQL:
select * from `my_table` where `select`='lala'
hingegen funktioniert wunderbar.
Bei Werten die nicht erwiesenermassen numerisch sind sollte man zusaetzlich auch mit Escaping arbeiten, bei MySQL kommt da in der Regel mysql_real_escape_string() zum Einsatz. Hier ist jedoch Vorsicht geboten, denn PHP bringt eine Einstellung mit die von Haus aus escapen kann, die Magic-Quotes. Falls diese Einstellung aktiv ist muessen diese entweder erst entfernt werden oder es wird dann nicht mehr mit mysql_real_escape_string() gearbeitet. Ersteres ist da meiner Meinung nach der bessere Weg.
Ich nutze dafuer diese Funktionen:
PHP:
function remove_magic_quotes($string)
{
	if (get_magic_quotes_gpc())
		{
			$string=stripslashes($string);
		}
	return $string;
}
function quote_string($string)
{
	global $sqldb;
	return $sqldb->escape_string(remove_magic_quotes($string));
}
$sqldb->escape_string() entspricht im Grunde mysql_real_escape_string(), ist nur halt eine Methode einer meiner Klassen.
Jeder Wert (sogar Zahlen, da hab ich auf totale Paranoia gesetzt ;) ) der bei mir an die Datenbank geht wird durch quote_string() gejagt, welches ja wiederum remove_magic_quotes() nutzt um evtl. vorhandene Magic Quotes zu entfernen.
 
Ich hätte das Skript wohl so geschrieben:
PHP:
if( !empty($_GET['gallery']) ) {
	$query = '
		SELECT
		        `gallery`.`name`,
		        `images`.`…`
		  FROM
		        `gallery`
		  INNER JOIN
		        `images` ON `gallery`.`id` = `image`.`gallery_id`
		  WHERE
		        `gallery`.`id` = '.intval($_GET['gallery']).'
		';
	$result = mysql_query($query);
	if( mysql_num_rows($result) == 1 ) {
		echo 'Galerie: '.mysql_result($result, 0, 'name');
		while( $row = mysql_fetch_assoc($image) ) {
			// …
		}
	}
}
Damit ist alles in einer Abfrage erledigt.

Die Magic Quotes würde ich eher generell deaktivieren oder zumindest gleich am Anfang des Skriptes entfernen und nicht bei jedem Wert einzeln.
 
Zurück