Czy istnieje sposób zdefiniowania klasy, aby rozszerzyć inną klasę tylko wtedy, gdy ta druga klasa jest dostępna?Rozszerzenie klasy dynamicznej
Odpowiedz
ma nic, co pozwoli Ci zrobić
class Foo extendsIfExist Bar
Ale można monkeypatch Foo z runkit „s
Przykład z PHP Manual:
class myParent {
function parentFunc() {
echo "Parent Function Output\n";
}
}
class myChild {
}
runkit_class_adopt('myChild','myParent');
myChild::parentFunc();
Rozszerzenie runkit jest dostępne z PECL. Jednakże, jego użycie jest zniechęcane, ponieważ jego użycie jest prawie zawsze wskaźnikiem wadliwego projektu.
Zastrzeżenie: Jestem zakładając, tylko coś jak w poniższym przykładzie jest powód, dlaczego pytasz pytanie. Zignoruj tę część odpowiedzi, jeśli nie jest.
Jeśli w środowisku wykonawczym wymagana jest pewna funkcjonalność warunkowo, należy rozważyć agregację klasy, z której należy rozszerzyć, np. spróbować czegoś wzdłuż linii
interface Loggable
{
public function log($message);
}
class Foo implements Loggable
{
protected $logger;
public function setLogger($logger)
{
$this->logger = $logger;
}
public function log($message)
{
if($this->logger !== NULL) {
return $this->logger->log($message);
}
}
}
W przykładzie powyżej, funkcjonalność chcemy to log()
. Zamiast więc wykrywać, czy klasa rejestratorów jest dostępna, a następnie monkeypatchować tę funkcjonalność do naszej klasy Foo, informujemy, że wymaga tej funkcji poprzez dodanie interfejsu Loggable. Jeśli istnieje klasa Logger, tworzymy ją i agregujemy w Foo. Jeśli nie istnieje, możemy nadal wywoływać logi, ale nic nie zrobimy. To znacznie więcej niż solid.
Rozwiązanie zapewniające "rozszerzenie jeśli istnieje" bez użycia eval: http://stackoverflow.com/a/9898049/441739 –
Masz na myśli to?
<?php
class Foo{
}
if(class_exists('Foo')){
class SubFoo extends Foo{
}
}
if(class_exists('Bar')){
class SubBar extends Bar{
}
}
$a = new SubFoo; // OK
$b = new SubBar; // Fatal error: Class 'SubBar' not found
Niezły, ale lepszy od podejścia 'eval()'! –
Jest to odpowiedź i przedłużenie odpowiedzi Pekki.
pierwsze w Pekka, myślę, że eval jest całkowicie błędne, co jest nie tak z
if(class_exists("bar"))
{
class foo extends bar
{
}
}
to również moja odpowiedź również.
napotkał podobny wymóg niedawno, gdzie klasa w mojej bibliotece potrzebne do dynamicznie rozciągają się od ClassB (jeśli istnieje), w przeciwnym razie rozciągać się od klasy A.
Moje rozwiązanie (mój kod jest przestrzeni nazw, samo pojęcie odnosi się niezależnie) :
namespace someNamespace;
spl_autoload_register(function($class) {
if (strcasecmp($class, 'someNamespace\SomeFakeClass') === 0) {
if (class_exists('ClassB',false)) {
class_alias('ClassB', 'someNamespace\SomeFakeClass');
} else {
class_alias('ClassA', 'someNamespace\SomeFakeClass');
}
}
}, true, true);
/** @noinspection PhpUndefinedClassInspection */
/** @noinspection PhpUndefinedNamespaceInspection */
class MyClass extends \someNamespace\SomeFakeClass {
# ... real logic here ...
}
Stosując powyższy roztwór, klasa MojaKlasa dynamicznie dziedziczyć ClassB jeśli występuje, poza dziedziczy ono od ClassA.
To rozwiązanie pozwala uniknąć używania eval, co jest dużym plusem dla mnie.
Mam nadzieję, że to pomoże.
EDIT: Tylko uwaga, notacja @noinspection istnieje tak że IDE takich jak PHPStorm nie będzie raportować błędy dotyczące nieistniejącej klasy.
Zrobiłem to w ten sposób.
Błąd, jeśli pliki są zewnętrzne. Błąd krytyczny: deklaracje klasy nie mogą być zagnieżdżone. –
- 1. Wywołanie dynamicznej klasy
- 2. klasy dynamicznej metody dodawania do klasy
- 3. Rozszerzenie klasy a kategoria klasy
- 4. Inwokacja metody dynamicznej klasy w Dart
- 5. Czy można usunąć właściwości z klasy dynamicznej?
- 6. Haml: jak ustawić wartość klasy dynamicznej?
- 7. Co to jest rozszerzenie klasy?
- 8. java, rozszerzenie klasy z konstruktorem klasy głównej ma parametr
- 9. Python klasa dekorator powoduje rozszerzenie klasy rekurencji
- 10. Rozszerzenie klasy żądania ekspresowego w Przepływie
- 11. Tworzenie instancji klasy dynamicznej programowo w PHP ze zmiennymi argumentami?
- 12. Tworzenie nazwy klasy dynamicznej przy użyciu @while pętlę
- 13. Dołączanie klasy dynamicznej do widoku mającego klasę statyczną
- 14. Czy dyrektywa AngularJS może pobrać nazwę klasy z dynamicznej zawartości?
- 15. Jaki jest układ pamięci dynamicznej macierzy X dynamicznej tablicy X?
- 16. Ścieżki pomocników ścieżki dynamicznej
- 17. Mechanizm dynamicznej manipulatora agregatora
- 18. jak zmusić klas schematu opracowano rozszerzenie konkretnej klasy poza schemat
- 19. W scala czy możliwe jest rozszerzenie klasy wymagającej parametrów?
- 20. Kotlin: Jak rozszerzenie klasy enum z funkcją przedłużacza
- 21. Java rodzajowych - rozszerzenie klasy rodzajowe z funkcją rodzajowy
- 22. IIS7 kompresji dynamicznej zawartości z niestandardowej obsługi
- 23. Jak ustawić attr_accessor dla zmiennej instancji dynamicznej?
- 24. tworzenie dynamicznej tablicy ciągów C++
- 25. ładowanie biblioteki dynamicznej z elisp
- 26. Tworzenie dynamicznej listy przekątnej widoku
- 27. Wartość początkowa dynamicznej tablicy C++
- 28. Dezaktywacja dynamicznej daty AngularUI Datepicker
- 29. "Obiekt" nie zawiera definicji dynamicznej
- 30. Tworzenie dynamicznej roli w ansible
To nie ma większego sensu z architektonicznego punktu widzenia - musisz rozszerzyć klasę, albo nie. Co próbujesz osiągnąć? (Może być łatwiejszy sposób.) –
Nie powinno być powodu do dynamicznego tworzenia klas, powinieneś mieć solidny system, który nigdy nie powinien wymagać czegoś takiego. chyba że, jak stwierdzono powyżej, może istnieć prostsze podejście do celu. – RobertPitt
RobertPitt ma 100% poprawności. Ponownie zastanowiłbym się nad problemem, ponieważ wygląda na to, że istnieje większy błąd w strukturze, który należy najpierw zbadać. –