2012-02-21 13 views
7

Mam ciąg znaków zawierający nazwę klasy i chcę uzyskać stałą i wywołać metodę (statyczną) z tej klasy.Stała klasa dostępu i metoda statyczna z ciągu

<?php 
$myclass = 'b'; // My class I wish to use 

$x = new x($myclass); // Create an instance of x 
$response = $x->runMethod(); // Call "runMethod" which calls my desired method 

// This is my class I use to access the other classes 
class x { 
    private $myclass = NULL; 

    public function __construct ($myclass) { 
     if(is_string($myclass)) { 
      // Assuming the input has a valid class name 
      $this->myclass = $myclass; 
     } 
    } 

    public function runMethod() { 
     // Get the selected constant here 
     print $this->myclass::CONSTANT; 

     // Call the selected method here 
     return $this->myclass::method('input string'); 
    } 
} 


// These are my class(es) I want to access 
abstract class a { 
    const CONSTANT = 'this is my constant'; 

    public static function method ($str) { 
     return $str; 
    } 
} 

class b extends a { 
    const CONSTANT = 'this is my new constant'; 

    public static function method ($str) { 
     return 'this is my method, and this is my string: '. $str; 
    } 
} 
?> 

Jak oczekiwano (bardziej lub mniej), stosując $variable::CONSTANT lub $variable::method(); nie działa.

Zanim zapytam, co próbowałem; Próbowałem tak wielu rzeczy, o których w zasadzie zapomniałem.

Jakie jest najlepsze podejście, aby to zrobić? Z góry dziękuję.

Odpowiedz

22

Aby uzyskać dostęp do stałej, należy constant():

constant($this->myClass.'::CONSTANT'); 

Należy pamiętać: Jeśli pracujesz z przestrzeniami nazw, trzeba specjalnie dodać nazw do łańcucha nawet jeśli zadzwonisz constant() z tej samej przestrzeni nazw !

na wezwanie, będziesz musiał użyć call_user_func():

call_user_func(array($this->myclass, 'method')); 

Jednakże: to nie jest bardzo wydajny, więc warto przyjrzeć się swojej konstrukcji obiektu hierarchii. Może istnieć lepszy sposób na uzyskanie pożądanego rezultatu, użycie dziedziczenia itp.

+0

A co do metody? –

+0

Zaktualizowano odpowiedź! – Rijk

+0

Pow! Szybka i łatwa odpowiedź, która działała jak czar. Dzięki! –

1

Można to osiągnąć, ustawiając zmienną tymczasową. Nie jest to najbardziej elegancki sposób, ale działa.

public function runMethod() { 
    // Temporary variable 
    $myclass = $this->myclass; 
    // Get the selected constant here 
    print $myclass::CONSTANT; 

    // Call the selected method here 
    return $myclass::method('input string'); 
} 

Myślę, że to zrobić z dwuznaczności ::, przynajmniej to, co jest komunikat o błędzie sugerując (PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM)

+1

Po prostu chciałem napisać dokładnie tę samą odpowiedź.Myślę, że byłaby to najbardziej "rozsądna" wersja. Chociaż całkowite przepisanie z dziedziczeniem byłoby znacznie lepsze. – apfelbox

2

Korzystanie call_user_func zadzwonić metoda statyczna:

call_user_func(array($className, $methodName), $parameter); 
1

Klasy zdefiniowane jako abstrakcyjne nie mogą być tworzone instancjami, a każda klasa zawierająca przynajmniej jedną abstrakcyjną metodę musi być również abstrakcyjna. Metody zdefiniowane jako abstrakcyjne po prostu deklarują podpis metody - nie mogą zdefiniować implementacji.

Podczas dziedziczenia z klasy abstrakcyjnej wszystkie metody oznaczone jako abstrakcyjne w deklaracji klasy rodzica muszą być zdefiniowane przez dziecko; dodatkowo, metody te muszą być zdefiniowane z taką samą (lub mniej ograniczoną) widocznością. Na przykład, jeśli metoda abstrakcyjna jest zdefiniowana jako chroniona, implementację funkcji należy zdefiniować jako chronioną lub publiczną, ale nie prywatną. Ponadto sygnatury metod muszą być zgodne, tzn. Wskazówki typów i liczba wymaganych argumentów muszą być takie same. Dotyczy to również konstruktorów od PHP 5.4. Przed 5.4 sygnatury konstruktorów mogą się różnić. Patrz http://php.net/manual/en/language.oop5.abstract.php

0

w php 7 można użyć tego kodu

echo 'my class name'::$b; 
+1

Podczas gdy ta odpowiedź może rozwiązać problem PO, zaleca się podanie jasnego wyjaśnienia, w jaki sposób osiąga to rozwiązanie. Umieszczanie odpowiedzi tylko na podstawie kodu może być nieprzydatne dla OP i przyszłych użytkowników. Proszę opracuj. –

+1

rozwiązanie jest jasne! ponieważ tytuł pytania to ** Stała klasy dostępu i metoda statyczna z ciągu ** –

Powiązane problemy