[PHP] Function returning but continues execution
Hi, I have come across what appears to be a bug in PHP, but one that I am having difficulty writing test code for. Also, the bug only happens on a Linux build of PHP - the code is working as expected on Windows. This is on both PHP 5.2.0 and the very latest snapshots: Windows: 5.2.1RC4-dev Jan 19 2007 16:16:57 Linux: PHP Version 5.2.1RC4-dev Jan 22 2007 11:54:28 (php5.2-200701221130.tar.gz) The configure line is: './configure' '--with-apxs2=/usr/local/apache2/bin/apxs' '--with-curl' '--with-freetype-dir=/usr' '--with-gd' '--with-gettext' '--with-jpeg-dir=/usr' '--with-mysql' '--with-openssl' '--with-pdo-mysql' '--with-pear' '--with-png-dir=/usr' '--with-zlib' '--enable-calendar' '--enable-exif' '--enable-gd-native-ttf' '--enable-pdo' '--enable-soap' '--enable-sockets' and no 3rd party extensions are enabled. The code that is causing the problem exists within a class in a function called approve_friend. This is called by a "public" page with a parameter provided in GET being passed to the function approve_friend: $username = filter_input(INPUT_GET, 'username', FILTER_SANITIZE_STRING); if (!empty($username)) { if ($username != $_SESSION['user']['username']) { if ($core->user->add_friend($username)) { echo 1; } else { echo 2; } } } There is code in place of echo 1 and echo 2 but it's not relevant. Here, the code checks to make sure the username submitted is the not the same as the currently logged in use. If not, it will execute the $core->user->add_friend function. add_friend runs through as follows: 1. Makes a call to $this->get_user where it gets data for the username $username provided when calling the function. It returns an array. $friend = $this->get_user(1, NULL, $username); 2. Grabs some data from the session about the currently logged in user $user['name'] = filter_var($_SESSION['user']['name'], FILTER_SANITIZE_STRING); $user['user_id'] = filter_var($_SESSION['user']['user_id'], FILTER_SANITIZE_NUMBER_INT); $user['username'] = filter_var($_SESSION['user']['username'], FILTER_SANITIZE_STRING); $user['friend_count'] = filter_var($_SESSION['user']['friend_count'], FILTER_SANITIZE_NUMBER_INT); 3. Checks to make sure $friend has a value if (empty($friend)) { return false; } 4. Checks to make sure that the friend being added is not already added. if (!empty($_SESSION['user']['friends'])) { if (in_array($friend['user_id'], $_SESSION['user']['friends'])) { return false; } } This is the point at which there is a problem. If I add this code before #4: print_r($_SESSION['user']['friends']); echo $friend['user_id']; exit; Then I get the following output: Array ( [0] => 3 ) 3 i.e. $_SESSION['user']['friends'] is an array with the key 0 and the value 3 and $friend['user_id'] has a value of 3. Therefore, the in_array() check above will return true and the function will return false. No further code in the function should execute. This is what happens on Windows - 2 is output to the page because the add_friend function has returned false. Now, after #4, there is more code. This code is only supposed to execute if the friend doesn't already exist - it adds the friend, increments the friend count and sends an e-mail. // Insert into friends $core->database->exec('INSERT INTO users_friends SET user_id = "'.$user['user_id'].'", user_friend_id = "'.$friend['user_id'].'", status = 1'); $core->database->exec('INSERT INTO users_friends SET user_id = "'.$friend['user_id'].'", user_friend_id = "'.$user['user_id'].'"'); // Update friend count $core->database->exec('UPDATE users_insiders SET friend_count = "'.++$user['friend_count'].'" WHERE user_id = "'.$user['user_id'].'"'); // E-mail sending code using phpmailer return true; On my Linux server, the function returns false at step #4 as it should do, but it appears to continue executing. The friend count is incremented and the page execution slows temporarily whilst the mail is being sent (not a problem in testing). However, no e-mail actually gets sent. The key is that the function is returning false but it continues to execute! If I stick in an exit; after the in_array() check at point #4, this doesn't happen. There are no other places where this function is called, and it is only called once. Strangely, if I force the values of the 2 variables before the in_array() check: $_SESSION['user']['friends'] = array(0 => 3); $friend['user_id'] = 3; it reacts as expected - the function returns false and no further code is executed. Anyone have any suggestions? Regards, David Mytton -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Function returning but continues execution
I can't see how there is a bug in my code if when I echo the contents of the 2 variables, they are exactly the same as when I set them manually. Except in the former the function "continues executing" but in the latter it doesn't. I also cannot see how the function can return false and execute the SQl query when it is only called once. David Roman Neuhauser wrote: # [EMAIL PROTECTED] / 2007-01-22 15:17:16 +: The key is that the function is returning false but it continues to execute! If I stick in an exit; after the in_array() check at point #4, this doesn't happen. There are no other places where this function is called, and it is only called once. Strangely, if I force the values of the 2 variables before the in_array() check: $_SESSION['user']['friends'] = array(0 => 3); $friend['user_id'] = 3; it reacts as expected - the function returns false and no further code is executed. Anyone have any suggestions? You have a bug somewhere in your code. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Function returning but continues execution
Yes, I know it looks like a bug in my code because I'm not able to write a test case that can reproduce it simply enough to report as a bug - hence why I am posting here. However, the behaviour I am describing surely suggests some kind of issue somewhere in PHP itself. My reasoning for this is if I echo the 2 variables I get: Array ( [0] => 3 ) and 3 and the bug appears. But if I set them manually before the in_array test: $_SESSION['user']['friends'] = array(0 => 3); $friend['user_id'] = 3; it works as expected. Am I wrong in thinking that this has to be a bug in PHP? I have used debug_backtrace() to find out what is going on as regards how many times the function is being executed - that is the first thing I checked because it does indeed suggest that it is being executed multiple times, however, the back trace only reveals 1 call/execution. David Roman Neuhauser wrote: # [EMAIL PROTECTED] / 2007-01-22 15:31:55 +: Roman Neuhauser wrote: # [EMAIL PROTECTED] / 2007-01-22 15:17:16 +: The key is that the function is returning false but it continues to execute! If I stick in an exit; after the in_array() check at point #4, this doesn't happen. There are no other places where this function is called, and it is only called once. Strangely, if I force the values of the 2 variables before the in_array() check: $_SESSION['user']['friends'] = array(0 => 3); $friend['user_id'] = 3; it reacts as expected - the function returns false and no further code is executed. Anyone have any suggestions? You have a bug somewhere in your code. I can't see how there is a bug in my code if when I echo the contents of the 2 variables, they are exactly the same as when I set them manually. Except in the former the function "continues executing" but in the latter it doesn't. I also cannot see how the function can return false and execute the SQl query when it is only called once. You have presented no proof that there's a bug in the PHP. What you have presented looks like you have a bug, and the function gets called more than once. Have you used a debugger? See http://xdebug.org/. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Function returning but continues execution
I added this in and it outputs 1 as I suspected - the function is being called only once. David Robert Cummings wrote: On Mon, 2007-01-22 at 16:36 +, David Mytton wrote: Yes, I know it looks like a bug in my code because I'm not able to write a test case that can reproduce it simply enough to report as a bug - hence why I am posting here. However, the behaviour I am describing surely suggests some kind of issue somewhere in PHP itself. My reasoning for this is if I echo the 2 variables I get: Array ( [0] => 3 ) and 3 and the bug appears. But if I set them manually before the in_array test: $_SESSION['user']['friends'] = array(0 => 3); $friend['user_id'] = 3; it works as expected. Am I wrong in thinking that this has to be a bug in PHP? I have used debug_backtrace() to find out what is going on as regards how many times the function is being executed - that is the first thing I checked because it does indeed suggest that it is being executed multiple times, however, the back trace only reveals 1 call/execution. A backtrace won't indicate multiple calls unless they are recursive. Try add the following to your function: Cheers, Rob. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Function returning but continues execution
At the very bottom of your function place another return with a string like return 'FOUND THE END OF FUNCTION'; now, echo the return of the function and see if it really the return function that you think it is that is returning false, or you are just hitting the end of the function. Jim Yeah I tried this - I have confirmed that the return is the one I think it is. However, it seems this is actually being caused by some weirdness with mod_rewrite. Basically, if I use the rewritten URL e.g. example.com/section/addfriend/will/ which rewrites to index.php?cmd=section/addfriend&username=will I get this bug. But if I access index.php?cmd=section/addfriend&username=will directly then it works fine. This is definitely not a bug in my code but something to do with PHP, Apache and/or mod_rewrite. Unless anyone can suggest otherwise, I think it's going to be far too complex to debug and produce a test case because of the complexity of the code and working out where the bug actually is in PHP, Apache or mod_rewrite. So I'm just going to work around it. David -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Function returning but continues execution
Roman Neuhauser wrote: Can we see your mod_rewrite configuration? RewriteCond, RewriteRule, all that jazz. There are a number of rules but the only one that is relevant for this page is: RewriteRule ^section/addfriend(/)?(.*)$ index.php?cmd=section/addfriend&username=$2 David -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Function returning but continues execution
Roman Neuhauser wrote: Ok, what does RewriteLog contain for one such request? RewriteLogLevel 9. http://paste.lisp.org/display/35779 David -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Function returning but continues execution
Roman Neuhauser wrote: Bzzzt, I'm an idiot. It doesn't, of course. You're still missing [L] and that's what I was trying to point you at until the cat ran over my keyboard... Alright. So if the rewrite rules were (and they are): RewriteRule ^section/account(/)?$ index.php?cmd=section/account RewriteRule ^section/addfriend(/)?(.*)$ index.php?cmd=section/addfiend&username=$2 RewriteRule ^section/approvefriend(/)?(.*)$ index.php?cmd=section/approvefriend&username=$ RewriteRule ^section/deletefriend(/)?(.*)$ index.php?cmd=section/deletefriend&username=$2 RewriteRule ^section(/)?$ index.php?cmd=section/index RewriteRule ^anothersection(/)?(.*)$ index.php?cmd=listingnav&url=anothersection/$2 Where would the correct place be? David -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Function returning but continues execution
Roman Neuhauser wrote: append [L,NS] to all RewriteRules Done that, but the problem is still there - doesn't seem to have made any difference. David -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Function returning but continues execution
Roman Neuhauser wrote: Can I see the rewrite log for a single request now? Please make sure it's only one request. http://paste.lisp.org/display/35791 David -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Function returning but continues execution
Jochem Maas wrote: rewrite 'section/addfriend/will' -> 'index.php?cmd=section/addfriend&username=will' rewrite 'section/addfriend/templates/js/jquery.js' -> 'index.php?cmd=section/addfriend&username=templates/js/jquery.js' and what's the bet that this second rewritten url is the bogey man here. Yeah it was - the JS library was being requested and rewritten to the PHP file. Seems some data was being added to the variable in the function before it was being checked empty and so not returning false as it should have done. Thanks for everyone's help. David -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php