PHP开关,为什么不';这不管用吗?
我有一个奇怪的问题,我似乎无法解决。我有一个相当复杂的代码,但我已经简化了它,问题仍然存在 见下文:PHP开关,为什么不';这不管用吗?,php,arrays,switch-statement,Php,Arrays,Switch Statement,我有一个奇怪的问题,我似乎无法解决。我有一个相当复杂的代码,但我已经简化了它,问题仍然存在 见下文: <?php $meta = array('meta_title' => 'correct'); switch (true) { case empty($meta['meta_description']): $meta['meta_description'] = 'incorrect'; case empty($meta['meta_keywords'
<?php
$meta = array('meta_title' => 'correct');
switch (true) {
case empty($meta['meta_description']):
$meta['meta_description'] = 'incorrect';
case empty($meta['meta_keywords']):
$meta['meta_keywords'] = 'incorrect';
case empty($meta['meta_title']):
$meta['meta_title'] = 'incorrect';
}
print_r($meta);
switch (true) {
case empty($meta['meta_description']): // MATCH
$meta['meta_description'] = 'incorrect'; // EXECUTE
case empty($meta['meta_keywords']): // SKIP
$meta['meta_keywords'] = 'incorrect'; // EXECUTE
case empty($meta['meta_title']): // SKIP
$meta['meta_title'] = 'incorrect'; // EXECUTE
}
记住要中断
:
$meta = array('meta_title' => 'correct');
switch (true) {
case empty($meta['meta_description']):
$meta['meta_description'] = 'incorrect';
break;
case empty($meta['meta_keywords']):
$meta['meta_keywords'] = 'incorrect';
break;
case empty($meta['meta_title']):
$meta['meta_title'] = 'incorrect';
break;
}
print_r($meta);
同样,上述内容也毫无意义
不应对上述内容使用switch语句
尝试使用if…elseif…
:
if(empty($meta['meta_description']))
$meta['meta_description'] = 'incorrect';
elseif(empty($meta['meta_keywords']))
$meta['meta_keywords'] = 'incorrect';
elseif(empty($meta['meta_title']))
$meta['meta_title'] = 'incorrect';
您没有任何break
语句。在每个案例中添加一个,它就会起作用
发生的情况是,第一个案例(empty(
)的计算结果为true
,在没有任何break
语句的情况下,其余案例的代码也会执行,因此meta\u关键字
被设置为不正确,meta\u title
鉴于这就是switch
语句的工作方式,您可能不希望使用switch
语句。您可能正在寻找更像这样的东西:
$meta = array('meta_title' => 'correct');
if (empty($meta['meta_description']))
$meta['meta_description'] = 'incorrect';
if (empty($meta['meta_keywords']))
$meta['meta_keywords'] = 'incorrect';
if (empty($meta['meta_title']))
$meta['meta_title'] = 'incorrect';
print_r($meta);
或者您可以使用循环:
$meta = array('meta_title' => 'correct');
$properties = array('meta_description', 'meta_keywords', 'meta_title');
foreach ($properties as $property)
{
if (empty($meta[$property]))
$meta[$property] = 'incorrect';
}
print_r($meta);
这两种方法应该产生相同的结果,但是如果您有更多的属性,那么循环将更容易和更短。Break不会解决问题。因为有很多需要,否则不行。你的代码也没有意义。你听说过foreach吗
<?php
$MetaDefault = array('meta_description', 'meta_title', 'meta_keywords');
$Meta = array('meta_title' => 'correct');
foreach($MetaDefault as $Row){
if(!isset($Meta[$Row])){
$Meta[$Row] = 'incorrect';
}
}
print_r($Meta);
?>
如果您断开,它将退出开关。
您的其他变量将不会被测试。
If/else也会这样做。它没有按您的要求执行的原因是,如果情况1为真,则情况2和3会自动触发(如果情况2为真,则情况3总是触发)。这不是开关的作用。您实际上只需要3个独立的if
子句:
<?php
$meta = array('meta_title' => 'correct');
if (empty($meta['meta_description']))
$meta['meta_description'] = 'incorrect';
if (empty($meta['meta_keywords']))
$meta['meta_keywords'] = 'incorrect';
if (empty($meta['meta_title']))
$meta['meta_title'] = 'incorrect';
print_r($meta);
引用以下内容:
了解switch语句在中的执行方式很重要
为了避免错误。switch语句逐行执行
(事实上,一句话一句话)。在开始时,没有代码是可用的
执行。仅当发现case语句的值
匹配PHP开始执行的开关表达式的值
声明。PHP继续执行这些语句,直到结束
或第一次看到break语句时。如果
你不能在案件陈述的结尾写中断陈述
列表中,PHP将继续执行以下情况的语句
您实际要做的是:
<?php
$meta = array('meta_title' => 'correct');
switch (true) {
case empty($meta['meta_description']):
$meta['meta_description'] = 'incorrect';
}
switch (true) {
case empty($meta['meta_keywords']):
$meta['meta_keywords'] = 'incorrect';
}
switch (true) {
case empty($meta['meta_title']):
$meta['meta_title'] = 'incorrect';
}
print_r($meta);
一旦单个案例
为真,将执行开关块中除其他案例
语句之外的所有其他代码。见:
switch语句逐行执行(实际上是逐语句执行)。开始时,不执行任何代码。只有当发现case语句的值与switch表达式的值匹配时,PHP才会开始执行这些语句。PHP将继续执行这些语句,直到开关块结束,或者第一次看到break语句为止。如果不在案例语句列表的末尾编写break语句,PHP将继续执行以下案例的语句
因此,这里发生的情况如下:
<?php
$meta = array('meta_title' => 'correct');
switch (true) {
case empty($meta['meta_description']):
$meta['meta_description'] = 'incorrect';
case empty($meta['meta_keywords']):
$meta['meta_keywords'] = 'incorrect';
case empty($meta['meta_title']):
$meta['meta_title'] = 'incorrect';
}
print_r($meta);
switch (true) {
case empty($meta['meta_description']): // MATCH
$meta['meta_description'] = 'incorrect'; // EXECUTE
case empty($meta['meta_keywords']): // SKIP
$meta['meta_keywords'] = 'incorrect'; // EXECUTE
case empty($meta['meta_title']): // SKIP
$meta['meta_title'] = 'incorrect'; // EXECUTE
}
请注意,完全不执行以下case
语句体:
switch(true) {
case false:
echo "Not Executed\n";
case true:
echo "Executed\n";
case print("Condition Not Executed\n"):
echo "Also Executed\n";
}
这将打印:
Executed
Also Executed
+1用于将代码简化为可用的示例。在每个案例结束时,您都忘记了打断。同意Nanne的观点-人们没有意识到这有多重要:)尽管人们的评论可能是正确的,但您可以通过各种方式来完成,这让我感兴趣。为什么这样不行?如果删除另外两种情况,则true==empty(blah)
确实可以按预期工作,但当其他的empty存在时,它就不能工作了。。让我讨厌;)正是我所想的。我实际上是用另一种方式写的,但我只是在胡闹,试图得到更短的代码。有趣的是,如果你在数组中添加meta_描述和meta_关键字,它们都不会触发。如果我打断了,它会破坏逻辑。我真的把每一个例子都当作3个独立的if来使用,只是想寻找一种缩短代码的方法。我可以这样做,但那需要很多行。这并不是说我不能再做一次,我只是想知道为什么第三个案例验证为真并运行下一行(如果有意义的话)。如果我这样做,那么我很感兴趣的是一个循环进入等式,然后是一个if,它不能达到性能效率?为什么其他案例的代码会触发,如果他们的情况不应该,那么你需要休息一下才能不执行其他“腿”这一事实是显而易见的,但这不是答案,不是吗?如果它不计算其他“腿”,而只是执行所有代码,那看起来像个bug,不是吗?@JamesLeckenby:循环不是坏事。这正是制作循环的目的。在这种情况下,使用循环对性能的任何影响都可以忽略不计。@Nanne:您应该仔细阅读switch
语句的工作原理。这不仅仅是它在PHP中的工作方式,在大多数(如果不是所有)C派生语言中也是如此。这通常被称为“失败”。在到达break
语句之前,以下“分支”上的所有代码都将执行。因此,您的意思是,如果不中断,则将在不检查其大小写的情况下执行以下所有代码。。那是。。。出乎意料……啊,我以为这就是问题所在。不过,这看起来不奇怪吗?我原以为它会不间断地掉下来测试下一个案例!并非意外-这正是开关的用途。如果您不是有意这样做的,则不应使用开关
。它用来替换一个长的if/elseif/elseif/else,而不是一系列独立的if语句,现在完全有意义了,并解释了微定时器的结果!