I am working on some code that is read from a socket, and it is mistaken when it receives certain large input. I went to add a unit test for this before fixing it, but got stuck because I cannot mock fread (and other PHP built-in functions that I use, for example, fsockopen , feof , etc.).
In simple words, my problem is that this code does not work with "Fatal error: cannot override fgets () ...":
function fgets($fp){ return "xxx"; }
I understand that I can create a socket wrapper class that uses my real code, and then I could create a layout for this wrapper class. But this is The Tail Wagging The Dog, and I can think of reasons why this is a bad idea, other than the principle of things. (For example, to make the code more complex, efficiency, the presence of a refactoring code has not been tested yet.)
So my question is how to replace the built-in fgets() implementation with my own, as part of the unit test? (Or, if you want to think outside the box, the question can be formulated as follows: how can I control the string returned by fgets($socket) when $socket is the return value from fsockopen ?)
ASIDE
Installing apd as the correct answer requires is hard work; it was last released in 2004 and does not support php 5.3 out of the box. There is no Ubuntu package for it, as well as pecl install apd . So, here are the procedures for installing it (this is for ubuntu 10.04) (everything is done as root):
pecl download apd tar xzf apd-1.0.1.tgz cd apd-1.0.1 phpize ./configure
See https://bugs.php.net/bug.php?id=58798 for the fix you need to do. NB. there is only one line that you really have to change, so you can do it manually, as follows: open php_apd.c in a text editor, go to line 967 and replace the line CG(extended_info) = 1 with this:
CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
Finally, you need to add a php.ini entry to activate it. See http://php.net/manual/en/apd.installation.php