Klasse 3 soll Klasse 2 UND 1 erben

Hallo,

@Marvin Schmidt: sehr schön, so stell ich mir das vor :)

Gibt es denn dazu ein Tutorials oder haste nen Link wo du das her hast....weil würde mir das gerne mal genauer ansehn und druchlesen.
Wenn du dich mit Design Patterns allgemein beschäftigen willst, würde ich dir Head First Design Patterns wärmstens empfehlen. Die Beispiele darin sind zwar in Java implementiert, aber das sehr gut vermittelte Wissen kann meist problemlos in andere Sprachen übertragen werden. Bei PHP-spezifischer Literatur kann dir Marvin sicher mehr sagen.

Was ist denn das Problem daran, wenn jede Klasse seine eigene Mysql Instanz hat?
Es ist umständlich, weil man für jedes Objekt eine eigene MySQL-Instanz erzeugen muss. Dabei wiederholt sich gezwungenermaßen ein Codeblock immer wieder quer über die Klassendeklarationen hinweg. Will man an der Instantiierung der MySQL-Klasse projektglobal eine Kleinigkeit ändern, so muss man das für jede Klasse extra tun. Das wirkt sich natürlich negativ auf die Wartbarkeit aus.

Dann wäre es zu Analysezwecken vielleicht auch mal ganz interessant, sämtliche SQL-Abfragen eines Seitenaufrufs mitzuloggen und eine entsprechende Statistik am Seitenende auszugeben. Mit einer Singleton-Instanz der MySQL-Klasse kein größeres Problem – hat man aber viele Instanzen über die Applikation hinweg verteilt, muss man hierzu erst mal feststellen, welche Objekte gerade im Speicher liegen, welche davon eine eigene MySQL-Instanz besitzen und schlussendlich von diesen die Informationen abfragen und sinnvoll zusammenführen. Wenn man Pech hat, sind aber zum Zeitpunkt der Auswertung einige MySQL-Instanzen schon wieder verschwunden und man verliert damit Informationen.

Das allein wären jetzt schon zwei Gründe, die massiv gegen deine Art des Vorgehens sprechen. Natürlich funktioniert deine Lösung auch, das stelle ich nicht in Frage. Aber man verschenkt damit eben ein großes Maß an Flexibilität.

Grüße,
Matthias
 
Ah ok danke :) du hast mich überzeugt....naja dann werde ich wohl nochmal bissle was umschreiben müssen.....zum Glück war ich mit dem CMS noch net so weit....und zum Glück ist OOP ja so wunderbar schön leicht veränderbar :P

Also danke sag ich denn ma :)

MFG Niels
 
So also habe mal bissle was schon geändert und in Singelton geschrieben.

Nun stellt sich mir ein Prob in den Weg.

Und zwar bekomme ich bei meiner counter.php-Klasse folgenden Fehler:

Fatal error: Call to a member function

Das heißt ja eigentlich, dass versucht wurde auf eine Funktion der Klasse zuzugreifen, dies aber nicht geht, da die Klasse nicht aufgerufen wurde.

So aber das Kann nicht sein.

In meiner index.php habe ich z.b. nach diese Reihenfolge:
PHP:
<?php
require_once("module/registry.php");
include("module/mysql.php");
include("module/parser.php");
include("module/counter.php");

// ......

#########################################################
############# Klassenobjecte laden ######################
#########################################################
$Connection = new mysql($dbhost, $dbuser, $dbpw, $dbname);
$tpl = new tpl();
#########################################################
############# Objecte instanzieren ######################
#########################################################
$registry = Registry::getInstance();
$registry->register('mysql', $Connection);
$registry->register('showtpl', $tpl);

//.....
// So und hier die gesamte counter.php-Klasse

   class counter extends mysql
   {
        var $ip;
		var $zeiger;
		var $datum;
		var $db;
		
		   //##################################################################################//
		   // 1. Initalisiert Instanzen                                                        //
		   // 2. Klassen einbinden                                                             //
		   //##################################################################################//
		   function init_classes()
		   {
		   $registry = Registry::getInstance();
		   $this->db = $registry->get('mysql');
		   }
		   
		   //##################################################################################//
		   // 1. Initaliesert benötigte Infos                                                  //
		   //##################################################################################//
		   function init()
		   {
		       $this->ip = $_SERVER['REMOTE_ADDR'];
			   $this->datum = date("d.m.Y");
		   }
		   //##################################################################################//
		   // 1. Überprüft, ob IP schon in entsprechender Datenbank besteht(an jetzigem Datum) //
		   //     -> Wenn JA, zeiger=1                                                         //
		   //     -> Wenn NEIN, zeiger =0                                                      //
		   //##################################################################################//
		   function ip_pruefen($table)
		   {
			   $ipselect = $this->db->query("SELECT * FROM `$table` WHERE ip='".$this->ip."' AND date='".$this->datum."'");
			   $iprows = mysql_num_rows($ipselect);
			      if($iprows > 0)
				  {
				     $this->zeiger = TRUE;
				  }
				  if($iprows = 0)
				  {
				     $this->zeiger = FALSE;
				  }
			  return $this->zeiger;
		   }
		   
		   //###########################################################################//
		   // 1. Schreibt eine Ip in eine Datenbank $table                              //
		   //###########################################################################//
		   function ip_schreiben($table)
		   {
			   $ip_write_task = $this->db->query("INSERT INTO $table (ip, date) VALUES('".$this->ip."', '".$this->datum."')");
			   if (!$ip_write_task)
			     {
				 return FALSE;
				 }
				 else
				 {
				 return TRUE;
				 }
		   }
   }
?>


Mache ich mit der Reihenfolge vielleicht was falsch?

Würde mich sehr doll über Hilfe freuen :)

MFG Niels
 
Ah siehste das habe ich vergessen beim Umbauen wegzumachen :)

Ändert aber nichts am Fehler :

Fatal error: Call to a member function query() on a non-object in K:\Webserver\xampp\htdocs\cmsoop\module\counter.php on line 34

Also der Fehler wird halt dadurch verursacht, dass ich nun in der Klasse Counter auf die Instanz mysql mit $this->db->query zugreife...

MFG Niels
 
Hallo,

wird counter::init_classes irgendwo aufgerufen? Das würde sich eigentlich im Konstruktor ganz gut machen. Hast du die Registry-Klasse aus diesem Thema 1:1 übernommen? Dann wäre es eigentlich nicht verkehrt, wenn du auch mit den OOP-Konstrukten von PHP5 arbeiten würdest.

Grüße,
Matthias
 
OOP Konstrukten von PHP5?! Also ich lerne jez seit 2 wochen so nach der schule ein bissle OOP deswegen bin ich da noch net so wirklicj drinne.....ich möchte na klaro alles auf php5 Basis machen :)

Und Nein das wird nirgends aufgerufen :)

MFG Niels

EDIT: Counter Init Classes wird jez aufgerufen^^.....sonst kann es ja gar net gehen :)

Aber bekomme immer noch den Fehler.......

Fatal error: Call to a member function init_classes

MFG Niels
 
Zuletzt bearbeitet:
Fatal error: Call to a member function query() on a non-object in K:\Webserver\xampp\htdocs\cmsoop\module\counter.php on line 34

Also der Fehler wird halt dadurch verursacht, dass ich nun in der Klasse Counter auf die Instanz mysql mit $this->db->query zugreife...

Hi,
wenn du das tust, muss gewährleistet sein, dass die Klassenvariable db auch auf die Instanz der MySQL-Klasse zeigt. Deswegen solltest du das - wie schon von Matthias gesagt - im Konstruktor erledigen, da die Objekte ja auf jeden Fall benötigt werden.

PHP:
class Counter {
    private $ip_table;
    private $data_table;
    private $db;
        
    function __construct($data_table, $ip_table) {
        $this->data_table = $data_table;
        $this->ip_table = $ip_table;

        $registry = Registry::getInstance();
        $this->db = $registry->get('mysql');
    }
    
    [...]
}

Die init-Methode könntest du dir einsparen, indem du für zeit- und datumsspezifische Spalten die dafür vorgesehenen Typen DATE, DATETIME und TIMESTAMP verwendest und dann mit den MySQL-eigenen Datums- und Zeitfunktionen arbeitest.

Beispiel (IP-Sperre für die Zählung von Besuchern):
PHP:
function updateIPTable() {
    $sql = "DELETE FROM " .
                $this->ip_table . "
            WHERE
                UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(count_time) > 300";

    $res =& $this->db->query($sql);
    if (PEAR::isError($res)) {
        die($res->getMessage());
    }

    return $this->db->affectedRows($res);
}

Wie man sieht, kann man so alle IP-Einträge, die älter als 5 Minuten sind, ganz einfach aus der Tabelle löschen und muss nicht mit PHP das Datum zurückrechnen.
Außerdem erleichert es einem die Arbeit sehr, wenn es darum geht Besucherstatistiken eines bestimmten Zeitraumes zu ermitteln.
PHP:
/* aktueller Tag */
... WHERE count_date = CURDATE()
/* voheriger Tag */
... WHERE count_date = DATE_SUB(CURDATE(), INTERVAL 1 DAY)
/* gesamte Woche */
... WHERE WEEK(count_date) = WEEK(CURDATE())

Bezüglich PHP Patterns kann ich www.patternsforphp.com empfehlen.

Gruß
Marvin
 
So nochma ne Frage zum Thema OOP solange es den Thread noch gibt^^

Also ich habe jetzt die Abfrage um die Kategorien einer Gallerie auszulesen gekürzt, und zwar in der Klasse der gallerie lese ich die Kategorien so aus:

PHP:
<?php
//#################################################################//
		 // 1. Liest die Kategorien aus und gibt diese zurück               //
		 //#################################################################//
		 function gal_kats()
		 {
		   $kats = $this->db->query("SELECT * FROM `gal_kats` ORDER BY `erstellt` DESC");
		   return $this->db->fetch_array($kats);
		 }
?>

So und in der Gallery.php verarbeite ich diese dann so:
PHP:
<?php
// Galleriekategorien auslesen
while ($kat_data = $gallery->gal_kats())
{
$gal_content .= $index->showtpl("gallery/gal_kats", array("gal_name" => $kat_data['name'],
                                                          "gal_fotos" => $kat_data['anzahl'],
														  "gal_datum" => $kat_data['erstellt'],
														  "gal_link" => "?gallery.php&id=".$kat_data['cid']));
}
?>

So das Prob ist als ich noch alles umständlich ohne gallery-klasse ausgelsen habe,
da ging es aber nun bekomme ich eine Art Dauerschleife, denn mein Browser läd und läd und läd aber nix passiert... :(

Habt ihr ne Idee....wird vielleicht bei der Funktion zum Auslesen mit return nicht alles zurückgegeben?

MFG Niels
 
Zurück