|
Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com |
php-general Digest 27 Jul 2005 08:26:01 -0000 Issue 3590
php-general-digest-help
lists.php.net
Date: Wed Jul 27 2005 - 03:26:01 CDT
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
php-general Digest 27 Jul 2005 08:26:01 -0000 Issue 3590
Topics (messages 219378 through 219398):
Re: ibase_connect...how to specify a port?
219378 by: Jochem Maas
Re: Using PHP to get user input via checkbox through a data base
219379 by: Jim Moseby
Re: Object Inheritance, get_class() and a static function call
219380 by: axel
219385 by: axel
test (just delete)
219381 by: Fam Ruijters-Verberne
becoming root user within php
219382 by: Tom Cruickshank
219389 by: Vidyut Luther
Re: On register_shutdown_function: What might be the problem?
219383 by: Rasmus Lerdorf
219386 by: Rasmus Lerdorf
219387 by: Liang ZHONG
219390 by: Liang ZHONG
219391 by: Rasmus Lerdorf
219392 by: Liang ZHONG
219393 by: Rasmus Lerdorf
install or interference problem
219384 by: Fam Ruijters-Verberne
Delivery reports about your e-mail
219388 by: itb.itb.ac.id
Re: quick question about using capital letters coding w/ PHP
219394 by: Dotan Cohen
219396 by: Dotan Cohen
open_basedir Question
219395 by: Aaron Greenspan
php mySql question
219397 by: Ned Kotter
Re: Very Basic question: What IDE/tools I need to begin using PHP?
219398 by: Shaw, Chris - Accenture
Administrivia:
To subscribe to the digest, e-mail:
php-general-digest-subscribe
lists.php.net
To unsubscribe from the digest, e-mail:
php-general-digest-unsubscribe
lists.php.net
To post to the list, e-mail:
php-general
lists.php.net
----------------------------------------------------------------------
attached mail follows:
James wrote:
> How do you specify a port to connect to? I tried using localhost:3050
you can't/don't specify the port in your connection string.
> (3050 is the default port that Firebird) and that didn't work.
yeah somebody using the firebird extension! or trying at least. ;-)
you have to specify the port that firebird is bound to in the SERVICES
file (its name and location differ depending on your platform) -
on windows the firebird installer should do this for you.
on linux you have to edit /etc/services (the format is
pretty simple)
also check out the aliases.conf file which lives alongside your
fierbird.conf file where you can do stuff like:
mydb = '/path/to/your.gdb'
and then:
ibase_connect ( 'mydb', $username , $password );
which is nice and allows easy to port code :-)
>
>
> $host = 'localhost:/path/to/your.gdb' ;
IIRC the localhost part is not required, so the following will do:
$host = '/path/to/your.gdb'
by all means come back with firebird questions - as far as firebird/php
are concerning I am a 1 man [marketing] army :-)
computed-fields, multi-db transactions, views, triggers, constraints, stored procedures,
PROPER parameterized queries!
it's like using Oracle without the pre-requisite second mortgage, without the
the nightmare API AND (maybe most important) with the added bonus that you are not making some
twat like Larry Elison even richer :-)
for those of you who are strong in DBs/SQL give it a try it's great stuff!
> $username = 'SYSDBA';
> $password = 'masterkey';
do change this :-) and/or lock down port 3050 on your firewall.
rgds
>
> $dbh = ibase_connect ( $host , $username , $password );
attached mail follows:
>
> Hello everyone,
>
> What I want to do is have a form (which is already created)
> where the user selects (via checkbox) on an item or group of
> items (almost like a shopping cart). These items are stored
> in a MySql database and the program was written in PHP. So
> far I have created an insert form that inserts the products
> into a database. The database is displayed in a form where
> the user now needs to click on the select box so that he/she
> can choose their items. Once they have chosen the items a
> confirmation page is supposed to come out with the user's
> choices and the user will confirm that this is correct or not
> and either click submit or go back to choose again. If they
> click submit than I am supposed to receive an email with all
> of the user's choices. The part I am still stuck in is when
> the user attempts to choose, nothing really happens.
> Following is the code that displays the database and allows
> the user to choose via the check box....Any help would be
> appreciated.
>
> <?php require_once('Connections/connBlog.php'); ?>
> <?php
> mysql_select_db($database_connBlog, $connBlog);
> $query_Recordset1 = "SELECT * FROM ebay_products";
> $Recordset1 = mysql_query($query_Recordset1, $connBlog) or
> die(mysql_error());
> $row_Recordset1 = mysql_fetch_assoc($Recordset1);
> $totalRows_Recordset1 = mysql_num_rows($Recordset1);
> ?>
> <?php require_once('Connections/connBlog.php'); ?>
>
> <html>
> <head>
> <title>Untitled Document</title>
> <meta http-equiv="Content-Type" content="text/html;
> charset=iso-8859-1">
> </head>
> <body>
> <div align="center">
> <p> </p>
> <form action="" method="post" name="form1">
> <table width="75%" height="10%" border="10"
> align="center" cellpadding="0" cellspacing="0" bordercolor="#99FFCC">
> <tr>
> <td><div align="center">Description of Product</div></td>
> <td><div align="center">Coupon Amount</div></td>
> <td><div align="center">Expiration Date</div></td>
> <td><div align="center">Your Selection</div></td>
> </tr>
> <?php do { ?>
> <tr>
> <td width="65%">
> <div align="center"><?php echo
> $row_Recordset1['product']; ?></div></td>
> <td width="8%">
> <div align="center">$<?php echo
> $row_Recordset1['discount']; ?></div></td>
> <td width="15%">
> <div align="center"><?php echo
> $row_Recordset1['expire']; ?></div></td>
> <td width="2%">
> <div align="center">
> <input name="select" type="checkbox" id="select"
> value="checkbox">
> </div></td>
> </tr>
> <?php } while ($row_Recordset1 =
> mysql_fetch_assoc($Recordset1)); ?>
> </table>
> <table width="25%" border="0" cellspacing="0" cellpadding="0">
> <tr>
> <td>
> <div align="center">
> <input type="submit" name="Submit" value="Submit">
> </div></td>
> <td>
> <div align="center">
> <input name="back" type="button" id="back"
> value="Go Back">
> </div></td>
> </tr>
> </table>
> <p> </p>
> </form>
> <p> </p>
> </div>
> <p align="center"> <a href="ebayinsert.php">Insert Data</a></p>
> </body>
> </html>
> <?php
> mysql_free_result($Recordset1);
> ?>
Problems I see right off the bat are:
1) your form tag has no action (action=""), therefore no action will be
taken upon submit.
2) your checkboxes have no unique value, so even if your form WAS being
submitted to some other page, you wouldn't be able to tell which ones were
checked.
To solve these problems, set your form action to the page that is to process
the POST, then change this line:
> <input name="select" type="checkbox" id="select"
> value="checkbox">
...to be something like
> <input name="select" type="checkbox" id="select"
> value="<?php echo $row_Recordset1['product'];?>">
JM
attached mail follows:
Hello Richard,
thanks for for your answer.
> a> class ClassA {
> a> function getClassName() {
> a> return get_class($this); # [1]
> a> }
> a> }
> a> class ClassB extends ClassA { }
> a> echo ClassB::getClassName();
>
> a> this script echoes "Object" instead of "ClassB". but i would like to
> a> return the classname of the derived class without writing the method again.
>
> "The double colon, is a token that allows access to static, constant,
> and overridden members or methods of a class."
>
> Of which none of yours are (at least not in the code posted)
Sure! It's the first one: i'm calling a method of the class without
instantiaton. it works even though the method isn't declared static.
maybe this is the fault!?
class ClassA {
public static function getClassName() {
return get_class($this); // [1]
// or [2] return get_class(self);
// or [3] return __CLASS__;
}
}
class ClassB extends ClassA { }
echo ClassB::getClassName();
> Wouldn't get_parent_class() work in this situation?
No, because there is no parent class of ClassA and im searching for the
name of the derived class.
Maybe i will found the solution on
http://php.belnet.be/manual/en/language.oop5.static.php
Still reading...
Best regards,
Axel P.
attached mail follows:
Hello Jochem,
> either you tested some different code to what you posted above OR
> (your build of?) 5.0.3 is borked.
sorry, I didn't tested the code at all, because my code is more complex.
I just tried to show the problem.
class ClassA {
public static function getClassName() {
return get_class($this); // [1]
// or [2] return get_class(self);
// or [3] return __CLASS__;
}
}
class ClassB extends ClassA { }
echo ClassB::getClassName();
I am searching for a function to use in line [1] so that the script's
output is "ClassB".
> I tested this on 5.0.2 and 5.0.4 and both did exactly what I expected,
> namely
> output nothing - $this is not defined when you call ClassB::getClassName()
> (because you make a static call) so nothing is the only logical output.
my fault, again, sorry. I jumbled the different outputs. I understood
that this behaviour is coherent.
> maybe you mean:
>
> class ClassA {function getClassName() { return get_class($this); }}
> class ClassB extends ClassA {}
> $B = new ClassB();
> echo $B->getClassName();
>
> which _does_ work but is fairly pointless because you
> already know the classname in order to be able to create the object
> in the first place.
that's true. I don't want to use this. I just checked it.
> I don't really see what the problem is, can you give some
> more real world detail on what you are trying/want to do?
>
> otherwise (re-)read this chapter:
> http://php.belnet.be/manual/en/language.oop5.php
http://php.belnet.be/manual/en/language.oop5.static.php#48234
is better. but it seems that even debug_backtrace() is not what i'm
looking for...
>
> ... if you're _really_ into generic code then the reflection API
no, no generic code. ;)
regards
axel
attached mail follows:
test
attached mail follows:
Hello,
I'm in the process of executing system commands using php. The only problem
is that I am not entirely sure how to execute these system commands using
root user.
(I need root access to do a few things through php). Whenever I use the exec
command it uses the www user. Would anyone know? Thanks for any assistance!
Tom
attached mail follows:
Hi Tom,
First of all due to the "risks" involved in doing something like
this.. are you sure you need to do this as root ?
Secondly, are you sure this script will not be accessible via an
apache server ? (i.e this is not inside your document root?)
Your best bet is to use sudo (man sudo, man visudo).
I would suggest narrowing down the list of commands you want to run,
and only allowing those commands in your sudoers line.
The man pages have lots of examples.
On Jul 26, 2005, at 5:28 PM, Tom Cruickshank wrote:
> Hello,
> I'm in the process of executing system commands using php. The only
> problem
> is that I am not entirely sure how to execute these system commands
> using
> root user.
> (I need root access to do a few things through php). Whenever I use
> the exec
> command it uses the www user. Would anyone know? Thanks for any
> assistance!
>
> Tom
>
attached mail follows:
I really didn't follow all that. But this stuff is not that complex.
header() sets a header to be sent when output goes out. header() does
not send an actual header at that point. If you don't send any output,
then the headers won't go out until the script terminates. If you have
any sort of output buffering enabled, then even if you think you are
sending something, you may only be buffering it, and in that case again
the headers won't go out until the request is done.
Also, ignore_user_abort() controls whether or not your script will be
terminated when we are able to detect that the user has aborted. A user
abort is defined as nobody being around to read the data we are sending
out. If you don't send anything, we can't detect if the browser has
gone away. Generally browsers will redirect as soon as they see a
Location: redirect header, but that could be client-speficic. If the
client sticks around after seeing the redirect and doesn't redirect
until after the server has closed the connection, then there is no way
to force a close. If it does redirect and close its end of the
connection, then if you set ignore_user_abort(false) your script will be
terminated as soon as it tries to send something further and your
shutdown function will be called at that point.
-Rasmus
Liang ZHONG wrote:
> Hi Rasmus,
>
> This may be a little bit long, sorry for taking your time.
>
> It still does not work as expected. I tried some experiment, and found
> that if I called some function or write some code line other then
> calling header(), the register_shutdown_function and other part of codes
> work as expected . For example:
> <?php
> set_time_limit(5);
> function f(){
> set_time_limit(10);
> //doing something time consuming
> }
>
> some_function();
>
> ?>
> The time limit of 5 will be the limit of the some_function() and the 10
> will be the limit of function f() respectively.
>
> Code example:
>
> -----------------------------------------------------------------------------------------------------------------------
>
> <?php
> set_time_limit(1);
> ignore_user_abort(true);
>
> function say_goodbye() {
> $st = connection_status();
> print "Status 1: ".$st."\n";
> set_time_limit(10);
> $st = connection_status();
> print "Status 2: ".$st."\n";
>
> $count=20000000;
> for($i=0; $i<$count; $i++){ }
> print "End!\n";
> exec("touch /home/.nappy/liang/liang.ns2user.info/php/bbb");
> }
>
> register_shutdown_function("say_goodbye");
> print "Sleeping...\n";
>
> $count=10000000;
> for($i=0; $i<$count; $i++){ }
>
> print "Done!\n";
>
> ?>
> ------------------------------------------------------------------------------------------------------------------------
>
> -bash-2.05b$ curl -N liang.ns2user.info/php/v.php
> Sleeping...
> <br />
> <b>Fatal error</b>: Maximum execution time of 1 second exceeded in
> <b>/home/.nappy/liang/liang.ns2user.info/php/v.php</b> on line
> <b>30</b><br />
> Status 1: 2
> Status 2: 2
> End!
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> if I change the time limit from 10 to 5 in function f()
>
> -bash-2.05b$ curl -N liang.ns2user.info/php/v.php
> Sleeping...
> <br />
> <b>Fatal error</b>: Maximum execution time of 1 second exceeded in
> <b>/home/.nappy/liang/liang.ns2user.info/php/v.php</b> on line
> <b>30</b><br />
> Status 1: 2
> Status 2: 2
> <br />
> <b>Fatal error</b>: Maximum execution time of 5 seconds exceeded in
> <b>/home/.nappy/liang/liang.ns2user.info/php/v.php</b> on line
> <b>14</b><br />
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> Change both the time limit to 10 will result:
>
> -bash-2.05b$ curl -N liang.ns2user.info/php/v.php
> Sleeping...
> Done!
>
> Status 1: 0
> Status 2: 0
> End!
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> But if the some_function is header() then the rule above does not work.
> It seems the function f()'s time limit also rule the header(). Only
> after the registered shutdown function finishes runing normally or by
> hit the expire time limit, will the header() return page to browser/http
> user agent. Example code with suggestion from Rasmus as:
>
> ------------------------------------------------------------------------------------------------------------------
>
> <?php
>
> set_time_limit(5);
>
> function f(){
> set_time_limit(100);
> $count=500000000;
> for($i=0; $i<$count; $i++){
> //sit here and loop for a bit so we can have time to hit Stop...
> echo "a \n"; flush();
> }
> echo "end";
> exec("touch /tmp/aaa");
> }
>
> register_shutdown_function('f');
>
> ignore_user_abort(true);
> header("Content-type: text/plain");
> header("Location: y.html");
>
> echo "foo\n"; flush();
> for($i=0;$i<10;$i++) { echo $i; sleep(1); }
> $fp = fopen("/tmp/foo.txt","a");
> fputs($fp,$i);
> fclose($fp);
> ?>
>
> ------------------------------------------------------------------------------------------------------------------
>
> After the file /tmp/foo.txt has been created, before the file /tmp/aaa
> being created, the y.html will not get to the browser or perl program
> using LWP::UserAgent. I think it is no way to close the connection
> actively by the php program to deliver the page sooner to end the http
> request, even I add lines and make code like this does not work:
>
> ----------------------------------------------------------------
> header("Content-type: text/plain");
> header("Cache-Control: no-store, no-cache");
> header("Location: y.html");
> header("Connection: close");
> ----------------------------------------------------------------
>
> My project act as a broker for user agent to a library database server
> called z39.50. Upon the request from user agent, my program need to
> connect a z39.50 server, getting data back 1 by 1, transforming to
> sepcial xml format and sending back to the request party. When the data
> repository is huge (sometimes up to million records), I have to get
> partial data transform and send back to user agent (normally a piece of
> perl code, called harvester) with a resumption token. The harvester will
> in a while loop send out another http request with the last resumption
> token and fetch data of next part, until finish all data fetching. The
> time to connect the database and do the query is a constant overhead. So
> it is not a good design that program need to connect the database and
> query upon each request with or with out resumption token. So my design
> is to connect to database and query only when the first initial request
> comes, and reponse back with partical data using header() and continue
> getting back data from z39 server. Upon next request, the program will
> only need to make sure the data needed has already stored in the
> harddrive and transform them and send them back.
> Since the user harvester agent normally has a 180 second timeout, it is
> necessary to respond within that period of time.
>
> I really need your suggestion. Thank you very much again.
>
>
> Liang
>
>
>
>
>> Try somthing lik
>
>
> e this:
>
>>
>> <?php
>> ignore_user_abort(true);
>> header("Location: redirect2.html");
>> echo "foo\n"; flush();
>> for($i=0;$i<10;$i++) { echo $i; sleep(1); }
>> $fp = fopen("/tmp/foo.txt","a");
>> fputs($fp,$i);
>> fclose($fp);
>> ?>
>>
>>
>> Liang ZHONG wrote:
>> > Sorry, does not seem to work here. The code below takes minutes to show
>> > up in browser.
>> >
>> > Any more suggestion?
>> >
>> ---------------------------------------------------------------------------------------
>>
>> >
>> > <?php
>> >
>> > set_time_limit(5);
>> >
>> > function f(){
>> > set_time_limit(100);
>> > $count=500000000;
>> > for($i=0; $i<$count; $i++){ }
>> > echo "end";
>> > exec("touch /home/.nappy/liang/liang.ns2user.info/php/aaa");
>> > }
>> >
>> > register_shutdown_function('f');
>> >
>> > ignore_user_abort(true);
>> > header("Content-type: text/plain");
>> > header("Location: y.html");
>> >
>> > $count=50000;
>> > for($i=0; $i<$count; $i++){ echo " \n"; }
>> > flush();
>> > ?>
>> >
>> ---------------------------------------------------------------------------------------
>>
>> >
>> >
>> > Liang
>> >
>> >>
>> >> If you don't flush some output after setting the header() then the
>> >> headers won't go out until the end of the request. So do something
>> like:
>> >>
>> >> ignore_user_abort(true);
>> >> header("Location: http://whatever");
>> >> echo "foo\n"; flush();
>> >>
>> >> Then whatever comes after this should run and the browser is long
>> gone.
>> >>
>> >> -Rasmus
>> >>
>> >>
>> >> Liang ZHONG wrote:
>> >> > I think I did not express myself clearly.
>> >> >
>> >> > What I want is to be able to redirect user an existing page (let
>> them
>> >> > get it immediately), and to close the connection actively, NOT
>> >> passively
>> >> > by user abort, at last, to run the function in background.
>> >> >
>> >> > But the redirecting using function header() with location has a
>> problem
>> >> > that header() always does return the page to user after the entire
>> >> > program, including registered showdown function finish running,
>> >> which is
>> >> > against the will. I put a time consuming task into a function that
>> >> > registered to be a shutdown function and hoping it runs after the
>> user
>> >> > has got the redirected page and the connection has been closed. But
>> >> > experiements (using browsers, curl command line tool as well as
>> >> > perl::LWP code) show that the user got the redirected page only
>> after
>> >> > the shutdown function finished, which is against the description of
>> >> > register_shutdown_function at php website.
>> >> >
>> >> > It seems only header() function use to redirect page has this
>> problem
>> >> > (not executed until register_shutdown_function finished) while other
>> >> > functions like print()/echo(), exec() have not.
>> >> >
>> >> > The code looks like:
>> >> >
>> >>
>> ---------------------------------------------------------------------------------------------
>>
>> >>
>> >> >
>> >> > <?php
>> >> > set_time_limit(1);
>> >> >
>> >> > function f(){
>> >> > set_time_limit(20);
>> >> > $count=50000000;
>> >> > for($i=0; $i<$count; $i++){ }
>> >> > echo "end";
>> >> > exec("touch /home/.nappy/liang/liang.ns2user.info/php/aaa");
>> >> > }
>> >> >
>> >> > register_shutdown_function('f');
>> >> >
>> >> > header("Content-type: text/plain");
>> >> > header("Location: y.html");
>> >> > ?>
>> >> >
>> >>
>> ---------------------------------------------------------------------------------------------
>>
>> >>
>> >> >
>> >> >
>> >> > http client who sends the request to the php program will only
>> get the
>> >> > page back as response after function f finsihes (file aaa created).
>> >> > Changing the $count will make a lot difference.
>> >> >
>> >> > My BIGGEST question is:
>> >> > How to make user get the redirect page immediately after the
>> >> header() is
>> >> > called, and not until function f() ends, while making sure that the
>> >> > function f() will finally fully (and might slowly) execute?
>> >> >
>> >> > Thank you very much for kindly replying.
>> >> >
>> >> > With high respect,
>> >> >
>> >> > Liang
>> >> >
>> >> >
>> >> >>
>> >> >> Liang ZHONG wrote:
>> >> >> > My Question is:
>> >> >> > What is the correct way to keep the function running after I
>> >> >> redirect an
>> >> >> > existing page to http client (which I want the client get
>> >> immediately)
>> >> >> > and then immediately close the connection?
>> >> >>
>> >> >> ignore_user_abort(true);
>> >> >>
>> >> >> -Rasmus
>> >> >>
>> >> >> --
>> >> >> PHP General Mailing List (http://www.php.net/)
>> >> >> To unsubscribe, visit: http://www.php.net/unsub.php
>> >> >>
>> >> >
>> >>
>> >> --
>> >> PHP General Mailing List (http://www.php.net/)
>> >> To unsubscribe, visit: http://www.php.net/unsub.php
>> >>
>> >
>>
>
attached mail follows:
That's a client-side issue then, because it is certainly sent. Trying
your exact script:
<?php
ignore_user_abort(true);
header("Location: redirect2.html");
echo "foo\n"; flush();
for($i=0;$i<10;$i++) { echo $i; sleep(1); }
$fp = fopen("/tmp/foo.txt","a");
fputs($fp,$i);
fclose($fp);
?>
It's at http://lerdorf.com/red.php if you want to test it yourself.
3:53pm colo:/var/www/lerdorf.com> telnet localhost 80
Trying 127.0.0.1...
Connected to colo.
Escape character is '^]'.
GET /red.php HTTP/1.0
HTTP/1.1 302 Found
Date: Tue, 26 Jul 2005 22:53:40 GMT
Server: Apache/1.3.33 (Debian GNU/Linux) PHP/4.4.1-dev
X-Powered-By: PHP/4.4.1-dev
Location: redirect2.html
Connection: close
Content-Type: text/html; charset=utf-8
foo
<10 second delay here>
Connection closed by foreign host.
-Rasmus
Liang ZHONG wrote:
> Thank you for replying. Sorry for being long again.
> I tried your suggestion of this:
>
> <?php
> ignore_user_abort(true);
> header("Location: redirect2.html");
> echo "foo\n"; flush();
> for($i=0;$i<10;$i++) { echo $i; sleep(1); }
> $fp = fopen("/tmp/foo.txt","a");
> fputs($fp,$i);
> fclose($fp);
> ?>
>
> The browser did not get the redirect page until the new $i(10) has been
> appended to file foo.txt.
>
> I also tried
> -----------------------------------------------
> ob_start();
> header("Location: http://liang.ns2user.info/php/y.html");
> echo "foo\n";
> ob_end_flush();
> -----------------------------------------------
>
> And does not work.
>
> I think it might be the case of what you suggest:
>
>> If the
>> client sticks around after seeing the redirect and doesn't redirect
>> until after the server has closed the connection, then there is no way
>> to force a close.
>
>
> So may I draw the conclusions:
> 1. Server in php can not actively close the connection to make the
> client see the redirect page immediately after the header has been set?
> 2. The connection is not closed even when the main php end and the
> shutdown function is running?
>
> If above conclusions are not true, could be somewhere that might be
> wrong due to the apache-php configuration or what?
>
> If those are true, I think I have to re-design the project flow control
> and it will take sometime while I have already finished the code
> assuming no above problem. Also I think this might result an awkward
> design for the project. (I mean jsp will be easier to achieve a
> relatively more elegant design).
>
> I use several other program langurages for many years, but new to php,
> so I probably made some assumption base on my experiences of other
> langurages but not true. The project I am working now to add
> enhancements is written on php. I try to keep the main design of it. I
> did not expect it would be difficult to achieve this:
>
> 1. write an xml page
> 2. let http client get this xml page in time
> 3. continue do something time consuming
>
> now I have difficulty in 2 and 3. My client is normally perl
> LWP::UserAgent, and sometimes browser. I wonder how to let the client
> get the page in time before I can continue to finish the rest of the
> work. Otherwise the client will timeout and get no result.
>
> Please help! Thank you.
>
> Liang
>
>>
>> I really didn't follow all that. But this stuff is not that complex.
>> header() sets a header to be sent when output goes out. header() does
>> not send an actual header at that point. If you don't send any output,
>> then the headers won't go out until the script terminates. If you have
>> any sort of output buffering enabled, then even if you think you are
>> sending something, you may only be buffering it, and in that case again
>> the headers won't go out until the request is done.
>>
>> Also, ignore_user_abort() controls whether or not your script will be
>> terminated when we are able to detect that the user has aborted. A user
>> abort is defined as nobody being around to read the data we are sending
>> out. If you don't send anything, we can't detect if the browser has
>> gone away. Generally browsers will redirect as soon as they see a
>> Location: redirect header, but that could be client-speficic. If the
>> client sticks around after seeing the redirect and doesn't redirect
>> until after the server has closed the connection, then there is no way
>> to force a close. If it does redirect and close its end of the
>> connection, then if you set ignore_user_abort(false) your script will be
>> terminated as soon as it tries to send something further and your
>> shutdown function will be called at that point.
>>
>> -Rasmus
>>
>> Liang ZHONG wrote:
>> > Hi Rasmus,
>> >
>> > This may be a little bit long, sorry for taking your time.
>> >
>> > It still does not work as expected. I tried some experiment, and found
>> > that if I called some function or write some code line other then
>> > calling header(), the register_shutdown_function and other part of
>> codes
>> > work as expected . For example:
>> > <?php
>> > set_time_limit(5);
>> > function f(){
>> > set_time_limit(10);
>> > //doing something time consuming
>> > }
>> >
>> > some_function();
>> >
>> > ?>
>> > The time limit of 5 will be the limit of the some_function() and the 10
>> > will be the limit of function f() respectively.
>> >
>> > Code example:
>> >
>> >
>> -----------------------------------------------------------------------------------------------------------------------
>>
>> >
>> > <?php
>> > set_time_limit(1);
>> > ignore_user_abort(true);
>> >
>> > function say_goodbye() {
>> > $st = connection_status();
>> > print "Status 1: ".$st."\n";
>> > set_time_limit(10);
>> > $st = connection_status();
>> > print "Status 2: ".$st."\n";
>> >
>> > $count=20000000;
>> > for($i=0; $i<$count; $i++){ }
>> > print "End!\n";
>> > exec("touch /home/.nappy/liang/liang.ns2user.info/php/bbb");
>> > }
>> >
>> > register_shutdown_function("say_goodbye");
>> > print "Sleeping...\n";
>> >
>> > $count=10000000;
>> > for($i=0; $i<$count; $i++){ }
>> >
>> > print "Done!\n";
>> >
>> > ?>
>> >
>> ------------------------------------------------------------------------------------------------------------------------
>>
>> >
>> > -bash-2.05b$ curl -N liang.ns2user.info/php/v.php
>> > Sleeping...
>> > <br />
>> > <b>Fatal error</b>: Maximum execution time of 1 second exceeded in
>> > <b>/home/.nappy/liang/liang.ns2user.info/php/v.php</b> on line
>> > <b>30</b><br />
>> > Status 1: 2
>> > Status 2: 2
>> > End!
>> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> > if I change the time limit from 10 to 5 in function f()
>> >
>> > -bash-2.05b$ curl -N liang.ns2user.info/php/v.php
>> > Sleeping...
>> > <br />
>> > <b>Fatal error</b>: Maximum execution time of 1 second exceeded in
>> > <b>/home/.nappy/liang/liang.ns2user.info/php/v.php</b> on line
>> > <b>30</b><br />
>> > Status 1: 2
>> > Status 2: 2
>> > <br />
>> > <b>Fatal error</b>: Maximum execution time of 5 seconds exceeded in
>> > <b>/home/.nappy/liang/liang.ns2user.info/php/v.php</b> on line
>> > <b>14</b><br />
>> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> > Change both the time limit to 10 will result:
>> >
>> > -bash-2.05b$ curl -N liang.ns2user.info/php/v.php
>> > Sleeping...
>> > Done!
>> >
>> > Status 1: 0
>> > Status 2: 0
>> > End!
>> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> >
>> > But if the some_function is header() then the rule above does not work.
>> > It seems the function f()'s time limit also rule the header(). Only
>> > after the registered shutdown function finishes runing normally or by
>> > hit the expire time limit, will the header() return page to
>> browser/http
>> > user agent. Example code with suggestion from Rasmus as:
>> >
>> >
>> ------------------------------------------------------------------------------------------------------------------
>>
>> >
>> > <?php
>> >
>> > set_time_limit(5);
>> >
>> > function f(){
>> > set_time_limit(100);
>> > $count=500000000;
>> > for($i=0; $i<$count; $i++){
>> > //sit here and loop for a bit so we can have time to hit Stop...
>> > echo "a \n"; flush();
>> > }
>> > echo "end";
>> > exec("touch /tmp/aaa");
>> > }
>> >
>> > register_shutdown_function('f');
>> >
>> > ignore_user_abort(true);
>> > header("Content-type: text/plain");
>> > header("Location: y.html");
>> >
>> > echo "foo\n"; flush();
>> > for($i=0;$i<10;$i++) { echo $i; sleep(1); }
>> > $fp = fopen("/tmp/foo.txt","a");
>> > fputs($fp,$i);
>> > fclose($fp);
>> > ?>
>> >
>> >
>> ------------------------------------------------------------------------------------------------------------------
>>
>> >
>> > After the file /tmp/foo.txt has been created, before the file /tmp/aaa
>> > being created, the y.html will not get to the browser or perl program
>> > using LWP::UserAgent. I think it is no way to close the connection
>> > actively by the php program to deliver the page sooner to end the http
>> > request, even I add lines and make code like this does not work:
>> >
>> > ----------------------------------------------------------------
>> > header("Content-type: text/plain");
>> > header("Cache-Control: no-store, no-cache");
>> > header("Location: y.html");
>> > header("Connection: close");
>> > ----------------------------------------------------------------
>> >
>> > My project act as a broker for user agent to a library database server
>> > called z39.50. Upon the request from user agent, my program need to
>> > connect a z39.50 server, getting data back 1 by 1, transforming to
>> > sepcial xml format and sending back to the request party. When the data
>> > repository is huge (sometimes up to million records), I have to get
>> > partial data transform and send back to user agent (normally a piece of
>> > perl code, called harvester) with a resumption token. The harvester
>> will
>> > in a while loop send out another http request with the last resumption
>> > token and fetch data of next part, until finish all data fetching. The
>> > time to connect the database and do the query is a constant
>> overhead. So
>> > it is not a good design that program need to connect the database and
>> > query upon each request with or with out resumption token. So my design
>> > is to connect to database and query only when the first initial request
>> > comes, and reponse back with partical data using header() and continue
>> > getting back data from z39 server. Upon next request, the program will
>> > only need to make sure the data needed has already stored in the
>> > harddrive and transform them and send them back.
>> > Since the user harvester agent normally has a 180 second timeout, it is
>> > necessary to respond within that period of time.
>> >
>> > I really need your suggestion. Thank you very much again.
>> >
>> >
>> > Liang
>> >
>> >
>> >
>> >
>> >> Try somthing lik
>> >
>> >
>> > e this:
>> >
>> >>
>> >> <?php
>> >> ignore_user_abort(true);
>> >> header("Location: redirect2.html");
>> >> echo "foo\n"; flush();
>> >> for($i=0;$i<10;$i++) { echo $i; sleep(1); }
>> >> $fp = fopen("/tmp/foo.txt","a");
>> >> fputs($fp,$i);
>> >> fclose($fp);
>> >> ?>
>> >>
>> >>
>> >> Liang ZHONG wrote:
>> >> > Sorry, does not seem to work here. The code below takes minutes
>> to show
>> >> > up in browser.
>> >> >
>> >> > Any more suggestion?
>> >> >
>> >>
>> ---------------------------------------------------------------------------------------
>>
>> >>
>> >> >
>> >> > <?php
>> >> >
>> >> > set_time_limit(5);
>> >> >
>> >> > function f(){
>> >> > set_time_limit(100);
>> >> > $count=500000000;
>> >> > for($i=0; $i<$count; $i++){ }
>> >> > echo "end";
>> >> > exec("touch /home/.nappy/liang/liang.ns2user.info/php/aaa");
>> >> > }
>> >> >
>> >> > register_shutdown_function('f');
>> >> >
>> >> > ignore_user_abort(true);
>> >> > header("Content-type: text/plain");
>> >> > header("Location: y.html");
>> >> >
>> >> > $count=50000;
>> >> > for($i=0; $i<$count; $i++){ echo " \n"; }
>> >> > flush();
>> >> > ?>
>> >> >
>> >>
>> ---------------------------------------------------------------------------------------
>>
>> >>
>> >> >
>> >> >
>> >> > Liang
>> >> >
>> >> >>
>> >> >> If you don't flush some output after setting the header() then the
>> >> >> headers won't go out until the end of the request. So do something
>> >> like:
>> >> >>
>> >> >> ignore_user_abort(true);
>> >> >> header("Location: http://whatever");
>> >> >> echo "foo\n"; flush();
>> >> >>
>> >> >> Then whatever comes after this should run and the browser is long
>> >> gone.
>> >> >>
>> >> >> -Rasmus
>> >> >>
>> >> >>
>> >> >> Liang ZHONG wrote:
>> >> >> > I think I did not express myself clearly.
>> >> >> >
>> >> >> > What I want is to be able to redirect user an existing page (let
>> >> them
>> >> >> > get it immediately), and to close the connection actively, NOT
>> >> >> passively
>> >> >> > by user abort, at last, to run the function in background.
>> >> >> >
>> >> >> > But the redirecting using function header() with location has a
>> >> problem
>> >> >> > that header() always does return the page to user after the
>> entire
>> >> >> > program, including registered showdown function finish running,
>> >> >> which is
>> >> >> > against the will. I put a time consuming task into a function
>> that
>> >> >> > registered to be a shutdown function and hoping it runs after the
>> >> user
>> >> >> > has got the redirected page and the connection has been
>> closed. But
>> >> >> > experiements (using browsers, curl command line tool as well as
>> >> >> > perl::LWP code) show that the user got the redirected page only
>> >> after
>> >> >> > the shutdown function finished, which is against the
>> description of
>> >> >> > register_shutdown_function at php website.
>> >> >> >
>> >> >> > It seems only header() function use to redirect page has this
>> >> problem
>> >> >> > (not executed until register_shutdown_function finished) while
>> other
>> >> >> > functions like print()/echo(), exec() have not.
>> >> >> >
>> >> >> > The code looks like:
>> >> >> >
>> >> >>
>> >>
>> ---------------------------------------------------------------------------------------------
>>
>> >>
>> >> >>
>> >> >> >
>> >> >> > <?php
>> >> >> > set_time_limit(1);
>> >> >> >
>> >> >> > function f(){
>> >> >> > set_time_limit(20);
>> >> >> > $count=50000000;
>> >> >> > for($i=0; $i<$count; $i++){ }
>> >> >> > echo "end";
>> >> >> > exec("touch /home/.nappy/liang/liang.ns2user.info/php/aaa");
>> >> >> > }
>> >> >> >
>> >> >> > register_shutdown_function('f');
>> >> >> >
>> >> >> > header("Content-type: text/plain");
>> >> >> > header("Location: y.html");
>> >> >> > ?>
>> >> >> >
>> >> >>
>> >>
>> ---------------------------------------------------------------------------------------------
>>
>> >>
>> >> >>
>> >> >> >
>> >> >> >
>> >> >> > http client who sends the request to the php program will only
>> >> get the
>> >> >> > page back as response after function f finsihes (file aaa
>> created).
>> >> >> > Changing the $count will make a lot difference.
>> >> >> >
>> >> >> > My BIGGEST question is:
>> >> >> > How to make user get the redirect page immediately after the
>> >> >> header() is
>> >> >> > called, and not until function f() ends, while making sure
>> that the
>> >> >> > function f() will finally fully (and might slowly) execute?
>> >> >> >
>> >> >> > Thank you very much for kindly replying.
>> >> >> >
>> >> >> > With high respect,
>> >> >> >
>> >> >> > Liang
>> >> >> >
>> >> >> >
>> >> >> >>
>> >> >> >> Liang ZHONG wrote:
>> >> >> >> > My Question is:
>> >> >> >> > What is the correct way to keep the function running after I
>> >> >> >> redirect an
>> >> >> >> > existing page to http client (which I want the client get
>> >> >> immediately)
>> >> >> >> > and then immediately close the connection?
>> >> >> >>
>> >> >> >> ignore_user_abort(true);
>> >> >> >>
>> >> >> >> -Rasmus
>> >> >> >>
>> >> >> >> --
>> >> >> >> PHP General Mailing List (http://www.php.net/)
>> >> >> >> To unsubscribe, visit: http://www.php.net/unsub.php
>> >> >> >>
>> >> >> >
>> >> >>
>> >> >> --
>> >> >> PHP General Mailing List (http://www.php.net/)
>> >> >> To unsubscribe, visit: http://www.php.net/unsub.php
>> >> >>
>> >> >
>> >>
>> >
>>
>
attached mail follows:
Thank you for replying. Sorry for being long again.
I tried your suggestion of this:
<?php
ignore_user_abort(true);
header("Location: redirect2.html");
echo "foo\n"; flush();
for($i=0;$i<10;$i++) { echo $i; sleep(1); }
$fp = fopen("/tmp/foo.txt","a");
fputs($fp,$i);
fclose($fp);
?>
The browser did not get the redirect page until the new $i(10) has been
appended to file foo.txt.
I also tried
-----------------------------------------------
ob_start();
header("Location: http://liang.ns2user.info/php/y.html");
echo "foo\n";
ob_end_flush();
-----------------------------------------------
And does not work.
I think it might be the case of what you suggest:
>If the
>client sticks around after seeing the redirect and doesn't redirect
>until after the server has closed the connection, then there is no way
>to force a close.
So may I draw the conclusions:
1. Server in php can not actively close the connection to make the client
see the redirect page immediately after the header has been set?
2. The connection is not closed even when the main php end and the shutdown
function is running?
If above conclusions are not true, could be somewhere that might be wrong
due to the apache-php configuration or what?
If those are true, I think I have to re-design the project flow control and
it will take sometime while I have already finished the code assuming no
above problem. Also I think this might result an awkward design for the
project. (I mean jsp will be easier to achieve a relatively more elegant
design).
I use several other program langurages for many years, but new to php, so I
probably made some assumption base on my experiences of other langurages but
not true. The project I am working now to add enhancements is written on
php. I try to keep the main design of it. I did not expect it would be
difficult to achieve this:
1. write an xml page
2. let http client get this xml page in time
3. continue do something time consuming
now I have difficulty in 2 and 3. My client is normally perl LWP::UserAgent,
and sometimes browser. I wonder how to let the client get the page in time
before I can continue to finish the rest of the work. Otherwise the client
will timeout and get no result.
Please help! Thank you.
Liang
>
>I really didn't follow all that. But this stuff is not that complex.
>header() sets a header to be sent when output goes out. header() does
>not send an actual header at that point. If you don't send any output,
>then the headers won't go out until the script terminates. If you have
>any sort of output buffering enabled, then even if you think you are
>sending something, you may only be buffering it, and in that case again
>the headers won't go out until the request is done.
>
>Also, ignore_user_abort() controls whether or not your script will be
>terminated when we are able to detect that the user has aborted. A user
>abort is defined as nobody being around to read the data we are sending
>out. If you don't send anything, we can't detect if the browser has
>gone away. Generally browsers will redirect as soon as they see a
>Location: redirect header, but that could be client-speficic. If the
>client sticks around after seeing the redirect and doesn't redirect
>until after the server has closed the connection, then there is no way
>to force a close. If it does redirect and close its end of the
>connection, then if you set ignore_user_abort(false) your script will be
>terminated as soon as it tries to send something further and your
>shutdown function will be called at that point.
>
>-Rasmus
>
>Liang ZHONG wrote:
> > Hi Rasmus,
> >
> > This may be a little bit long, sorry for taking your time.
> >
> > It still does not work as expected. I tried some experiment, and found
> > that if I called some function or write some code line other then
> > calling header(), the register_shutdown_function and other part of codes
> > work as expected . For example:
> > <?php
> > set_time_limit(5);
> > function f(){
> > set_time_limit(10);
> > //doing something time consuming
> > }
> >
> > some_function();
> >
> > ?>
> > The time limit of 5 will be the limit of the some_function() and the 10
> > will be the limit of function f() respectively.
> >
> > Code example:
> >
> >
>-----------------------------------------------------------------------------------------------------------------------
> >
> > <?php
> > set_time_limit(1);
> > ignore_user_abort(true);
> >
> > function say_goodbye() {
> > $st = connection_status();
> > print "Status 1: ".$st."\n";
> > set_time_limit(10);
> > $st = connection_status();
> > print "Status 2: ".$st."\n";
> >
> > $count=20000000;
> > for($i=0; $i<$count; $i++){ }
> > print "End!\n";
> > exec("touch /home/.nappy/liang/liang.ns2user.info/php/bbb");
> > }
> >
> > register_shutdown_function("say_goodbye");
> > print "Sleeping...\n";
> >
> > $count=10000000;
> > for($i=0; $i<$count; $i++){ }
> >
> > print "Done!\n";
> >
> > ?>
> >
>------------------------------------------------------------------------------------------------------------------------
> >
> > -bash-2.05b$ curl -N liang.ns2user.info/php/v.php
> > Sleeping...
> > <br />
> > <b>Fatal error</b>: Maximum execution time of 1 second exceeded in
> > <b>/home/.nappy/liang/liang.ns2user.info/php/v.php</b> on line
> > <b>30</b><br />
> > Status 1: 2
> > Status 2: 2
> > End!
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > if I change the time limit from 10 to 5 in function f()
> >
> > -bash-2.05b$ curl -N liang.ns2user.info/php/v.php
> > Sleeping...
> > <br />
> > <b>Fatal error</b>: Maximum execution time of 1 second exceeded in
> > <b>/home/.nappy/liang/liang.ns2user.info/php/v.php</b> on line
> > <b>30</b><br />
> > Status 1: 2
> > Status 2: 2
> > <br />
> > <b>Fatal error</b>: Maximum execution time of 5 seconds exceeded in
> > <b>/home/.nappy/liang/liang.ns2user.info/php/v.php</b> on line
> > <b>14</b><br />
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > Change both the time limit to 10 will result:
> >
> > -bash-2.05b$ curl -N liang.ns2user.info/php/v.php
> > Sleeping...
> > Done!
> >
> > Status 1: 0
> > Status 2: 0
> > End!
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >
> > But if the some_function is header() then the rule above does not work.
> > It seems the function f()'s time limit also rule the header(). Only
> > after the registered shutdown function finishes runing normally or by
> > hit the expire time limit, will the header() return page to browser/http
> > user agent. Example code with suggestion from Rasmus as:
> >
> >
>------------------------------------------------------------------------------------------------------------------
> >
> > <?php
> >
> > set_time_limit(5);
> >
> > function f(){
> > set_time_limit(100);
> > $count=500000000;
> > for($i=0; $i<$count; $i++){
> > //sit here and loop for a bit so we can have time to hit Stop...
> > echo "a \n"; flush();
> > }
> > echo "end";
> > exec("touch /tmp/aaa");
> > }
> >
> > register_shutdown_function('f');
> >
> > ignore_user_abort(true);
> > header("Content-type: text/plain");
> > header("Location: y.html");
> >
> > echo "foo\n"; flush();
> > for($i=0;$i<10;$i++) { echo $i; sleep(1); }
> > $fp = fopen("/tmp/foo.txt","a");
> > fputs($fp,$i);
> > fclose($fp);
> > ?>
> >
> >
>------------------------------------------------------------------------------------------------------------------
> >
> > After the file /tmp/foo.txt has been created, before the file /tmp/aaa
> > being created, the y.html will not get to the browser or perl program
> > using LWP::UserAgent. I think it is no way to close the connection
> > actively by the php program to deliver the page sooner to end the http
> > request, even I add lines and make code like this does not work:
> >
> > ----------------------------------------------------------------
> > header("Content-type: text/plain");
> > header("Cache-Control: no-store, no-cache");
> > header("Location: y.html");
> > header("Connection: close");
> > ----------------------------------------------------------------
> >
> > My project act as a broker for user agent to a library database server
> > called z39.50. Upon the request from user agent, my program need to
> > connect a z39.50 server, getting data back 1 by 1, transforming to
> > sepcial xml format and sending back to the request party. When the data
> > repository is huge (sometimes up to million records), I have to get
> > partial data transform and send back to user agent (normally a piece of
> > perl code, called harvester) with a resumption token. The harvester will
> > in a while loop send out another http request with the last resumption
> > token and fetch data of next part, until finish all data fetching. The
> > time to connect the database and do the query is a constant overhead. So
> > it is not a good design that program need to connect the database and
> > query upon each request with or with out resumption token. So my design
> > is to connect to database and query only when the first initial request
> > comes, and reponse back with partical data using header() and continue
> > getting back data from z39 server. Upon next request, the program will
> > only need to make sure the data needed has already stored in the
> > harddrive and transform them and send them back.
> > Since the user harvester agent normally has a 180 second timeout, it is
> > necessary to respond within that period of time.
> >
> > I really need your suggestion. Thank you very much again.
> >
> >
> > Liang
> >
> >
> >
> >
> >> Try somthing lik
> >
> >
> > e this:
> >
> >>
> >> <?php
> >> ignore_user_abort(true);
> >> header("Location: redirect2.html");
> >> echo "foo\n"; flush();
> >> for($i=0;$i<10;$i++) { echo $i; sleep(1); }
> >> $fp = fopen("/tmp/foo.txt","a");
> >> fputs($fp,$i);
> >> fclose($fp);
> >> ?>
> >>
> >>
> >> Liang ZHONG wrote:
> >> > Sorry, does not seem to work here. The code below takes minutes to
>show
> >> > up in browser.
> >> >
> >> > Any more suggestion?
> >> >
> >>
>---------------------------------------------------------------------------------------
> >>
> >> >
> >> > <?php
> >> >
> >> > set_time_limit(5);
> >> >
> >> > function f(){
> >> > set_time_limit(100);
> >> > $count=500000000;
> >> > for($i=0; $i<$count; $i++){ }
> >> > echo "end";
> >> > exec("touch /home/.nappy/liang/liang.ns2user.info/php/aaa");
> >> > }
> >> >
> >> > register_shutdown_function('f');
> >> >
> >> > ignore_user_abort(true);
> >> > header("Content-type: text/plain");
> >> > header("Location: y.html");
> >> >
> >> > $count=50000;
> >> > for($i=0; $i<$count; $i++){ echo " \n"; }
> >> > flush();
> >> > ?>
> >> >
> >>
>---------------------------------------------------------------------------------------
> >>
> >> >
> >> >
> >> > Liang
> >> >
> >> >>
> >> >> If you don't flush some output after setting the header() then the
> >> >> headers won't go out until the end of the request. So do something
> >> like:
> >> >>
> >> >> ignore_user_abort(true);
> >> >> header("Location: http://whatever");
> >> >> echo "foo\n"; flush();
> >> >>
> >> >> Then whatever comes after this should run and the browser is long
> >> gone.
> >> >>
> >> >> -Rasmus
> >> >>
> >> >>
> >> >> Liang ZHONG wrote:
> >> >> > I think I did not express myself clearly.
> >> >> >
> >> >> > What I want is to be able to redirect user an existing page (let
> >> them
> >> >> > get it immediately), and to close the connection actively, NOT
> >> >> passively
> >> >> > by user abort, at last, to run the function in background.
> >> >> >
> >> >> > But the redirecting using function header() with location has a
> >> problem
> >> >> > that header() always does return the page to user after the entire
> >> >> > program, including registered showdown function finish running,
> >> >> which is
> >> >> > against the will. I put a time consuming task into a function that
> >> >> > registered to be a shutdown function and hoping it runs after the
> >> user
> >> >> > has got the redirected page and the connection has been closed.
>But
> >> >> > experiements (using browsers, curl command line tool as well as
> >> >> > perl::LWP code) show that the user got the redirected page only
> >> after
> >> >> > the shutdown function finished, which is against the description
>of
> >> >> > register_shutdown_function at php website.
> >> >> >
> >> >> > It seems only header() function use to redirect page has this
> >> problem
> >> >> > (not executed until register_shutdown_function finished) while
>other
> >> >> > functions like print()/echo(), exec() have not.
> >> >> >
> >> >> > The code looks like:
> >> >> >
> >> >>
> >>
>---------------------------------------------------------------------------------------------
> >>
> >> >>
> >> >> >
> >> >> > <?php
> >> >> > set_time_limit(1);
> >> >> >
> >> >> > function f(){
> >> >> > set_time_limit(20);
> >> >> > $count=50000000;
> >> >> > for($i=0; $i<$count; $i++){ }
> >> >> > echo "end";
> >> >> > exec("touch /home/.nappy/liang/liang.ns2user.info/php/aaa");
> >> >> > }
> >> >> >
> >> >> > register_shutdown_function('f');
> >> >> >
> >> >> > header("Content-type: text/plain");
> >> >> > header("Location: y.html");
> >> >> > ?>
> >> >> >
> >> >>
> >>
>---------------------------------------------------------------------------------------------
> >>
> >> >>
> >> >> >
> >> >> >
> >> >> > http client who sends the request to the php program will only
> >> get the
> >> >> > page back as response after function f finsihes (file aaa
>created).
> >> >> > Changing the $count will make a lot difference.
> >> >> >
> >> >> > My BIGGEST question is:
> >> >> > How to make user get the redirect page immediately after the
> >> >> header() is
> >> >> > called, and not until function f() ends, while making sure that
>the
> >> >> > function f() will finally fully (and might slowly) execute?
> >> >> >
> >> >> > Thank you very much for kindly replying.
> >> >> >
> >> >> > With high respect,
> >> >> >
> >> >> > Liang
> >> >> >
> >> >> >
> >> >> >>
> >> >> >> Liang ZHONG wrote:
> >> >> >> > My Question is:
> >> >> >> > What is the correct way to keep the function running after I
> >> >> >> redirect an
> >> >> >> > existing page to http client (which I want the client get
> >> >> immediately)
> >> >> >> > and then immediately close the connection?
> >> >> >>
> >> >> >> ignore_user_abort(true);
> >> >> >>
> >> >> >> -Rasmus
> >> >> >>
> >> >> >> --
> >> >> >> PHP General Mailing List (http://www.php.net/)
> >> >> >> To unsubscribe, visit: http://www.php.net/unsub.php
> >> >> >>
> >> >> >
> >> >>
> >> >> --
> >> >> PHP General Mailing List (http://www.php.net/)
> >> >> To unsubscribe, visit: http://www.php.net/unsub.php
> >> >>
> >> >
> >>
> >
>
attached mail follows:
I tested the link (http://lerdorf.com/red.php) using browser (firefox 1.0),
it worked as expected, the page of redirect2.html displayed within 2
seconds. I put the exact code to my testing envirionment (2 places), as this
one: http://liang.ns2user.info/php/red.php , and the page shows up in about
13 seconds using the SAME browser.
Observation 1.
============
Same client(web browser on same mechine), same code on different runing
environment make difference.
I use perl code (to get page from http://lerdorf.com/red.php)
----------------------------------------------------------
#!/usr/bin/perl -w
use strict;
use LWP::Simple;
use LWP::UserAgent;
# get input from command line
my ($url) =
ARGV;
# set default URL if none is given
if ( !$url ){
$url = 'http://liang.ns2user.info/liang/y.php';
print STDOUT qq{Using $url as url to fetch\n};
}
# get the html page from the web, into a string
my $ua = LWP::UserAgent->new(keep_alive=>1, timeout=>180);
my $req = HTTP::Request->new( GET => $url );
my $res = $ua->request( $req );
if(!$res->is_success){
my $error = $res->message();
print STDOUT qq{ERRO: with pid of $$ has ended for the following error:
$error};
exit;
}
my $htmlPage = $res->content;
print $htmlPage."\n";
exit;
----------------------------------------------------------
It takes about 13 seconds to get:
~~~~~~~~~~~~~~~~~~~~~~~~~~
marvin:~/liang.ns2user.info/perl> ./http_req.pl http://lerdorf.com/red.php
You are now on redirect2.html
~~~~~~~~~~~~~~~~~~~~~~~~~~
Observation 2.
=============
Different clients (browser and perl LWP::UserAgent) request same code on the
same mechane result differently.
Question:
========
Could it be because of the configuration of linux/apache/php on the server
side instead of client side make the difference?
(2 of my testing environments are red hat linux with apache 2.0 and one is
php5.04 another is 4.3.10.)?
The php configuration is: http://liang.ns2user.info/php/info.php. I have no
read permission of those httpd.conf files so do not know how apache
configured.
Any hint? Thank you.
Liang
>That's a client-side issue then, because it is certainly sent. Trying
>your exact script:
>
>
><?php
>ignore_user_abort(true);
>header("Location: redirect2.html");
>echo "foo\n"; flush();
>for($i=0;$i<10;$i++) { echo $i; sleep(1); }
>$fp = fopen("/tmp/foo.txt","a");
>fputs($fp,$i);
>fclose($fp);
>?>
>
>It's at http://lerdorf.com/red.php if you want to test it yourself.
>
>3:53pm colo:/var/www/lerdorf.com> telnet localhost 80
>Trying 127.0.0.1...
>Connected to colo.
>Escape character is '^]'.
>GET /red.php HTTP/1.0
>
>HTTP/1.1 302 Found
>Date: Tue, 26 Jul 2005 22:53:40 GMT
>Server: Apache/1.3.33 (Debian GNU/Linux) PHP/4.4.1-dev
>X-Powered-By: PHP/4.4.1-dev
>Location: redirect2.html
>Connection: close
>Content-Type: text/html; charset=utf-8
>
>foo
><10 second delay here>
>Connection closed by foreign host.
>
>-Rasmus
>
>Liang ZHONG wrote:
> > Thank you for replying. Sorry for being long again.
> > I tried your suggestion of this:
> >
> > <?php
> > ignore_user_abort(true);
> > header("Location: redirect2.html");
> > echo "foo\n"; flush();
> > for($i=0;$i<10;$i++) { echo $i; sleep(1); }
> > $fp = fopen("/tmp/foo.txt","a");
> > fputs($fp,$i);
> > fclose($fp);
> > ?>
> >
> > The browser did not get the redirect page until the new $i(10) has been
> > appended to file foo.txt.
> >
> > I also tried
> > -----------------------------------------------
> > ob_start();
> > header("Location: http://liang.ns2user.info/php/y.html");
> > echo "