[PHP] PHP script starten vauit een Script

Pagina: 1
Acties:
  • 167 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • om3ega
  • Registratie: Maart 2001
  • Laatst online: 00:11
Ik heb geen haar meer op mijn hoofd zitten (allemaal eruit getrokken) ..

Gek word ik van dit probleem...

Ik heb een (display.php) pagina wat d.m.v. xmlHTTP een TEXT file uitleest en deze elke seconde ververst. Dit werkt perfect.

Ik heb een PHP (timer.php) script wat elke seconde deze TEXT file bijwerkt en een teller ophoogt.
Dit werkt ook perfect (loopt bijvoorbeeld 60 seconden lang)

Ik krijg het op geen enkele manier voor elkaar dat ik de timer.php kan starten en de uitvoer van het script verder kan laten gaan. PHP wacht totdat timer.php klaar is met tellen en gaat dan pas verder.

Wat heb ik allemaal geprobeerd :

timer.php opstarten via de CLI met alle mogelijke execute commando's in PHP

shell_exec ("php timer.php");
exec ("php timer.php");
Passthru ("php timer.php");
etc..

Omdat het een windows systeem is : php-win gebruikt

shell_exec ("php-win timer.php");
exec ("php-win timer.php");
Passthru ("php-win timer.php");
etc..

Wat mij opvalt is het volgende :

In een command prompt intikken : php timer.php geeft 5 seconden geen prompt , script doet zijn werk en dan na 5 seconden weer de prompt.

Als ik php-win gebruik krijg ik direct een prompt en het script loopt interactief door op de achtergrond.

Waarom werkt dit dan niet als ik het aanroept vanuit een script? Waarom wacht het script dan toch nog steeds die 5 seconden voordat het script verder gaat.

Waarvoor wil ik deze methode gebruiken?
Er is een zwaar script geschreven wat bestanden opzoekt en upload naar een andere server. Dit process moet gestart worden d.m.v. een start-knop in de webbrowser. Dit process moet onafhankelijk lopen van de PHP-CGI environment waar de webserver PHP scripts in draaien. (Dus geen time-out settings etc etc) .. Ook moet de gebruiker rustig het venster kunnen sluiten of kunnen verlaten zonder dat het PHP script geterminate wordt.

Hier de test code :

(Niet conform XHTML of welke standaard dan ook , maar het gaat om het idee..)

display.php
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<script language="JavaScript">

var xmlhttp=false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
// JScript gives us Conditional compilation, we can cope with old IE versions.
// and security blocked creation of the objects.
  try {
  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
   try {
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
   } catch (E) {
    xmlhttp = false;
   }
  }
@end @*/

if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
  xmlhttp = new XMLHttpRequest();
}

function loadFragmentInToElement(fragment_url, element_id) {
    var element = document.getElementById(element_id);
    
    xmlhttp.open("GET", fragment_url);
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
      element.innerHTML = xmlhttp.responseText;
      }
    }
    xmlhttp.send(null);
}

         function update() {
          loadFragmentInToElement ('https://intranet/cli/status.txt', 'synchronizestatus');
//          items=open("", "items");
//          setTimeout("alert(synchronizestatus.innerHTML)",2000)
//                  items.document.write (synchronizestatus.innerHTML);          
          repeat = setTimeout("update()",1000);
          }

function submit_action(action){ items_to_synchronize.action.value=action; items_to_synchronize.submit(); };
function set_vis(elm, div){ disp=div.style; if(disp.display=='inline'){disp.display='none'; elm.value='view';}; else {disp.display='inline'; elm.value='hide';};}

window.onload = update;

</script/>

<h1>Synchronization Status</h1>
<br>De teller is : 
<span id="synchronizestatus"></span>


<?

//Hier onder is iets wat ik al veelvuldig heb aangepast zoals in het verhaal staat hierboven)
passthru("php-win timer.php");

?>


timer.php

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

$x = 0;

while ($x < 5)  // 5 seconds
{
/* counter */
$data = fopen("status.txt","r"); 
$count = fgets($data,1000);
$count=$count + 1 ;
$data = fopen("status.txt","w"); // opens to write and deletes the old count
fwrite($data, $count);
fclose($data);
sleep(1);
$x++;
}
?>



Systeem enviroment :
code:
1
2
Windows NT  5.0 build 2195 
PHP Version 5.1.0RC1


Oja.. wat wel belangrijk is om te weten is dat display.php een onderdeel van een CMS. Dit script wordt dus ergens geinclude. Het is dus essentieel dat dit script de rest van het CMS niet ophoudt.

[ Voor 6% gewijzigd door om3ega op 21-10-2005 11:32 ]


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Mischien dat je ignore_user_abort nodig hebt? Of begrijp ik het probleem niet?

Heb je die timer.php eigenlijk wel nodig? Kun je niet gewoon direct aan een php scriptje die text vragen ipv. via zo'n omweg?

[ Voor 34% gewijzigd door Michali op 21-10-2005 11:44 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • om3ega
  • Registratie: Maart 2001
  • Laatst online: 00:11
timer.php is in dit voorbeeld een substitute voor een erg groot ingewikkeld script wat allerlei dingen doet en de status van zijn acties in een file wegschrijft. Het principe is het zelfde ..

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
En die ignore_user_abort helpt niet?

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • WormLord
  • Registratie: September 2003
  • Laatst online: 10:10

WormLord

Devver

Misschien moet je eens kijken naar popen en proc_open, die zijn namelijk niet blocking. Ik weet echter niet of dat gaat werken op een windows machine.

Een php-script dat via een browser word aangeroepen kan echter ook resistent gemaakt worden tegen timeouts (set_time_limit) en user-aborts (ignore_user_abort).

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Waarom gebruik je een PHP script om dingen te timen? Waarom niet gewoon een cronjob (of de Windows-equivalent daarvan) maken die een PHP-script aanroept die hetzelfde doet als de timer zonder te wachten?

Wat je verder kan doen: zet bovenaan display.php deze regel:
PHP:
1
ob_start();

en onderaan, maar boven de include van timer.php:
PHP:
1
ob_end_flush();

Op die manier forceer je dat er alvast uitvoer naar de browser gestuurd wordt, maar wat je browser daarmee doet is browserafhankelijk voor zover ik weet. Ik zou eerder mijn eerste suggestie proberen.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
De consle wacht op output van het programma voordat hij verder gaat met de rest.
Truuk is dus de uitvoer naar een bestand te laten schrijven, zodat er geen uitvoer is. Hiervoor staan een groot aantal voorbeelen in de user notes op php.net, waarvan ik geen enkele poging in je TS zie teru gkomen.

Voor Windows;
PHP:
1
pclose(popen("start /b <program> <args>", 'r'));


Voor Unix
PHP:
1
exec("$ProgExec > /dev/null &");


Zoek naar "background" in de users notes op onder andere http://nl3.php.net/exec

Acties:
  • 0 Henk 'm!

  • om3ega
  • Registratie: Maart 2001
  • Laatst online: 00:11
Ik had bovenstaande ook gelezen. Helaas werkt dit niet zoals het hoort.

Wat heb ik nog gechecked :

Omdat de webserver IIS draait met een eigen user account heb ik gechecked de IIS user bij alle directorys waar files staan die ge-execute moeten worden genoeg rechten heeft. Dit klopt.

Het feit waar het om gaat nu is niet waarom ik iets op deze manier doe en niet via een cron o.i.d. maar heel basic ...-->

PHP:
1
2
3
4
5
<?php
echo "Start moeilijk langdurend process";
system("D:\Inetpub\php\php.exe D:\Inetpub\www\process.php");
echo "Onder tussen moet je hier gewoon verder kunnen...en niet wachten tot bovenstaande process klaar is..";
?>


process.php moet dus gaan draaien als afzonderlijke thread. process.php genereert geen output... draait gewoon heel lang....

Wat hierboven staat werkt dus allemaal niet :'(

[ Voor 7% gewijzigd door om3ega op 21-10-2005 14:23 ]


Acties:
  • 0 Henk 'm!

  • Digihelp ®
  • Registratie: Maart 2001
  • Laatst online: 18-08 11:09
Heb je hier al gekeken:
http://nl3.php.net/ignore_user_abort ? Werd al eerder genoemd, maar er staat een mooi
voorbeeld.

voorbeeld:
I wrote a simple function that can "spawn" another thread within the webserver by making async http request. The page that is being spawned can call ignore_user_abort() and do whatever it wants in the background...

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

   function http_spawn($page)
   {
       $basepath=ereg_replace('[^/]*$', '', $_SERVER['PHP_SELF']);
       $cbSock=fsockopen('localhost', $_SERVER['SERVER_PORT'], $errno, $errstr, 5);
       if ($cbSock)
       {
           fwrite($cbSock, "GET {$basepath}{$page} HTTP/1.0\r\n"
               ."Host: {$_SERVER['HTTP_HOST']}\r\n\r\n");
       }
   }
?>

Example:
<?php

   if ($search_initialized)
       http_spawn("ftindex.php");
?>


hopelijk helpt dit je.

Acties:
  • 0 Henk 'm!

  • om3ega
  • Registratie: Maart 2001
  • Laatst online: 00:11
Sorry voor mijn late reactie. Ik moest even wachten tot ik weer op mijn werk was om dit uit te proberen. Helaas werkt dit ook niet.

Ik twijfel er overigens niet aan dat veel van de bovenstaande genoemde methodes normaliter werken. Ik ben dan ook bang dat de IIS server roet in het eten gooit qua permissies.

Anyhow.. De oplossing die ik nu nog heb is een pop-up openen dien het script aftrapt met daarin de melding dat deze popup gesloten mag worden (misschien kan ik dat zelfs automatisch doen d.m.v. Javascript) ...

Jammer.. want dit is een lelijke methode vind ik persoonlijk :) ... Maar nood breekt wet ;) .. Allemaal toch bedankt voor jullie inbreng en wellicht helpt dit topic ooit nog eens iemand met een gelijkwaardig probleem.

Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
ignore_user_abort zorgt alleen dat de script-uitvoer doorgaat zelfs wanneer op de stop-knop in de browser wordt gedrukt, of het laden op een andere wijze afgebroken.
Waar hethierom gaat is dat PHP blijft wachten op de output van een programma, terwijl dit ongewenst is.

Zoals al gezegd dien je deze output naar een bestand te laten schrijven om dit gedrag te voorkomen. Ik heb ook ooit eens een executable gehad welke dit doel had. Je kon hem aanroepen met een ander bestand al parameter, welke vervolgens op de achgergrond werd uitgvevoerd. Een omweg voor wat je hier wilt, aangezien dat ook kan door het meegeven van een paar parameters.
Maar zie hier; http://www.mikekohn.net/mikehup.php

[ Voor 4% gewijzigd door frickY op 24-10-2005 13:06 ]

Pagina: 1