-3

I am using a code snippet with goto function in PHP

Here is my code

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";
    }
}

The issue is that it is displaying

There was a brown crowThere was a white crow

Now it seems when its getting goto x; its running to the goto label x; and running it.

But why the label y is also getting executed? Shouldnot it be left over, when $a=3 ?

EDIT:

Note-- People are asking me, why I am usig Goto. The code i pasted was just to make u all inderstand a scenario i have faced. My actual situation code is a vast one. And it seemed that i need to use goto in that case.

May be if i put my original code ober here. then people will understand the situation. May be seeing the actual position, people will stop downvoting me

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);
Smruti Singh
  • 565
  • 1
  • 4
  • 14
  • Properly format you code so you can actually see what is going on – PeeHaa Aug 21 '14 at 11:56
  • They're jump labels, not branch constructs. It's basically a split up switch-`case` list here. – mario Aug 21 '14 at 11:57
  • Just because you used curly braces after `x` it doesn't mean that the section will be the one in between them. When you go to a label the script runs everything under it. – mishu Aug 21 '14 at 11:57
  • ok, so how can i prevent one of the label not getting executed, if the other one is getting executed – Smruti Singh Aug 21 '14 at 12:01
  • Just a humble request to tell me the reason, why the answer is being downvoted? – Smruti Singh Aug 21 '14 at 12:19

4 Answers4

5

The x: and y: are just placeholder labels, there's nothing to prevent execution falling through from x: to y:.

That's pretty irrelevant though, why are you using goto's?

EDIT

After seeing your update, you simply don't need goto's. Code execution will fall through to ship: whether or not you have the goto's there. Where's the other label that you have in your example?

I suspect that what you are trying to do, is call ship in only a subset of examples. The answer to this would be to extract ship into a separate function() and call that instead.

EDIT 2

After seeing your 'answer' I feel the need to expand further. Your 'trick' is just bad practice all over and not using the available php constructs. Here's what I would recommend doing:

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";
}
Community
  • 1
  • 1
Rob Forrest
  • 7,329
  • 7
  • 52
  • 69
2

Because after x there's y, if you move the y over the x it would somehow work:

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

Anyway this is very bad programming style.

enter image description here

Watching your edit you can easily move ship in a function and call that instead of using goto.

Community
  • 1
  • 1
Ende Neu
  • 15,581
  • 5
  • 57
  • 68
  • My issue is not with the alternate position of the goto labels. If i go by your answer and put $a = 1, the also the same issue will happen, isnt it?? – Smruti Singh Aug 21 '14 at 11:58
  • 1
    Yes exactly, you have to separate the two instruction somehow, if they come one after another they will be executed sequentially, I want to emphasize though that you should not be using `goto`. – Ende Neu Aug 21 '14 at 12:00
0

I think I know what's going on here, I'm not of the mind that goto is an evil tool like other people have commented. I think it's comparable to a construction workers use of dynamite. it's got things it works well for and things it doesn't work well for, and it's so easy to use wrong and muck things up worse then they where before.

what's going on here is that your using the labels like function calls and that's not what they are. and the brackets you got around the code for each label doesn't functionally do anything in this situation. it's really just for the benefit of the person reading the code it doesn't control the flow at all. also unlike with functions that only run the snippet of code when the function is called the stuff under a label is always ran when execution gets down to that point regardless of it the label was called or not.

so the reason why both items are showing up is because the first goto does what you expect and jumps down to the x label and then it continues from there and because the y is just a label and not a function or an if block there is nothing to tell it to skip the code so it just keeps going and execute that code too.

Kit Ramos
  • 1,533
  • 1
  • 15
  • 32
-3

ok i got solution to my answer, which well somehow is a trick.

Most people say that goto is a bad practise, but I found out that, if used with proper knowledge of flow, Goto proves to be a strong tool that gives solution to your problem

What i found out is given below over here. Hope this may help someone to solve their issues.

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*/
     }
} 
Smruti Singh
  • 565
  • 1
  • 4
  • 14
  • Why its being downvoted? Can anybody be generous and give some reason? – Smruti Singh Aug 21 '14 at 12:44
  • That would be me, see my answer. – Rob Forrest Aug 21 '14 at 12:55
  • 1
    It is a solution yes, but not an elegant one. – Matt Burrow Aug 21 '14 at 12:57
  • i have a restriction using functions... it won't fit in my scenario. But anyways, thanks for your downvote. Really appreciate the help. People like you really encourages others. – Smruti Singh Aug 21 '14 at 12:57
  • @SmrutiSingh Please do elaborate on how you have a restriction on using functions, that sounds intriguing. – Rob Forrest Aug 21 '14 at 14:29
  • @SmrutiSingh as for your other comment, you've come to a question and answer site that tries its hardest to adhere to best practice. Unless you give people all of the information that they need, i.e. I can't use functions, then you'll get told what best practice suggests. If you don't like that answer, then try yahoo answers ;) – Rob Forrest Aug 21 '14 at 14:31