note 73132 added to function.fopen
| From: | andrew at NOSPAM dot neonsurge dot com | Date: | Sat, 10 Feb 2007 02:22:43 +0000 |
| Subject: | note 73132 added to function.fopen | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-123197@lists.php.net to get a copy of this message | ||
My recent findings on high-performance fopen/fsockopen usage.
Note #1: The performance comparison below regarding curl is obsolete when utilizing certain things
in this comment. My performance tests download and upload about 97% as fast as curl with a custom
non-socket blocking HTTP Transport class written for a high performance system in PHP5.
Note #2: fopen and fsockopen have a "feature' that always forces DNS resolution. Check
this code...
<?php for ($i = 0; $i < 50; $i++) {
$errno = $errstr = "";
//$ip = gethostbyname("php.net"); $a = fsockopen($ip,22,$errno,$errstr,10); //FAST way
$a = fsockopen("php.net",22,$errno,$errstr,10); //SLOW way
$ab = fread($a,4096); unset($a, $ab);
} ?>
fsockopen() and fopen() always force php.net to be resolved every time and in this example above it
resolves the name 50 seperate times and does not use the local cache. To get around this,
gethostbyname() does use your local DNS cache properly, it will not try to get the IP from your DNS
server 50 times. The above code for me to a personal server took 87 seconds the fast way, and 5.74
seconds the slow way, a 650% increase. And this is single-threaded! ;)
Note #3: I see a lot of notes and people mentioning non-blocking sockets, especially for HTTP
transport. I thought I would share a little from my experience. First, the above command
fsockopen() allows you to specify a timeout, after you check if it's opened properly (as you
should _always_) you just need to...
<?php stream_set_blocking($a,0);?>
From this point on certain considerations must be taken. Remember you are not blocking anymore, so
when you want to write or read a lot of data it will always return to you instantly. Which is
important since you need to check the return value of your writes and reads against how much you
expect to read/write. For reading if you do not know how long it is, checking for EOF works also.
This is in fact a neat feature and state, since you can now make a read/write loop to send/receive a
lot of data and check the time/timeout value(s) constantly. If that timeout is hit you can throw
back errors properly to whatever function/method/code called your transport function/class. The
graceful failure with custom shorter failure times allows your application to continue, especially
web-based applications where fopen alone and even curl under certain circumstances does not follow
your requested timeouts, it will wait a full 60-90 seconds, depending on your OS.
Good ways to test a custom non-blocking timeout supported transport method described above is to
make one first, and then transfer a large file with it, and halfway through unplug your network
cable. Curl or fopen/fread/fwrite alone will croak and make your applications wait a full 60-90
seconds, whereas a nice custom class will check if no data has been transferred for 15 seconds (or
less!) and will fail gracefully with a error.
If anyone is interested in chatting about this feel free to contact me or add to this comment.
----
Server IP: 64.71.164.2
Probable Submitter: 66.238.64.20
----
Manual Page -- http://www.php.net/manual/en/function.fopen.php
Edit -- https://master.php.net/note/edit/73132
Del: integrated -- https://master.php.net/note/delete/73132/integrated
Del: useless -- https://master.php.net/note/delete/73132/useless
Del: bad code -- https://master.php.net/note/delete/73132/bad+code
Del: spam -- https://master.php.net/note/delete/73132/spam
Del: non-english -- https://master.php.net/note/delete/73132/non-english
Del: in docs -- https://master.php.net/note/delete/73132/in+docs
Del: other reasons-- https://master.php.net/note/delete/73132
Reject -- https://master.php.net/note/reject/73132
Search -- https://master.php.net/manage/user-notes.php