PHP Klassen-Entwicklung

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • PHP Klassen-Entwicklung

    Hallo, ich habe ein Problem was Klassenentwicklung angeht. Ich habe schon mehrer Klassen geschrieben und vieles versucht OOP auf zu bauen, das klappt eigentlich auch gnaz super, jedoch bin ich nicht zufireden. PHP ist sehr flexibel was den Syntax angelangt. ZB.: ist man nicht verpflichtet Variablen innerhalb einer Klasse zu deklarieren. Die Initialisierung einer Variable kann mitten im Code passieren.

    Beispiel:

    Quellcode

    1. class foo1 {
    2. function bar1 ($test1) {
    3. $result = mysql_query("SELECT id FROM table LIMIT 1");
    4. list ($id) = mysql_fetch_row($result);
    5. return $id;
    6. }
    7. }


    Diese Klasse wäre korrekt und Syntax-mäßig richtig FAZIT PHP gibt keine Warung oder keine Fehlermeldung.

    Beispiel 2:

    Quellcode

    1. class foo2 {
    2. public $test2;
    3. public $id;
    4. public $result;
    5. public function __construct ($test2) {
    6. $this->$test2 = $test2;
    7. $this->result = mysql_query("SELECT id FROM table LIMIT 1");
    8. list ($this->id) = mysql_fetch_row($this->result);
    9. return $this->id;
    10. }
    11. }
    Alles anzeigen


    Auch diese Klasse wäre korrekt.

    So mehr man liest um so mehr input bekommt man irgendwann kennt man "zig" methoden ein Problem zu lösen, oder wie man es macht. Was jeder im endefekkt verwendet ist egal, da beides richtig ist...

    Meine Frage ist jetzt, was ist DIE richtige Lösung, ich versuche mich strikt an Codingstandards zu halten (http://pear.php.net/manual/en/standards.php)

    Jeoch steht da nicht drinne wie man eine Klasse baut :). Jedes buch was man liest jedes HowTo macht es anders. Mittlerweile habe ich so viele verschiedene Klassen das ich sage, alle sind "schxxx".

    Warum ich jetzt darauf komme? Weil ich gerade vor einem Probelm stehe.

    Ich habe eine Datenbank, geraete und vorlagen. (Geraete gehören IMMER zu vorlagen)

    So um das ganze Programm duch zu ziehen (SELECT INSERT UPDATE) woll ich eine Klasse schreiben. Diesmal aber so, das sie jeden Standard enspricht.

    SKIZZE:

    Klasse:

    GERAETE
    -> SN:
    -> Name:
    -> Hersteller:


    Objekte:

    Vorlagen
    ->SN: 123
    -> Name: Test
    -> Hersteller: ich

    EinzelGeraet:
    ->SN: (von Vorlage)+456
    -> Name: von Vorlage
    -> Hersteller: von Vorlage


    Theoretisch ist die Klasse kein Problem. Aber der sinn an OOP ist es auch das man bestimmte Sache wiederverwenden kann, das verkompliziert sehr viel.

    Hat wer eine Ahnung wie man zu dem Bsp. eine Saubere Klasse (die irgend einem Standard entspricht) baut?

    Ich habe meine Post soweit ausgeweitet, weil ich der Meinung bin das OOP das einer der komplexisten Themen überhaubt ist, was Programmierung betrifft.
    Erst wenn der letzte FTP Server kostenpflichtig, der letzte GNU-Sourcecode verkauft, der letzte Algorithmus patentiert, der letzte Netzknoten kommerzialisiert, die letzte Newsgroup moderiert wird, werdet Ihr merken, dass man mit Geld allein nicht programmieren kann.
  • Re: PHP Klassen-Entwicklung

    "JFoX" schrieb:

    PHP gibt keine Warung oder keine Fehlermeldung.

    Prinzipiell ist es sinnvoll das Error-Reporting einzuschalten:

    Quellcode

    1. error_reporting(E_ALL);


    Deine beiden Beispiele sind sicher korrekt und lauffähig, aber nicht gleich!
    1) Im ersten Beispiel verwendest du normale Variablen. Im zweiten Beispiel allerdings Attribute!
    2) Im ersten Beispiel rufst du deine Aktion wie folgt auf:

    Quellcode

    1. $foo = new foo1;
    2. $foo->bar1($input);

    Für das zweite Beispiel würde folgendes genügen:

    Quellcode

    1. $foo = new foo2($input);

    Um auch im ersten Beispiel einen Konstruktor nachzustellen müßtest du die Methode bar1 in foo1 umbenennen. Dann sähe der Aufruf ähnlich wie in Beispiel 2 aus:

    Quellcode

    1. $foo = new foo1($input);

    3) Das erste Beispiel ist vermutlich für PHP4, das zweite verwendet Neuerungen von PHP5. __construct z.B. steht meines Wissens nach in PHP4 noch nicht zur Verfügung.
  • Jop ist richtig __construct wird als erstes ausgeführt, genau wie eine Methode den den Klassen name trägt.

    Quellcode

    1. class foo1 {
    2. var $result;
    3. var $test1;
    4. var $id;
    5. public function bar1 ($test1) {
    6. $result = mysql_query("SELECT id FROM table LIMIT 1");
    7. list ($id) = mysql_fetch_row($result);
    8. return $id;
    9. }
    10. }
    Alles anzeigen


    Diese Klasse ist auch richitg und lauffähig. Sprich PHP ist so variabel und dynamisch, das es für mich irgendwie keinen Standard gibt. Wenn man mal andere Sprachen anschaut ist mehr oder weniger alles klar definiert. Wenn es verschiende möglichkeiten gibt, aber die immer das selbe machen... Ich weiß nicht so richtig was ich nun verwenden soll...
    Erst wenn der letzte FTP Server kostenpflichtig, der letzte GNU-Sourcecode verkauft, der letzte Algorithmus patentiert, der letzte Netzknoten kommerzialisiert, die letzte Newsgroup moderiert wird, werdet Ihr merken, dass man mit Geld allein nicht programmieren kann.
  • So ich habe mal eine Klasse entwickelt, die Das mit den Geräten regelt (erstma nur ein Result). Das ziel sollte sein, das Quasi einer die Klasse entwicklt und einer die Abfrage baut, und unabhänig von einander laufen... So muss niemand von dem anderen kenntniss haben was den Code betrifft, lediglich sind nur die Schnittstellen bekannt.

    geraete.inc.php

    Quellcode

    1. <?php
    2. class geraete {
    3. var $vorlagenResult;
    4. var $count;
    5. var $array;
    6. var $returnArray;
    7. public function vorlagenResult() {
    8. $this->array = array ('vorlagenID', 'geraeteName', 'geraeteType', 'hersteller', 'seriennummer');
    9. $this->vorlagenResult = "SELECT vorlagenID, geraeteName, geraeteType, hersteller, serienNummer FROM vorlagen";
    10. $this->count = count($this->array)-1;
    11. $this->returnArray = array($this->vorlagenResult, $this->count);
    12. return $this->returnArray;
    13. }
    14. }
    15. ?>
    Alles anzeigen


    test.php

    Quellcode

    1. <?php
    2. require_once 'DB.php';
    3. $dsn = array(
    4. 'phptype' => 'mysql',
    5. 'username' => 'xxx',
    6. 'password' => 'xxx',
    7. 'hostspec' => 'localhost',
    8. 'database' => 'xxx'
    9. );
    10. $options = array(
    11. 'debug' => 2,
    12. 'portability' => DB_PORTABILITY_ALL
    13. );
    14. $db =& DB::connect($dsn, $options);
    15. $error =& PEAR::isError($db);
    16. include ("template/class/geraete.inc.php");
    17. $Geraete = new geraete();
    18. $newArray = $Geraete->vorlagenResult();
    19. $vorlagenResult =& $db->query($newArray[0]);
    20. while ($row =& $vorlagenResult->fetchRow()) {
    21. for ($i = 0; $i <= $newArray[1]; $i++) {
    22. echo $row[$i];
    23. }
    24. echo "<br />";
    25. }
    26. ?>
    Alles anzeigen


    So meine Frage, ist das eine Entwicklungsweise die man Modular verwenden kann?

    Also Bsp.: pro Modul 1 oder mehere Klassen in diesem von mir vorgeführten Stiel. Da die Schnittstellen bekannt sind, kann man Sie ohne Probleme ansprechen.

    Für aktive Vorschläge wäre ich sehr dankbar! (Wie man den Code besser/professioneller machen kann).

    so long

    FoX
    Erst wenn der letzte FTP Server kostenpflichtig, der letzte GNU-Sourcecode verkauft, der letzte Algorithmus patentiert, der letzte Netzknoten kommerzialisiert, die letzte Newsgroup moderiert wird, werdet Ihr merken, dass man mit Geld allein nicht programmieren kann.
  • Hm leider kann man kein Pauschalrezept von OOP angeben. Da du aber um Tipps gebeten hast: Normalerweise macht man Attribute von Klassen private und greift dann mittels einer get, bzw- set-Methode darauf zu.

    Objektorientiert zu Programmieren ist sicher nicht einfach, und vorallem der Einstieg fällt einem schwer. Aber PHP ist vielleicht auch die falsche Sprache um das ganze zu erlernen.

    Es ist zwar so, dass bei der objektorientierung die Wiederverwendbarkeit als super Feature angepriesen wird, aber du wirst mit der Zeit feststellen, dass die meisten Probleme einfach zu speziell sind, um Klassen wiederzuverwenden. Die Wieverwendbarkeit findest du meistens ins Datenstrukturen wieder. Da bauen Stacks auf Listen auf, oder Queues auf Listen.

    Bei php, kommt es meistens wirklcih darauf an, was man machen will, es gibt sicherlich Skripte, bei der macht Objektorientierung mehr Sinn, als bei anderen, so zumindest meine bisherige Erfahrung. Meistens mixt man beides...

    Falls du noch was zum schmökern suchst: galileocomputing.de/openbook/oo/

    Um mal etwas zu deiner Klasse zu sagen:

    returnArray wird ja sowieso nur zur Rückagabe verwendet, von daher würde ich keine, von daher macht es wenig Sinn das als Attribut der Klasse zu sehen.
    Das mit den get-/set-Methoden habe ich ja schon angesprochen.
    Des Weiteren würde ich vielleicht auch eher die Datenbankabfrage innerhalb der Klasse ansiedeln, da das ja sowieso der Sinn ist.

    Du könntest das ganze natürlich soweit treiben, dass du das ganze soweit abstrahierst, dass du eine abstrakte Klasse bastelst mit einee finale Methode, die die Datenbankabfrage kapselt - die jeweiligen Geräte erben von diesr Klasse und benutzen soz. die Methode um die Datenbankabfrage durchzuführen.

    Ich hoff das alles ist halbwegs verständlich :roll: :?
  • Danke das hat mir schon weiter geholfen, genau das ist ja eines der Probleme die ich habe die wiederverwendbarkeit :-), Ich mache eigentlich schon eine ganze Weile OOP, nur musst ich heute expliziert geststellen, das ich wenn es gut kommt nur Code-Schnipsel wiederverwenden kann, meine Klassen muss ich fast alle neu schreiben, also bin ich dran mir einen Standard zusammen zu bastelen, wo man mehr wieder verwenden kann und auch andere damit arbeiten können. Das das thema nicht gerade das leichteste ist, ist mir klar :)

    Im endefekt soll mein Beispiel bezwecken das einer auf Datenbank Informationen zu greifen kann, ohne den Inhalt der Klasse so wie die Datenbankstruktur bis ins kleinste zu kennen.

    Ich denke mal das die Modulare Entwicklung vorallem wenn man mehrere Programmierer hat nicht einfach ist.

    Aber was ich nicht verstehe ist die Aussage von dir

    get, bzw- set-Methode, muss zugeben das ist mir noch nicht unter gekommen.

    Werde meine Klasse aber mal noch besser machen, mit vererbung etc. und einer so genannten Final methode...

    so long

    FoX
    Erst wenn der letzte FTP Server kostenpflichtig, der letzte GNU-Sourcecode verkauft, der letzte Algorithmus patentiert, der letzte Netzknoten kommerzialisiert, die letzte Newsgroup moderiert wird, werdet Ihr merken, dass man mit Geld allein nicht programmieren kann.
  • "JFoX" schrieb:

    Aber was ich nicht verstehe ist die Aussage von dir get, bzw- set-Methode, muss zugeben das ist mir noch nicht unter gekommen.

    Eines der zentralen Prinzipien der OOP ist die Kapselung der Daten. Aus diesem Grund erstellen Hardcore-OOPler für (fast) jedes Attribut eine get- und eine set-Methode um von außen darauf zugreifen zu können. Das Attribut wird dabei als private deklariert.

    Das macht vor allem dann Sinn, wenn die Daten der Attribute noch in irgendeiner Weise bearbeitet werden müssen bevor sie an einen Außenstehenden übergeben werden.

    Ich gehöre aber ehrlich gesagt zu denen die sich den Aufwand diese zusätzlichen Methoden zu schreiben spart. Mir ist die Übersichtlichkeit wichtiger. Es gibt in der Praxis wenige Fälle wo eine Anpassung der Werte beim Zugriff anderer Objekte nötig ist. In diesen speziellen Fällen kann man durchaus auf Getter & Setter zurückgreifen.
  • Achso PPP (Public Private Protected)..., verstehe, habe das nur falsch aufgefasst. Werde mein Beispiel mal überarbeiten und versuchen es auf "Hardcore" Basis zu bauen. Was ich eingestehen muss das Theoretische KnowHow von OOP ist easy die Praxis an sich auch (ne Klasse bauen ist nicht schwer). Aber was da komplizierte ist, ist das Modulare Konzept, alles so hinzubiegen und zu Planen das es wirklich:

    1. Sinn ergibt
    2. Sinnvolle schnittstellen nach ausßen
    3. Sicherheit (PPP)
    4. Wiederverwendbarkeit (wenn möglich in mehreren Projekten) <-- ist das häftigste

    Ich persönlich beschäftige mich schon lange mit OOP aber genau die 4 Punkte habe ich bis jetzt nur sehr sehr selten verwirklicht. Es ist ein schickes Theme jedoch nicht ohne, nun verstehe ich auch warum fiele Literaturen OOP nur anschneiden, weil das einfach den kompletten rahmen sprengen würde. Das schwierigste ist nicht die Klassen zu schreiben, sondern die durchdachte Planung...

    Um zurück zum thema zu kommen, ich versuche mal mein Beispiel sinngemäß zu überarbeiten :)
    Erst wenn der letzte FTP Server kostenpflichtig, der letzte GNU-Sourcecode verkauft, der letzte Algorithmus patentiert, der letzte Netzknoten kommerzialisiert, die letzte Newsgroup moderiert wird, werdet Ihr merken, dass man mit Geld allein nicht programmieren kann.
  • Hallo Gemeinde,

    Ich habe meine Planung mal komplett neu gemacht:

    Es soll eine Klasse geben wo die Grund-Funktionen gebaut werden, dann werden diese Grund-Funktionen an die Kindklasse vererbt und dort bis zum fertigen "Return" weiter bearbeitet. So hat man eine Saubere Struktur, man kann mit mehrern leuten arbeiten, da diese die Schnittstellen flexibel nutzen könne.

    Anbei, die Klassen und deren benutzung (abgespeckte Form am Beispiel von Select, Update etc kann sich dann jeder selber dazu malen xD).

    class.inc.php

    Quellcode

    1. <?php
    2. class Geraet {
    3. protected $statement;
    4. protected $result;
    5. protected function selectVorlage()
    6. {
    7. global $db;
    8. switch (TRUE) {
    9. case empty($this->statement[1]):
    10. $this->result =& $db->query("SELECT ".$this->statement[0]." FROM vorlagen");
    11. break;
    12. case !empty($this->statement[1]):
    13. $this->result =& $db->query("SELECT ".$this->statement[0]." FROM vorlagen WHERE ".$this->statement[1]."");
    14. break;
    15. }
    16. }
    17. }
    18. class Vorlage extends Geraet {
    19. public function select($statement)
    20. {
    21. $this->statement = $statement;
    22. parent::selectVorlage();
    23. echo "Vorlagen wurden ausgelesen<br />";
    24. return $this->result;
    25. }
    26. }
    27. ?>
    Alles anzeigen


    index.php

    Quellcode

    1. <?php
    2. require_once 'DB.php';
    3. $dsn = array(
    4. 'phptype' => 'mysql',
    5. 'username' => 'xxx',
    6. 'password' => 'xxx',
    7. 'hostspec' => 'localhost',
    8. 'database' => 'xxx'
    9. );
    10. $options = array(
    11. 'debug' => 2,
    12. 'portability' => DB_PORTABILITY_ALL
    13. );
    14. $db =& DB::connect($dsn, $options);
    15. $error =& PEAR::isError($db);
    16. include ("class.inc.php");
    17. ?>
    18. <?php
    19. $sql = array(0 => "vorlagenID, geraeteName", 1 => "vorlagenID='3'");
    20. $obj = new Vorlage();
    21. $query = $obj->select($sql);
    22. while ($row =& $query->fetchRow()) {
    23. echo $row[0] ."=>". $row[1] ."<br />";
    24. }
    25. ?>
    Alles anzeigen


    Ich würde es super toll finden wenn sich ein paar finden und nochmals Ihre Meinung und Vorschläge preisgeben.

    Ich werde noch einiges verändern (ist die beta Planung xD)

    PS: Muss eingestehen den Versuch Klassen auf ein "Hardcore" Level zu bauen ist verdammt hart. Aber wenn man mal den Code von der Optik betrachtet sieht der echt geil aus xD *sich mal an den E*** krault*
    so long

    JFoX
    Erst wenn der letzte FTP Server kostenpflichtig, der letzte GNU-Sourcecode verkauft, der letzte Algorithmus patentiert, der letzte Netzknoten kommerzialisiert, die letzte Newsgroup moderiert wird, werdet Ihr merken, dass man mit Geld allein nicht programmieren kann.
  • Was als Vorschlag zu verstehen ist:
    * alle includes und requires an den Kopf der Datei.
    * einheitliche Verwendung als Sprachkonstrukt oder als Funktion. Ich finde es als Sprachkonstrukt schöner.

    Was gar nicht geht:
    * Ausgaben innerhalb von Funktionen ;)
    * du nutzt zwar den PEAR Klasse, aber SQL Injection ist immer noch möglich. Variablen musst du als Parameter übergeben#

    Falsch: $db->query("SELECT ".$this->statement[0]." FROM vorlagen");
    Richtig: $db->query("SELECT ? FROM vorlagen; ", array($this->statement[0]));