Looping code while function loads

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

nutkenz
Forum Contributor
Posts: 155
Joined: Tue Jul 19, 2005 12:25 pm

Post by nutkenz »

CoderGoblin wrote:JS Timing event link at w3schools.com
This doesn't work for PHP I think, and if it does, it only delays the problem... I can't think of a way to use this function in order to solve the issue of the browser closing connection due to that one function taking too long to complete. :(
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

Is this being run on Linux boxen or Winthroes? And if you can indeed update the browser incrementally, why not fork a child proc and communicate with it via some other mechanism (like shared memory or even just a file)?
nutkenz
Forum Contributor
Posts: 155
Joined: Tue Jul 19, 2005 12:25 pm

Post by nutkenz »

BDKR wrote:Is this being run on Linux boxen or Winthroes? And if you can indeed update the browser incrementally, why not fork a child proc and communicate with it via some other mechanism (like shared memory or even just a file)?
:?

...you should know I first typed the word ECHO about a month ago so I really don't know what you just said. :)

Let's give it a try anyway:

Is this being run on Linux boxen or Winthroes?
>> RedHat 7.3 i686

And if you can indeed update the browser incrementally
>> Well, this works when it's not busy with the function, I can keep it alive as long as I want then, but whenever it starts the function, the loop waits for that to complete... Which is only logical I suppose but I'd like to keep looping so the browser doesn't die before the WHOIS result has been found.

why not fork a child proc and communicate with it via some other mechanism (like shared memory or even just a file)
>> Because I really really don't know how... Educate me :wink:
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post by CoderGoblin »

I've been playing with XMLHTTP today and have the problem of a page needing the following:
1) May take a very long time to load initially (Indication of working would be good).
2) Needs to be updated on a regular basis.

as a proof of concept I developed the following with may be of some use... (See also Burrito's tutorial which I ripped off) for more info on XMLHTTP.

index.php

Code: Select all

<?php 
session_start();
$_SESSION['counter']=0;
?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 
<html>
<head>
   <title>Test HTTPRequestIdea</title>
   <meta http-equiv="Content-Script-Type" content="text/javascript">
   <script src="request.js"></script>
</head>
 
<body topmargin="0" leftmargin="0" marginheight="0" marginwidth="0" onLoad="updateWait('namez',1000,0,5,'.');updateIt('test.php','namez',10000)">
<h1>Hello</h1> 
<div align="center" id="namez">
Loading
</div>
</body>
</html>
test.php

Code: Select all

<?php
    session_start();
    
    if (empty($_SESSION['counter'])) {
        $_SESSION['counter']=1;
    } else {
        $_SESSION['counter']++;
    }
    usleep(5000000); // fake long execution time
    echo("<h1>Current Counter ".$_SESSION['counter'].'</h1>');
?>
request.js

Code: Select all

var update_timer=new Array(); // May have multiple sections on a form needing to be updated
var wait_timer=new Array(); // May have multiple load points. 

try{
   if (window.XMLHttpRequest){ // check for firefox and other browsers
      reqsend = new XMLHttpRequest(); // create object for ff and other browsers
   }else{ // not firefox or the like...
      reqsend = new ActiveXObject('Microsoft.XMLHTTP'); // create object for IE 5.0 or later (at least I think it's 5.0 ^o)
   }
}catch(e){
     location="failed.php"; 
};

function updateIt(what,to_elem,refresh){
   try{
      reqsend.open("POST", what, true); 
      stuff="";
      reqsend.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 
      reqsend.setRequestHeader("Content-Length",stuff.length); 
      reqsend.send(stuff); 
      reqsend.onreadystatechange = function(){  
      if ((reqsend.readyState == 4) && (reqsend.status == 200)) {
            if (reqsend.responseText.length) {
            	document.getElementById(to_elem).innerHTML = reqsend.responseText;
            	if (wait_timer[to_elem] != undefined) {
            		clearTimeout(wait_timer[to_elem]); // If load has completed we need to cancel the waiting Timer
            		wait_timer[to_elem]=null; // Just to be nice
                }
            }
         }
      };
   }catch(e){
     location="failed.php";
   }
   if (refresh>0) update_timer[to_elem]=setTimeout("updateIt('"+what+"','"+to_elem+"',"+refresh+")",refresh);
}

function updateWait(to_elem,refresh,level,max,use_str)
{
   var use_elem=document.getElementById(to_elem);
   
   if (level<max) {
     level++;
	 use_elem.innerHTML=use_elem.innerHTML+use_str;
   } else {
     use_elem.innerHTML=use_elem.innerHTML.substr(0,((use_elem.innerHTML.length)-(level*use_str.length)))+use_str;;
     level=1;
   }
   if (refresh>0) wait_timer[to_elem]=setTimeout("updateWait('"+to_elem+"',"+refresh+","+level+","+max+",'"+use_str+"')",refresh);	
}
Not neat or commented and has some potential problems but may be worth a look. In your case simply replace

Code: Select all

<body topmargin="0" leftmargin="0" marginheight="0" marginwidth="0" onLoad="updateWait('namez',1000,0,5,'.');updateIt('test.php','namez',10000)">
with

Code: Select all

<body topmargin="0" leftmargin="0" marginheight="0" marginwidth="0" onLoad="updateWait('namez',1000,0,5,'.');updateIt('test.php','namez',0)">
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

nutkenz wrote: ...you should know I first typed the word ECHO about a month ago so I really don't know what you just said. :)
LOL! OK. I didn't now that but I'd have to say you're not doing that bad if you need to have this conversation in such a
short period of time.
nutkenz wrote: Well, this works when it's not busy with the function, I can keep it alive as long as I want then, but whenever it starts the function, the loop waits for that to complete... Which is only logical I suppose but I'd like to keep looping so the browser doesn't die before the WHOIS result has been found.
Yeah, you are right that it is logical. Essentially, this is an issue between blocking and non-blocking (normally in reference to I/O). Most of the
things we are going to call natively in PHP will block, or in other words, stop any other execution until they've finished. This is one of the nice
things about threads and each spun thread can run without negative effect on the process that spawned it.

So....
nutkenz wrote:Because I really really don't know how... Educate me :wink:
Forking is when a process (your running script or program) essentially creates (clones) what is a child process. Almost like mitosis (LOL). It will then ascertain that it is a child and execute the appropriate logic based on it's status. The idea in this case was that once the child was generating some useful (whois) information, it could write that information to a segment of shared memory. The parent process could try to read this shared memory in the loop with a tad delay between each try. If their is no information there, it continues to loop instead of waiting for the function to continue.

HOWEVER, using fork() may not be an option when running with Apache. All the time I ever used it was in CLI stuff.

Another option is to create a cli (command line) script that can be called by what what you have running. If you add an "&" at the end, it should detach and run on it's own without holding up the works. It too could write to shared memory when it's finished and your web script could exit it's loop when it sees that your cli script is finished.

Lastly, the Asynchronus Javascript stuff that some otheres in thread should work fine, but I think there is a lot more mojo needed here to get it running.


Cheers,
BDKR
nutkenz
Forum Contributor
Posts: 155
Joined: Tue Jul 19, 2005 12:25 pm

Post by nutkenz »

BDKR wrote:HOWEVER, using fork() may not be an option when running with Apache. All the time I ever used it was in CLI stuff.
I'm afraid I'm running Apache
BDKR wrote:Another option is to create a cli (command line) script that can be called by what what you have running.
Damn, the one good match about this on Google seems to be down, and Google cache doesn't work either...

I'm not sure what a command line script is, but what I have in mind now (I doubt that is what you meant, but mentioning it made me think of this) is the PHP page triggering a linux shell script which parses another PHP page and saves the result somewhere, which is checked by the loop. However, it would be hard to get the variables passed I suppose.

So how would I create a cli?
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

nutkenz wrote:
BDKR wrote:Another option is to create a cli (command line) script that can be called by what what you have running.
I'm not sure what a command line script is, but what I have in mind now (I doubt that is what you meant, but mentioning it made me think of this) is the PHP page triggering a linux shell script which parses another PHP page and saves the result somewhere, which is checked by the loop. However, it would be hard to get the variables passed I suppose.
PERFECT! That's exactly what I was thinking.
nutkenz wrote: So how would I create a cli?
I don't think we need this question anymore eh? :wink:

Anyway, I don't see why a shell script wouldn't work. Give it a go and let us know how it works out. :)

Cheers
Post Reply