note 73132 added to function.fopen

From: 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

« previous php.notes (#123197) next »