PHP中的goto函数问题

时间:2014-08-21 11:53:26

标签: php goto

我在PHP中使用带goto函数的代码片段

这是我的代码

function goto_test()
{
    $a = 3;
    if($a == 3)
       {
          goto x;

       }
    else
       {
          if($a == 2)
             echo "Thuthmekri";
          else if($a==1)
             goto y;

       }
    echo "Thothamon";   

    x:
    {
        echo "There was a brown crow";
    }

    y:
    {
        echo "There was a white crow";
    }
}

问题是它正在显示

There was a brown crowThere was a white crow

现在看来它正在goto x;运行到goto标签x;并运行它。

但为什么标签y也被执行了?在$a=3

时,不应该遗留下来

编辑:

注意 - 人们问我,为什么我会使用Goto。我粘贴的代码只是为了让你理解我面临的一个场景。我的实际情况代码是一个巨大的代码。在这种情况下,我似乎需要使用goto。

如果我把我原来的代码放在这里,可能会。然后人们会了解情况。可能会看到实际位置,人们会停止向我倾斜

if($this->session->userdata('discount_on')==true && $this->session->userdata('discount_on')==2)
{    
    if($this->session->userdata('discount_over')==true && $this->session->userdata('discount_over')==1)
    {
        if($this->session->userdata('discount_type')==1)
        {
            $tot_disc = round(floatval($total_amount * floatval($discount_info[0]['discount_amount']/100)),2);
        }
        else if($this->session->userdata('discount_type')==2)
        {
            $tot_discount = round(floatval($r_cur * (floatval($discount_info[0]['discount_amount']))),2);
        }
        $total_amount = round(floatval($total_amount - $tot_discount),2); 
    }   
}   


if( $this->session->userdata('discount_type')==true && $this->session->userdata('discount_type')==3)
{
    if($this->cart->total() < $discount_info[0]['discount_amount'])
    {
        goto ship;
    }
    else
    {
        if($discount_info[0]['discount_country']==$country)
        { 
            $shipping_charge = 0.00;
        }                   
        else if($discount_info[0]['discount_country']=="0")
        {
            $shipping_charge = 0.00;
        }
        else if($discount_info[0]['discount_country']=="-1" 
                && 
                $primary_country[0]['country_id']!=$country)
        {
            $shipping_charge = 0.00;
        }
        else
        {
            goto ship;

        }
    }
}
else
{
    goto ship;
}

    ship:
    {
        $primary_total_amount = round(floatval($total_amount/$r_cur),2);
        $shipping_info = $this->autoload_model->get_data_from_table("td_shippingcharge","*",
                            "td_shippingcharge.shippingcharge_country = '$country'
                                AND td_shippingcharge.shippingcharge_type = '2'
                                AND td_shippingcharge.s_range  <= '$primary_total_amount'
                                AND td_shippingcharge.e_range > '$primary_total_amount'")->result_array();

        if(count($shipping_info)>0) /* if shipping details of particular country with range of item exists-----*/
            {
                $main_shipping = $shipping_info[0]['shippingcharge_price'];
                if($shipping_info[0]['shippingcharge_country']==$primary_country[0]['country_id'])
                    /*------ if the country selected is primary country, 
                                then provincial shipping charge will be calculated------*/
                {
                    $province_shipping = $this->autoload_model->get_data_from_table("td_provinceship","*","td_provinceship.state_id = '$state'
                            AND td_provinceship.provinceship_status = '1'
                            AND td_provinceship.shippingcharge_id  = '".$shipping_info[0]['shippingcharge_id']."'")->result_array();
                    if(count($province_shipping)>0)/*-- in provincial shipping charge amount exists and enabled----*/
                        {
                            $provincecharge = $province_shipping[0]['provinceship_amount'];
                        }
                    else 
                        $provincesharge = 0.00;
                    $shipping_charge = floatval($main_shipping) + floatval($provincecharge);
                }
                else
                    $shipping_charge = floatval($main_shipping);

            }
        else /*--- shipping details of rest of the countries with range of item exists ---*/
            {
                $restshipping_info = $this->autoload_model->get_data_from_table("td_shippingcharge","*",
                                "td_shippingcharge.shippingcharge_country = '-1' 
                                 AND 
                                 td_shippingcharge.shippingcharge_type = '2' 
                                 AND 
                                 td_shippingcharge.s_range  <= '$primary_total_amount' 
                                 AND 
                                 td_shippingcharge.e_range > '$primary_total_amount'")->result_array();
                if(count($restshipping_info)>0)
                    {
                        $shipping_charge = $restshipping_info[0]['shippingcharge_price'];
                    }
                else
                    $shipping_charge = 0.00;
            }

    }       
$_SESSION['primary_del_charge'] = $shipping_charge;
$_SESSION['del_charge'] = round(floatval($r_cur * $_SESSION['primary_del_charge']),2);

4 个答案:

答案 0 :(得分:5)

x:y:只是占位符标签,没有什么可以阻止从x:y:的执行。

这是非常无关紧要的,你为什么要using goto

修改

看到您的更新后,您根本不需要转到。无论你是否有goto,代码执行都会落到ship:。您的示例中的其他标签在哪里?

我怀疑你要做的是,只在一部分例子中调用ship。答案是将ship提取到单独的function()中,然后再将其调用。

编辑2

看到你的“回答”后,我觉得有必要进一步扩大。你的“技巧”只是糟糕的做法而不是使用可用的php结构。这是我建议做的事情:

function goto_test()
{
    $a = 3;
    if($a == 3)
       {
          echo x();

       }
    else
       {
          if($a == 2)
             echo "Thuthmekri";
          else if($a==1)
             echo y();

       }
    echo "Thothamon";   
}

function x()
{
    return "There was a brown crow";
}

function y()
{
    return "There was a white crow";
}

答案 1 :(得分:2)

因为在x y之后,如果您将y移到x之上,它会以某种方式运作:

y:
{
    echo "There was a white crow";
}
x:
{
    echo "There was a brown crow";
}

无论如何this is very bad programming style

enter image description here

观看您的修改,您可以轻松地在功能中移动ship并调用该功能,而不是使用goto

答案 2 :(得分:0)

我想我知道这里发生了什么,我并不认为goto是一个像其他人评论过的邪恶工具。我认为它可以与建筑工人使用炸药相媲美。它有适合它的东西以及它不能很好地工作的东西,它很容易使用错误和糟糕的东西比以前更糟糕。

这里发生的是你使用像函数调用这样的标签,而不是它们是什么。在这种情况下,每个标签代码周围的括号在功能上都没有做任何事情。它实际上只是为了阅读代码的人的利益,它根本无法控制流程。与在调用函数时仅运行代码片段的函数不同,标签下的东西总是在执行到达该点时运行,无论标签是否被调用。

所以这两个项目出现的原因是因为第一个goto做了你想要的并跳转到x标签,然后它从那里继续,因为y只是一个标签,而不是一个函数或一个if块没有什么可以告诉它跳过代码所以它只是继续执行并执行该代码。

答案 3 :(得分:-3)

好的,我得到了我的答案的解决方案,这在某种程度上是一个技巧。

大多数人都认为goto是一种不好的做法,但我发现,如果使用适当的流量知识,Goto被证明是一个强大的工具,可以解决您的问题

我发现的内容在下面给出了。希望这可以帮助某人解决他们的问题。

function goto_test()
{
    $a = 3;
    if($a == 3)
       {
          goto x;

       }
    else
       {
          if($a == 2)
             echo "Thuthmekri";
          else if($a==1)
             goto y;

       }
    echo "Thothamon";   

    x:
    {
        echo "There was a brown crow";
        goto end_of_code;
    }

    y:
    {
        echo "There was a white crow";
        goto end_of_code;
    }

    end_of_code:
     {
         /* you can put an echo over here, or if you dont want to show something, keep it blank*/
     }
}