7

Reopened:

Since PHP is a server-side language I had the assumption that it didn't matter what browser I used, but apparently not so. I had only been using Google Chrome.

I installed WAMP on my local machine so I can test it locally to see if it did the same as my shared hosting account. Both codes worked the way they should (in Chrome mind you). Then I looked at the exact same code on my shared hosting -- one worked, the other didn't.

I called my shared hosting support and they tried to duplicate the issue and said they weren't finding it. So I tried it in Firefox with them on the line and in IE, lo and behold... it worked perfectly in both just like on WAMP.

This still isn't making much sense to me. I'm using PHP 5.3 on my shared hosting account with a well known hosting company but not getting anywhere because they can't really troubleshoot code. They can replicate the issue but can't answer why. I'm going to try to find out more in the next weeks and post an update as I know more.

What I'm trying to do is this:

  • Generate a range of numbers
  • Shuffle them into a random order
  • Copy that array of randomly ordered numbers into a session array
  • Get the first value of the array, delete that value, and shift all the values down by one

Here's my issue:

I tried using array_shift(); and it worked fine the first run but each time I ran the code after it would remove the first two elements.

To test what was going on I tried to print the array first, do array_shift();, and then print the array again to see what happened.

Expected Results:

Run #1:

[0]=>5 [1]=>2 [2]=>1 [3]=>4 [4]=>3  //print_r($array);
                                    //execute array_shift($array);
[0]=>2 [1]=>1 [2]=>4 [3]=>3         //print_r($array);

Run#2:

[0]=>2 [1]=>1 [2]=>4 [3]=>3         //print_r($array);
                                    //execute array_shift($array);
[0]=>1 [1]=>4 [2]=>3                //print_r($array);

Actual Results:

Run #1:

[0]=>5 [1]=>2 [2]=>1 [3]=>4 [4]=>3  //print_r($array);
                                    //execute array_shift($array);
[0]=>2 [1]=>1 [2]=>4 [3]=>3         //print_r($array);

Run#2:

[0]=>1 [1]=>4 [2]=>3                //print_r($array);
                                    //execute array_shift($array);
[0]=>4 [1]=>3                       //print_r($array);

My issue (cont.)

So then I tried using reset($array);, unset($array[0]);, and array_splice($array,1,0); as an alternative to array_shift($array); and it worked! Then I tried to compare them side by side and cleaned up the code and now they are doing the opposite of each other. Sometimes reset, unset, and array_shift; will even jump through up to 7 cells in the array when called once. array_shift(); is working the way I want it to now but I want to know why. It's driving me nuts! If someone could please help me I'd be so appreciative.

Code Dump:

unset, reset, splice

<?php
session_start();
$min = A; 
$max = S;

if((!isset($_SESSION['image'])) || ($_SESSION['image'] == null))
{
$numbers = range($min, $max);  //set a range for all images 
shuffle($numbers); //shuffle the order for randomness

$_SESSION['image'] = $numbers;

echo "<br />Current value: " . $_SESSION['image'][0] . "<br />";
print_r($_SESSION['image']);

reset($_SESSION['image']);
unset($_SESSION['image'][0]);
array_splice($_SESSION['image'],1,0);
echo "<br />New value: " . $_SESSION['image'][0] . "<br />";
echo "<br />1st exec<br />";

}
else
{
echo "<br />Current value: " . $_SESSION['image'][0] . "<br />";
print_r($_SESSION['image']);



reset($_SESSION['image']);
unset($_SESSION['image'][0]);
array_splice($_SESSION['image'],1,0);
echo "<br />New value: " . $_SESSION['image'][0] . "<br />";
echo "<br />2nd exec<br />";

}
?>

shift

<?php
session_start();
$min = A; 
$max = S;

if((!isset($_SESSION['id2'])) || ($_SESSION['id2'] == null))
{
$numbers = range($min, $max);  //set a range for all images 
shuffle($numbers); //shuffle the order for randomness

$_SESSION['id2'] = $numbers;

echo "<br />Current value: " . $_SESSION['id2'][0] . "<br />";
print_r($_SESSION['id2']);

array_shift($_SESSION['id2']);
echo "<br />New value: " . $_SESSION['id2'][0] . "<br />";
echo "<br />1st execution<br />";

}
else
{
echo "<br />Current value: " . $_SESSION['id2'][0] . "<br />";

print_r($_SESSION['id2']);

array_shift($_SESSION['id2']);
echo "<br />New value: " . $_SESSION['id2'][0] . "<br />";
echo "<br />2nd execution<br />";

}
?>
Jeff Reeves
  • 81
  • 1
  • 8
  • is there any chance something (perhaps some javascript) is creating another request between your first and second run? – xception Sep 19 '12 at 23:57
  • That's what I was wondering. There is nothing else on these pages. Those are the full dumps. You can see an example of them in action on: [link]http://jeffbooru.com/test.php [link]http://jeffbooru.com/test2.php – Jeff Reeves Sep 19 '12 at 23:59
  • Set a counter in your $_SESSION so you actually know how often the code was called (that would be a cheap way to debug that). – hakre Sep 19 '12 at 23:59
  • I would just close my browser completely and then re-run it but I know what you mean. I'll implement it later tonight when I'm at home. Come to think of it, what would be a good way of inserting a counter on it? Wouldn't it just go true or false based on if it's set or not? – Jeff Reeves Sep 20 '12 at 00:00
  • test.php does 2 array_shift calls while test2.php does only one, you sure you're running the actual code you wrote here? You can check my results by refreshing each page. There appears a second exec text when running test.php too which means you're probably missing the else there. I suspect you forgot you update both files while editing and only test2 has the latest version. – xception Sep 20 '12 at 00:05
  • As far as I can see, test.php and test2.php seem to work as expected. Did you fix the problem already? – SteAp Sep 20 '12 at 00:55
  • Do you rewrite urls with htaccess or the like? Could it be the request of favicon.ico is redirected to your php file behind the curtains? – Mahn Sep 20 '12 at 01:51
  • @user1684373 it's not a bug, chrome does this intentionally to try speed up loading times, and it should be taken into account when developing for chrome. See: http://stackoverflow.com/questions/4460661/what-to-do-with-chrome-sending-extra-requests – Mahn Sep 20 '12 at 15:44

2 Answers2

2

To ultimately learn what's going on, I propose to register a tick-function. The tick-function can execute at each PHP statement execution.

Here's a simple one, which traces line/file of each statement (feel free to add further details):

// Execute at each single statement
declare(ticks=1);

// Function to get called at each executing statement    
function logEachStatement() {

  $traceInfo = debug_backtrace();
  $lastActivation = $traceInfo[ count( $traceInfo ) - 1 ];

  $info = "\n" 
        . $lastActivation[ 'line' ]  . '@' . $lastActivation[ 'file' ] 
        ;

  $targetFile = dirname( __FILE__ ) . '/stmnt.log' );

  file_put_contents( $targetFile, $info, FILE_APPEND );

}

// using a function as the callback
register_tick_function( 'logEachStatement', true );

While there are other options to track down the problem, this one does not require external infrastructure.

SteAp
  • 11,853
  • 10
  • 53
  • 88
1

Assuming that you pasted the actual code, the only way for this to happen is if you made an unintentional intermediate request. It would be impossible for us to determine how or why this is the case with only the given information, though.

My suggestion is to use your browser dev tool of choice (e.g. Firebug) and monitor the network tab to make sure that only one request is being sent to the script. If this doesn't turn up your problem, add some simple debug logging, such as this:

$log = date('Y-m-d H:i:s')
     . ' :: Request received from '
     . $_SERVER['REMOTE_ADDR']
     . "\n";
file_put_contents('/path/to/your/log/file', $log, FILE_APPEND);

Then check your log after your test to make sure only one entry was added.

FtDRbwLXw6
  • 27,774
  • 13
  • 70
  • 107
  • This is literally the actual code. I was about ready to throw myself out the window trying to figure this out. The array_shift was broken up until I tried to rewrite it using reset, unset, and array_splice. I'm glad to see that I wasn't crazy. – Jeff Reeves Sep 20 '12 at 06:33