PHPLerner: Hilfe bei PHP Erklärungen

Liebe Self Gemeinde,

bei stöbern im Netz bin ich auf ein paar PHP Übungen und Fragen gestossen. (teilweise Zend)

Manches ist mir nicht so klar, daher mal meine Bitte ob jemand mal meine Erklärungsversuche durchsieht oder genaue Infos dazu gibt. Hier die Fragen:

Beispiel1:

$x = "08";
$y = 08;
$z = "47";

$x += 15;
$y += "15";
$z += 11;

echo $x $y $z;

Liefert als Ergebnis:

231558

Ist das so weil:

Der Wert 23 bei $x weil PHP den String "08" automatisch als Zahl 8 erkennt und 8 + 15 = 23 ist?

Der Wert 15 bei $y weil PHP die Zahl 08 als 0 interpretiert und daher Gesamt = 15 ergibt?

Der wert 58 bei $z weil PHP den String "47" als Zahl 47 interpretiert und + 11 dann 58 ergibt?

Beispiel 2

Warum bringt dieser Code Syntax Error?

define ('CONSTANT', 1);
define ('_CONSTANT', 0);
define ('EMPTY', ''); 
if (!empty(EMPTY)) { //hier erster Syntax Error
		if (!(boolean) _CONSTANT)) { // wirft auch einen Fehler
		print "One";
			}
} else if (constant('CONSTANT') == 1) {
		print "Two";
}

Kommt der erste Fehler weil empty() nur bei Variablen geht? Wenn man dann aber den Code ändert nach if (EMPTY == "")) { ..passt es trotzdem nicht? Weil EMPTY ein geschützter Begriff ist? Mit _EMPTY geht es.

Was passt PHP an dieser Zeile nicht? if (!(boolean) _CONSTANT)) {

Beispiel 3

$x = (bool) " " * (int) (string) 12E-1; echo $x;

Ergibt 1 aber warum?

Was macht denn überhaupt (string) 12E-1 und wofür steht 12E-1 ? Wenn man nur echo (string) 12E-1 eingibt kommt 1,2 zu Stande

Beispiel 4

$p = "PHP";
$P = "php";
echo ($p < $P) + 2 * ($p > $P) + 3 * ($p == $P);

Das ergibt 1.

echo ($p < $P) ; ergibt 1 aber warum? wäre doch wie PHP ist kleiner php. Wird hier nach Groß Kleinschreibung verglichen? echo ($p > $P) ergibt "Leer" aber warum? und ($p == $P); ist vermutlich false

Wie muss man dann obiges Konstrukt lesen? Etwa so?

3 * false ist 0 plus 2 + Leer ist 0 plus 1 von ($p < $P) ist dann als Ergebnis 1 ?

Beispiel 5

$str = 'abcdef';
if (strpos($str, 'a')) {
	echo "Zeichen 'a' gefunden";
} else {
	
	echo "Buchstabe 'a' wurde nicht gefunden";
}

Warum wird hier immer in den Else Zweig gesprungen? Weil das Zeichen a am Anfang vom String steht und daher 0 liefert ?

Danke Gruss

  1. Tach!

    Der Wert 23 bei $x weil PHP den String "08" automatisch als Zahl 8 erkennt und 8 + 15 = 23 ist?

    Ja.

    Der Wert 15 bei $y weil PHP die Zahl 08 als 0 interpretiert und daher Gesamt = 15 ergibt?

    Vor PHP 7 wurden Oktalzahlen mit fehlerhaften Stellen vor dieser Stelle abgeschitten. Die 8 ist falsch, die 0 bleibt übrig. Bei 018 beispielsweise käme 1 raus. Ab PHP7 soll das einen Parse-Fehler geben. http://php.net/manual/en/language.types.integer.php

    Der wert 58 bei $z weil PHP den String "47" als Zahl 47 interpretiert und + 11 dann 58 ergibt?

    Ja.

    if (!empty(EMPTY)) { //hier erster Syntax Error

    empty() erwartete bis PHP 5.5 eine Variable.

      if (!(boolean) _CONSTANT)) { // wirft auch einen Fehler
    

    Bitte Fehlermeldungen nicht nur erwähnen, sondern auch ihren Inhalt anführen. Da ist eine Klammer) zu viel.

    Wenn man dann aber den Code ändert nach if (EMPTY == "")) { ..passt es trotzdem nicht?

    Wegen der überflüssigen Klammer.

    Was macht denn überhaupt (string) 12E-1 und wofür steht 12E-1 ?

    Das (string) ist eine Typkonvertierung, 12E-1 ist die Literalschreibweise für eine Exponentialzahl (hier: 12 mal 10 hoch -1).

    $x = (bool) " " * (int) (string) 12E-1;
    echo $x;

    Ergibt 1 aber warum?

    Das Leerzeichen typkonvertiert nach Boolean ergibt true. 12E-1 konvertiert nach String ergibt "1.2", konvertiert nach int ergibt 1, true im numerischen Kontext ist 1, 1*1 = 1.

    echo ($p < $P) ; ergibt 1 aber warum? wäre doch wie PHP ist kleiner php. Wird hier nach Groß Kleinschreibung verglichen? echo ($p > $P) ergibt "Leer" aber warum? und ($p == $P); ist vermutlich false

    Nimm mal lieber var_dump(), das ist genauer als echo, denn echo ändert bestimmte Werte beim Ausgeben. true wird zu 1 beispielsweise. Und dann teste die Ausdrücke einzeln. Wirds dann klarer?

    if (strpos($str, 'a')) {

    Warum wird hier immer in den Else Zweig gesprungen? Weil das Zeichen a am Anfang vom String steht und daher 0 liefert ?

    Ja. Siehe Handbuch zur Funktion strpos() für die Umgehung des Problems. Handbuchlesen ist immer eine gute Idee, besonders bei unbekannten Funktionen.

    dedlfix.

    1. Tach!

      Achja, die Type Comparison Table ist auch immer eine gute Anlaufstelle, um die Eigenheiten PHPs beim Typkonvertieren zu sehen. Andere Sprachen machen das nämlich teilweise anders.

      dedlfix.

    2. Hallo,

      Der Wert 15 bei $y weil PHP die Zahl 08 als 0 interpretiert und daher Gesamt = 15 ergibt?

      Vor PHP 7 wurden Oktalzahlen mit fehlerhaften Stellen vor dieser Stelle abgeschitten. Die 8 ist falsch, die 0 bleibt übrig. Bei 018 beispielsweise käme 1 raus. Ab PHP7 soll das einen Parse-Fehler geben. http://php.net/manual/en/language.types.integer.php

      ah, interessant.

      12E-1 ist die Literalschreibweise für eine Exponentialzahl (hier: 12 hoch -1).

      nein, sondern 12 mal 10 hoch -1.

      So long,
       Martin

      --
      Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
      - Douglas Adams, The Hitchhiker's Guide To The Galaxy
      1. Tach!

        12E-1 ist die Literalschreibweise für eine Exponentialzahl (hier: 12 hoch -1).

        nein, sondern 12 mal 10 hoch -1.

        Hab ich doch geschrieben, du musst dich verlesen haben ... ;)

        dedlfix.

    3. $y = 08;
      

      Ab PHP7 soll das einen Parse-Fehler geben. http://php.net/manual/en/language.types.integer.php

      Falls das "soll" als Gerücht begriffen wird: Ich kann dieses weitaus bessere Verhalten von PHP7 bestätigen:

      PHP Parse error:  Invalid numeric literal in ...
      

      PHP-Versionen unter 7 geben nicht einmal eine Notiz aus. Daten stillschweigend zu verändern ist (ob dokumentiert oder nicht) schlicht und einfach "Mist".

  2. Hallo,

    Manches ist mir nicht so klar, daher mal meine Bitte ob jemand mal meine Erklärungsversuche durchsieht oder genaue Infos dazu gibt.

    schau'mer mal ... :-)

    $x = "08";
    $y = 08;
    $z = "47";
    
    $x += 15;
    $y += "15";
    $z += 11;
    
    echo $x $y $z;
    

    Liefert als Ergebnis:

    231558

    Ist das so weil:

    Der Wert 23 bei $x weil PHP den String "08" automatisch als Zahl 8 erkennt und 8 + 15 = 23 ist?

    Ja.

    Der Wert 15 bei $y weil PHP die Zahl 08 als 0 interpretiert und daher Gesamt = 15 ergibt?

    Ja. Hier ist es etwas gemeiner: Zahlen, die mit einer führenden Null notiert werden, interpretiert PHP als Oktalzahlen. Aber eigentlich würde ich bei der Zuweisung $y = 08; schon einen Syntaxfehler erwarten, weil es im Oktalsystem keine Ziffer 8 gibt.

    Der wert 58 bei $z weil PHP den String "47" als Zahl 47 interpretiert und + 11 dann 58 ergibt?

    Ja. Identisch mit dem ersten Fall.

    define ('CONSTANT', 1);
    define ('_CONSTANT', 0);
    define ('EMPTY', ''); 
    if (!empty(EMPTY)) { //hier erster Syntax Error
    		if (!(boolean) _CONSTANT)) { // wirft auch einen Fehler
    		print "One";
    			}
    } else if (constant('CONSTANT') == 1) {
    		print "Two";
    }
    

    Kommt der erste Fehler weil empty() nur bei Variablen geht?

    Ja, korrekt.

    Wenn man dann aber den Code ändert nach if (EMPTY == "")) { ..passt es trotzdem nicht?
    Weil EMPTY ein geschützter Begriff ist?

    Nicht exakt ein geschützter Begriff - aber bei Funktionen und funktions-ähnlichen Konstrukten ist PHP nicht case-sensitive. Der Bezeichner EMPTY wäre daher identisch mit der Pseudofunktion empty().

    Was passt PHP an dieser Zeile nicht?
    if (!(boolean) _CONSTANT)) {

    Kann ich auf Anhieb nicht sagen.

    
    > $x = (bool) " " * (int) (string) 12E-1;
    > echo $x;
    
    

    Ergibt 1 aber warum?

    Mal langsam. Also: 12E-1 ist normalisiert 1.2, also steht da (string) 1.2, und das ergibt den String "1.2". Dann ein Typecasr nach int, und man erhält 1. Der zweite Faktor der Multiplikation ist also 1. Davor steht (bool) " ", und ein nicht-leerer String ergibt im boolschen Kontext true, also 1.

    Was macht denn überhaupt (string) 12E-1

    Es wandelt den float-Zahlenwert in einen String um.

    und wofür steht 12E-1 ?

    Das ist die wissenschatliche Notation und steht als Abkürzung für 12 * 10⁻¹, aber üblicherweise normalisiert man die Darstellung dann so, dass die Mantisse im Bereich [1.0 .. 10.0[ liegt. Also ist der Ausdruck gleichwertig mit 1.2 * 10⁰.

    Wenn man nur echo (string) 12E-1 eingibt kommt 1,2 zu Stande

    Eben. qed. :-)

    $p = "PHP";
    $P = "php";
    echo ($p < $P) + 2 * ($p > $P) + 3 * ($p == $P);
    

    Das ergibt 1.

    echo ($p < $P) ; ergibt 1 aber warum? wäre doch wie PHP ist kleiner php. Wird hier nach Groß Kleinschreibung verglichen?

    Exakt. Es wird Zeichen für Zeichen verglichen, und "P" hat den Code 0x50, "p" den Code 0x70. Groß- und Kleinbuchstaben sind einfach verschiedene Zeichen, und die Großbuchstaben kommen in der Codetabelle zuerst.

    echo ($p > $P) ergibt "Leer" aber warum?

    Was meinst du mit "Leer"? Nein, das sollte false ergeben, also numerisch interpretiert 0.

    und ($p == $P); ist vermutlich false

    Ja.

    Wie muss man dann obiges Konstrukt lesen? Etwa so?

    3 * false ist 0 plus 2 + Leer ist 0 plus 1 von ($p < $P) ist dann als Ergebnis 1 ?

    Ja, nur dass ich mit dem "Leer" nicht einverstanden bin und da auch false erwarten würde.

    $str = 'abcdef';
    if (strpos($str, 'a')) {
    	echo "Zeichen 'a' gefunden";
    } else {
    	
    	echo "Buchstabe 'a' wurde nicht gefunden";
    }
    

    Warum wird hier immer in den Else Zweig gesprungen?
    Weil das Zeichen a am Anfang vom String steht und daher 0 liefert ?

    Genau, und 0 ist, als boolscher Wert interpretiert, false. Also ist die Bedinung nicht erfüllt. Bei solchen Funktionen, die 0 als gültigen Wert zurückgeben können, muss man höllisch aufpassen. Am besten ist in so einem Fall, typsicher zu vergleichen:

    $str = 'abcdef';
    if (strpos($str, 'a')!==false) {
    	echo "Zeichen 'a' gefunden";
    } else {
    	
    	echo "Buchstabe 'a' wurde nicht gefunden";
    }
    

    Der Operator !== bewirkt hier einen exakten Vergleich, bei dem keine automatische Typumwandlung stattfindet.

    So long,
     Martin

    --
    Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
    - Douglas Adams, The Hitchhiker's Guide To The Galaxy
    1. Hallo,

      Dann ein Typecasr nach int,

      Wir haben früher mal "Typecast" gesagt, aber heute nimmt man sowas ja nicht mehr so genau... ;)

      Gruß
      Kalk

      PS: Bestimmt machst du hier gleich den Dedlfix und sagst, dass du das doch geschrieben hast

      1. Hi,

        Dann ein Typecasr nach int,

        Wir haben früher mal "Typecast" gesagt, aber heute nimmt man sowas ja nicht mehr so genau... ;)

        ja, das muss man entspannt sehen. Manchmal nehme ich einfach die Tasten, die zufällig gerade da sind und um die Gunst der Finger wetteifern. :-)

        PS: Bestimmt machst du hier gleich den Dedlfix und sagst, dass du das doch geschrieben hast

        Nö, das wäre ja langweilig.

        So long,
         Martin

        --
        Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
        - Douglas Adams, The Hitchhiker's Guide To The Galaxy
      2. Hi,

        Dann ein Typecasr nach int,

        Wir haben früher mal "Typecast" gesagt, aber heute nimmt man sowas ja nicht mehr so genau... ;)

        in Zeiten von Flickr, Frappr, Twittr usw. ist Typecasr doch ganz okr ...

        cu,
        Andreas a/k/a MudGuard