PHP Frage, mehrere Klassen und ihr Umgang

Domi83

Rear Admiral
Registriert
Feb. 2010
Beiträge
5.332
Hallo Leute, ich habe da mal eine kleine Frage zum Umgang mit den Klassen (class) in PHP5 :)

Es geht um folgendes, ein Kumpel und ich haben eine Seite wo mehrere Orte, deren Bundesländer und Länder aufgelistet sind. Somit gibt es folgende Klassen
PHP:
<?php
 class land {
  public function list() {   }
  public function ausgabe() {   }
 }
 class bundesland {
  public function list() {   }
  public function ausgabe() {   }
 }
 class ort {
  public function list() {   }
  public function ausgabe() {   }
 }
?>
Ich hoffe mal, die Namen der Klassen und deren Aufgaben ist verständlich. Die Methoden machen nichts weiter als mir eine Liste der Orte etc. erstellen, und die Ausgabe gibt mir zu einem genaueren Ort die Details aus.

Jetzt kommt der Punkt wo ich mal wissen wollte, ob man das besser gestalten kann... kann man diese Klassen irgendwie sinnvoll verbinden / kombinieren?

Sprich, rufe ich eine Liste der Länder ab, muss ich nur die Länder ansprechen.. spreche ich ein Land an, bekomme ich die Details "function ausgabe"!!

Beim Bundesland bin ich mir noch nicht 100% sicher, aber wenn ich sagen ich möchte Details "function ausgabe" zu Bayern haben, möchte ich auch wissen zu welchem Land das gehört :)

Spreche ich nun einen Ort an (München), möchte ich wissen in welchem Bundesland das liegt und in welchem Land... ich hoffe man versteht bis hierhin was ich meine :)

Muss ich jetzt wenn ich einen Ort öffne, alle klasse einzeln initialisieren mit folgendem Beispiel,
PHP:
<?php
 $land = new land();
 $bundesland = new bundesland();
 $ort = new ort();
?>
oder macht Ihr das über einen anderen Weg..?

Es geht um folgendes, wenn ich jetzt einen Ort öffne, rufe ich ja nicht nur diese drei Klassen ab, sondern ich habe noch drei weitere Klassen mit relevanten Informationen die ich benötige für z.B. einen Ort oder ein Bundesland und hoffe Ihr könnt mir da mal einen Ansatz geben.

Oder macht Ihr das so, indem Ihr ganz simple jede Klasse einladet und gut ist..?!
Kurz vorweg, ich habe für die Orte eine "orte.php" Datei, für Bundesländer eine "bundesland.php" und für die Länder eine "land.php", sowie eine index.php als auch eine impressum.php :)

Da ich noch nie mit Templates gearbeitet habe und mich schon mit dem einen oder anderen Framework befasst habe, habe ich es wieder sein lassen... :)

Problematik an der Seite ist auch, die Seite hat teils Datenbank basierte Inhalte (Land, Orte, Bundesland) und auch Inhalte die statisch generiert sind und nicht aus der Datenbank gelesen werden. Dazu kommt dann noch die Problematik, dass ein komplett Umbau auf Datenbank nicht so einfach realisiert werden kann, da es SEO Technisch wieder eine andere Geschichte ist.. es müssen URLs angepasst werden etc., und da wird dann wieder ein weiterer im Bunde knartschig wegen schon indexierten URLs bei google etc.

Darum wollte ich nur mal fragen wie Ihr das handhabt und ob es für meine aktuelle Situation einen Ansatz gibt..?! :)

Klingt komisch, vielleicht auch komplex und verwirrend.. aber ich hoffe man kann mir bis hierhin folgen.

Gruß, Domi
 
Für URLs gibts ja Modrewrite. Wobei für ne Datenbank nicht unbedingt die URL verändert werden muss?

Funktioniert denn schon was oder wo hängts? wenn du nur die Ausgabe willst wirst du halt u.u. von 3 Leuten 3 verschiedene Lösungen bekommen. Oder gehts darum wie man Klassen erstellt und nutzt?
 
Es gibt drei Wege, wie das zu lösen wäre. Ich versuch das mal einfach und verständlich zu erklären.

Wobei es bei Dir - auf den ersten Blick - sinniger wäre das ganze einfach per Funktionen zu lösen, anstatt den Weg über Klassen zu gehen, die sowieso nix anderes machen, als Funktionen zu bündeln.

1.) MVC ... Model, View, Controller
Das wäre der komplizierte und aufwändigste, aber am Ende der übersichtlichste Weg. Die meisten Frameworks basieren auf dem MVC Prinzip. Du trennst damit die Logik (Controller), die Daten-Quelle (Model) und die Ausgabe (View).

2.) Klassen per "extends" Verbinden
im Grunde verbindet man die Klassen in einer Art "Kreis".
Man muss sich dabei aber genau überlegen mit welcher Klasse man anfängt, sinnvoll wäre zb eine Klasse, die die ganzen Ausgaben-Funktionen beinhaltet oder eine, die globale Funktionen, welche in allen drei anderen Klassen verwendet werden, beinhaltet. Die Klassen "Bundesland", "Ort" und "Land" würden diese Globale Klasse um spezifische Funktionen erweitern.

Code:
<?php
class globale_funktionen() {
...
}

class bundesland extends globale_funktionen {
....
}
?>

Sobald du die Klasse "bundesland" instanzierst, stehen dir automatisch auch die funktionen der "globale_funktionen" Klasse zur Verfügung, Du musst die "globale_funktionen" Klasse also nicht selbst nochmal in einer Variable aufrufen.

3.) Eine globale Klasse, die die anderen Klassen aufruft.

Du kannst die 3 Klassen definieren und am Ende eine Klasse bauen, die die Funktionen der anderen Klassen verwendet und diese instanziert, wenn diese benötigt wird.

Code:
class bundesland {
function ausgabe() {
...
}
}

class globale_klasse {
function __construct() {
$this->bundesland = new bundesland();
}

function bundesland() {
$this->bundesland->ausgabe();
}
}

$global = new globale_klasse;
$global->bundesland();
 
Zuletzt bearbeitet:
Ich bin nicht sicher, ob ich das Problem richtig verstanden habe. Die Antworten von Znrl und hedsht sprechen zumindest dafür, dass sie es beide anders verstanden haben als ich. Wenn ich aber mal danach gehe, wie ich es verstanden habe, wäre meine Lösung folgende:

Die Klasse ort kriegt einen Member vom Typ bundesland, der angibt, welchem Bundesland der jeweilige Ort angehört, die Klasse bundesland wiederum einen Member vom Typ land, der angibt, welchem Land das Bundesland angehört. Etwa so:

PHP:
class land
{
    var $name;
    
    function land($name)
    {
        $this->name = name;
    }
}

class bundesland
{
    var $name;
    var $land;
    
    function bundesland($name, $land)
    {
        $this->name = $name;
        $this->land = $land;
    }
}

class ort
{
    var $name;
    var $bundesland;
    
    function ort($name, $bundesland)
    {
        $this->name = $name;
        $this->bundesland = $bundesland;
    }
}
Das Instanziieren ginge dann so:
PHP:
var $deutschland = new land("Deutschland");
var $bayern = new bundesland("Bayern", $deutschland);
var $muenchen = new bundesland("München", $bayuern);
Die ausgabe()-Funktionen sähen dann z.B. so aus:
PHP:
// in Klasse land
function ausgabe()
{
    return $this->name;   // z.B. "Deutschland"
}
// in Klasse bundesland
function ausgabe()
{
    return $this->name.", ".$this->land->ausgabe();  // z.B. "Bayern, Deutschland"
}
// in Klasse ort
function ausgabe()
{
    return $this->name.", ".$this->bundesland->ausgabe();  // z.B. "München, Bayern, Deutschland"
}
Zum Anzeigen der Ausgabe dann
PHP:
echo $muenchen->ausgabe();
Soll jede Klasse noch eine Methode list() haben, die alle Instanzen der jeweiligen Klasse ausgibt, so müsste diese Methode statisch sein und den Inhalt eines statischen Arrays ausgeben, in das jeder Konstruktoraufruf den Namen (Landesname, Bundeslandesname, Ortsname) hineinschreibt.
PHP:
land::list();  // "Deutschland", "Frankreich", "Niederlande", "Schweiz", ...
bundesland::list();  // "Bayern", "Hessen", "Saarland", ...
ort::list(); // "München", Nürnberg", "Rosenheim", ...
 
@Sculletto klassennamen schreibt man groß, list() ist schon eine php funktion, der konstruktor in php sieht so aus __construct() und var sollte man in php5 nicht emhr benutzen.

würde ne abstrakte klasse schreiben in der ich die sachen die von allen klassen verwendet werden reinschreibe. Die Klassen würde ich dann auch gleichzeitig als container klassen verwenden.

PHP:
abstract class Place {
protected $id = 0;
protected $name;
protected $children = array();


abstract function display();
abstract function load();
abstract function loadChildren();

//mappt ein assoziatives array aus einem mysql result auf die klassen eigenschaften.. 
//eigenschaften muessen protected sein
public function map($data) {
$properties = get_object_vars($this);
        foreach ($data as $key => $value) {
            if (key_exists($key, $properties)) {
                $this->$key = $value;
            }
        }
}
}

im $children array sind dann objekte von typ der unterliegenden klasse.. zum beispiel bei land bundesland..

die klassen würden erstmal so aussehen
PHP:
class Land extends Place {

public function load() {
//datenbankabfrage ein Land

$this->map($assoc_array);

//die bundeslaender laden
$this->loadChildren();
}

public function loadChildren() {
//datenbank abfrage alle Laender des Landes
$bundesland = new Bundesland();
//bundeslaender werden in das children array gespeichert
$this->children[] = $bundesland->map($assoc_result);
}

public function display() {
echo '<strong>' . $this->name . '</strong><hr />';
echo '<ul>';
foreach ($this->children as $child) {
$child->display();
}
echo '</ul>';
}
}

bei der display methode werden auch die display methoden aller kinder ausgeführt.. bei dem land sind die kinder halt die bundesländer die als kinder wiederum städte haben und deren display methoden ausführen.. hoffe das ist einigermaßen verständlich
 
klomann83 schrieb:
@Sculletto klassennamen schreibt man groß,
du hast dich im Adressaten geirrt. Der TE war es, der mit kleinen Klassennamen daherkam, ich habe das nur von ihm übernommen.

klomann83 schrieb:
list() ist schon eine php funktion,
die hier?

http://php.net/manual/de/function.list.php

Die hat aber offenbar nicht die vom TE gewünschten Eigenschaften.

klomann83 schrieb:
der konstruktor in php sieht so aus __construct()
ich habe mich an

http://www.html-world.de/program/php_7.php

gehalten. Ist das falsch, was die da schreiben?

klomann83 schrieb:
und var sollte man in php5 nicht emhr benutzen.
man kann die var-Einträge auch weglassen, die Zuweisung im Konstruktor übernimmt dann die Rolle der Deklaration. Als jemand, der aus dem C++/Java-Lager kommt, finde ich es aber einfach übersichtlicher, Felder außerhalb des Konstruktors zu deklarieren.
 
Moin, also mein Plan war.. mit wenig Befehlen, viel bewegen zu können. Vorausgesetzt, mein Ansatz oder Grundgedanke ist nicht verkehrt.

In meiner Ausgabe Datei für die Stadt sieht es in den ersten Zeilen aktuell wie folgt aus..,
PHP:
<?php
 require_once("./inc/config.php");
 $laender = new laender($cfg['sql']);
 $bundeslaender = new bundeslaender($cfg['sql']);
 $staedte = new staedte($cfg['sql']);

 $name['land'] = $laender->ausgabe($_GET['land']);
 $name['bundesland'] = $bundeslaender->ausgabe($_GET['bundesland']);
 $name['stadt'] = $staedte->ausgabe($_GET['stadt']);
?>
Die Variable $cfg['sql'] habe ich in meiner Config Datei deklariert, darin befinden sich die Zugangsdaten zu der MySQL Datenbank.. und ich wollte halt mal wissen, ob man das noch irgendwie optimieren kann. Das ist nur ein Teil aus sieben Zeilen, aber vielleicht lässt es sich ja optimieren :)

Falls es von Interesse ist, meine config.php die ich ganz am Anfang einlese, hat folgenden Inhalt...
PHP:
<?php
 $cfg = array();

 // Globale Pfad Angaben
 $cfg['http'] = 'http://'.$_SERVER['SERVER_NAME'];
 $cfg['root'] = $_SERVER['DOCUMENT_ROOT'];

 // Globale SQL Daten
 $cfg['sql']['host'] = "";
 $cfg['sql']['user'] = "";
 $cfg['sql']['pass'] = "";
 $cfg['sql']['daba'] = "";

 // Include Pfad und Autoloader
 ini_set("include_path", get_include_path().PATH_SEPARATOR.$cfg['root'].'/inc');
 function myAutoload($class) {
   require_once('class.'.strtolower($class).'.php');
 }
 spl_autoload_register('myAutoload');
?>
Im Prinzip ist es eine Performance und übersichts- Geschichte und man kann mir ein wenig folgen.. mehr fällt mir jetzt gerade nicht ein... ansonsten folgt ein Edit von mir :)

Gruß, Domi
 

Ähnliche Themen

F
Antworten
20
Aufrufe
5.753
Zurück
Oben