Aufruf der privaten Methode von einer Klasse geerbt
Möchte ich umsetzen einer hook-system in mein einfaches ORM in PHP:
class Record {
public function save() {
if (method_exists($this,"before_save")) {
$this->before_save();
}
//...Storing record etc.
}
}
class Payment extends Record {
private function before_save() {
$this->payed_at = time();
}
}
$payment = new Payment();
$payment->save();
Dies führt zu einem Fatalen Fehler:
Fatal error: Call to private method Zahlung::before_save() aus
Rahmen 'Datensatz' in
Sinn macht.
Konnte ich den Bereich ändern, um der öffentlichkeit, aber das scheint ugly: niemand, aber die Bezahlung hat nichts zu tun mit before_save()
. Es ist am besten, Links, private, IMHO.
Wie kann ich Datensatz-Aufruf einer privaten Methode auf die Klasse erbt von der Platte?
- kann mir jemand sagen, warum diese Frage wurde eine negative Stimmen ???
- Danke @hakra. Ich verpasste ein Teil in der Dokumentation "deklarierten Membern geschützt werden können, der Zugriff ist nur innerhalb der Klasse selbst und von geerbten und den Eltern Klassen". Und immer davon ausgegangen, geschützt zu werden für die Kinder und sich selbst nur. Anscheinend ist es Bereiche zu den Eltern zu. Sorgfalt, um diese eine Antwort, die ich akzeptieren kann?
- Könnten Sie bitte ein wenig höflicher? Wenn Sie wirklich sind, die genervt von Menschen, nicht etwas zu wissen, sind Sie wahrscheinlich an der falschen Stelle auf eine Q&Einem forum.
- Ich fügte hinzu, ein anser. Was ich meine ist, dass neben dem technischen problem der Wahl der falschen Sichtbarkeit Bezeichner
extends
bedeutet "ist-ein" aber die Bezahlung ist nicht ein Datensatz, oder ist es? Ein Nein, ich bin nicht genervt von deiner Frage und es ist absolut fair, um nicht alles wissen. Ich wollte nur legen Sie es Weg von der schieren technischen problem. - Die Zahlung ist ein (Datenbank) - Eintrag, @hakra. Das ist das, was ich soll und wie es umgesetzt wird.
- Dann ist es in Ordnung, bis es wieder etwas anderes in Ihrer Anwendung. Dann müssten Sie führen etwas anderes, z.B. ein record-Objekt. Aber dann würden die Namen wurden bereits getroffen. Also wahrscheinlich einige bessere Namen sagen, wie
PaymentRecord
. Nur ein Hauch. - wenn Sie richtig sind, das ist weit über der Frage, die ich gestellt hier. Und eigentlich Recht fraglich; aber für Ihr ease-of-mind: ich vereinfachte den Namen zu klären, mein problem, meine tatsächlichen Anwendung verwendet namespaces und anderen Krempel.
- auch andere sind jetzt schon darauf, Sie aus, dass das Problem komplexer ist. Aber du hast Recht, das war nicht das, was Sie gefragt haben, so dass ich nur Links, die in einem Kommentar (der, wie sich herausstellte, Sie zu stören, also nochmal sorry dafür, bitte nicht beleidigt fühlen).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Fügen Sie eine dummy -
before_save
Funktion, um IhreRecord
Klasse, seine zugänglich zu geschützt. Nun, alle Klassen, Erben vonRecord
wird diese Funktion, wenn Sie nicht überschreiben, es wird sich NICHTS tun. Wenn Sie ihn überschreiben, es kann die Umsetzung der gewünschten Funktionalität.before_save()
.Record
eine abstrakte Klasse. Aber sonst ja, Datensatz müsste eine stub, die alle benötigten Methoden möglich, so kann man sehen, an welchem Punkt Sie definiert wurden usw.SplObjectStorage
für Hinweise, wie man leicht bauen der Registrierung Teil.Überprüfen Sie die Fehlermeldung
Dies bedeutet, dass Sie versuchen, eine Funktion aufzurufen, definiert in
Payment
während Sie innerhalbRecord
. KlasseRecord
keinenbefore_save
Methode, weil es ist weiter bis in der Vererbungskette als dort, wo die Funktion definiert ist.In anderen Worten, da die Eltern-Kind-Beziehung ist
Record (is parent of) Payment
,Payment
hat Zugang zuRecords
Funktionen (Kraft der Erben von den Eltern), aber nicht Umgekehrt (für die Eltern nicht "Erben" untergeordnete Klasse von Funktionen). Sie können Ihre Funktion geschützt, die es geben wird, den Zugang nach oben und unten die Vererbungskette, aber möchten Sie vielleicht zu überdenken, Architektur und entscheiden Sie, ob Sie wollen es so.. Idealerweise sollten Sie haben die Funktion definiert inRecord
habe und es überschriebenPayment
Auch (und ich könnte falsch sein mit diesem), aber die überprüfung ausdrücklich für
method_exists
ist in der Regel nicht erforderlich, es sei denn, Sie erstellen ein wirklich dynamisches system, in dem Laufzeit-Klassen können überlappt werden und/oder erzeugt werden. Wenn Sie die Definition einer Klasse-basierten system von Grund auf und Sie wissen, wie Sie Nähen die einzelnen Stücke, in der Regel würden Sie nicht brauchen, um zu überprüfen, während der Laufzeit, wennmethod_exists
...nur so ein Gedanke..ändern, den Umfang zu geschützt:
http://php.net/manual/en/language.oop5.visibility.php
Sichtbarkeit und die Regeln der Vererbung in PHP:
Record
sollte/kann die Funktionbefore_save
!class test{
}
$testobj = new test;
echo $testobj->caller();
Erhalten Sie 5 als Ausgang.
Durch diese Weise können Sie den Zugriff auf die private Funktion einer Klasse.