在PHP中按类(instanceof)切换

len*_*ahy 21 php instanceof switch-statement

可以if( .. instanceof ...), elseif(... instanceof ...), ... 用开关替换块吗?

例如:

<?php
$class = ..... //some class

if($class instanceof SomeClass) {
    //do something
} elseif($class instanceof SomeAnotherClass) {
    //do something else
}
Run Code Online (Sandbox Code Playgroud)

Iva*_*van 55

有人喜欢这样:

$class = get_class($objectToTest);

switch($class) {  
    case 'TreeRequest':
        echo "tree request";
        break;
    case 'GroundRequest':
        echo "ground request";
        break;
}
Run Code Online (Sandbox Code Playgroud)

或这个:

switch(true) {  
    case $objectToTest instanceof TreeRequest:
        echo "tree request";
        break;
    case $objectToTest instanceof GroundRequest:
        echo "ground request";
        break;
}
Run Code Online (Sandbox Code Playgroud)

  • 对使用第一个示例的任何人发出警告:它与`instanceof`不同,因为它忽略了类继承和实现. (15认同)
  • 那个开关(真),:+1: (3认同)
  • 当然,这是可能的.但是**为什么**为什么**你想要首先做到这一点?`if(.. instanceof ...),elseif(... instanceof ...)`没有错.不仅第一个例子不正确,而且第二个例子也占用更多空间,降低了可读性和效率(因为它阻止编译"case"语句,因为它们是动态的.不要做这样的事情. (3认同)

whi*_*row 17

以下更正确:

$class = get_class($objectToTest);

switch($class) {  
    case TreeRequest::class:
        echo "tree request";
        break;
    case GroundRequest::class:
        echo "ground request";
        break;
}
Run Code Online (Sandbox Code Playgroud)

这样就可以正确地比较命名空间(你不必输入它们),如果有任何变化,例如命名空间或类名,你会得到一个体面的IDE错误,通知你代码被破坏了.

  • 记住,这样你就会错过子类(类继承和实现) (5认同)
  • 为了确保该解决方案即使在“$objectToTest”是代理时也能正常工作,您可以使用“$class = ClassUtils::getClass($objectToTest);” (3认同)

Jso*_*owa 14

使用match表达式,它看起来像这样:

return match(get_class($object)) {  
   TreeRequest::class => "tree request",
   GroundRequest::class => "ground request",
   default => "default request"
};
Run Code Online (Sandbox Code Playgroud)

请记住,它错过了继承并且仅采用当前类。考虑继承的匹配表达式:

return match(true) {  
   $object instanceof TreeRequest=> "tree request",
   $object instanceof GroundRequest => "ground request",
   default => "default request"
};
Run Code Online (Sandbox Code Playgroud)