PHP empty() auf __get-Accessor

Lesezeit: 3 Minuten

Benutzer-Avatar
Leekräfte

Bei der Verwendung von PHP 5.3 erlebe ich ein seltsames / nicht intuitives Verhalten bei der Bewerbung empty() auf dynamische Objekteigenschaften, die über die abgerufen werden __get() Überlastfunktion. Betrachten Sie das folgende Code-Snippet:

<?php

class Test {

  protected $_data= array(
   'id'=> 23,
   'name'=> 'my string'
  );

  function __get($k) {
    return $this->_data[$k];
  }

}

$test= new Test();
var_dump("Accessing directly:");
var_dump($test->name);
var_dump($test->id);
var_dump(empty($test->name));
var_dump(empty($test->id));

var_dump("Accessing after variable assignment:");
$name= $test->name;
$id= $test->id;
var_dump($name);
var_dump($id);
var_dump(empty($name));
var_dump(empty($id));

?>

Die Ausgabe dieser Funktion ist wie folgt. Vergleichen Sie die Ergebnisse der empty() überprüft die erste und zweite Ergebnismenge:

Satz Nr. 1, unerwartetes Ergebnis:

string(19) "Accessing directly:"
string(9) "my string"
int(23)
bool(true)
bool(true)

Erwarten Sie, dass Satz Nr. 1 dasselbe wie Satz Nr. 2 zurückgibt:

string(36) "Accessing after variable assignment:"
string(9) "my string"
int(23)
bool(false)
bool(false)

Das ist wirklich verwirrend und nicht intuitiv. Die Objekteigenschaften geben aber nicht leere Strings aus empty() betrachtet sie als leere Zeichenfolgen. Was ist denn hier los?

  • Sieht wirklich sehr merkwürdig aus. Meine einzige Meinung dazu ist, dass empty() als Sprachkonstrukt die Getter-Funktion irgendwie umgeht. Aber das wäre ein riesig Fehler in meinem Verständnis – es muss eine bessere Erklärung geben. Interessiert zu sehen, was kommt.

    – Pekka

    11. Januar 2010 um 23:56 Uhr

  • interessant, isset() gibt bei direktem Zugriff true zurück.

    – Nickf

    12. Januar 2010 um 0:01 Uhr

  • Alan Storm hat es richtig verstanden, es gibt eine magische __isset-Funktion, die aufgerufen wird, wenn ein Member von empty() überprüft wird.

    – Pekka

    12. Januar 2010 um 0:04 Uhr

Benutzer-Avatar
Alan Sturm

Basierend auf einer Lektüre des empty‘s Handbuchseite und Kommentaren (Strg-F für Isset und/oder doppelte Unterstriche), sieht es so aus, als wäre dies ein bekanntes Verhalten, und wenn Sie möchten, können Sie Ihre __set und __get Methoden u empty Um gut zusammen zu spielen, gibt es eine implizite Annahme, dass Sie a implementieren __isset auch magische Methode.

Es ist ein bisschen unintuitiv und verwirrend, aber das passiert bei den meisten Meta-Programmierungen, insbesondere in einem System wie PHP.

In diesem Beispiel ruft empty() die Überladungsfunktion __isset() auf, nicht die Überladungsfunktion __get(). Versuche dies:

class Test {

  protected $_data= array(
   'id'=> 23,
   'name'=> 'my string'
  );

  function __get($k) {
    return $this->_data[$k];
  }

  function __isset($k) {
    return isset($this->_data[$k]);
  }

}

1159400cookie-checkPHP empty() auf __get-Accessor

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy