views:

109

answers:

2

I have a rough program sketched thusly:

if (condition){
  //redirect to some page
}
else{
 echo $some_var;
}

So when I test is and the condition is true, it does the redirect, but also throws notices that there are undefined variables $some_var (that are pulled from a DB and WON'T be defined if the condition is true).

So does the code continue to evaluate after the if? This is not what I've expected.

If you want to dig, here's the actual code (it's CodeIgniter, but it's mostly self-documenting) and the test case is a garbage "gift code" that's not in the DB, so that count_all_results WILL == 0. The notices thrown are that $uses is undefined.

 $data['message'] = null;

 //seeing if code is valid
 $submitted_code = $_POST['code'];
 $this->db->where('code', $submitted_code);
 $this->db->from('codes');
 if ($this->db->count_all_results() == 0){
  $data['message'] = "This is not a valid gift code, sorry! You'll need to read our partner blogs, or listen to our favored Twitterers to find a valid code.";
  $this->load->view('submission_form_view', $data);
 }
 else {

 //seeing if code has any uses left
 $this->db->where('code', $submitted_code);
 $this->db->from('redemption_information');
 $used_so_far = $this->db->count_all_results();
 $this->db->select('uses');
 $query = $this->db->get_where('codes', array('code' => $submitted_code));
 foreach ($query->result() as $result)
 {
   $uses = $result->uses;
 }

 echo "Uses: $uses Used so far: $used_so_far <br />";

 if ($uses <= $used_so_far) {
  $this->load->view('over_used_view');
 }
 else
 {
 //these values are auto-escaped, so no worries on SQL injection
 if ($this->db->insert('redemption_information', $_POST)) {
  $data['message'] = "Your order has been taken, thanks for your interest!";
  $this->load->view('success_view', $data);
 }
 else {
  $data['message'] = "There was an error with your order. Please try again.";
  $this->load->view('submission_form_view', $data);
 }
 }
 }
A: 

The else block will always be executed if the preceeding if block is false

You can test is isset($uses) to avoid the warning and instantiate a default value for $uses

Edit

Create a default value for $uses:

    $uses= null;
    foreach ($query->result() as $result)
    {
            $uses = $result->uses;
    }
pygorex1
+4  A: 

There's a difference between parsing and evaluation. The notices you're getting are parse notices (it's parsing the variable in the else statement and not seeing a previous assignment, so it throws a notice), but the statement isn't actually evaluated if the if condition is true.

Amber
So does the PHP "interpreter" (for lack of knowing what the actual word is) read the whole thing BEFORE evaluation, or what? Where can I read up on this process?
Alex Mcp
@Alex: yes, that's right.
klez
Hm. I don't have a really good source on hand for explaining the entire process, but some googling found this set of slides which does some of the explaining: http://sebastian-bergmann.de/archives/868-PHP-Compiler-Internals.html
Amber
Also, yes, it parses the entire file before running any of it (and thus you won't see any output at all of there is a parse *error* - but parse notices will still let the file run), and then evaluates the resultant bytecode (and thus runtime errors can appear even after some output is generated).
Amber