views:

365

answers:

5

Hello all,

I make an AJAX request to see if a sesion variable has been set. I make a GET request to this script:

<?php session_start();

while(true){
    if(isset($_SESSION['screen_name'])){
     return true;
     break;
    }
}

?>

Clearly there are problems with this script and I wanted to solve these problems such as the continuous checking and waste of resources.

Scenario: I am trying to implement the oAuth method that twitgoo have used. You click "sign in" and then a window pops up for you to sign in to twitter. If you are successful, twitter redirects to a call back URL (which I guess sets session info) and the window is closed. Once this is done your message is posted to twitter. I am trying to achieve this and I am nearly there but I am unsure of my script above.

I would appreciate any help in making this script not so wasteful and if you have a better implementation, I would love to hear it.

Thanks all

Update

I have been give two good options which do you think is more efficient between:

1) Polling the server every few seconds using JS instead of the while loop eating up CPU cycles

2) Keep the while loop but "ease up" on the level of checking meaning no more http requests will be wasted

+1  A: 

I may be saying something really stupid here, but wouldn't you be better off just taking out the while loop and leaving the polling up to javascript?

Daniel
The problem is AJAX requests are Asynchronous so it's actually not too bad of an idea to have the waiting on the server side, I'd probably have a max of 30 seconds or something.
Hardwareguy
That's what usually happens. The script times out.
Abs
JavaScript may be asynchronous, but PHP ain't. One script executing is not influenced by another script executing. Unless you force them to cross-communicate by explicitly writing values to a file somewhere, but that is HIGHLY NOT RECOMMENDED.
deceze
+4  A: 

This is a PHP script? Is there any condition that may change the state of $_SESSION['screen_name'] other than a page refresh/new poll, i.e. a restart of the script in the first place?

The $_SESSION variable depends on the request. It's not going to change while the script runs, unless changed by the script. All this script does is either return true if the condition is met, or loop until the timeout is hit. The condition is either true on the first try or never will be.

deceze
A session variable will be set by another script. I thought the above script will be able to pick up on this as there will be change in the session text files right?
Abs
$_SESSION is only populated from the session datastore once -- I believe at session_start().
Frank Farmer
+3  A: 

Unfortunately, all you've created here is an infinite loop. If $_SESSION['screen_name'] isn't set the first time through, it's never, ever going to be set. Once you've loaded a PHP script, the environment variables will not change. You will never receive another session cookie, nor will any of $_GET, $_POST, $_SESSION, etc. ever be modified, unless you do it explicitly inside the script, or the script ends and you make another request.

My suggestion here would be something like this:

if(isset($_SESSION['screen_name'])){
    return true;
    break;
}
else {
  //output JSON encoded error message
}

If you exit your script when the required session variable isn't set and send a response back to the browser, then the browser can decide what to do. Perhaps make another request, maybe wait ten seconds, maybe load a login dialog.

zombat
Good Point. I should be polling the server rather than doing it like I am now.
Abs
A: 

How about this:

screen_name_check.php

<?php session_start();
if (isset($_SESSION['screen_name']))
    return "1";
return "0";
?>

page.html

<script type="text/javascript">
    check_screen_name_interval = window.setIterval(function(){
     // AJAX call screen_name_check.php
     if (data=="1") {
  window.clearInterval(check_screen_name_interval);
  // do whatever JS needs with that session set
  // or AJAX call a different PHP page like screen_name_is_set.php
     }
    }, 2000);
</script>
Robert
Yes, this is something will work that Daniel suggested too. Its one of my options but I stil think the server checking will be better but I am being told by deceze that this is something that will not work. I think I will go for the JS polling option as it seems the one that everyone agrees on and I seem to get it. :)
Abs
+1  A: 

store your result in memcache, then use the while loop with usleep() between iterations checking memcache for the variable.

This will allow you to do essentially a long poll instead of having to chain a bunch of xmlhttprequests waiting for the result.

Jason