Zur Navigation

PHP4 OOP Frage

1 Isildur

Und zwar schreibe ich an einer Webseite in PHP4, da viele ISPs ja noch kein PHP5 haben.
Nun habe ich bisher keine wirkliche Erfahrung mit OOP und ich weiß, dass PHP nicht gut geeignet ist um das zu lernen aber es ist nunmal die Sprache in der ich mein derzeitiges Projekt verfasse.

Meine Frage bezieht sich darauf, dass ich mehrere Klassen habe und die Methoden einer Klasse im Code einer anderen Klasse verwenden möchte.
Also ich habe z.B. eine Datenbankklasse und eine Adminklasse und möchte nun in der Adminklasse eine DB-Aktion durchführen und will dazu eine Methode aus der DB-Klasse nutzen.

Mein erster Ansatz(außerhalb der Klassen):
include db_class.php;
$db = new DB;
include admin_class.php;
$admin = new Admin;

Führt zu
Zitat:
Fatal error: Call to a member function on a non-object in


Wie realisiere ich sowas am geschicktesten?

08.08.2006 12:48

2 Jörg Kruse

Hallo Isildur,

ich bin leider auch nicht der Experte in OOP ;), aber vielleicht bietet sich hier die Verwendung des :: Operators an, siehe Beschreibung auf php.net

08.08.2006 18:52 | geändert: 08.08.2006 18:53

3 Rudy

Könntest Du die Zeile posten, in der der Fehler auftritt?
Verwende beim Einbinden von Klassen besser require anstatt include, da die Klassenskripts zwingend benötigt werden.
Ob das Objekt richtig erzeugt wird, kannst Du z.B. mit var_dump($admin) bzw. var_dump($DB) überprüfen. Stelle error_reporting(E_ALL) ein, damit Du von vornherein alle auftretenden Fehler siehst. Weiters könntest Du die Objekte in der Session registrieren, ähnlich wie ich hier mal geschrieben hatte, und require_once verwenden. Du musst so die Datei nur einmal einbinden.

08.08.2006 19:45

4 Isildur

Hier in der Zeile tritt das Problem auf, was ja auch logisch ist, da ich das Objekt($db) außerhalb der Klasse im prozeduralen Teil erzeuge.
function useradd(){
         $username = $db->safeFormat($_POST['name']);
         ...
         }

Die Idee mit den Sessions hat was, dann könnte ich auch innerhalb von Klasse mit $_SESSION['objekt'] auf die Objekte und ihre Methoden zugreifen oder?

08.08.2006 20:16

5 Rudy

oh, innerhalb einer Funktion geht das so nicht.

Du musst entweder das Objekt per Referenz der Funktion in den Parametern übergeben, linkst das Objekt vorher per Referenz an eine Variable des Objekts (falls es sich bei der Funktion um eine Methode handelt), oder Du deklarierst innerhalb der Funktion die Variable als Referenz auf die globalen Variablen außerhalb der Funktion:

function useradd(){
   global $db;     
   $username = $db->safeFormat($_POST['name']);
        ...
}

Die Idee mit den Sessions hat was, dann könnte ich auch innerhalb von Klasse mit $_SESSION['objekt'] auf die Objekte und ihre Methoden zugreifen oder?
In dem Beispiel vom Link kannst Du dann über die Variable darauf zugreifen, weil sie am Anfang des Skripts an die Session-Variable gebunden wird, z.B.

...
$_SESSION['DB'] = new DB;
$db =& $_SESSION['DB'];....
Wenn Du dann in $db schreibst, schreibst Du zugleich auch die Session-Variable. Sobald die Objekte erzeugt sind, kannst Du das new sparen und es reicht $db=& $_SESSION['DB']. Innerhalb von Funktionen gilt dann aber dasselbe: entweder Du wiederholst das Linken der lokalen (Objekt-)Variable an die Session, greifst direkt auf $_SESSION zu, oder Du deklarierst die lokale Variable als global.

08.08.2006 20:33 | geändert: 08.08.2006 20:55

6 Isildur

Vielen Dank für deine ausführliche Antwort. Dieser Post kommt etwas später, da ich durch den Wiederbeginn der Schule etc. etwas beschäftigt war.

Die Variante mit
global $object;
scheint die einfachste zu sein und funktioniert auch. Die Variante mit den Sessions werde ich in Betracht ziehen sollte ich feststellen, dass ich Attribute über verschiedene Seiten hinweg brauche.

Eine Referenz ist eine Art alias(vgl. Shell) oder Softlink(vgl. Linux) für eine Variabel oder?

linkst das Objekt vorher per Referenz an eine Variable des Objekts
Also:
var $db =& $db
oder wie sähe das in Code verwandelt aus?

11.08.2006 21:42

7 Rudy

Teste mal folgendes:

$a = 3;
$b =& $a;
$b = 10;
echo $a; //10

Du kannst in PHP mit dem =& eine Variable per Referenz zuweisen, in der Art wie Zeiger(Pointer) in anderen Programmiersprachen funktionieren - nur einfacher. Das kannst Du so verstehen, dass eine Variable, die per Referenz zugewiesen wird, auf den Speicherbereich der anderen Variable zeigt. Im Beispiel zeigt durch die Zuweisung $b=& $a die Variable $b auf den Speicherbereich von $a, deshalb ändert sich der Wert von $a, wenn Du danach in $b schreibst. De facto hast Du dann nur einen Speicherbereich, aber 2 Variablenbezeichner dafür. $a und $b sind also verlinkt. Das kannst Du auch mit arrays machen, oder wie vorher erwähnt, mit einer Variable und einem Array-Element aus dem Superglobal $_SESSION ($db =& $_SESSION['db']).

Beispiel mit einer Funktion:

function foo(& $x) {
   $x += 1;
}

function bar($x) {
  $x += 1;
}

$a = 1;
bar($a);
echo $a; // 1
foo(& $a);
echo $a;  // 2

Die Variable $a wird per Referenz an die Funktion foo() übergeben, deshalb hat das Schreiben in $x Auswirkungen auf die übergebene Variable $a, zu ihr wird 1 dazugezählt. An bar() wird die Variable per Wert übergeben, $x ist da eine lokale Variable innerhalb der Funktion.

anderes Beispiel (OOP):

<?php


class a {
  var $v1 = 1;
  var $v2 = 2;
  var $v3 = 3;
}

class b {
  var $a;

  var $v4 = 4;
  var $v5 = 5;
  var $v6 = 6;
  function b(& $a) {
    $this->a =& $a;
  }
}


class c {
  var $a;
  var $b;

  var $v7 = 7;
  var $v8 = 8;
  var $v9 = 9;

  function c(& $a, & $b) {
    $this->a =& $a;
    $this->b =& $b;
  }
}

$a = new a;
$_SESSION['a'] =& $a;
$b = new b(& $a);
$_SESSION['b'] =& $b;
$c = new c(& $a, & $b);
$_SESSION['c'] =& $c;

?>
<pre>
<?php print_r($_SESSION); ?>
</pre>
Es sieht nun so aus, also ob 7 Objekte und 21 v-Variablen in der Session wären, in Wirklichkeit sind es genauso viele wie Du erzeugt hast: 3 Objekte mit insgesamt 9 v-Variablen. Der Rest sind Referenzen, die im Speicher fast nichts belegen. Innerhalb der Objekte kannst Du direkt auf die anderen verlinkten zugreifen, z.B. in $b über $this->a auf das vorher erzeugte und im Konstruktor von $b per Referenz übergebene Objekt $a.

12.08.2006 00:18

8 lukasc (Gast)

hello,
da du vielleicht in zukunft noch mehr objekte mit db fähigkeiten ausstatten willst, solltest du dir vielleicht das ganze mit 'patten' angehen.
1.) Schreib eine DB.php mit allen nötigen CRUD methoden (Create,Read,Update,Delete) und Methoden wie: Get($id), GetList(...),
Delete($id), DeleteList(...).

2.) Schreib ein DBinterface.php mit funktionsrümpfen und signaturen aber nicht die Query sachen, sondern nur für Get(), GetList(), Delete(), DeleteList(), Save(), SaveNew().

3.) Schreib eine Klasse für dein Objekt:
class bla extends DB implements DBinterface{
function Save($user){
parent::Save($user);
}
}

so kannst du flexibler arbeiten und erweitern ohne viel aufwand.

29.11.2007 23:58

Beitrag schreiben (als Gast)

Die Antwort wird nach der Überprüfung durch einen Moderator freigeschaltet.





[BBCode-Hilfe]