user2271677
user2271677

Reputation: 13

PHP random string which refreshes every two seconds

I need a random string that refreshes every two seconds, so that you'll get an effect of a word that is mixed every two seconds. This is my code:

function rand_string( $length ) {
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  

    $size = strlen( $chars );
    for( $i = 0; $i < $length; $i++ ) {
        $str .= $chars[ rand( 0, $size - 1 ) ];
    }

    return $str;

Then I want to repeat this a number of times, not unlimited, so I used this piece of code:

$random = rand_string( 9 );
for($i=0; $i < 5; $i++) {
   echo $random;
   flush();
   sleep(2);
}

Somehow the page waits 10 seconds and then shows my string, and my string shows up five times the same, and not one time refreshing every two seconds. Could you please help me?

Upvotes: 1

Views: 2358

Answers (4)

Craig Tullis
Craig Tullis

Reputation: 10497

Try something like the example below. Substitute a URL that points at a page/service on your own server which returns the next string value (and nothing else). Be sure to set the content type in your response (from the server) to "text/plain".

As stated/indicated/hinted in other posts, the issue is that HTTP is a stateless protocol. The browser sends a request. The server sends a response. The end. :-) The PHP code executes exclusively on the server, where its job is only generating content for the web browser. But it does not interact with the browser in any way beyond that. Once all of the content generated by the PHP code is emitted to the browser, the PHP code is finished. You should read up a bit on concepts like output buffering. You can exercise a little bit of control over whether your PHP code buffers up all the output then sends it to the browser all-at-once, or trickles it out as it generates it. But you simply cannot use PHP code to interactively change anything on the web page. Once you send it to the browser, it's sent and that's it. You can't call it back and change it.

Now, having said that, you certainly can use PHP code to emit JavaScript code, which can then interact with the DOM in the browser, and also make AJAX calls back to different resources on the server, which can in turn be different PHP pages that do whatever you need them to and return results for display or for further processing in the browser (which could lead to additional AJAX calls to the server, although "chatty" does not generally equal "good").

AJAX (Asynchronous JavaScript and XML) is a technology that lets you make calls back to the web server from your web page without reloading the entire page. You can use JavaScript timer functions like setInterval() and setTimeout() to implement delays or to create recurring events, like your text update. Don't get too hung up on the "XML" in "AJAX." A newer data encapsulation standard called JSON has become very popular and is at least as usable via AJAX as XML is in virtually all cases. JSON is "JavaScript Object Notation," and the standard is basically just serialized JavaScript data structures, very natural to work with.

In fact, in the example I show below, neither XML nor JSON is utilized (in the interest of simplicity). But either XML or JSON could have easily been used and probably should be in a serious service implementation.

The XMLHttpRequest object is the magic bit that makes AJAX possible. XMLHttpRequest, setInterval(), setTimeout() and tons of other APIs utilize asynchronous callbacks. So that is another concept you will need to embrace. An asynchronous callback is just a function that you pass to, for example, setInterval() so that it will be able to "call you back" when the timer event occurs (you pass a reference to the function). In the meantime, your interface isn't locked up waiting for the callback. Thus it is asynchronous. My example below also uses inline (unnamed, anonymous) functions called closures, which is another concept that is very important for modern JavaScript programming.

Finally, I would heartily recommend using something like jQuery. Well, I'd recommend jQuery. There are other JavaScript frameworks, but I'm not entirely sure there is much point in looking at any of the others any more. The example below does not use jQuery.

The main thing you are accomplishing with your original example, since PHP executes exclusively on the server, is to make your page take longer to completely finish rendering, which means it takes longer for your request to disconnect from the web server, which in turn is tying up a connection resource on the server that no other browser instances can utilize until the request finishes at least 10 seconds after it starts.

<html>
    <head>
    </head>
    <body>
        <div id="blah">Watch me change.</div>

        <script language="javascript">

            // set callback function, to be called every 2 seconds
            setInterval( function() {
                if (window.XMLHttpRequest) {
                    xmlhttp = new XMLHttpRequest();
                }
                else { // IE6, IE5
                    xmlhttp = new ActiveXObject( "Microsoft.XMLHTTP" );
                }

                // callback function called for each state change, "4" means request finished.
                xmlhttp.onReadyStateChange = function() {
                    if( 4 == xmlhttp.readyState && 200 == xmlHttp.status ) {
                        document.getElementById("blah").innerHTML = xmlHttp.responseText;
                    }
                }

                xmlhttp.open( "GET", "http://source-of-new-string...", true );
                xmlhttp.send();

            }, 2000 );

        </script>
    </body>
</html>

Upvotes: 1

Jean
Jean

Reputation: 7673

Somehow the page waits 10 seconds and then shows my string

First, PHP can't do what you wishes. PHP sends the web page content to the browser which in turn displays it.

So the browser may choose the amount of data that it needs to receive before even starting to display the page.

There is your delay: five times sleep(2);. The browser waits the end of the connection before displaying data.

My string shows up five times the same

Secondly, the code below only prints five times the content of the variable $random, which is never changed in the for loop. So five times the same content.

$random = rand_string( 9 );
for($i=0; $i < 5; $i++) {
   echo $random;
   flush();
   sleep(2);
}

There is your repetition: five times echo $random;.

Notes

  • $random is a variable. For the rand() function, see here.
  • For random strings, see: PHP random string generator
  • PHP may not be suited for what you want to do I need a random string that refreshes every two seconds. The refreshing part could be obtained through javascript or at worst, by refreshing the page every two seconds and by displaying a new string along with the old ones. This will leave the illusion that a new string is added (with the ugly page loading moment in-between).

Upvotes: 0

Chris Palmer Breuer
Chris Palmer Breuer

Reputation: 690

header('Content-Type: text/html; charset=UTF-8');
function rand_string( $length ) {
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  

    $size = strlen( $chars );
    for( $i = 0; $i < $length; $i++ ) {
        $str .= $chars[ rand( 0, $size - 1 ) ];
    }

    return $str;
}
for($i=0; $i < 5; $i++) {
   $random = rand_string(9);
   echo $random;
   flush();
   ob_flush();
   sleep(2);
}

You need to define the variable $random new within the loop.

Upvotes: 0

Niels Keurentjes
Niels Keurentjes

Reputation: 41958

You do not understand the fundamentals of web development yet. The single PHP script you wrote first generates a string, then loops 5 times, outputting the generated string and then sleeping for 2 seconds, and when the script is finished it is flushed to the browser. As such it's obvious that, since you only called the function once, you see 5 identical strings after 10 seconds.

Having a new string appear every 2 seconds is just not possible with the stateless thing that is an 'HTTP request'. You would need to use Ajax-callbacks to achieve that effect, invoked from the client side every 2 seconds.

Upvotes: 0

Related Questions