[PHP] Function returning but continues execution

2007-01-22 Thread David Mytton

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

2007-01-22 Thread David Mytton
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

2007-01-22 Thread David Mytton
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

2007-01-22 Thread David Mytton
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

2007-01-22 Thread David Mytton
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

2007-01-22 Thread David Mytton

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

2007-01-22 Thread David Mytton

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

2007-01-22 Thread David Mytton

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

2007-01-22 Thread David Mytton

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

2007-01-22 Thread David Mytton

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

2007-01-23 Thread David Mytton

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