Klassennamen aus einer abgeleiteten statischen Klasse abfragen=?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Klassennamen aus einer abgeleiteten statischen Klasse abfragen=?

    Ich werde aus den Kommentaren zu get_class() auf php.net nicht klar. Das Problem wird bestätigt, aber keine Lösung gezeigt.

    Ich habe eine allgemeine Plugin-Klasse.
    Von dieser werden Plugin-Klassen abgeleitet.

    Diese Plugin-Klassen werden statisch aufgerufen, um sich in ein allgemeines Register zu hängen. Also so:

    PHP-Code:
    // die allgemeine Klasse

    class allgemeinePluginKlasse
     
    {
       var 
    $pfad null;
       var 
    $name null;
       
       function 
    init() 
       ...

     } 

    // ein abgeleitetes Plugin

    class meinPlugin extends allgemeinePluginKlasse
     
    {
      
       
    // Diese Methode soll statisch aufgerufen werden:

       
    function init()
        {
          echo 
    "Hallo. Ich bin das Plugin namens ".__CLASS__."!";
       
        }

     }

    // statischer Aufruf
    meinPlugin::init();

    // Ergebnis unter PHP 4

    HalloIch bin das Plugin namens allgemeinePluginKlasse
    die Konstante __CLASS__ gibt mir immer nur die Urklasse zurück.
    Auf get_class() kann ich nicht zurückgreifen, weil ich mich hier ja nicht im Objektkontext befinde.

    Weiß jemand, wie man an den Klassennamen der abgeleiteten Klasse rankommt?
    Muß wie gesagt noch PHP4-Kompatibel sein.
    Zuletzt geändert von pekka; 06.11.2008, 19:57.

  • #2
    Also, mit PHP 4 bekomme ich bei __CLASS__ die abgeleitet Klasse.

    PHP-Code:
    <?php
        
        
    class firstClass {
            function 
    getClass() {
                return 
    __CLASS__;
            }
        }
        
        class 
    secondClass extends firstClass {
            function 
    getClass() {
                return 
    __CLASS__;
            }
        }
        
        echo 
    phpversion(); // 4.4.7
        
    echo '<br />';
        echo 
    firstClass::getClass(); // firstClass
        
    echo '<br />';
        echo 
    secondClass::getClass(); // secondClass


    ?>
    Zuletzt geändert von unset; 06.11.2008, 21:00.
    [FONT="Helvetica"]twitter.com/unset[/FONT]

    Shitstorm Podcast – Wöchentliches Auskotzen

    Kommentar


    • #3
      Du suchst wohl: get_called_class()

      Aber das gibts erst mit PHP5.3: http://de.php.net/manual/en/function...lass.php#86230

      PHP-Code:
      <?php
      error_reporting
      (E_ALL);
      ini_set('display_errors'TRUE); 


      abstract class 
      Singleton
      {
          private static 
      $instances= array();
          
          final public static function 
      getInstance()
          {
            
      $class get_called_class();
            if(empty(
      self::$instances[$class]))
              
      self::$instances[$class] = new $class;
            return 
      self::$instances[$class];
          }

          protected function 
      __construct(){}
          final private function 
      __clone(){}
      }


      class 
      mytest extends Singleton
      {

      }

      $my MyTest::getInstance();

      echo 
      get_class($my);
      ?>
      Also:
      Mit PHP4 keine Chance!
      Zuletzt geändert von combie; 06.11.2008, 22:11.
      Wir werden alle sterben

      Kommentar


      • #4
        Original geschrieben von combie
        Du suchst wohl: get_called_class()

        Also:
        Mit PHP4 keine Chance!
        Das stimmt imho nicht. Es gibt für get_called_class() ein (zugegeben) recht unschönes Workaround über debug_backtrace. Ich glaube das mal im Zusammenhang mit dem ActiveRecord-Pattern gelesen zu haben. Google spuckt bestimmt was aus

        Grüße
        Nieder mit der Camel Case-Konvention

        Kommentar


        • #5
          Naja, evtl. bin ich da ja etwas zu dogmatisch, aber ich finde:
          Sowohl Debug Backtrace als auch Reflection sollten nicht im Regelbetrieb eingesetzt werden.
          Wir werden alle sterben

          Kommentar


          • #6
            Original geschrieben von combie
            Naja, evtl. bin ich da ja etwas zu dogmatisch, aber ich finde:
            Sowohl Debug Backtrace als auch Reflection sollten nicht im Regelbetrieb eingesetzt werden.
            Ich denke das ist tatsächlich eine Glaubensfrage. Ich habe auch bewusst angemerkt, dass der Umweg recht unschön ist.
            Bei Reflection sehe ich persönlich das gar nicht so eng, zumal sie in einiger Hinsicht im produktiven Betrieb sehr nützlich sein kann.
            Mir gings nur darum zu erwähnen, dass es doch eine und nicht keine Chance gibt

            Hier ist übrigens das Ungetüm aus dem PHP-Manual (User Comments zu Late Static Binding):
            PHP-Code:
            /**
             * Return called class name
             *
             * @author Michael Grenier
             * @param int $i_level optional
             * @return string
             */
            function get_called_class ($i_level 1)
            {
                
            $a_debug debug_backtrace();
                
            $a_called = array();
                
            $a_called_function $a_debug[$i_level]['function'];
                for (
            $i 1$n sizeof($a_debug); $i $n$i++)
                {
                    if (
            in_array($a_debug[$i]['function'], array('eval')) ||
                        
            strpos($a_debug[$i]['function'], 'eval()') !== false)
                        continue;
                    if (
            in_array($a_debug[$i]['function'], array('__call''__callStatic')))
                        
            $a_called_function $a_debug[$i]['args'][0];
                    if (
            $a_debug[$i]['function'] == $a_called_function)
                        
            $a_called $a_debug[$i];
                }
                if (isset(
            $a_called['object']) && isset($a_called['class']))
                    return (string)
            $a_called['class'];
                
            $i_line = (int)$a_called['line'] - 1;
                
            $a_lines explode("\n"file_get_contents($a_called['file']));
                
            preg_match("#([a-zA-Z0-9_]+){$a_called['type']}
                            
            {$a_called['function']}( )*\(#"$a_lines[$i_line], $a_match);
                unset(
            $a_debug$a_called$a_called_function$i_line$a_lines);
                if (
            sizeof($a_match) > 0)
                    
            $s_class = (string)trim($a_match[1]);
                else
                    
            $s_class = (string)$a_called['class'];
                if (
            $s_class == 'self')
                    return 
            get_called_class($i_level 2);
                return 
            $s_class;

            Zuletzt geändert von Griecherus; 06.11.2008, 23:21.
            Nieder mit der Camel Case-Konvention

            Kommentar


            • #7
              Hey, vielen Dank für die rege Diskussion!

              @unset: Was ich falsch dargestellt habe: Der __CLASS__ -Aufruf findet in der Basisklasse statt. Sorry.

              Uaaah, das Ungetüm ist für eine schlanke, schnelle Plugin-Verwaltung natürlich ein bisschen arg Dann gleich noch eine ganz blöde PHP4-OOP-Frage: Gibt es im statischen Kontext einen Weg, an die (in der Klassendefinition gesetzten) Variablen einer Klasse ranzukommen?
              Also

              PHP-Code:

              // die allgemeine Klasse

              class allgemeinePluginKlasse
               
              {
                
                 var 
              $classname "allgemeinePluginKlasse";
                 
                 function 
              showClassname() 
                  {
                 
              // So gehts statisch natürlich nicht
                 
              echo $this->classname;
                
                }

               } 

              // ein abgeleitetes Plugin

              class meinPlugin extends allgemeinePluginKlasse
               
              {
                
                var 
              $classname "meinPlugin";  

               }

              // Gewünschte Ausgabe: "meinPlugin"

              meinPlugin::showClassname();   // Fehler: Cannot use $this when not in object context 

              Kommentar


              • #8
                PHP 4 ist eh schon offiziell eingestellt. Wozu noch dafür programmieren? Nur weil es noch irgendwelche Steinzeit-Server gibt, die die halbe Informatikgeschichte verschlafen haben?

                Kommentar


                • #9
                  Da PHP4 keine statichen Eigenschaften kennt, wird das auch nicht viel..

                  Aus meiner Wühlkiste, evtl. kannst da was mit angangen:
                  PHP-Code:
                  <?php

                  // PHP4 Singleton Factory
                  function & singleton($class)
                  {
                    static 
                  $instances = array();
                    
                  $class strtolower($class);
                    if(!isset(
                  $instances[$class]))
                        
                  $instances[$class] = & new $class;
                    return 
                  $instances[$class];
                  }


                  class 
                  test
                  {
                      
                  // Diese Methode muß in jede betreffnende Klasse kopiert werden
                      
                  function & getInstance() 
                      {
                        return  
                  singleton(__CLASS__);
                      }
                  }


                  $mytest = & test::getInstance();
                  ?>
                  Zuletzt geändert von combie; 07.11.2008, 00:02.
                  Wir werden alle sterben

                  Kommentar


                  • #10
                    OffTopic:
                    Du hast Singleton sehr gerne, oder?
                    Nieder mit der Camel Case-Konvention

                    Kommentar


                    • #11
                      Nicht wirklich ..
                      Nur wegen der Ähnlichkeit des Problems habe ich sie hier erwähnt. Es ist eine der wenigen Situationen, wo uns die Vererbung in PHP einen derben Streich spielt.
                      Wir werden alle sterben

                      Kommentar


                      • #12
                        Das Problem hatte ich vor geraumer Zeit selbst (ActiveRecord ^^, wohl auch ähnliches Problem). Das bin ich dann so umgangen, dass die Methode, bei dir zum Beispiel init(), eine protected (in PHP4 darfst du sie dann halt nicht aufrufen) Methode aufruft und den zu verwendenden Klassennamen übergibt, analog zu combie's letztem Beispiel. Und das funktioniert auch ziemlich gut, da du über call_user_func auch wieder auf überschriebene Methoden der Unterklasse zu greifen kannst.

                        PHP-Code:
                        class ActiveRecord {
                            public static function 
                        find() {
                                
                        $args=func_get_args();
                                return(
                        self::_find(__CLASS__$args));
                            }
                            protected static function 
                        _find($class$args) {
                                
                        // ...
                            
                        }
                        }

                        class 
                        MyAR extends ActiveRecord {
                            public static function 
                        find() {
                                
                        $args=func_get_args();
                                return(
                        self::_find(__CLASS__$args));
                            }

                        Etwas unschön ist nur, dass du die Aufrufe entsprechend in jedem AR hast. War hier aber kein Problem, da die Unterklassen eh generiert werden.

                        Kommentar

                        Lädt...
                        X