it-swarm.com.de

make switch use === Vergleich nicht == Vergleich In PHP

Gibt es trotzdem etwas, damit der folgende Code immer noch einen Schalter verwendet und b nicht a zurückgibt? Vielen Dank!

$var = 0;
switch($var) {
    case NULL : return 'a'; break;
    default : return 'b'; break;
}

Mit if-Anweisungen würden Sie das natürlich so machen:

$var = 0;
if($var === NULL) return 'a';
else return 'b';

Bei komplexeren Beispielen wird dies jedoch ausführlich.

64
Aaron Yodaiken

Entschuldigung, Sie können keinen ===-Vergleich in einer switch-Anweisung verwenden, da laut switch () Dokumentation :

Beachten Sie, dass der Switch/Case den Vergleich verliert.

Dies bedeutet, dass Sie eine Problemumgehung finden müssen. Von der lockeren Vergleichstabelle können Sie die Tatsache nutzen, dass NULL == "0" durch Typumwandlung falsch ist:

<?php
$var = 0;
switch((string)$var) 
{
    case "" : echo 'a'; break; // This tests for NULL or empty string   
    default : echo 'b'; break; // Everything else, including zero
}
// Output: 'b'
?>

Live Demo

48
Peter Ajtai

Nicht bei switch - es werden nur sogenannte "lose" Vergleiche durchgeführt. Sie können ihn jederzeit durch einen if/else if-Block ersetzen, indem Sie === verwenden.

7
Adam Wright

Vermutlich schalten Sie die Variable ein und erwarten Ganzzahlen. Warum nicht einfach den Integer-Status der Variablen vorher mit is_int($val) prüfen?

3
Matt Esch

Ich hatte das gleiche Problem in einem Switch mit einem String, der Zahlen enthielt ("15.2" entspricht "15.20" in einem Switch für PHP).

Ich habe das Problem gelöst, einen Buchstaben vor dem zu vergleichenden Text hinzugefügt

$var = '15.20';
switch ('#'.$var) {
    case '#15.2' :
      echo 'wrong';
    break;
    case '#15.20' :
      echo 'right';
    break;
}
3
caiofior

make switch use === Vergleich nicht == Vergleich in PHP

Leider verwendet switch einen losen Vergleich und soweit ich weiß, gibt es keine Möglichkeit, das zu ändern.

1
quantumSoup

Nee. Von der Handbuchseite :

Beachten Sie, dass Switch/Case lockeren Vergleich macht. 

Wenn Sie nur zwei Bedingungen haben, verwenden Sie eine if wie Ihr zweites Beispiel. Ansonsten prüfen Sie zuerst nach NULL und schalten Sie die anderen Möglichkeiten ein:

if (is_null($var))
{
  return 'a';
}

switch ($var)
{
    // ...
}
1

Die switch-Anweisung in PHP löst nur Vergleiche (==) auf http://www.php.net/manual/de/control-structures.switch.php

Verwenden Sie if/elseif/else, wenn Sie strenge Vergleiche benötigen.

1
Esteban

Hier ist Ihr ursprünglicher Code in einer "strengen" switch-Anweisung:

switch(true) {
    case $var === null:
        return 'a';
    default:
        return 'b';
}

Dies kann auch komplexere switch-Anweisungen wie folgt behandeln:

switch(true) {
    case $var === null:
        return 'a';
        break;
    case $var === 4:
    case $var === 'foobar':
        return 'b';
    default:
        return 'c';
        break;
}
1
thespacecamel

Ich benutze einfach 

$var === null and $var = -1; // since switch is not type-safe
switch ( $var ) {
    case 0:
        # this tests for zero/empty string/false
        break;
    case -1:
        # this tests for null
        break;
}

Ich denke, das sieht immer noch sehr gut aus, wenn der Kommentar, der mit // beginnt, zurückbleibt (und diejenigen, die mit # beginnen, werden wahrscheinlich am besten gelöscht).

1
raveren

Das ist nicht möglich.

Sie können jedoch die if-Anweisungen inside die switch einfügen:

switch($var) {
    // Loose cases here

    case 0:
        if($var === NULL) {
            return 'a';
        }

        // Fall through

    default:
        return 'b';
}

Oder einfach:

switch($var) {
    // Loose cases here

    default:
        if($var === NULL) {
            return 'a';
        }

        return 'b';
}
0
strager

Eine der besten Möglichkeiten ist, den NULL-Wert mithilfe von is_null zu überprüfen.

<?php
echo getValue();
function getValue()
{
    $var = 0;   
    switch(true) {
        case is_null($var) : return 'a'; break;
        default : return 'b'; break;
    }
}
?>
0

Sie können auch den Typ der Variablen einschalten:

switch (gettype($var)) {
...
}
0
greg

Wenn Sie sowohl value als auch type Ihrer Variablen testen möchten, erstellen Sie eine neue string - Variable , die beide Informationen enthält, und vergleichen Sie sie mit Ihren verschiedenen Szenarien (durch Verkettung) ) es sollte für Ihren Fall funktionieren, wenn Sie alle möglichen Typen implementieren (gemäß gettype () documentation ), Beispiel:

<?php
    $var= 9999;
    $valueAndTypeOfVar = (string)$var.' '.gettype($var);
    switch($valueAndTypeOfVar) {
        case "$var boolean" : echo 'a'; break;
        case "$var integer" : echo 'b'; break; 
        case "$var double" : echo 'c'; break;
        case "$var string" : echo 'd'; break; 
        case "$var array" : echo 'e'; break;
        case "$var object" : echo 'f'; break; 
        case "$var resource" : echo 'g'; break;
        case "$var NULL" : echo 'h'; break; 
        case "$var unknown type" : echo 'i'; break; 
        default: echo 'j'; break;
    }

   // Outputs: 'b'
?>

Erstellen Sie eine aussageähnliche Klasse und fügen Sie die gewünschte Logik ein. Solange "true" -Methoden $this zurückgeben (und nichts anderes, um Fehlalarme zu vermeiden.)

class Haystack
{
    public $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function isExactly($n)
    {
        if ($n === $this->value)
            return $this;
    }
}

$var = new Haystack(null);

switch ($var) {
    case $var->isExactly(''):
        echo "the value is an empty string";
        break;

    case $var->isExactly(null):
        echo "the value is null";
        break;
}

Oder Sie können Ihren Schalter in die eigentliche Klasse einordnen:

class Checker
{
    public $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function isExactly($n)
    {
        if ($n === $this->value)
            return $this;
    }

    public function contains($n)
    {
        if (strpos($this->value, $n) !== false)
            return $this;
    }

    public static function check($str)
    {
        $var = new self($str);

        switch ($var) {
            case $var->isExactly(''):
                return "'$str' is an empty string";
            case $var->isExactly(null):
                return "the value is null";
            case $var->contains('hello'):
                return "'$str' contains hello";
            default:
                return "'$str' did not meet any of your requirements.";
        }
    }
}

var_dump(Checker::check('hello world'));   # string(28) "'hello world' contains hello"

An diesem Punkt möchten Sie möglicherweise neu bewerten, was Sie mit dem, was Sie überprüfen, tun möchten, und stattdessen eine echte Validierungsbibliothek verwenden.

0
user1718888

Ich denke, dass Sie aus Ihrem Beispielcode eine Reihe normaler Fälle und einen Sonderfall (hier null) haben.

Das einfachste, was ich herausfinden kann, ist, diesen Fall vor dem Wechsel zu behandeln:

if ($value === null) {
    return 'null';
}

switch ($value) {
    case 0:
        return 'zero';
    case 1:
        return 'one';
    case 2:
        return 'two';
}

Fügen Sie möglicherweise auch einen Kommentar hinzu, damit sich null unerwartet auf den 0-Fall bezieht (auch das Gegenteil: 0 würde mit einem null-Fall übereinstimmen).

0
Gras Double