Kenan: Gültigkeit von Variablen

0 49

Gültigkeit von Variablen

Kenan
  • php
  1. 0
    dedlfix
    1. 0
      T-Rex
      1. 0
        dedlfix
        1. 0

          Gültigkeit von Variablen - Lesbarkeit und Konvention

          tami
          1. 0
            dedlfix
            1. 0
              tami
              1. 0
                dedlfix
                1. 0
                  tami
                  1. 0
                    dedlfix
                    1. 0

                      Lesbarkeit und Konvention in PHP und Javascript

                      tami
                      1. 0
                        dedlfix
                        1. 0
                          tami
                          1. 0
                            dedlfix
                            1. 0

                              Lesbarkeit und Konvention in PHP und Javascript "==" und "==="

                              tami
                              1. 0
                                dedlfix
                                1. 0
                                  tami
                                  1. 0
                                    dedlfix
                                    1. 0

                                      Lesbarkeit und Konvention .- "heile Welt ... zusammenlügen"

                                      tami
                                      1. 0
                                        dedlfix
                                  2. 0
                                    Sven Rautenberg
                                    1. 0
                                      tami
                                      1. 0
                                        tami
                                      2. 1
                                        Sven Rautenberg
                                        1. 0

                                          Wo funktioniert (braucht man) "==" und nicht "==="

                                          tami
                                          1. 0
                                            Matthias Apsel
                                            1. 0
                                              tami
                                            2. 1
                                              Sven Rautenberg
                                              1. 0

                                                "==" auch bei Arrays und Objekten "gefährlich" ...;

                                                tami
                                                1. 0
                                                  dedlfix
                                                  1. 0

                                                    "==" auch bei Arrays und Objekten "gefährlich"/fehleranfällig

                                                    tami
                                                    1. 0
                                                      dedlfix
                                                      1. 0
                                                        tami
                                                        1. 0
                                                          bubble
                                                          1. 0
                                                            tami
                                                            1. 0
                                                              dedlfix
                                                              1. 0
                                                                tami
                                                2. 2
                                                  Sven Rautenberg
                                                  1. 0

                                                    "==" bei Arrays "gefährlich"? Crockford on Programming Style...

                                                    tami
                                          2. 0
                                            Matthias Apsel
  2. 0
    tami
    1. 0
      dedlfix
      1. 0

        Gültigkeit von Variablen - Coding Style

        tami
        1. 0
          dedlfix
          1. 0
            tami
  3. 0
    Sven Rautenberg
    1. 0

      Variablen-Initialisierung mit "null" === Prinzipienbefriedigung?

      tami
      1. 0
        dedlfix
      2. 0
        Sven Rautenberg

Hallo Leute,

ich bin noch etwas neu in PHP und mich überrascht dieses Verhalten hier:

  
class A { }  
  
class B {  
	  
	public function bla($a) {  
		if($a instanceof A) {  
			$m = 'F';  
			return $m;  
		}  
		return $m;  
	}	  
}  
  
$b = new B();  
$re = $b->bla(new B());  
echo $re . ' ' . gettype($re);  

Anscheinend muss man $m in der Methode bla() nicht erst initialisieren? Sprich so:

	public function bla($a) {  
		$m = null;  
                if($a instanceof A) {  
			$m = 'F';  
			return $m;  
		}  
		return $m;  
	}

Ich kenne das aus Java und da kriegt man Fehler geschmissen. Ist es dann die korrekte Art die Initialisierung wegzulassen?

Danke für die Antwort.

  1. Tach!

    Anscheinend muss man $m in der Methode bla() nicht erst initialisieren?

    PHP-Variablen kennen keinen Initialisierungsmechanismus. Sie werden beim ersten (auch lesendem) Gebrauch angelegt.

    Ist es dann die korrekte Art die Initialisierung wegzulassen?

    Es ist aber trotzdem eine gute Idee, sie gezielt zu initialisieren. Das gilt besonders für Arrays (und Strings), die in einer Schleife gefüllt werden sollen. Falls die Schleife nicht läuft, weil die Bedingung nicht erfüllt ist, gibt es sonst keine Array-Variable (oder String-), wenn sie nicht vorher mit $foo=array(); explizit initialisiert wurde. Die Folge ist dann, dass ein nachfolgender lesender Zugriff mindestens eine Notice-Meldung erzeugt (wird mit auf E_ALL gestelltem error_reporting angezeigt).

    Will man über ein nicht initialisiertes und nicht befülltes Array mit foreach iterieren, bekommt man eine Warnng (wenn ich mich recht erinnere). Einfacher Array-Element-Zugriff kann ein unerwartetes Ergebnis liefern, besonders wenn PHP die Variable zu String typecastet oder sie aus einem früheren Gebrauch noch ein String ist. Früherer Gebrauch kann auch eine Fehlerquelle sein, vor allem, wenn man alles im globalen Adressraum ablaufen lässt und nicht mehr dran denkt, dass eine Variable bereits anderswo erzeugt wurde und sie ohne erneute Initialisierung wiederverwendet.

    dedlfix.

    1. Es ist aber trotzdem eine gute Idee, sie gezielt zu initialisieren. Das gilt besonders für Arrays (und Strings

      ... und Klassenvariablen. Das dient zum einen der Übersicht zum anderen schützt es ähnlich wie dedlfix schon sagte vor Fehlern, wenn man sich die gesetzte Variable verlässt.

      Gruß
      Ergänzender
      T-Rex

      1. Tach!

        Es ist aber trotzdem eine gute Idee, sie gezielt zu initialisieren. Das gilt besonders für Arrays (und Strings
        ... und Klassenvariablen. Das dient zum einen der Übersicht zum anderen schützt es ähnlich wie dedlfix schon sagte vor Fehlern, wenn man sich die gesetzte Variable verlässt.

        Kommt drauf an. Wenn der erwartete Wert einer Klassenvariable auch null sein kann, ist es nicht notwendig, ihn explizit zu setzen. Bei Objektvariablen, die sowieso im Konstruktor initialisiert werden, ist es ebenfalls überflüssig, ihnen einen Wert zuzuweisen. - Und dann gibts da noch diejenigen, die ungeachtet von fachlichen oder sprachtechnischen (Nicht-)Notwendigkeiten aus Prinzip immer eine Zuweisung vornehmen. Nun könnte man noch argumentieren, dass im Falle von null das ausdrückliche Zuweisen zeigen soll, dass da null vorkommen kann. Nunja, wenn das so wichtig ist, wäre eher ein (phpDoc-)Kommentar angebracht.

        dedlfix.

        1. hi,

          Tach!

          Es ist aber trotzdem eine gute Idee, sie gezielt zu initialisieren. Das gilt besonders für Arrays (und Strings
          ... und Klassenvariablen. Das dient zum einen der Übersicht zum anderen schützt es ähnlich wie dedlfix schon sagte vor Fehlern, wenn man sich die gesetzte Variable verlässt.

          Kommt drauf an. Wenn der erwartete Wert einer Klassenvariable auch null sein kann, ist es nicht notwendig, ihn explizit zu setzen. Bei Objektvariablen, die sowieso im Konstruktor initialisiert werden, ist es ebenfalls überflüssig, ihnen einen Wert zuzuweisen. - Und dann gibts da noch diejenigen, die ungeachtet von fachlichen oder sprachtechnischen (Nicht-)Notwendigkeiten aus Prinzip immer eine Zuweisung vornehmen. Nun könnte man noch argumentieren, dass im Falle von null das ausdrückliche Zuweisen zeigen soll, dass da null vorkommen kann. Nunja, wenn das so wichtig ist, wäre eher ein (phpDoc-)Kommentar angebracht.

          https://forum.selfhtml.org/?t=215185&m=1473238

          Und aus weiteren Klassen des Zend-Frameworks:

            
          abstract class Zend_Uri  
          {  
              /**  
               * Scheme of this URI (http, ftp, etc.)  
               *  
               * @var string  
               */  
              protected $_scheme = '';  
            
              /**  
               * Global configuration array  
               *  
               * @var array  
               */  
              static protected $_config = array(  
                  'allow_unwise' => false  
              );  
          
          
          class Zend_Registry extends ArrayObject  
          {  
              /**  
               * Class name of the singleton registry object.  
               * @var string  
               */  
              private static $_registryClassName = 'Zend_Registry';  
            
              /**  
               * Registry object provides storage for shared objects.  
               * @var Zend_Registry  
               */  
              private static $_registry = null;  
            
              /**  
               * Retrieves the default registry instance.  
               *  
               * @return Zend_Registry  
               */  
              public static function getInstance()  
              {  
                  if (self::$_registry === null) {  
                      self::init();  
                  }  
            
                  return self::$_registry;  
              }  
          
          

          Douglas Crockfort hebt bei seiner in den Augen einiger peniblen Art der Code-Konventionen immer wieder hervor, dass es um die Lesbarkeit des Codes geht. Intantiiere ich Variablen am Anfang einer Klasse, geht es ja wohl nur um die Lesbarkeit. Man liest, dass es sie gibt und welchen Anfangswert sie haben (aus dem man dann auch u.U. schließen kann, was mal draus werden soll). Der Kommentar gehört natürlich dazu. Aber ohne Variablendefinition ja wohl kein Kommentar, so zumindest verstehe ich die in meinen Augen bisher sehr sinnvolle Konvention beim Zend Framework.

          mfg

          tami

          1. Tach!

            Douglas Crockfort hebt bei seiner in den Augen einiger peniblen Art der Code-Konventionen immer wieder hervor, dass es um die Lesbarkeit des Codes geht. Intantiiere ich Variablen am Anfang einer Klasse, geht es ja wohl nur um die Lesbarkeit. Man liest, dass es sie gibt und welchen Anfangswert sie haben (aus dem man dann auch u.U. schließen kann, was mal draus werden soll). Der Kommentar gehört natürlich dazu. Aber ohne Variablendefinition ja wohl kein Kommentar, so zumindest verstehe ich die in meinen Augen bisher sehr sinnvolle Konvention beim Zend Framework.

            Unterscheide

            class foo {
              function qux() {
                echo $this->bar;
              }
            }

            und

            class foo {
              var $bar;

            function qux() {
              ...
            }

            und

            class foo {
              var $bar = null;

            function qux() {
              ...
            }

            Das $bar ganz wegzulassen und dann zu verwenden ist normalerweise nicht besonders sinnvoll oder praktisch. (Eine Ausnahme wäre Get/Set-Magie). Also Variante 1 scheidet schonmal aus. Es geht in diesem Zweig nur um die Varianten zwei und drei. $bar ist also in jedem Fall vorhanden. Variante drei hat ein überflüssiges "= null". Ebenso überflüssig wären andere Werte, die im Konstruktor sowieso überschrieben werden. In diesen beiden Fällen eine Zuweisung vorzunehmen, dient lediglich der Prinzip-Befriedigung. (Wenn ich das in C# mache, dann kassiert das der ReSharper ein.) Unnützer Code verschlechtert in meinen Augen die Lesbarkeit (genauso wie if ($var == true) und Konsorten).

            Wenn ich programmiere und dabei ein anderes System verwende, will ich nicht immer in dessen Code schauen, um wichtige Informationen zu bekommen. Wichtige Dinge, darunter zählen auch Default-Werte, sollten in der Inline-Dokumentation erwähnt sein, die mir meine IDE direkt in meinen Code einblendet, wenn ich irgendwas verwende. Und dann ist es auch praktisch egal, ob der Wert nun explizit oder erst im Konstruktor gesetzt wird.

            dedlfix.

            1. hi,

              Das $bar ganz wegzulassen und dann zu verwenden ist normalerweise nicht besonders sinnvoll oder praktisch. (Eine Ausnahme wäre Get/Set-Magie). Also Variante 1 scheidet schonmal aus. Es geht in diesem Zweig nur um die Varianten zwei und drei. $bar ist also in jedem Fall vorhanden. Variante drei hat ein überflüssiges "= null". Ebenso überflüssig wären andere Werte, die im Konstruktor sowieso überschrieben werden. In diesen beiden Fällen eine Zuweisung vorzunehmen, dient lediglich der Prinzip-Befriedigung.

              Ach, das kann ich mir bei den Zend-Framework-Entwicklern garnicht vorstellen, dass es denen um Prinzipbefriedigung geht.

              Wenn ich programmiere und dabei ein anderes System verwende, will ich nicht immer in dessen Code schauen, um wichtige Informationen zu bekommen. Wichtige Dinge, darunter zählen auch Default-Werte, sollten in der Inline-Dokumentation erwähnt sein, die mir meine IDE direkt in meinen Code einblendet, wenn ich irgendwas verwende. Und dann ist es auch praktisch egal, ob der Wert nun explizit oder erst im Konstruktor gesetzt wird.

              Vermutlich geht es auch eher darum, in dem was man macht oder wie mans macht, konsitent zu sein.

              mfg

              tami

              1. Tach!

                Ach, das kann ich mir bei den Zend-Framework-Entwicklern garnicht vorstellen, dass es denen um Prinzipbefriedigung geht.

                Es ist einfacher, strenge Prinzipien aufzustellen, anstatt jeden Teilnehmer so zu schulen, dass er in jeder Situation das angemessene macht. Das kann nämlich mal so und mal so aussehen und ist auch oft subjektiv. Eine festes Prinzip kann die Diskussionen um solche Fälle abkürzen, wenn man nicht das Prinzip als solches infrage stellt. Mir scheint, dass diejenigen, die nach festen Regeln leben wollen in der Mehrheit sind. Insofern nehme ich an, dass die Prinzipbefriedigung einen entscheidenden Anteil an der Aufstellung solcher Regeln hat, auch wenn das wohl selbst nicht so wahrgenommen wird.

                Vermutlich geht es auch eher darum, in dem was man macht oder wie mans macht, konsitent zu sein.

                Ja. Mir aber nicht. Konsistenz ist für mich kein Ziel, das über allem anderen steht. Besonders nicht, wenn die Konsistenz nur um ihrer selbst willen da ist und eingehalten werden muss. Solch ein Korsett ziehe ich mir ungern an. Das heißt nicht, dass bei mir gar keine Ordnung vorhanden ist. Sie ist schon sehr hoch, aber eben unterhalb der Grenze zur Überflüssigkeit.

                dedlfix.

                1. hi,

                  ja, bei Crockford aber geht es - so wie ich ihn verstehe - allein um Bug-Vermeidung und Fehlerfindung. Er hat alles rausgeschmissen bei Javascript, was ihn schon mal Stunden wenn nicht sogar Tage bei der Bugfindung gekostet hat. Passiert ein Code JSLint, hat er per se weniger Fehler, das wäre  die Theorie dahinter. Und er ist lesbarer! Was wiederum auch bei der eventuellen Bug-Findung hilft oder aber auch bei der Erweiterung.

                  Bei den Klassen und Variablen beim Zend-Framework interpretiere ich es mal so, dass, wenn ich davon ausgehen kann, dass alle Variablen vorab deklariert werden, ich auch damit genau weiß, welche Variablen überhaupt in der Klasse vorkommen. Quasi ein Inhaltsverzeichnis. Das macht es übersichtlich und konsistent. Es geht doch allein um einen Praktikabilitätsgewinn (in der Regel unterm Strich eine z.T. enorme Zeitersparnis). Die Vorträge (yahoo theater) von Crockford und auch die Argumente derer, die das Hinterfragen (die führt er da in seinen Vorträgen auch an), finde ich da sehr lehrreich und gehen genau auch immer wieder um das Argument, "jemand" wolle Regeln um ihrer selbst Willen aufstellen.

                  mfg

                  tami

                  1. Tach!

                    Bei den Klassen und Variablen beim Zend-Framework interpretiere ich es mal so, dass, wenn ich davon ausgehen kann, dass alle Variablen vorab deklariert werden, ich auch damit genau weiß, welche Variablen überhaupt in der Klasse vorkommen. Quasi ein Inhaltsverzeichnis.

                    Dagegen hab ich auch nichts einzuwenden, dass sie in der Klassendefinition aufgeführt werden (außer in Sonderfällen, die sich nicht vermeiden lassen, dann aber dokumentiert gehören. Mittlerweile kennt phpdoc sogar @property(-read/-write), mit dem sich nicht direkt vorhandene "magische" Eigenschaften dokumentieren und in der IDE autovervollständigen lassen).

                    Das macht es übersichtlich und konsistent. Es geht doch allein um einen Praktikabilitätsgewinn (in der Regel unterm Strich eine z.T. enorme Zeitersparnis).

                    Ja, aber sinnlose Initialisierungen oder unnötige umständliche Schreibweisen (à la if ($foo == true)) bringen keinen Gewinn. Die hindern mitunter den Lesefluss, weil man da eine eventuelle Bewandnis dahinter sucht, die nicht wirklich vorhanden ist.

                    Die Vorträge (yahoo theater) von Crockford und auch die Argumente derer, die das Hinterfragen (die führt er da in seinen Vorträgen auch an), finde ich da sehr lehrreich und gehen genau auch immer wieder um das Argument, "jemand" wolle Regeln um ihrer selbst Willen aufstellen.

                    Vergleich mal nicht Äpfel mit Birnen. Javascript hat einige sehr trickreiche Eigenschaften, vor allem was Semikola betrifft. Da mag das ander aussehen. Wir reden hier aber von PHP und (unnötigen bis unsinnigen) Variableninitialisierungen. Und ich sehe es als noch weniger sinnvoll an, Prinzipien eines Systems unbedingt auf ein anderes übernehmen zu wollen. Jedes hat seine eigene Philosophie und ich denke, man fährt am besten, wenn man nach dieser und nicht zu sehr nach irgendwelchen allgemeinen Prinzipien handelt.

                    Etwas das sinnvoll ist, sollte verstanden und aus dem Herzen heraus angewendet werden, nicht (nur) aufgrund einer Regel.

                    dedlfix.

                    1. hi,

                      Ja, aber sinnlose Initialisierungen oder unnötige umständliche Schreibweisen (à la if ($foo == true)) bringen keinen Gewinn. Die hindern mitunter den Lesefluss, weil man da eine eventuelle Bewandnis dahinter sucht, die nicht wirklich vorhanden ist.

                      Naja, es fragt sich, was du da mit "==" bezwecken willst. Anders und u.U. "besser" wäre if ($foo === true). Das deckt sich übrigens mit Javascript. Das "==" gibt unter Umständen "true", wo es garnicht erwartet wird, kommt glaube ich sogar genau so in einem Vortrag von Crockford vor, deshalb "ächtet" er m.E. das "==" und lässt nur "===" zu, mag aber sein, dass ich da irre ...;

                      S.a. "Crockford's advice is: Prefer forms that are error-resistant.
                      This is aligned closely with my own advice: Prefer explicit forms to implicit forms."
                      http://osric.com/chris/accidental-developer/2012/01/douglas-crockford-programming-style-and-your-brain/

                      Etwas das sinnvoll ist, sollte verstanden und aus dem Herzen heraus angewendet werden, nicht (nur) aufgrund einer Regel.

                      Nun ja, das mag man so sehen und trifft für den Einzelprogrammierer bestimmt zu. In einem Team wäre es mir als Leiter egal, ob das aus dem Herzen heraus kommt, wenn ich nämlich der Überzeugung wäre, dass gewisse Dinge der Fehlervermeidung dienen (können).

                      mfg

                      tami

                      1. Tach!

                        Ja, aber sinnlose Initialisierungen oder unnötige umständliche Schreibweisen (à la if ($foo == true)) bringen keinen Gewinn. Die hindern mitunter den Lesefluss, weil man da eine eventuelle Bewandnis dahinter sucht, die nicht wirklich vorhanden ist.
                        Naja, es fragt sich, was du da mit "==" bezwecken willst. Anders und u.U. "besser" wäre if ($foo === true).

                        Das ist unter Umständen noch schlechter, weil ich mich dann an solchen Stellen aufhalte und frage, warum denn nun der Typ wichtig ist und nicht auch 0, array() oder Leerstrings die Bedingung erfüllen. Der typsichere Vergleich hat seinen Sinn bei strlen(), wo es einen Unterschied zwischen false und 0 gibt. Aber das nun aus Prinzip an jeder Stelle anzuwenden ist wenig sinnvoll.

                        Das deckt sich übrigens mit Javascript.

                        Andere Baustelle. Andere Bedingungen. Nicht 1:1 auf PHP übertragbar.

                        dedlfix.

                        1. hi,

                          Tach!

                          Ja, aber sinnlose Initialisierungen oder unnötige umständliche Schreibweisen (à la if ($foo == true)) bringen keinen Gewinn. Die hindern mitunter den Lesefluss, weil man da eine eventuelle Bewandnis dahinter sucht, die nicht wirklich vorhanden ist.
                          Naja, es fragt sich, was du da mit "==" bezwecken willst. Anders und u.U. "besser" wäre if ($foo === true).

                          Das ist unter Umständen noch schlechter, weil ich mich dann an solchen Stellen aufhalte und frage, warum denn nun der Typ wichtig ist und nicht auch 0, array() oder Leerstrings die Bedingung erfüllen. Der typsichere Vergleich hat seinen Sinn bei strlen(), wo es einen Unterschied zwischen false und 0 gibt. Aber das nun aus Prinzip an jeder Stelle anzuwenden ist wenig sinnvoll.

                          Du schlössest damit schlicht die Möglichkeit aus, dass der Vergleich wahr ist, obwohl du das nicht wolltest oder erwartet hättest. Wieso macht es Sinn, alle u.g. Möglichkeiten mit einzuschließen, um die es eigentlich garnicht geht. Eine prinzipielle Fehlerquelle die unnötig ist.

                          <?php  
                          class A {  
                          }  
                          $a = new A();  
                          var_dump(true == $a);  
                          $b = "abc";  
                          var_dump(true == $b);  
                          $c = 123;  
                          var_dump(true == $c);  
                          $d = "false";  
                          var_dump(true == $d);  
                          $e = array(1,"2","abc");  
                          var_dump(true == $e);  
                          
                          

                          alles boolean (true);

                          mfg

                          tami

                          1. Tach!

                            Das ist unter Umständen noch schlechter, weil ich mich dann an solchen Stellen aufhalte und frage, warum denn nun der Typ wichtig ist und nicht auch 0, array() oder Leerstrings die Bedingung erfüllen. Der typsichere Vergleich hat seinen Sinn bei strlen(), wo es einen Unterschied zwischen false und 0 gibt. Aber das nun aus Prinzip an jeder Stelle anzuwenden ist wenig sinnvoll.
                            Du schlössest damit schlicht die Möglichkeit aus, dass der Vergleich wahr ist, obwohl du das nicht wolltest oder erwartet hättest.

                            Ist denn der Anwendungsfall gegeben, dass nur ein boolescher Wert übergeben werden darf? Es geht mir um die Fälle, bei denen nicht direkt zu sehen ist (sei es durch Kommentar oder dokumentiertes Funktionsergebnis), dass zum Beispiel false aber nicht 0 erwartet wird.

                            Wieso macht es Sinn, alle u.g. Möglichkeiten mit einzuschließen, um die es eigentlich garnicht geht. Eine prinzipielle Fehlerquelle die unnötig ist.

                            Diese Frage lässt sich nur für den jeweiligen Anwendungsfall klären und nicht pauschal.

                            dedlfix.

                            1. hi,

                              Wieso macht es Sinn, alle u.g. Möglichkeiten mit einzuschließen, um die es eigentlich garnicht geht. Eine prinzipielle Fehlerquelle die unnötig ist.

                              Diese Frage lässt sich nur für den jeweiligen Anwendungsfall klären und nicht pauschal.

                              Der Anwendungsfall wäre: wenn $a entweder ein Objekt ist (kann auch leer sein) oder ein String mit mindestens einem Zeichen oder eine Zahl ungleich 0 oder ein Array (darf aber nicht leer sein).

                              Und die Zusammenfassung auf "==" bietet eben nicht die detailierte Info (Ich glaube das ist genau das Argument von Crockford). O.g. muss ich als Leser und/oder Autor wissen, im Zweifelsfalle erhöht eben das einzelne Abtesten der o.g. Alternativen die Lesbarkeit, denn der Leser kann verunsichert werden, weil er u.U. nicht genau weiß ob a) alle o.g. vier Alternativen mit zwei Besonderheiten wirklich alles umfasst und b) nicht weiß, ob der Autor sich dabei nicht doch vertan hat, weil er es selbst nicht richtig (vollständig) wusste. Das zumindest die Argumentation, wie ich sie verstehe. Bei Javascript gibt es da meine ich noch mehr absurde Geschichten beim Objektvergleich. Aber der Grundsatz ist ja übertragbar.

                              mfg

                              tami

                              1. Tach!

                                Diese Frage lässt sich nur für den jeweiligen Anwendungsfall klären und nicht pauschal.
                                Der Anwendungsfall wäre:

                                Wenn du einen Anwendungsfall hast, der das erfordert, dann ist das doch ok. Es geht mir nur darum, das === nicht nur des Prinzips wegen generell statt == oder impliziter Boolean-Prüfung (if ($foo) ...) zu verwenden, sondern nur wenn es eine Begründung für die Typprüfung gibt. Die Frage, die sich der Programmierer vor der Entscheidung zwischen === und == stellen muss ist, ob es Nachteile bringt, PHPs Typkonvertierung an dieser Stelle auszuschalten.

                                O.g. muss ich als Leser und/oder Autor wissen, im Zweifelsfalle erhöht eben das einzelne Abtesten der o.g. Alternativen die Lesbarkeit,

                                Für den Zweifelsfall ist es nicht sinnvoll, ihn durch einen anderen Zweifelsfall zu ersetzen (oder des Prinzips wegen weitere Zweifelsfälle einzubauen), sondern ihn mit einem Kommentar aufzuklären.

                                Bei Javascript gibt es da meine ich noch mehr absurde Geschichten beim Objektvergleich. Aber der Grundsatz ist ja übertragbar.

                                Meines Wissens sind das diese Problemfälle, die die Empfehlung zu === rechtfertigen. Aber für PHP sind die Vergleichvarianten übersichtlich und dokumentiert. Ich sehe keinen Grund eine generelle ===-Empfehlung für PHP auszusprechen.

                                dedlfix.

                                1. hi,

                                  Tach!

                                  Diese Frage lässt sich nur für den jeweiligen Anwendungsfall klären und nicht pauschal.
                                  Der Anwendungsfall wäre:

                                  Wenn du einen Anwendungsfall hast, der das erfordert, dann ist das doch ok.

                                  Es geht nicht um "ok", es geht um die Frage, ob es eine weniger fehleranfällige bzw. explizitere Schreibweise gibt.

                                  Für den Zweifelsfall ist es nicht sinnvoll, ihn durch einen anderen Zweifelsfall zu ersetzen (oder des Prinzips wegen weitere Zweifelsfälle einzubauen), sondern ihn mit einem Kommentar aufzuklären.

                                  Naja, im Code darf der Zweifelsfall wohl auch aufgeklärt werden.

                                  Meines Wissens sind das diese Problemfälle, die die Empfehlung zu === rechtfertigen. Aber für PHP sind die Vergleichvarianten übersichtlich und dokumentiert. Ich sehe keinen Grund eine generelle ===-Empfehlung für PHP auszusprechen.

                                  Tja, die Liste ist genau der Punkt. Wer die nicht zu 100% auswendig kann, kann bei einer eventuellen Fehlersuche straucheln. $x="0" ist bool-false. Und was mit befüllten Arrays und leeren Objekten ist, steht da garnicht. Ich behaupte mal provokant, den Fall, wo auch "==" in PHP eine gleichwertige Aussagekraft hat, gibt es nicht. Es ist schlicht "Faulheit" des Programmierers und schließt immer mehr ein, als man braucht. Und "Faulheit" wäre aus meiner Sicht übrigens Fehlerquelle Nr. 1.

                                  mfg

                                  tami

                                  1. Tach!

                                    Wenn du einen Anwendungsfall hast, der das erfordert, dann ist das doch ok.
                                    Es geht nicht um "ok", es geht um die Frage, ob es eine weniger fehleranfällige bzw. explizitere Schreibweise gibt.

                                    Nein, nicht generell.

                                    Für den Zweifelsfall ist es nicht sinnvoll, ihn durch einen anderen Zweifelsfall zu ersetzen (oder des Prinzips wegen weitere Zweifelsfälle einzubauen), sondern ihn mit einem Kommentar aufzuklären.
                                    Naja, im Code darf der Zweifelsfall wohl auch aufgeklärt werden.

                                    Das setzt voraus, dass === generell besser wäre als == und sämtliche Zweifelsfälle zweifelsfrei ausräumt. Das sehe ich aber nicht so.

                                    Meines Wissens sind das diese Problemfälle, die die Empfehlung zu === rechtfertigen. Aber für PHP sind die Vergleichvarianten übersichtlich und dokumentiert. Ich sehe keinen Grund eine generelle ===-Empfehlung für PHP auszusprechen.
                                    Tja, die Liste ist genau der Punkt. Wer die nicht zu 100% auswendig kann, kann bei einer eventuellen Fehlersuche straucheln.

                                    Man darf auch nachschlagen. Und Programmieren ist keine Tätigkeit für Idioten, um das mal so zu sagen. Du wirst nicht ohne grundlegende Kenntnisse, allein mit Prinzipien programmieren können. Du brauchst das Wissen auch für die Fälle, bei denen du Code bekommst, der sich nicht an deine Prinzipien hält. Das Lernen/Wissen wird dir nicht erspart.

                                    $x="0" ist bool-false. Und was mit befüllten Arrays und leeren Objekten ist, steht da garnicht.

                                    Nicht-leere Arrays sind false, gefüllte sind true. Das steht auf der Seite zum Boolean-Typ. Man sollte nun 1 und 1 zusammenzählen können, dass ein nicht-leeres Array sich gegenteilig zu dem leeren verhält. Ebenfalls auf der Boolean-Typ-Seite steht, dass Objekte niemals false sind (PHP 4 ignorierend).

                                    Ich behaupte mal provokant, den Fall, wo auch "==" in PHP eine gleichwertige Aussagekraft hat, gibt es nicht. Es ist schlicht "Faulheit" des Programmierers und schließt immer mehr ein, als man braucht. Und "Faulheit" wäre aus meiner Sicht übrigens Fehlerquelle Nr. 1.

                                    Warum sollte man bei Konfigurationswerten "TRUE"/"FALSE" vorschreiben, wenn es 1/0 auch tut?
                                    Warum sollte man bei mysql(i)_query() strikt auf FALSE prüfen, wenn das Ergebnis im Nicht-Fehlerfall auf keinen Fall zu false castet?

                                    Der typsichere Vergleich bringt in den beiden Fällen und anderen keinen Vorteil. Er würde nur (mir) implizit sagen wollen, dass es ein zu false kompatibles Ergebnis oder einen solchen Wert geben kann, der keinesfalls mit false verwechselt werden darf.

                                    PHP ist nun mal keine typsichere Sprache. Wer das nicht mag, sollte sie nicht mit Prinzipien zu einer solchen umzubiegen versuchen, nur um sich eine heile Welt zusammenzulügen.

                                    dedlfix.

                                    1. hi,

                                      PHP ist nun mal keine typsichere Sprache. Wer das nicht mag, sollte sie nicht mit Prinzipien zu einer solchen umzubiegen versuchen, nur um sich eine heile Welt zusammenzulügen.

                                      Die Frage ist doch allein, wo Du Dir mit der Typendurchlässigkeit Fehlerpotential einhandeln könntest. Und ob Du mit ein-zwei-drei Zeichen mehr dies (komplett) ausschließen kannst. Um "Lügen" und eine "heile Welt" geht es mMn garnicht.

                                      if (false === $result) { wäre doch (auch) ein klares Statement ...;

                                      mfg

                                      tami

                                      1. Tach!

                                        Die Frage ist doch allein, wo Du Dir mit der Typendurchlässigkeit Fehlerpotential einhandeln könntest.

                                        Warum soll ich das nicht im Einzelfall entscheiden können, sondern auf ein ständig anzuwendendes Prinzip setzen, das aber oftmals unnötig? Ich bin ein Kopf-Mensch und kann das an Ort und Stelle durch Nachdenken entscheiden. Ich muss da nicht dem Bauch (oder Darm nach Crockford) die Oberhand lassen.

                                        dedlfix.

                                  2. Moin!

                                    Tja, die Liste ist genau der Punkt. Wer die nicht zu 100% auswendig kann, kann bei einer eventuellen Fehlersuche straucheln. $x="0" ist bool-false. Und was mit befüllten Arrays und leeren Objekten ist, steht da garnicht.

                                    Wenn du so codest, dass du die Grenz- und nicht dokumentierten Fälle mit deinem Code triffst, machst du grundsätzlich was falsch.

                                    Deine Annahme setzt voraus, dass völlig unmotiviert die gesamte Vielfalt von Bools, Strings, Arrays, Objekten etc. auf diesen einen Vergleich treffen kann.

                                    Wer coded denn so einen Müll, wo sowas passieren kann?

                                    Selbst wenn du nun "selbstgemachte simple Formularvalidierung" sagst, kommst du lediglich auf "nur Strings und Arrays" - und selbst dann ist immer noch nicht geklärt, was denn der tatsächliche Anwendungskontext ist.

                                    - Sven Rautenberg

                                    1. hi Sven,

                                      Tja, die Liste ist genau der Punkt. Wer die nicht zu 100% auswendig kann, kann bei einer eventuellen Fehlersuche straucheln. $x="0" ist bool-false. Und was mit befüllten Arrays und leeren Objekten ist, steht da garnicht.

                                      Wenn du so codest, dass du die Grenz- und nicht dokumentierten Fälle mit deinem Code triffst, machst du grundsätzlich was falsch.

                                      Deine Annahme setzt voraus, dass völlig unmotiviert die gesamte Vielfalt von Bools, Strings, Arrays, Objekten etc. auf diesen einen Vergleich treffen kann.

                                      Wer coded denn so einen Müll, wo sowas passieren kann?

                                      Selbst wenn du nun "selbstgemachte simple Formularvalidierung" sagst, kommst du lediglich auf "nur Strings und Arrays" - und selbst dann ist immer noch nicht geklärt, was denn der tatsächliche Anwendungskontext ist.

                                      Was du schreibst ist sicher richtig, allein ich kapiere es nicht. Die (theoretische) Frage aus meiner Sicht war allein, wann denn if ($x == false) eine expliziten Schreibweise mit "===" überlegen wäre bzw. weniger fehleranfällig. Bzw. in wie weit sich das Argument von Crockford in Bezug auf Javascript und die Nutzung von "==" vs. "===" auf PHP übertragen lässt. Der Punkt ist da ja die Eindeutigkeit beim Lesen des Codes. Und das schließt die Frage des Lesenden ein, ob der Autor hier "==" benutzt hat, weil er alle o.g. Fälle mit einschließen möchte, oder ob er es "nur" aus "Faulheit" nutzt, weil er nicht weiß, ob da ein "", 0, "0", leeres Array oder sonstwas, was nach bool-gecastet zu false wird. Mir leuchtet Crockfords Argument bezüglich "===" einfach ein. Auch im PHP-Kontext. Und zwar allein in Bezug auf Fehleranfälligkeit, was, wenn ich meinen Eindruck hier nochmal aus dem Forum und aus eigener Erfahrung wiedergebe, in erster Linie an "schlampiger" und unübersichtlicher Codierung (Coding-Style) liegt. Aber selbst im Javascript-Kontext wird ja Crockford kontrovers diskutiert. Das scheint ja dann auch gerne mal ein persönliches Ding zu werden, dass sich da jemand in seinen Freiheiten ganz weltanschaulich eingeschränkt sieht.

                                      mfg

                                      tami

                                      1. hi,

                                        so in diese Richtung sollte meine Argumentation gehen:

                                        "== is useless.

                                        It’s not transitive. "foo" == TRUE, and "foo" == 0… but, of course, TRUE != 0.

                                        == converts to numbers when possible (123 == "123foo"… although "123" != "123foo"), which means it converts to floats when possible. So large hex strings (like, say, password hashes) may occasionally compare true when they’re not. Even JavaScript doesn’t do this.

                                        For the same reason, "6" == " 6", "4.2" == "4.20", and "133" == "0133". But note that 133 != 0133, because 0133 is octal. But "0x10" == "16" and "1e3" == "1000"!

                                        === compares values and type… except with objects, where === is only true if both operands are actually the same object! For objects, == compares both value (of every attribute) and type, which is what === does for every other type. What."

                                        http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/

                                        mfg

                                        tami

                                      2. Moin!

                                        Was du schreibst ist sicher richtig, allein ich kapiere es nicht. Die (theoretische) Frage aus meiner Sicht war allein, wann denn if ($x == false) eine expliziten Schreibweise mit "===" überlegen wäre bzw. weniger fehleranfällig. Bzw. in wie weit sich das Argument von Crockford in Bezug auf Javascript und die Nutzung von "==" vs. "===" auf PHP übertragen lässt. Der Punkt ist da ja die Eindeutigkeit beim Lesen des Codes.

                                        Crockfords Ansatz bei Javascript ist, die kritikwürdige Erfindung der Sprache in nur 10 Tagen dahingehend abzumildern, dass man um all diese fragwürdigen "Features" freiwillig einen großen Bogen macht, bzw. absichtlich Uneindeutigkeiten durch sprachlich überflüssiges Hinzufügen von Syntax verständlicher und eindeutiger macht. "Implizit" ist böse, "explizit" ist besser.

                                        Da PHP vermutlich auch solch eine Sprache mit kritikwürdigen Stellen ist (wenngleich es länger gedauert hat, sie zu erfinden), ist derselbe Ansatz auch hier möglich, und ich würde ihn vorbehaltlos unterstützen: Finger weg von Uneindeutigkeiten (beispielsweise sollten IF und Schleifen ihren Codeblock IMMER mit geschweiften Klammern umschließen, auch wenn es nur ein Statement ist), "explizit" ist besser als "implizit".

                                        Für Javascript gibts "JSLint", in PHP den "PHP_Codesniffer" mit diversen modularen Checks. Und eine endlose Diskussion in jeder Entwicklergruppe, welchen Coding Style man denn benutzen will.

                                        Und genau das haben wir hier auch: Die Diskussion wird nicht beendbar sein, weil das einzige verifizierbare Argument "Es funktioniert korrekt" ist, und alles andere lediglich auf der gefühlten Problematik basiert, die aber nicht quantifizierbar ist.

                                        Obwohl ich also dazu tendiere, lieber den Äquivalenzvergleich === zu verwenden, kann man daraus keine generelle Regel machen, weil manche Vergleiche damit nicht funktionieren.

                                        Und das schließt die Frage des Lesenden ein, ob der Autor hier "==" benutzt hat, weil er alle o.g. Fälle mit einschließen möchte, oder ob er es "nur" aus "Faulheit" nutzt, weil er nicht weiß, ob da ein "", 0, "0", leeres Array oder sonstwas, was nach bool-gecastet zu false wird.

                                        Diese Frage stellt sich eben nur selten. Das wäre mein in kryptische Worte gegossenes Gegenargument gewesen: Wenn man Code schreibt, bei der es einen Unterschied macht, ob man == oder === benutzt, und der Unterschied erschließt sich nicht sofort, sondern es kommen Zweifel auf, ob der Code korrekt ist bzw. eigentlich die jeweils andere Variante gemeint war, der hat vorher und um diese Codestelle drumherum schon viel falsch gemacht. Das wiederum ist komplett auf Crockfords Linie, dass man Uneindeutigkeiten vermeiden sollte.

                                        - Sven Rautenberg

                                        1. hi Sven,

                                          danke für die umfangreiche und mMn fachlich hilfreiche Antwort.

                                          Obwohl ich also dazu tendiere, lieber den Äquivalenzvergleich === zu verwenden, kann man daraus keine generelle Regel machen, weil manche Vergleiche damit nicht funktionieren.

                                          Hast Du dazu ein Beispiel, wo "==" funktioniert aber nicht "==="?

                                          mfg Robert aka tami fka ...

                                          1. Om nah hoo pez nyeetz, tami!

                                            Hast Du dazu ein Beispiel, wo "==" funktioniert aber nicht "==="?

                                            0 == 0.0   //true  
                                            0 === 0.0  //false, da int != float
                                            

                                            Matthias

                                            --
                                            Der Unterschied zwischen Java und JavaScript ist größer als der zwischen TeX und Textmarker.

                                            1. hi Matthias,

                                              0 == 0.0   //true

                                              0 === 0.0  //false, da int != float

                                                
                                              Ja. Die Frage ist aber, ob es überhaupt ein Beispiel gibt, wo der typenfreie Vergleich Sinn macht. Denn die Liste der Dinge die mit 0 "==" sind, ist lang und ich vermute, Du (wie auch ich) könntest sie nicht zu 100% (!) auswendig.  
                                                
                                              ~~~php
                                                
                                              $g = "foo";  
                                              var_dump(true == $g);  
                                              $g = "foo";  
                                              var_dump(0 == $g);  
                                              
                                              

                                              gibt:
                                              bool(true)
                                              bool(true)

                                                
                                              var_dump(0 == true);  
                                              
                                              

                                              gibt aber natürlich
                                              bool(false)

                                              S.a. Verlinkungen bei einem meiner Beiträge hier. Meine (gewagte) These ist: wie in Javascript ist "==" in PHP auch grundsätzlich "bad", und zwar immer. Das geht aber vermutlich zu weit ;-). Sven hat das ja gestern sehr pointiert dargelegt. Ich warte noch auf das Beispiel, wo es nur mit "==" geht. Oder eben "besser".

                                              mfg

                                              tami

                                            2. Moin!

                                              Om nah hoo pez nyeetz, tami!

                                              Hast Du dazu ein Beispiel, wo "==" funktioniert aber nicht "==="?

                                              0 == 0.0   //true

                                              0 === 0.0  //false, da int != float

                                                
                                              Das ist ein schlechtes Beispiel, weil man Floats sowieso nicht exakt vergleichen soll. Der akademische Einwand ist aber natürlich korrekt.  
                                                
                                              Spannend wirds beim Vergleich von zwei Arrays oder zwei Objekten:  
                                                
                                              Bei zwei Arrays prüft "==" lediglich, dass dieselben Keys und Values in beiden Arrays vorhanden sind. Mit "===" müssen diese aber außerdem noch in derselben Reihenfolge vorliegen und denselben Typ haben.  
                                                
                                              Wenn es also nur darum geht, dass die Werte in Array 1, die ich über irgendeine Funktion eingesammelt habe, "gleich" dem Array 2 ist, ist der Vergleich mit "==" vermutlich schlauer, sofern mich die Reihenfolge nicht interessiert, und ich auf die interne Typprüfung verzichten kann.  
                                                
                                              Bei Objekten ist es ganz ähnlich: Der strikte Vergleich ist nur dann wahr, wenn ich in den zwei Variablen zweimal dieselbe Instanz des Objekts stehen habe. Der Vergleich mit "==" hingegen ist wahr, wenn die zwei Objekte von derselben Klasse sind und ihre Eigenschaften gleich sind. Wobei anzumerken ist, dass hier vermutlich der Äquivalenzvergleich === häufiger anzutreffen ist, weil man vermutlich zum komplexeren Vergleich zweier Objekte sowieso eigenen Code schreiben muss. Die identische Instanz zu erkennen ist hingegen alternativlos.  
                                                
                                               - Sven Rautenberg
                                              
                                              1. hi Sven,

                                                Spannend wirds beim Vergleich von zwei Arrays oder zwei Objekten:

                                                Bei zwei Arrays prüft "==" lediglich, dass dieselben Keys und Values in beiden Arrays vorhanden sind. Mit "===" müssen diese aber außerdem noch in derselben Reihenfolge vorliegen und denselben Typ haben.
                                                Wenn es also nur darum geht, dass die Werte in Array 1, die ich über irgendeine Funktion eingesammelt habe, "gleich" dem Array 2 ist, ist der Vergleich mit "==" vermutlich schlauer, sofern mich die Reihenfolge nicht interessiert, und ich auf die interne Typprüfung verzichten kann.

                                                Also ich sage mal, dass das "nicht sinnvoll" ist und gebe folgenden Code zu bedenken:

                                                  
                                                $myArray1[0] = "1abc";  
                                                $myArray1[1] = "1cde";  
                                                $myArray2["0"] = 1;  
                                                $myArray2["1"] = 1;  
                                                var_dump($myArray1 == $myArray2);  
                                                
                                                

                                                Ergebnis: bool(true)

                                                Da könnte ich jetzt vermutlich noch mehr Unfug einbauen.

                                                Bei Objekten ist es ganz ähnlich: Der strikte Vergleich ist nur dann wahr, wenn ich in den zwei Variablen zweimal dieselbe Instanz des Objekts stehen habe. Der Vergleich mit "==" hingegen ist wahr, wenn die zwei Objekte von derselben Klasse sind und ihre Eigenschaften gleich sind. Wobei anzumerken ist, dass hier vermutlich der Äquivalenzvergleich === häufiger anzutreffen ist, weil man vermutlich zum komplexeren Vergleich zweier Objekte sowieso eigenen Code schreiben muss. Die identische Instanz zu erkennen ist hingegen alternativlos.

                                                  
                                                class Minimal {  
                                                	public function __construct($a, $b) {  
                                                		$this->a = $a;  
                                                		$this->b = $b;  
                                                	}  
                                                }  
                                                $objA = new Minimal("1abc", "2def");  
                                                $objB = new Minimal(1,2);  
                                                var_dump($objA == $objB);  
                                                
                                                

                                                Gibt auch bool(true).

                                                Wie macht das Sinn???

                                                Ich denke, beim Array müsste man vorher sortieren mit keysort oder was auch immer und dann mit "===" vergleichen. Und bei Objekten - wenn ich die überhaupt mal und wenn ja in welchem Anwendungsfall??? vergleichen wollen würde - schreibst Du ja auch, macht dann nur in der Regel  "===" Sinn.

                                                Ich bleibe jetzt mal bei meiner zugegeben etwas provokanten These, dass "==" allenfalls ein Einfallstor für Bugs ist und deshalb _nicht_ verwendet werden sollte ;-). But: I do not want to hurt anybodys feelings!!! ;-)))

                                                mfg

                                                tami

                                                1. Tach!

                                                  Wie macht das Sinn???

                                                  Sinn ist kein Absolut-Kriterium. Sinnvoll ist etwas, das zu einer gegebenen Aufgabenstellung eine Lösung findet und das problemos mit allen, auch ungewöhnlichen Ausgangs- und Randbedingungen. Ohne Aufgabenstellung nur allein mit einem Prinzip ist Sinnhaftigkeit nicht zu beurteilen.

                                                  dedlfix.

                                                  1. hi dedlfix,

                                                    Tach!

                                                    Wie macht das Sinn???

                                                    Sinn ist kein Absolut-Kriterium. Sinnvoll ist etwas, das zu einer gegebenen Aufgabenstellung eine Lösung findet und das problemos mit allen, auch ungewöhnlichen Ausgangs- und Randbedingungen. Ohne Aufgabenstellung nur allein mit einem Prinzip ist Sinnhaftigkeit nicht zu beurteilen.

                                                    Naja, ein potentieller Grad von Fehleranfälligkeit bezieht sich doch auf _jeden_ Anwendungsfall. Ich vermisse auch nach wie vor das konkrete Beispiel. Wer möchte Arrays und/oder Objekte bei welcher Aufgabenstellung vergleichen und es ist ihm egal, ob ein key 0 und der andere "0" ist und auch, ob da in den Werten eine 1 steht oder "1mitGanzVielString".

                                                    Da ich ja mittlerweile mal behaupte, dass es keinen sinnvollen Einsatz dieses "==" gibt [ich mag mich ja täuschen!], kann das nur mit einem konkreten Beispiel "widerlegt" werden. Dann braucht man auch gar nicht weiter theoretisch zu diskutieren. Und so lange es das nicht gibt, bleibt die provokative These in meinen Augen "wahr"(scheinlich).

                                                    mfg Robert aka tami

                                                    1. Tach!

                                                      Sinn ist kein Absolut-Kriterium. Sinnvoll ist etwas, das zu einer gegebenen Aufgabenstellung eine Lösung findet und das problemos mit allen, auch ungewöhnlichen Ausgangs- und Randbedingungen. Ohne Aufgabenstellung nur allein mit einem Prinzip ist Sinnhaftigkeit nicht zu beurteilen.
                                                      Naja, ein potentieller Grad von Fehleranfälligkeit bezieht sich doch auf _jeden_ Anwendungsfall.

                                                      Der obige Satz gilt sinngemäß auch für den Begriff "Fehler".

                                                      dedlfix.

                                                      1. hi dedlfix,

                                                        Sinn ist kein Absolut-Kriterium. Sinnvoll ist etwas, das zu einer gegebenen Aufgabenstellung eine Lösung findet und das problemos mit allen, auch ungewöhnlichen Ausgangs- und Randbedingungen. Ohne Aufgabenstellung nur allein mit einem Prinzip ist Sinnhaftigkeit nicht zu beurteilen.
                                                        Naja, ein potentieller Grad von Fehleranfälligkeit bezieht sich doch auf _jeden_ Anwendungsfall.

                                                        Der obige Satz gilt sinngemäß auch für den Begriff "Fehler".

                                                        Weiß jetzt nicht, wie das zu verstehen ist. Es geht doch wirklich um die grundsätzliche _Anfälligkeit_ für Fehler. In ganz vielen Fällen funktioniert (funzt) es der These zufolge ja. Aber wenns mal nicht "funzt", weil da doch ein String irgendwo reingerutscht ist warum auch immer, dann kommt keiner drauf, an der Stelle zu suchen. Aber umgekehrt: wenn ich mit "===" diesen unscharfen Vergleich ausschließe, schließe ich zu 100% diese Fehlerquelle aus. Sind 100% zu 100% - ?. Aber ohne sinnvolles Beispiel bleibt es doch eh dabei, dass trotz ausgiebiger Diskussion von fachlich mehr oder weniger versierten Personen niemandem ein sinnvolles und nicht fehleranfälliges Beispiel für "==" in PHP eingefallen ist. Das kann man doch mal so stehen lassen, bis eins kommt ;-) ...

                                                        mfg

                                                        tami

                                                        1. Aber ohne sinnvolles Beispiel bleibt es doch eh dabei, dass trotz ausgiebiger Diskussion von fachlich mehr oder weniger versierten Personen niemandem ein sinnvolles und nicht fehleranfälliges Beispiel für "==" in PHP eingefallen ist. Das kann man doch mal so stehen lassen, bis eins kommt ;-) ...

                                                          Zwar nicht wirklich Array oder Objekt aber wäre nicht

                                                          for($i=1; $i<$length; $i++) {  
                                                                 echo $obj->get($i);  
                                                                 if($i % 15 == 0) {  
                                                                        echo "\n";  
                                                                 }  
                                                          }
                                                          

                                                          so ein Beispiel?

                                                          MfG
                                                          bubble

                                                          --
                                                          If "god" had intended us to drink beer, he would have given us stomachs. - David Daye
                                                          1. hi,

                                                            Aber ohne sinnvolles Beispiel bleibt es doch eh dabei, dass trotz ausgiebiger Diskussion von fachlich mehr oder weniger versierten Personen niemandem ein sinnvolles und nicht fehleranfälliges Beispiel für "==" in PHP eingefallen ist. Das kann man doch mal so stehen lassen, bis eins kommt ;-) ...
                                                            Zwar nicht wirklich Array oder Objekt aber wäre nicht

                                                            for($i=1; $i<$length; $i++) {

                                                            echo $obj->get($i);
                                                                   if($i % 15 == 0) {
                                                                          echo "\n";
                                                                   }
                                                            }

                                                            
                                                            > so ein Beispiel?  
                                                              
                                                            Naja, funktioniert das mit "===" nicht? Du weißt doch, dass du nur und ausschließlich hier zwei Ints miteinander vergleichen willst. Alles andere ist implizit \_nicht\_ gewollt. Wenn dir zwischendrin dein $i umgeschrieben würde in ein "" (leerer String, vermutlich auch leeres Array würde gehen oder auch leeres Objekt?), wäre dein Vergleich immer noch richtig (was bei einem zusätzlichen Absatz u.U. nicht so tragisch wäre). Das willst du im strengeren Sinne, und nur darum geht es, aber nicht zulassen. Von den Beispielen, dass es auch mit "==" "funzt", gibt es natürlich eine Menge.  
                                                              
                                                            Du schreibst ja auch nicht statt 1+2=3 1+2 ungefähr gleich 3, obwohl es stimmt (=funzt) ...;  
                                                              
                                                            mfg  
                                                              
                                                            tami
                                                            
                                                            1. Tach!

                                                              if ($i % 15 == 0) {
                                                              Wenn dir zwischendrin dein $i umgeschrieben würde [...]

                                                              ... dann hast du ein Problem, bei dem dir dein === weder ein richtiges Ergebnis zaubert, noch dich informiert, dass da was kaputt ist. Es bringt also gar nichts in diesem Fall. Es ist einfach nur sinnlos, hier auf den exakten Typ zu prüfen.

                                                              dedlfix.

                                                              1. hi,

                                                                Tach!

                                                                if ($i % 15 == 0) {
                                                                Wenn dir zwischendrin dein $i umgeschrieben würde [...]

                                                                ... dann hast du ein Problem, bei dem dir dein === weder ein richtiges Ergebnis zaubert, noch dich informiert, dass da was kaputt ist. Es bringt also gar nichts in diesem Fall. Es ist einfach nur sinnlos, hier auf den exakten Typ zu prüfen.

                                                                Ja, das errinnert an Crockford und die Argumentationen im Bereich Javascript. Es liegt an dem einen Zeichen mehr. Du willst eigentlich nur prüfen, ob beide Werte 0 sind. Prüfst aber gleichzeitig (Performance) auch noch die 20 anderen Fälle, in denen diese Aussage wahr ist. Dadurch bist Du potentiell (nicht in jedem Fall) unscharf und fehleranfällig. Ich bleibe dabei, dass sich diese Diskussion auch was die "Emotionen" angeht, mit der Crockford-Javascript-JSLint-Diskussion im Wesentlichen deckt. Ich suche mal einen Vortrag von Crockford raus, wo es darum und auch zB. um das "fall-through" beim Switch geht. Da geht es auch um die Psychodynamik (Crockford war erst auch sicher, dass man mit einem switch keinen Fehler bauen könnte bzw. ihm ein Fallthrough nicht passiert). Keine Ahnung, ob das bei PHP in Bezug auf ein Switch ähnlich ist. Ich beziehe mich jetzt mal nur auf "==" vs. "===".

                                                                mfg

                                                                tami

                                                2. Moin!

                                                  Also ich sage mal, dass das "nicht sinnvoll" ist und gebe folgenden Code zu bedenken:

                                                  Du kannst immer Code konstruieren, der den Unsinn irgendeiner Methode demonstriert.

                                                  $myArray1[0] = "1abc";
                                                  $myArray1[1] = "1cde";
                                                  $myArray2["0"] = 1;
                                                  $myArray2["1"] = 1;
                                                  var_dump($myArray1 == $myArray2);

                                                  
                                                  > Ergebnis: bool(true)  
                                                    
                                                  Numerische Strings werden übrigens immer in Integer gewandelt. PHP kann keine numerischen Strings als Array-Key, außer man castet ein Object zum Array - und kriegt damit eklige Probleme.  
                                                    
                                                  Mein Gegenbeispiel:  
                                                  ~~~php
                                                    
                                                  $myArray1[0] = "1abc";  
                                                  $myArray1[1] = "1cde";  
                                                  $myArray2[1] = "1cde";  
                                                  $myArray2[0] = "1abc";  
                                                  var_dump($myArray1 == $myArray2);  
                                                  var_dump($myArray1 === $myArray2);  
                                                    
                                                  
                                                  

                                                  Ergebnis: bool(true) und bool(false)

                                                  Wie macht das Sinn???

                                                  Macht ziemlich viel Sinn im richtigen Kontext - und genau darum gehts. Wenn ich annähernd identische Arrays aus derselben Quelle kriege und sie vergleichen will, aber die Key-Reihenfolge ist eventuell unterschiedlich...

                                                  Ich denke, beim Array müsste man vorher sortieren mit keysort oder was auch immer und dann mit "===" vergleichen.

                                                  Sortieren kostet Zeit. Und ich muss direkt zweimal sortieren, statt direkt nur einmal zu vergleichen.

                                                  - Sven Rautenberg

                                                  1. hi Sven,

                                                    Moin!

                                                    Also ich sage mal, dass das "nicht sinnvoll" ist und gebe folgenden Code zu bedenken:

                                                    Du kannst immer Code konstruieren, der den Unsinn irgendeiner Methode demonstriert.

                                                    Nö, mit "===" nicht, oder?

                                                    Macht ziemlich viel Sinn im richtigen Kontext - und genau darum gehts. Wenn ich annähernd identische Arrays aus derselben Quelle kriege und sie vergleichen will, aber die Key-Reihenfolge ist eventuell unterschiedlich...

                                                    Ja, ich wüsste jetzt zwar nicht, wie man das zustande kriegt, dass die Arrays nicht die korrekte Reihenfolge haben, aber mag ja sein. Die Kosten ("trade off" - s. Link zu Crockfords Vortrag) sind, dass die Werte im Array auch nur mit "==" verglichen werden. Wenn Du sagst, dass die Quelle sicher ist und dieser Vergleich (wahrscheinlich ;-) keinen Fehler produziert, ist das ja ein gutes Beispiel.

                                                    Mein Gegenbeispiel:

                                                    $myArray1[0] = "1abc";
                                                    $myArray1[1] = "1cde";
                                                    $myArray2[1] = "1cde";
                                                    $myArray2[0] = "1abc";
                                                    var_dump($myArray1 == $myArray2);
                                                    var_dump($myArray1 === $myArray2);

                                                    
                                                    > Ergebnis: bool(true) und bool(false)  
                                                      
                                                    O.k., die Alternative mit 100%igem Vergleich des Inhalts:  
                                                      
                                                    ~~~php
                                                    $myArray1[0] = "1abc";  
                                                    $myArray1[1] = "1cde";  
                                                    $myArray2[1] = "1cde";  
                                                    $myArray2[0] = "1abc";  
                                                    var_dump($myArray1 == $myArray2); // Inhalt wird "nur" mit "==" verglichen  
                                                    sort($myArray1);  
                                                    sort($myArray2);  
                                                    var_dump($myArray1 === $myArray2); // Inhalt ist jetzt 100% ident geprüft  
                                                    
                                                    

                                                    Klar, zwei Zeilen mehr mit jeweils einmal sort();

                                                    Sortieren kostet Zeit. Und ich muss direkt zweimal sortieren, statt direkt nur einmal zu vergleichen.

                                                    Wobei wohl 1. der PHP-Prozessor sowieso intern sotieren muss, sonst kriegt er die beiden Arrays ja nicht verglichen und 2. du nicht 100% sicher bist, dass die Inhalte/Werte 100% ident sind.

                                                    Ich füge hier mal den Link zum Crockfordvortrag ein, mit einer "Trackliste" bis zum zweiten drittel (double vs. triple equal).

                                                    Programming Style and Your Brain
                                                    14:48 - on javascript, but applicable for all languages
                                                    16:58 - hey my code does not work
                                                    17:15 - discipline
                                                    17:44 - jslint will hurt your feeling
                                                    18:44 - curly braces (coding style) - left or right
                                                    20:22 - start making up reasons (for left or right)
                                                    21:17 - be consitent [klar]
                                                    22:28 - design-error (semikolon insertion) [only javascript]
                                                    23:07 - prefer forms that are error resistant
                                                    23:29 - 0 cost big benefit
                                                    23:47 - switch statement story
                                                    26:07 - "that hardly ever happens" is another way of saying "it happens"
                                                    27:33 - good style can produce better programs
                                                    29:39 - reducing error rate in mideval
                                                    31:10 - programs must communicate clearly to people
                                                    32:04 - spaces
                                                    33:46 - immediately invocable function expressions [only javascript]
                                                    35:50 - semikolon insertion again [javascript only]
                                                    36:15 - with-statement [dont use] ... 37:15 "but sometimes its usefull..."
                                                    37:00 - confusion must be broken
                                                    37:30 - double equal vs. triple equal (its hard to tell if its beeing used right)
                                                    39:00 - If there is a feature of a language that is sometimes problematic,
                                                            and if it can be replaced with another feature that ist more reliable,
                                                            then always use the more reliable feature

                                                    ... geht noch weiter, ingesamt eine Stunde.

                                                    mfg

                                                    tami

                                          2. Om nah hoo pez nyeetz, tami!

                                            oder auch aktuell aus dem Forum, allerdings aus dem Bereich JavaScript: t=215256&m=1473846 ff.

                                            Matthias

                                            --
                                            Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Sau und Sauron.

  2. hi,

    Ich kenne das aus Java und da kriegt man Fehler geschmissen. Ist es dann die korrekte Art die Initialisierung wegzulassen?

    Auch wenn dedlfix aufs Zend-Framework nicht so steht, finde ich, dass ein Blick, grade wenn man schon mit anderen Sprachen zu tun hat(te) was bringen kann:

    http://framework.zend.com/manual/1.12/en/coding-standard.coding-style.html

    mfg

    tami

    1. Tach!

      Ich kenne das aus Java und da kriegt man Fehler geschmissen. Ist es dann die korrekte Art die Initialisierung wegzulassen?
      Auch wenn dedlfix aufs Zend-Framework nicht so steht, finde ich, dass ein Blick, grade wenn man schon mit anderen Sprachen zu tun hat(te) was bringen kann:
      http://framework.zend.com/manual/1.12/en/coding-standard.coding-style.html

      Der ZF-Coding-Style sagt nur nichts zum Thema Initialisierung von Variablen aus, sondern wie Code aussehen muss, der Variablen etwas zuweist.

      Du hättest auch auf den allgemeinen PHP-Coding Standard PSR verweisen können, aber auch der sagt nichts zur Initialisierung aus, sondern nur zur Schreibweise.

      dedlfix.

      1. hi,

        Tach!

        Ich kenne das aus Java und da kriegt man Fehler geschmissen. Ist es dann die korrekte Art die Initialisierung wegzulassen?
        Auch wenn dedlfix aufs Zend-Framework nicht so steht, finde ich, dass ein Blick, grade wenn man schon mit anderen Sprachen zu tun hat(te) was bringen kann:
        http://framework.zend.com/manual/1.12/en/coding-standard.coding-style.html

        Der ZF-Coding-Style sagt nur nichts zum Thema Initialisierung von Variablen aus, sondern wie Code aussehen muss, der Variablen etwas zuweist.

        Du hättest auch auf den allgemeinen PHP-Coding Standard PSR verweisen können, aber auch der sagt nichts zur Initialisierung aus, sondern nur zur Schreibweise.

        Naja, wenn man das mit dem Coding-Standard von JSLint / Douglas Crockford (http://www.jslint.com/ vergleicht, schon.

        Die geben doch keine Beispiele (Funktionen ohne(!) Deklaration), wenn sie das nicht in ihren Beispielen dann korrekt machen. Im Gegensatz dazu mecker JSLint, wenn man die Variablen nicht initialisiert, auch wenn das in Javascript keinen Fehler werfen würde.

        Es lohnt sich auch, mal eine der Zend-Framework-Dateien zu öffnen und anzuschauen, wie sie dort die Variablen initialisieren.

        mfg

        tami

        1. Tach!

          Es lohnt sich auch, mal eine der Zend-Framework-Dateien zu öffnen und anzuschauen, wie sie dort die Variablen initialisieren.

          Alles schön und gut, nur sind das üblicherweise nur Anwendungen von Wissen/Regeln/Mustern. Da steht meist nicht daneben, warum das so geschrieben/verwendet wurde. Erst wenn man das Wissen zur Funktionsweise hat, kann man in den vorhandenen Bibliotheken lesen und in dem Code die Muster etc. erkennen.

          dedlfix.

          1. hi,

            Tach!

            Es lohnt sich auch, mal eine der Zend-Framework-Dateien zu öffnen und anzuschauen, wie sie dort die Variablen initialisieren.

            Alles schön und gut, nur sind das üblicherweise nur Anwendungen von Wissen/Regeln/Mustern. Da steht meist nicht daneben, warum das so geschrieben/verwendet wurde. Erst wenn man das Wissen zur Funktionsweise hat, kann man in den vorhandenen Bibliotheken lesen und in dem Code die Muster etc. erkennen.

            Ausschnitt aus der View.php

              
            class Zend_View extends Zend_View_Abstract  
            {  
                /**  
                 * Whether or not to use streams to mimic short tags  
                 * @var bool  
                 */  
                private $_useViewStream = false;  
              
                /**  
                 * Whether or not to use stream wrapper if short_open_tag is false  
                 * @var bool  
                 */  
                private $_useStreamWrapper = false;  
              
                /**  
                 * Constructor  
                 *  
                 * Register Zend_View_Stream stream wrapper if short tags are disabled.  
                 *  
                 * @param  array $config  
                 * @return void  
                 */  
                public function __construct($config = array())  
                {  
                    $this->_useViewStream = (bool) ini_get('short_open_tag') ? false : true;  
                    if ($this->_useViewStream) {  
                        if (!in_array('zend.view', stream_get_wrappers())) {  
                            require_once 'Zend/View/Stream.php';  
                            stream_wrapper_register('zend.view', 'Zend_View_Stream');  
                        }  
                    }  
              
                    if (array_key_exists('useStreamWrapper', $config)) {  
                        $this->setUseStreamWrapper($config['useStreamWrapper']);  
                    }  
              
                    parent::__construct($config);  
                }  
            
            

            erkennt man doch schon einiges ...;

            mfg

            tami

  3. Moin!

    Anscheinend muss man $m in der Methode bla() nicht erst initialisieren?
    Ich kenne das aus Java und da kriegt man Fehler geschmissen. Ist es dann die korrekte Art die Initialisierung wegzulassen?

    Nein, das ist nicht korrekt.

    Erstens: Du kriegst von PHP dazu auch Meckerei, allerdings nur in Form einer Notice (sofern du sie nicht abgeschaltet hast). Das heißt also, dass PHP das zwar nicht schön findet, aber trotzdem weitermacht.

    Aber zweitens: Solche Notices kommen ja nicht ohne Grund. Wenn man pauschal nie seine Variablen initialisiert, dann kann man sich vor Notices nicht mehr retten, und muss sie gezwungenermaßen ignorieren, aber der ordentliche Programmierer initialisiert seine Variablen. Und dann sind solche Notices eine wertvolle Debugginghilfe, denn eine nicht initialisierte Variable kann dann eigentlich nur einen Tippfehler im Variablennamen bedeuten.

    Und drittens: Notices zu generieren ist nicht kostenlos. Es kostet Performance. Also selbst wenn man gegen das Ordnungsargument aus Punkt 2 immun ist, schadet man sich im Hinblick auf die Ausführungsgeschwindigkeit.

    Und ja, nicht initialisierte Variablen haben den Wert "NULL".

    - Sven Rautenberg

    1. hi Sven,

      Und ja, nicht initialisierte Variablen haben den Wert "NULL".

      Du kennst das ZendFramework ja sehr gut. Ist es denn in Deinen Augen Unsinn, dass die schreiben:

      private static $_registry = null;  
      
      

      in der Klasse:

        
      class Zend_Registry extends ArrayObject  
      {  
          /**  
           * Class name of the singleton registry object.  
           * @var string  
           */  
          private static $_registryClassName = 'Zend_Registry';  
        
          /**  
           * Registry object provides storage for shared objects.  
           * @var Zend_Registry  
           */  
          private static $_registry = null;  
      
      

      S.a. https://forum.selfhtml.org/?t=215185&m=1473243 ff. und dedlfix Argument der "Prinzipienbefriedigung"

      mfg

      Robert aka tami fka ...

      1. Tach!

        Du kennst das ZendFramework ja sehr gut. Ist es denn in Deinen Augen Unsinn, dass die schreiben:
        [...]
        S.a. https://forum.selfhtml.org/?t=215185&m=1473243 ff. und dedlfix Argument der "Prinzipienbefriedigung"

        Zusatzfrage: Wie ist es mit dem Konstrukt in https://forum.selfhtml.org/?t=215185&m=1473238? Da wird $_useViewStream mit false initialisiert und dann im Konstruktor überschrieben zu werden. Genauso technisch sinnlos, wie ein null zuzuweisen, was sowieso drin steht. Bei in der Klassendefinition aufgeführten Klassen- und Objektvariablen gilt für das Anlegen nicht das Prinzip des ersten Zugriffs wie bei einfachen Variablen. Sie sind sofort mit dem angegebenen Wert oder null als Inhalt vorhanden.

        dedlfix.

      2. Moin!

        hi Sven,

        Und ja, nicht initialisierte Variablen haben den Wert "NULL".

        Du kennst das ZendFramework ja sehr gut. Ist es denn in Deinen Augen Unsinn, dass die schreiben:

        private static $_registry = null;

          
        Nein, das würde ich vom Kontext abhängig machen.  
          
        In einer Klasse, in der ausnahmslos alle Eigenschaften ohne Standardwert angelegt werden, hielte ich das Hinzufügen von "= null" für redundant.  
          
        Aber wenn die Initialwerte sich a) unterscheiden und b) relevant für das Funktionieren der Klasse sind (also z.B. nur eventuell von einem Konstruktor- oder Setter-Parameter überschrieben werden), würde ich den Initialwert einer nicht weiter definierten Eigenschaft durchaus kenntlich machen.  
          
        
        > in der Klasse:  
        >   
        > class Zend\_Registry extends ArrayObject  
          
        Das ist jetzt allerdings nicht die allerschönste Klasse, die man da als Beispiel heranziehen kann. Registries sind objektorientiert verkleidete globale Variablen - und die sind bekanntermaßen böse.  
          
         - Sven Rautenberg