Original von exe
Ich will mal das PHP-Manual zitieren:
Tatsächlich werden static Methodenaufrufe zum Kompilierungszeitpunkt aufgelöst. Bei der Nutzung des expliziten Klassennamens ist die Methode bereits gänzlich identifiziert und es kommen keine Vererbungsregeln zur Anwendung.
Selbst wenn du B::statisch() aufrufst wird das intern in A::statisch() übersetzt. Im Grunde gibt es den Kontext der aufrufenden Klasse gar nicht, da die statische Funktion ohne Umwege aufgerufen wird.
Es würde auch nicht viel Sinn ergeben das anders zu machen. Da statische Methoden zu ihrer Klasse gehören werden (oder sollten sie zumindest) nicht mit vererbt. Das bedeutet auch, dass wenn du B::statisch() aufrufst in Wirklichkeit A::statisch() aufgerufen wird da statisch() durch die Vererbung nicht in die Klasse B wandert. Das sie über die vererbte Klasse sichtbar werden, also mit B::statisch() aufgerufen werden können, ist dann mehr eine Nettigkeit der Sprache
Ich würde diese "Nettigkeit der Sprache" schon als Anwendung der Vererbungsregeln bezeichnen Aber natürlich hast du Recht: Die Methode wandert nicht von Klasse A nach B, sondern der Methoden-Aufruf wandert - bildlich gesprochen - von Klasse B nach A und die Methode wird im Kontext von Klasse A ausgeführt.
Du könntest natürlich noch in A::statisch() mit der Funktion debug_backtrace() den aktuellen Aufruf zurückverfolgen und damit die aufrufende Klasse herausbekommen. Aber ob das so eine schöne Lösung ist?
Das funktioniert leider auch nicht
Original von Agmemon
Daher halt die Frage nach einem konkreten Beispiel/Einsatzzweck, um Dir vielleicht helfen zu können, einen geeigneteren Ansatz zu finden.
Ich versuche eine Art Object-Relational-Mapping mit PDO als Grundlage zu realisieren. PDO bietet ja schon die Möglichkeit, Ergebniszeilen direkt als Objekte zu beziehen. Allerdings muss man die Logik (select, update,...) dieser Objekte selber implementieren und dafür wollte ich eine Basisklasse
DBObject schreiben.
Davon abgeleitete Klassen
Object1, Object2 unterscheiden sich z.B. bei einem SELECT vom Grundsatz her nur durch den SQL-String, die Logik bleibt die gleiche. Darum wollte ich die Methode
select() so in der Basisklasse implementieren, dass diese den SQL-String aus der abgeleiteten Klasse ließt:
abstract class DBObject {
static function select()
{
$stmt = self::$db_handler->prepare($aufrufende_klasse::SQL_SELECT);
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_CLASS, $aufrufende_klasse);
$objects = $stmt->fetchAll();
$stmt = null;
return $objects;
}
}
class Object1 extends DBObject {
const SQL_SELECT = 'SELECT * FROM objects1';
}
class Object2 extends DBObject {
const SQL_SELECT = 'SELECT * FROM objects2';
}
Soweit zumindest die Theorie...