OOP -

stewue

Grünschnabel
Hallo zusammen

bin gerade etwas hilflos wie ich mein Problem sauber lösen soll und hoffe jemand von euch kann mich aufklären wie ich es umsetzen soll. Ich weiss auch nicht genau wie ich mein Problem nennen soll, deshalb des komische Titel.

Zu meinem Problem...
Ich habe folgende Klassen:
db.class.php
PHP:
class DB
{
   public function __construct()
   {
     [...]
   }

   public function query ($sql)
   {
     [...]
   }
}

lib.class.php
PHP:
class Lib
{
   public function time_converter ($time)
   {
     [...]
 
     return (converted_time)
   }
}

login.class.php
PHP:
class Login
{
   public function __constructor ()
   {
     [...]
   }

   public function check ()
   {
     [...]
     (Zugriff auf Klasse DB)
     (Zugriff auf Methode time_converter)
     [...]
 
     return (true or false)
   }
}

weitere.class.php
PHP:
class Weitere
{
   public function __constructor ()
   {
     [...]
   }

   public function name ()
   {
     [...]
     (Zugriff auf Klasse DB)
     (Zugriff auf Methode time_converter)
   }
}

index.php
PHP:
include (alle xy.class.php Dateien importieren)

$lib = new Lib;
$db = new DB();

$login = new Login();
$weitere = new Weitere();

Also ich habe zwei Klassen Lib und DB die ich jeweils bei allen anderen Klassen (im Beispiel Login und Weitere) brauche. Wie stelle ich es am besten an? Meine Ansatz war bei der login.class.php Datei:

PHP:
class Login
{
   private $db;
   private $lib;

   public function __constructor ($db)
   {
     [...]
     $this->db = $GLOBALS['db'];
     $this->lib = $GLOBALS['lib'];
   }

   public function check ()
   {
     [...]
     $this->db->query("SQL");
     [...]
     return (true or false)
   }
}

Ich bin mir sicher es gibt viel elegantere Methoden um so etwas zu lösen :D

Würde mich freuen wenn mir jemand auf die Sprünge helfen würden. (Falls in den kleinen Codeschnipsel oben sonst noch gravierende Fehler seht nur sagen, habe mich noch nicht so viel mit OOP befasst)

Lg stewue

PS: Ups den Titel wollte ich gar nicht so wählen... Irgendein Moderator wird sicher so höfflich sein und den Thread sinnvoll umbenennen
 
Also erstmal, GLOBALS ist das Gegenteil von OOP (Datenkapselung). $db im Konstruktor zu übergeben ist die bessere Idee. Das heißt übrigens Dependency Injection.
Es gibt auch Tools, die sowas entsprechend halb-automatisch oder automatisch machen können. Die heißen dann DIC (Dependency Injection Container), bekanntes Beispiel ist Pimple.
Um das ganze include()-Gedöns loszuwerden benutzt man heute Autoloader (Bedenke: Große Softwareprojekte bestehen aus mehreren tausend PHP-Dateien). Im PHP Bereich gibt es hier den (neuen) PSR-4 Standard: http://www.php-fig.org/psr/psr-4/
Eine Implementierung dieses Standards findest du sowohl auf deren Seite alsauch im Composer (https://getcomposer.org/). Den wollte ich einfach nochmal erwähnen am Ende des textes, weil man ihn eifnach kennen sollte :D
 
Ok vielen Dank für deine Tipps. Ich werde mir mal das ganze anschauen. Benützt du bei kleineren Projekten ebenfalls DIC und autoloader oder machst du es dort einfach selbst "von Hand"?
 
Du kannst es aber auch mit einem Singleton probieren, zumindest was die Datenbank-Klasse betrifft. Bei Deiner Klasse "Lib" müsste man eben wissen, wozu diese dient. Wenn es sich dabei nur um eine Ansammlung von Helferfunktionen ist, dann müsste man überlegen, ob diese nicht anders gespeichert werden sollten.
 
Also entweder würde ich einen Namensraum dafür definieren, in welchem ich dann einfach Funktionen definieren, oder aber, was ich meistens mache, ich würde dafür Sorge tragen, dass man die Klasse, in welcher die Helferfunktionen definiert sind, nicht instantiierbar ist. Deshalb müssten dann auch alle Methoden statisch sein:
PHP:
class Library {
  private function __construct() {}
  private function __clone() {}
  private function __sleep() {}
  private function __wakeup() {}

  public static function convert_time( $time ) {
    /* do something */
    return $modified_time;
  }
}

Library::convert_time( "2014-08-12 20:11" );
 
Huhu,

ich würde dir ebenfalls, wie hier schon getan, raten zum Autoloader zurück zu greifen. Namespaces erleichtern dir die Übersichtlichkeit enorm.

Gibt auch hin und wieder ein Zusammenspiel zwischen Autoloader & Namespaces.

Sonst ist schon fast alles gesagt ;)
 
ComFreek, Du hast natürlich Recht, dass es blöd ist, wenn man mehrere Datenbankverbindungen gleichzeitig nutzt. Alternativ könnte man dann natürlich auch ein Multiton verwenden. Aber grundsätzlich bin ich mit Dir d'accord was den Punkt Dependency Injection betrifft.
 
Zurück