Objektorientiert anstelle prozedurale Schreibweise

  • PHP

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von 3daycliff.

    Objektorientiert anstelle prozedurale Schreibweise

    Guten Morgen.

    In PHP bin ich mittlerweile etwas erfahren und programmiere auch gerne darin.
    Insbesondere in Verbindung mit MySQL-Datenbanken.
    Gelernt und angeeignet habe ich mir bisweilen aber bisher die prozedurale Schreibweise, die objektorientierte nutze ich so gut wie gar nicht oder wenn, dann in Verbindung mit prozeduraler Schreibweise (was natürlich auch nicht super ist).

    Die objektorientierte Schreibweise finde ich tatsächlich aber irgendwie etwas übersichtlicher und würde sie mir daher gerne aneignen. Auch PDO würde ich mir gerne mal näher anschauen, allein aus dem Grund, dass dort Prepared Statements funktionieren (weiß gar nicht, ob das so in PHP OOP auch möglich ist ohne weiteres). Vor PDO fürchte ich mich allerdings noch etwas, zumal ich nicht weiß, ob ich in meiner zukünftigen Ausbildung PDO nutzen werde.

    Nun ja, ich wollte einfach mal eure Meinung hören. Prozedural oder objektorientiert? Meint ihr, es lohnt sich, eher objektorientiert zu programmieren? Auch wenn ich bisher eher prozedural geschrieben habe? Ist der Umstieg sehr schwer? Was haltet ihr von dieser Klasse hier: github.com/rorystandley/MySQLi-CRUD-PHP-OOP

    Danke im Voraus!
    Objektorientierter Stil find ich besser, aber das ist vermutlich Geschmackssache.
    Verwendest du PHP MYSQL oder eh schon MYSQLI ?
    Denn letzteres hat auch PreparedStatements.

    In jedem Fall lässt sich deine Frage nicht so richtig beantworten. Einzig das:
    die objektorientierte nutze ich so gut wie gar nicht oder wenn, dann in Verbindung mit prozeduraler Schreibweise


    Das würde ich nicht machen. Entscheide dich für eine Schreibweise.
    Das ist meine Signatur und sie wird wunderbar sein!
    Verwende natürlich MySQLi ;) Cool, könnte ich mir ja dann mal näher anschauen.

    Und kannst Du etwas zu der verlinkten GitHub Seite sagen?
    Ist die einigermaßen gut? Man könnte die ja dann auch umschreiben zu prepared Statements irgendwann.

    Danke im Voraus!
    Schaut nicht schlecht aus. Bin aber nicht 100% sicher ob ich die verwenden würde. Bin aber auch schon eine Weile raus bei PHP und nicht uptodate. Ich habe sonst einfach MySQLI verwendet.
    Das ist meine Signatur und sie wird wunderbar sein!
    Hi,

    MySqli kann auch Prepared Statements. Aber PDO is natürlich cooler. Und wirklich ned schwer.
    Ob du das in der Ausbildung "brauchst" weiß ich ned, jedenfalls ist es nie falsch, es richtig zu machen ;)

    PDO ist ja vor allem gut, wenn man das Prinzip der objektorientierten Programmierung verinnerlicht hat und die Vorteile gegenüber prozerduralem Spaghetti-Code zu nutzen weiß.

    PHP-Quellcode

    1. <?php
    2. /**
    3. * Datenbank-Verbindung
    4. * Wirst du nachher dann eher in ner separaten Datei haben, config.php oder whatever
    5. */
    6. define('MYSQL_HOST', 'localhost');
    7. define('MYSQL_USER', 'db_user');
    8. define('MYSQL_PASS', 'db_pass');
    9. define('MYSQL_DB', 'db_name');
    10. define('DEBUG', true);
    11. class DB extends PDO{
    12. public function __construct(){
    13. try{
    14. parent::__construct('mysql:host=' . MYSQL_HOST . ';dbname=' . MYSQL_DB . ';charset=utf8', MYSQL_USER, MYSQL_PASS, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
    15. $this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    16. }catch(Exception $e){
    17. if(DEBUG){
    18. echo $e->getMessage() . "<br>";
    19. }
    20. exit("<p>Verbindung zur Datenbank fehlgeschlagen, bitch!</p>");
    21. }
    22. }
    23. }
    24. # BAM, und schon kannst du es verwenden
    25. # Abfrage mit SELECT
    26. $db = new DB();
    27. $Benutzer = $db->query("SELECT * FROM `tbl_user`")->fetchAll();
    28. if(!empty($Benutzer)){
    29. echo "<pre>" . print_r($Benutzer, 1) . "</pre>";
    30. # Oder hübscher:
    31. echo "<table>";
    32. foreach($Benutzer as $row){
    33. echo "<tr>";
    34. echo "<td>" . htmlspecialchars($row['id'], ENT_QUOTES) . "</td>";
    35. echo "<td>" . htmlspecialchars($row['benutzername'], ENT_QUOTES) . "</td>";
    36. echo "</tr>";
    37. }
    38. echo "</table>";
    39. }else{
    40. echo "<p>Leider keine Ergebnisse.</p>";
    41. }
    42. # Sichere Datenbankeintragung mit INSERT (geht ja auch ohne Prepared Statements)
    43. $db->exec("INSERT INTO `tbl_user` SET `benutzername` = " . $db->quote($_POST['benutzername']) . "");
    44. # Hierbei nur beachten dass man die einfachen Anführungszeichen nicht doppelt setzt, weil die durch die quote() Methode schon automatisch mit eingefügt werden
    45. ?>


    Entgegen @Monos Meinung finde ich nicht, dass guter Stil mit Geschmack zu tun hat. Ansonsten hat er aber recht, gewöhne dir einen konsequenten Programmier-Stil an. Kein Mischmasch. Straight OOP ;)


    Link :thumbup:
    Hello World

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Link“ ()

    Hey @Link o/

    Nun, guter Stil ist etwas anderes. Das ist keine Stilfrage sondern eine Frage der Auffassung. OOP ist nicht gleich guter Stil. Es kommt in meinen Augen darauf an, wohin man will bzw. was man machen will. Möchte man in der höhere Abstraktionsebene und im Grunde in erster Linie bei Anwendungsentwicklung im Enduserbereich sein/bleiben, dann ist OOP das Maß aller Dinge. Will man eher Richtung, ich nenn es mal "Hardware nahe" Programmierung, dann ist OOP eher unnütz.

    Da PHP halt von Grund auf dreckig und inkonsequent ist(war? Wobei genau dieses Beispiel bei MYSQLI ja zeigt, dass es nach wie vor Mischmasch ist^^) bezüglich OOP ist das in meinen Augen halt Geschmackssache. ;)
    Daher sollte man das verwenden, was man selber besser lesen und verstehen kann. PDO ist definitv ne feine Sache und wenn man bei Webentwicklung und PHP bleibt sollte man sich IMMER mit den neueren Technologien auseinandersetzen.

    LG
    Das ist meine Signatur und sie wird wunderbar sein!
    Hi @Mono

    Da PHP halt von Grund auf dreckig und inkonsequent ist(war?

    Definitiv "Ist", nach wie vor xD Finde ich persönlich aber garnicht so schlimm ehrlich gesagt. Wen das stört der kann ja gern auf die explizite Typangabe bei Variablendeklarationen zurückgreifen. Macht aber kaum einer. Ich auch nicht.

    OOP meinte ich jetzt natürlich rein auf PHP bezogen, weil wir da ja grad beim Thema sind. Mit maschinennahen Sprachen kenn ich mich sowieso nicht aus (jedoch zumindest soweit als dass ich dir hier recht geben kann dass OOP da unnütz ist).

    Wir können uns auf jeden Fall drauf einigen, dass OOP mehr Vor- als Nachteile hat. Immer dann wenn mehrere Leute an einem Projekt arbeiten und eine große Codebasis existiert, macht OOP Sinn, schon allein wegen Wart- und Erweiterbarkeit.


    Link :thumbup:
    Hello World

    GCAsk schrieb:

    Vor PDO fürchte ich mich allerdings noch etwas, zumal ich nicht weiß, ob ich in meiner zukünftigen Ausbildung PDO nutzen werde.
    ich hab keine Ahnung von PHP, hab nur mal mitgekriegt, dass PDOs dem entsprechen, was in .Net die DBParameter sind.
    Demzufolge ist imo PDO absolutes Muss.
    Weil ansonsten öffnet man die Datenbank für Sql-Injection-Angriffe.

    (Klar altes PHP hat sich glaub fusselig ge-regext, um Sql-Injection abzuwehren, aber das ist sicher nicht mehr Stand der Technik)

    ErfinderDesRades schrieb:

    GCAsk schrieb:

    Vor PDO fürchte ich mich allerdings noch etwas, zumal ich nicht weiß, ob ich in meiner zukünftigen Ausbildung PDO nutzen werde.
    ich hab keine Ahnung von PHP, hab nur mal mitgekriegt, dass PDOs dem entsprechen, was in .Net die DBParameter sind.
    Demzufolge ist imo PDO absolutes Muss.
    Weil ansonsten öffnet man die Datenbank für Sql-Injection-Angriffe.

    (Klar altes PHP hat sich glaub fusselig ge-regext, um Sql-Injection abzuwehren, aber das ist sicher nicht mehr Stand der Technik)

    Oh, was für eine Ehre. Der Erfinder des Rades höchstpersönlich ^^

    Jein. Lässt sich auch mit normalem PHP MySQLi, Betonung hierbei auf i (improved) meistern. DBParameter sind wohl die Prepared Statements und das geht ja auch wohl mit MySQLi, wobei PDO von grundaus mehr DB unterstützt und es wohl wesentlich einfacher ist, diese zu nutzen.

    Und danke für die bisherigen Antworten. Ich denke, ich werde die oben verlinkte GitHub DB-Klasse mal forken und diese selbst schreiben, klein wenig anpassen und mich dadurch der objektorientierten Schreibweise hoffentlich mehr anvertraue ^^
    Ich will auch noch mal meinen Senf dazugeben:

    MySQLi-CRUD-PHP-OOP:
    zum verlinkten Beitrag mal meine persönliche Meinung: schmeiß weg.
    Auch wenn die Klasse recht gut kommentiert sein mag und 22 Sterne hat, ist die Qualität meiner Meinung nach bestenfalls "ausreichend" (inkonsistente Formatierung/Benennung, kein PHPDoc, seltsame Implementierungen [delete-Methode], keine Prepared Statmentes, schlechte Fehlerbehandlung, ...).

    Prozedural vs. OOP:
    Wenn du PHP als Scriptsprache (im Sinne von Batch / Shell-Script) verwendest ist der prozedurale-Stil vollkommen okay. Bei allem anderen (also im Prinzip dass, was online geht) empfehle ich OOP. Allein schon, weil alle(?) aktuellen Frameworks OO programmiert sind. PHP hat zwar immer noch Relikte aus alten Tagen aber in Sachen OO muss es sich wirklich nicht mehr verstecken.

    Apropos Framework: Du benutzt doch eins, oder? ;)
    Selbst bei kleinen Sachen nutze ich inzwischen immer eins. Für kleine Projekte und vielleicht für den Einstieg bieten sich "Micro-Frameworks" an (z.B. Slim, Silex, oder ggf. Lumen). Damit hat man bestimmte Themen wie DI, Routing, Templates, etc. bereits erschlagen.

    MySQLi vs. PDO
    Die Vorteile von PDO überwiegen in 99,9% der Fälle. Selbst wenn du prozedural programmieren solltest, würde ich dennoch PDO nutzen.
    Hier ein auch noch mal ein kurzes MySQLi-vs-PDO-Beispiel: Mysqli While Schleife Problem
    @3daycliff kennst du den vielleicht eine gute Klasse in GitHub mit den von dir erwähnten Sachen?
    Nutze kein Framework, auch wenn es mit Sicherheit vieles erleichtern würde, will ich aber eben vieles selber realisieren, allein schon um mehr zu lernen für die zukünftige Ausbildung ;) PDO nutzen die glaube ich auch nicht.
    Werde mir auf jeden Fall mal das objektorientierte näher bringen.
    Dachte halt, das könnte ich mit dieser gefundenen einfach gehaltenen GitHub Klasse sehr gut lernen.
    Hi,

    ich hab mir die oben verlinkte Github-Klasse jetzt auch mal angeschaut. Was für ein Scheißdreck, echt mal ^^
    Abgesehen davon brauchst dafür keine Drittanbieter-Klassen. Gut, wenn du willst kannst du dir nen Wrapper schreiben der von PDO erbt und von mir aus dort Methoden überschreiben um was auch immer damit anzustellen. Aber ansonsten braucht man überhaupt nix weiter als ne PDO-Instanz und dann läuft das. Einfacher geht's ja kaum. Hier noch ein Beispiel für die geläufigsten Aufgaben:

    PHP-Quellcode

    1. <?php
    2. define('MYSQL_HOST', 'localhost');
    3. define('MYSQL_USER', 'db_user');
    4. define('MYSQL_PASS', 'db_pass');
    5. define('MYSQL_DB', 'db_name');
    6. define('DEBUG', true);
    7. class DB extends PDO{
    8. public function __construct(){
    9. try{
    10. $options = [
    11. PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
    12. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    13. ];
    14. parent::__construct('mysql:host=' . MYSQL_HOST . ';dbname=' . MYSQL_DB . ';charset=utf8', MYSQL_USER, MYSQL_PASS, $options);
    15. $this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    16. }catch(Exception $e){
    17. if(DEBUG){
    18. echo $e->getMessage() . "<br>";
    19. }
    20. exit("<p>Verbindung zur Datenbank fehlgeschlagen, bitch!</p>");
    21. }
    22. }
    23. }
    24. # Instanz erstellen undso ...
    25. $db = new DB();
    26. # INSERT
    27. $Ergebnis = $db->exec("INSERT INTO `test` SET `field` = 'value'");
    28. # UPDATE
    29. $Ergebnis = $db->exec("UPDATE `test` SET `field` = 'value' WHERE `id` = 1");
    30. # WICHTIG:
    31. # PDO::exec() gib die Anzahl von Zeilen die geändert wurden oder false zurück. Um rauszufinden
    32. # ob der Befehl fehlgeschlagen ist, musst du mit !== bzw === false prüfen. Das Statement könnte ja zwar korrekt gewesen sein,
    33. # aber trotzdem keine Daten geändert haben.
    34. if($Ergebnis === false){
    35. echo "Fehler beim Ausführen der Abfrage.";
    36. }else{
    37. echo "Cool, es wurden " . $Ergebnis . " Datensätze geändert.";
    38. }
    39. # SELECT (mehrere Datensätze)
    40. $Ergebnis = $db->query("SELECT * FROM `test`")->fetchAll();
    41. # Ausgeben:
    42. foreach($Ergebnis as $row){
    43. echo $row['id'] . ": " . $row['value'] . "<br>";
    44. }
    45. # Oder bei unbekannten Feldnamen mit key-value
    46. foreach($Ergebnis as $key => $value){
    47. echo $key . ": " . $value . "<br>";
    48. }
    49. # SELECT (ein Datensatz)
    50. $Ergebnis = $db->query("SELECT * FROM `test` WHERE `id` = '1'")->fetch();
    51. # Ausgabe:
    52. echo $Ergebnis['id'];
    53. ?>


    Schluss jetz mit den Ausreden, nimm PDO und fertig :P

    Link :thumbup:
    Hello World

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Link“ ()

    Ok, danke @Link , du hast mich überzeugen können. Werde später mal damit rumexperimentieren :)

    Nur eine Frage:

    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION

    Ich meine gelesen zu haben, dass man das nicht anhaben soll, da, im Falle eines Fehlers, alles ausgegeben wird (inkl. Passwort)? Stimmt das? Wäre ja nicht gut. Zumindest maximal beim Testen gut, aber später dann nicht mehr ^^
    Hi,

    ja da hast du richtig gelesen. Später im Live-Betrieb solltest du das ausschalten. Daher weiter oben auch die DEBUG Variable. Könnte man auch hierfür zur Abfrage verwenden und dementsprechend die Fehlerbehandlung festlegen.

    Link :thumbup:
    Hello World

    Link schrieb:

    Hi,

    ja da hast du richtig gelesen. Später im Live-Betrieb solltest du das ausschalten. Daher weiter oben auch die DEBUG Variable. Könnte man auch hierfür zur Abfrage verwenden und dementsprechend die Fehlerbehandlung festlegen.

    Link :thumbup:


    Danke! Das heißt, ich setze später einfach nur define('DEBUG', false) statt define('DEBUG',true), kann den Code aber sonst so lassen ohne dass er das PW ausspuckt?
    Dann gleich noch eine Frage @Link.
    Bei Insert und Update will ich natürlich SQL-Injektion verhindern. Das geht ja jetzt wunderbar mit PDO.

    Ist das, was ich gerade gefunden habe, so gut?

    PHP-Quellcode

    1. $stmt = $db->prepare("SELECT * FROM table WHERE id=? AND name=?");
    2. $stmt->bindValue(1, $id, PDO::PARAM_INT);
    3. $stmt->bindValue(2, $name, PDO::PARAM_STR);
    4. $stmt->execute();
    5. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);


    bzw.

    PHP-Quellcode

    1. $stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name");
    2. $stmt->bindValue(':id', $id, PDO::PARAM_INT);
    3. $stmt->bindValue(':name', $name, PDO::PARAM_STR);
    4. $stmt->execute();
    5. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);


    danke im Voraus!