Ankündigung

Einklappen
Keine Ankündigung bisher.

Abhängigkeiten von Klassen zu Erweiterungen

Einklappen

Neue Werbung 2019

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

  • Abhängigkeiten von Klassen zu Erweiterungen

    TL;DR: Was ist eine sinnvolle Möglichkeit, Abhängigkeiten von Klassen zur Laufzeitabzufragen abzufragen?


    Bei einem Wrapper den ich für die PECL-Erweiterung yaml erstellt habe, ist mir beim testen aufgefallen, dass Klassen auch dann definiert worden sind, wenn in der entsprechenden Datei vor der Definition der entsprechenden Klasse eine Exception geworfen wird. Hier ein Beispiel wir ein gekürztes Testskript aufgebaut ist um das Problem zu verdeutlichen:

    PHP-Code:
    // yaml.php
    if(!extension_loaded('yaml')) {
        throw new 
    Exception('Extension "yaml" not loaded');
    }

    class 
    Yaml {

        const 
    ENCODING_UTF8 YAML_UTF8_ENCODING;



    PHP-Code:
    var_dump(class_exists('Yaml'));

    try {
        include 
    'yaml.php';
    }
    catch(
    Exception $exception) {
    }

    var_dump(class_exists('Yaml')); 

    Das Ergebnis des vorherigen Scripts:

    Code:
    bool(false)
    string(27) "Extension "yaml" not loaded"
    bool(true)
    Wie zu sehen ist, gibt das zweite var_dump ein true aus, was bedeutet, dass die Klasse Yaml existiert. Dies ist von Nachteil, da die Klasse ohne die entsprechende PECL-Erweiterung nicht funktionieren kann. Jetzt könnte man zusätzlich zu der Abfrage in der Datei in der die Klasse definiert wurde auch noch im __construct eine Abfrage hinzufügen ob die Erweiterung existiert:

    PHP-Code:
    if(!extension_loaded('yaml')) {
        throw new 
    Exception('Extension "yaml" not loaded');
    }

    class 
    Yaml {

        const 
    ENCODING_UTF8 YAML_UTF8_ENCODING;

        public function 
    __construct() {
            if(!
    extension_loaded('yaml')) {
                throw new 
    Exception('Extension "yaml" not loaded');
            }
        }



    Jetzt wird eine Exception beim include und wenn eine Instanz (per new) erstellt wird ausgegeben. Somit könnte keine Instanz der Klasse erstellt werden, jedoch noch statische Methoden und Konstanten abgefragt werden. Jedoch existiert immer noch eine wenig brauchbare Klasse und es kann auch kein Fallback definiert werden, das ohne diese Erweiterung auskommen würde.

    Also bin ich am Ende auf die einzig brauchbare Lösung gekommen, bei der eine Exception geworden wird, wenn die benötigte Erweiterung nicht vorhanden ist und auch keine Klasse definiert wird und somit durch einen Fallback ersetzt werden kann:

    PHP-Code:
    if(extension_loaded('yaml')) {
        class 
    Yaml {

            const 
    ENCODING_UTF8 YAML_UTF8_ENCODING;

        }
    }
    else {
        throw new 
    Exception('Extension "yaml" not loaded');

    Ist dies wirklich die beste (, schönste, tollste) Möglichkeit dies Abzufragen?


  • #2
    Wie zu sehen ist, gibt das zweite var_dump ein true aus, was bedeutet, dass die Klasse Yaml existiert.
    Ja, weil die Exception um Catch-Block überhaupt nicht behandelt wird, so läuft Dein Script brav weiter als ob nichts gewesen wäre


    Code:
    try {
        include 'yaml.php';
    }
    catch(Exception $exception) {
       // Hier muss die Exception verarbeitet werden!
    }
    vg
    jack
    -

    Kommentar


    • #3
      Mögliche Lösung: Du arbeitest mit Composer und holst dir damit symfony/yaml

      Kommentar


      • #4
        Wie zu sehen ist, gibt das zweite var_dump ein true aus, was bedeutet, dass die Klasse Yaml existiert.
        class_exists() prüft in der default-Einstellung auch nur, ob die Klasse geladen werden kann, nicht ob sie das auch wurde.

        Kommentar


        • #5
          PHP-Code:
          if(!extension_loaded('yaml')) {
              throw new 
          Exception('Extension "yaml" not loaded');
              return; 
          // <-- Rest der Datei wird nicht mehr ausgeführt

          Oder auch:
          PHP-Code:
          if(extension_loaded('yaml')) {
              class 
          Yaml {
              
          // ...
              
          }

          Grüße.

          Kommentar

          Lädt...
          X