So überprüfen Sie, ob eine Instanz einer Klasse in symfony2 nicht vorhanden ist

78

Ich möchte einige Funktionen ausführen, wenn die Entität Mitglied einiger Klassen ist, aber nicht einiger.

Es gibt eine Funktion namens instanceof.

Aber gibt es so etwas

if ($entity !instanceof [User,Order,Product])
Fata Morgana
quelle
1
instanceof ist keine Funktion, sondern ein Schlüsselwort. Und nein, es gibt nichts Vergleichbares in der PHP-Sprache. Sie müssten eine Funktion implementieren, um dies selbst zu tun.
GordonM
Uéo thằng nào có giải pháp ra hồn nhỉ
Vu Tran Kien

Antworten:

138

Geben Sie ihnen eine gemeinsame Schnittstelle und dann

if (!$entity instanceof ShopEntity)

oder bleib bei

if (!$entity instanceof User && !$entity instanceof Product && !$entity instanceof Order)

Ich würde es vermeiden, beliebige Funktionen zu erstellen, nur um einige Zeichen an einem einzigen Ort zu speichern. Auf der anderen Seite, wenn Sie es "zu oft" brauchen, haben Sie möglicherweise einen Designfehler? (Im Sinne von "zu viel Randfälle" oder so)

KingCrunch
quelle
63
wäre es nicht besser zu if (!($entity instanceof User))?
Daniel W.
6
@ DanFromGermany Macht keinen Unterschied. Vielleicht Lesbarkeit. Es liegt an dir.
KingCrunch
1
@KingCrunch Sehr konzeptionell verwirrend, warum es keinen Unterschied macht? Ich bevorzuge Dragos 'Antwort und Rationalisierung. So mache ich das, da es nur schmutzig erscheint, die zu überprüfende Instanz zu negieren, bevor Sie überprüft haben, was sie tatsächlich ist.
Jonathan
6
@ Jonathan See php.net/manual/en/language.operators.precedence.php Am Ende ist es nur etwa $a+$b+$cvs ($a+$b)+$c. Schon mal versucht 2**3**4 == (2**3)**4? ;)
KingCrunch
Stellen Sie sicher, dass Sie die Klasse importieren / verwenden, die Sie mit instanceof überprüfen. Z.B. denn if ( $entity instanceof Audio )ich muss haben use App\Entity\Audio;. PHP wird keinen Fehler auslösen, wenn Sie keine Klasse verwenden, die Sie überprüfen - aber Ihr If wird niemals ausgelöst.
sieben
70

Das PHP-Handbuch lautet: http://php.net/manual/en/language.operators.type.php

!($a instanceof stdClass)

Dies ist nur eine logische und "grammatisch" korrekte geschriebene Syntax.

!$class instanceof someClass

Die oben vorgeschlagene Syntax ist jedoch schwierig, da wir nicht genau angeben, in welchem ​​Umfang die Negation ausgeführt wird: die Variable selbst oder das gesamte Konstrukt von $class instanceof someclass. Wir müssen uns hier nur auf die Präzision des Betreibers verlassen [Bearbeitet dank @Kolyunya].

Dragos
quelle
6
Dies ist eine sauberere Lösung. Ich bin sicher, die Hälfte der Leute, die sich mit dieser Frage befassen, hat angefangen zu suchen, weil sie if (!$entity instanceof ShopEntity)nicht intuitiv ist ... Viele von uns verwenden sie !$entityals $entity === null.
Mimoralea
6
Was meinst du damit We will only have to rely here on the smart implementation of the PHP parser.? Es gibt die Sprachspezifikation, die eindeutig besagt, dass der instanceofOperator eine höhere Priorität als der !Operator hat.
Kolyunya
2
@Kolyunya Lesbarkeit, vs "hmm, das sieht komisch aus .. lass mich die Priorität des PHP-Operators nachschlagen ... ok, das überprüft"
Brad Kent
13

Vorrang des PHP-Operators

instanceof Operator ist kurz vor der Negation dann dieser Ausdruck:

!$class instanceof someClass

ist genau richtig in PHP und das tun Sie, was Sie erwarten.

ahurt2000
quelle
Wie Sie bereits erwähnt haben, lautet der Grundgedanke, dass die Priorität des instanceofOperators höher ist als !, sodass die Aussage ein echtes Ergebnis liefert. Vielen Dank
ako
1

Diese Funktion sollte es tun:

function isInstanceOf($object, Array $classnames) {
    foreach($classnames as $classname) {
        if($object instanceof $classname){
            return true;
        }
    }
    return false;
}

Ihr Code ist also

if (!isInstanceOf($entity, array('User','Order','Product')));
Bruno Schäpper
quelle
0
function check($object) {
    $deciedClasses = [
        'UserNameSpace\User',
        'OrderNameSpace\Order',
        'ProductNameSpace\Product',
    ];

    return (!in_array(get_class($object), $allowedClasses));
}
Yawa Yawa
quelle
Dies handhabt die Vererbung nicht gut.
Hkoosha
0

Oder Sie können diese versuchen

    $cls = [GlobalNameSpace::class,\GlobalNameSpaceWithSlash::class,\Non\Global\Namespace::class];
    if(!in_array(get_class($instance), $cls)){
        //do anything
    }
Zuko
quelle