Blähbauch: Doppeltes Array in Arraydefinition im Funktionskopf

Hallo Forum,

in meiner Klasse "query" habe ich folgenden Funktionskopf:

  
 function extend_sql($sql, $limit=array($conf['select_limit_grnd'], $conf['select_limit_ceil']))  
 {  
  
 }  

Bereits beim initialisieren der Klasse wird mir der Fehler angezeigt, der Parser hätte gerne ein ')'.

Das Array "conf" wurde in der Datei config.php festgelegt und kommt auch definitiv in meiner Klasse an.

Dennoch möchte der Fehler einfach nicht verschwinden.
Durch viel herumbasteln kam ich zu dem Ergebnis, dass die Funktion array() im Funktionskopf zwar erlaubt ist, dort aber keine Variabeln/Arrayelemente zulässt.
Denn schreibe ich

... array(0,30) ...
erhalte ich keine Fehlermeldung.

Ist die Vermutung so richtig? Wie kann ich trotzdem meine Arrayelemente aus $conf dort einfügen?

Lg
Blähbauch

  1. echo $begrüßung;

    function extend_sql($sql, $limit=array($conf['select_limit_grnd'], $conf['select_limit_ceil']))

    Der Defaultwert eines Funktionsarguments muss ein fester Wert sein, keiner der erst zur Laufzeit berechnet werden kann.

    Durch viel herumbasteln kam ich zu dem Ergebnis, dass die Funktion array() im Funktionskopf zwar erlaubt ist, dort aber keine Variabeln/Arrayelemente zulässt.
    Denn schreibe ich
    ... array(0,30) ...
    erhalte ich keine Fehlermeldung.
    Ist die Vermutung so richtig?

    Ja.

    Wie kann ich trotzdem meine Arrayelemente aus $conf dort einfügen?

    Gar nicht. Du musst dir was anderes einfallen lassen. Du könntest einen anderen Dummywert angeben, beispielsweise null. Auf diesen Dummywert testest du dann innerhalb der Funktion und initialisierst dann dein Array mit den eigentlich gewünschten Werten.

    echo "$verabschiedung $name";

  2. Moin!

    in meiner Klasse "query" habe ich folgenden Funktionskopf:

    function extend_sql($sql, $limit=array($conf['select_limit_grnd'], $conf['select_limit_ceil']))
    {

    }

    
    >   
    > Das Array "conf" wurde in der Datei config.php festgelegt und kommt auch definitiv in meiner Klasse an.  
      
    Wie dedlfix bereits ausführte, ist es nur erlaubt, feste Werte als Default für Funktionsparameter anzugeben, keine Variablen.  
      
    Dein Problem lässt sich grundsätzlich aber auch anders lösen. Einerseits wie von dedlfix vorgeschlagen: $limit = NULL, und in der Funktion dann die Prüfung, ob $limit NULL ist - wenn ja, dann werden die Standardwerte des $conf-Arrays verwendet.  
      
    Das ist aber keine schöne Lösung, denn damit legst du dich auf das Vorhandensein einer globalen Variablen fest.  
      
    Besser dürfte sein, diese Standardwerte direkt beim Instantiieren deiner Klasse zu übergeben, und dann schon als protected-Eigenschaft im Objekt zu speichern. Du greifts in der extend\_sql() also nicht auf $conf['fester\_wert'] zurück, sondern auf $this->\_conf['fester\_wert'], sofern nicht explizit ein Parameter übergeben wurde.  
      
    ~~~php
    class query {  
      protected $_conf=array();  
      public function __construct($conf=array()) {  
        $this->_conf = $conf;  
      }  
      public function extend_sql($sql, $limit=NULL) {  
        if (is_null($limit)) {  
          $lgrnd = $this->_conf['select_limit_grnd'];  
          $lceil = $this->_conf['select_limit_ceil'];  
        } elseif (is_array($limit)) {  
          list($lgrnd,$lceil) = $limit;  
        } else {  
          throw new Exception('Parameter Error for Limit: Must be an array');  
        }  
        // ...  
      }  
    }  
      
    $q = new query($conf);  
    $q->extend_sql('...'); // Standardwerte  
    $q->extend_sql('...',array(0,30)); // explizites Limit  
    
    

    Wie kann ich trotzdem meine Arrayelemente aus $conf dort einfügen?

    Zusätzlich zu dieser oben kurz skizzierten Methode wäre vermutlich die Verwendung des Registry-Patterns nicht falsch. Dann hättest du eine zentrale Instanz eines Objektes, in der alle Konfigurationsparameter gespeichert sind. Auf der anderen Seite aber erzeugt das, ähnlich wie eine globale Variable, unschöne Abhängigkeiten, die die Testbarkeit deines Codes negativ beeinflussen. Insofern ist das Übergeben von relevanten Konfigurationsparametern an den Konstruktor eine viel schönere Methode, jedenfalls aus Sicht der Testbarkeit.

    - Sven Rautenberg

    1. Hi Sven,

      public function extend_sql($sql, $limit=NULL) {

      if (is_null($limit)) {
            $lgrnd = $this->_conf['select_limit_grnd'];
            $lceil = $this->_conf['select_limit_ceil'];
          } elseif (is_array($limit)) {
            list($lgrnd,$lceil) = $limit;
          } else {
            throw new Exception('Parameter Error for Limit: Must be an array');
          }
          // ...
        }

        
      Das kannst du in PHP 5 dank [Type-Hinting](http://de3.php.net/manual/en/language.oop5.typehinting.php) sogar noch vereinfachen:  
        
      ~~~php
      public function extend_sql($sql, array $limit = null) {  
        if (null == $limit) {  
          $lgrnd = $this->_conf['select_limit_grnd'];  
          $lceil = $this->_conf['select_limit_ceil'];  
        }  
        else {  
          list ($lgrnd, $lceil) = $limit;  
        }  
        // ...  
      }
      

      Durch die Verwendung von == statt is_null() habe ich direkt noch ein mögliches Problem in deinem obigen Code beseitigt. Dein Code reagiert nämlich nicht auf ein leeres Array, wodurch eventuell sowohl $lgrnd und $lceil NULL sein könnten, was vielleicht nicht dem entspricht, was man erwartet hätte. Weil ein leeres Array aber auch == NULL ist, wird dieser Fall bei mir direkt abgefangen.

      Viele Grüße,
        ~ Dennis.