【问题标题】:using variable defined in IF statement in same statement using &&在使用 && 的同一语句中使用 IF 语句中定义的变量
【发布时间】:2017-03-08 14:20:29
【问题描述】:

似乎我不能在同一语句的后面部分使用 if 语句中定义的变量。有没有解决的办法?声明如下:

if ($cat = getCat($item) && 
    ($masterCat= getVC($cat) || $masterCat= getTC($cat))) {
    echo "success";
} else {
    echo "fail";
}

如您所见,$cat 是在第一部分中定义的。如果该部分评估为 False,则其他部分将不会运行。我的问题是我得到了

未定义变量:猫

即使在计算 &​​& 运算符的 RHS 之前调用了 getCat 并定义了 $cat。

构建此代码我了解了short circuit evaluationTruthy values,但现在我被困在尝试“单行”它。我可以嵌套 if 语句,但我想知道是否有办法做到这一点,其中“失败”部分只定义一次(在实际代码中更大,而不仅仅是回显“失败”;)

下面的函数

function getCat($pItem) {
    //looks up $pItem and returns a category or null if $pItem doesn't exist
}

function getVC($pCat) {
    //looks up $pCat quickly, returns master category or null if not in quick lookup table
}

function getTC($pCat) {
    //looks up $pCat thoroughly, 
    //returns master category OR
    //returns null if $pCat has expired (shouldn't happen but prevents crashing if it ever does)
}

【问题讨论】:

  • 您是否尝试过将其与 if 语句分开?如果问题是在条件中发生的分配,或者是否发生了其他奇怪的事情,这将很快告诉你。
  • 是的,这不是我想的那样,这是下面@Boldewyn 指出的问题。

标签: php if-statement


【解决方案1】:

你学习了短路评估,你的下一节课应该包括operator precedence :-)

简而言之:&& 的绑定比 = 强,因此代码的评估方式如下:

$cat = (getCat($item) && ($masterCat = (getVC($cat) || $masterCat = getTC($cat)))

在括号内,$cat 确实还没有定义。简单修复:自己添加括号:

if (($cat = getCat($item)) && 
    (($masterCat = getVC($cat)) || ($masterCat = getTC($cat)))) {
    echo "success";
} else {
    echo "fail";
}

Re: 代码风格,条件语句中的赋值在 PHP 中大多被认为是一个坏主意。也就是说,因为未来的读者无法快速区分“聪明”和错误==,需要在理解这种结构时进行思考。

要学习 PHP 语法,您的代码一切顺利,但在生产环境中,您可能需要遵循 @FatBoyXPC 的建议。

【讨论】:

  • 我确实知道优先级,但完全没有注意到这是正在发生的事情。这得到了答案,因为它回答了我提出的问题。阅读了各种反馈后,我想我应该按照@Code Lღver 建议的方式去做。
【解决方案2】:

为什么不在 if 条件之外定义这个变量:

$cat = getCat($item); //define the variable here
if ($cat && ($masterCat= getVC($cat) || $masterCat= getTC($cat))) {
    echo "success";
} else {
    echo "fail";
}

在 if 条件之外,变量 $cat 您也可以稍后使用。

【讨论】:

    【解决方案3】:

    如果问题是你无法让它作为一个单行线工作,为什么不停止阻碍自己呢?

    $cat = getCat($item);
    //Ternary if you getVC does not return null use it else use getTC
    $masterCat = isset(getVC($cat)) ? getVC($cat) : getTC($cat);
    
    if ($cat && $masterCat) {
        echo "success";
    } else {
        echo "fail";
    }
    

    虽然是的,但您的 if 语句还有两行可读,您不必担心某些奇怪的优先级,并且运行时速度不会降低。

    实际修改想法

    //if $cat was null I assume $masterCat should be
    if (isset($masterCat)) {
        echo "success";
    } else {
        echo "fail";
    }
    

    但实际上,您也可以通过捕捉案例并根据案例做事来给自己一些灵活性。

    $cat = getCat($item);
    if(isset($cat)){
        $masterCat = isset(getVC($cat)) ? getVC($cat) : getTC($cat);
        if(isset($masterCat)){
            //do work
        } else {
            //fail for no master
        }
    } else {
        //fail for no cat
    }
    

    一个划线器不是任何更好的可用和可读的代码。

    附加

    关于三元的双重调用。您可以先查找getVC,然后对其进行三元化处理。

    $masterCat = getVC($cat);
    $masterCat = isset($masterCat) ? $masterCat : getTC($cat);
    

    【讨论】:

    • 感谢您的反馈。我没有使用三元,因为我似乎会调用 getVC($cat) 两次。你也是对的,如果 $cat 为空,则 $mastercat 应该为空,因此如果 $pCat 为空,getVC() 和 getTC() 都返回空的打开条件将节省处理时间。除非我知道 $cat 是有效的,否则我根本不想给他们打电话。
    • @franki 关于三元的好点。我添加了另一种方法。看起来嵌套的ifs 是您真正需要的。请记住,从现在起 6 个月后,此代码甚至对您来说都是陌生的。让它易于阅读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-26
    • 1970-01-01
    • 2018-04-15
    • 2017-03-02
    • 2023-03-19
    • 2014-07-19
    • 1970-01-01
    相关资源
    最近更新 更多