Attempting to circumvent "golden hammer" issue

This commit is contained in:
Chris Boden 2011-09-07 11:19:28 -04:00
parent f2423f09e5
commit 3ef9f45de5
2 changed files with 69 additions and 5 deletions

View File

@ -10,7 +10,7 @@ class Socket {
/** /**
* @type resource * @type resource
*/ */
protected $_socket; public $_resource;
public static $_defaults = Array( public static $_defaults = Array(
'domain' => AF_INET 'domain' => AF_INET
@ -27,9 +27,9 @@ class Socket {
public function __construct($domain = null, $type = null, $protocol = null) { public function __construct($domain = null, $type = null, $protocol = null) {
list($domain, $type, $protocol) = static::getConfig($domain, $type, $protocol); list($domain, $type, $protocol) = static::getConfig($domain, $type, $protocol);
$this->_socket = @socket_create($domain, $type, $protocol); $this->_resource = @socket_create($domain, $type, $protocol);
if (!is_resource($this->_socket)) { if (!is_resource($this->_resource)) {
throw new Exception(); throw new Exception();
} }
} }
@ -73,6 +73,46 @@ class Socket {
return Array($domain, $type, $protocol); return Array($domain, $type, $protocol);
} }
/**
* Since PHP is retarded and their golden hammer, the array, doesn't implement any interfaces I have to hackishly overload socket_select
* @param Iterator|Array|NULL The sockets listed in the read array will be watched to see if characters become available for reading (more precisely, to see if a read will not block - in particular, a socket resource is also ready on end-of-file, in which case a socket_read() will return a zero length string).
* @param Iterator|Array|NULL The sockets listed in the write array will be watched to see if a write will not block.
* @param Iterator|Array|NULL The sockets listed in the except array will be watched for exceptions.
* @param int The tv_sec and tv_usec together form the timeout parameter. The timeout is an upper bound on the amount of time elapsed before socket_select() return. tv_sec may be zero , causing socket_select() to return immediately. This is useful for polling. If tv_sec is NULL (no timeout), socket_select() can block indefinitely.
* @param int
* @throws \InvalidArgumentException
* @todo See if this crack-pot scheme works!
*/
public function select(&$read, &$write, &$except, $tv_sec, $tv_usec = 0) {
$read = static::mungForSelect($read);
$write = static::mungForSelect($write);
$except = static::mungForSelect($except);
socket_select($read, $write, $except, $tv_sec, $tv_usec);
}
/**
* @param Iterator|Array|NULL
* @return Array|NULL
* @throws \InvalidArgumentException
*/
protected static function mungForSelect($collection) {
if (null === $collection || is_array($collection)) {
return $collection;
}
if (!($collection instanceof \Traversable)) {
throw new \InvalidArgumentException('Object pass is not traversable');
}
$return = Array();
foreach ($collection as $key => $socket) {
$return[$key] = ($socket instanceof \Ratchet\Socket ? $socket->_resource : $socket);
}
return $return;
}
/** /**
* @internal * @internal
* @param string * @param string
@ -82,7 +122,7 @@ class Socket {
*/ */
public function __call($method, $arguments) { public function __call($method, $arguments) {
if (function_exists('socket_' . $method)) { if (function_exists('socket_' . $method)) {
array_unshift($arguments, $this->_socket); array_unshift($arguments, $this->_resource);
return call_user_func_array('socket_' . $method, $arguments); return call_user_func_array('socket_' . $method, $arguments);
} }

View File

@ -62,9 +62,33 @@ class SocketTest extends \PHPUnit_Framework_TestCase {
$socket = Socket::createFromConfig($protocol); $socket = Socket::createFromConfig($protocol);
$config = $protocol::getDefaultConfig(); $config = $protocol::getDefaultConfig();
// chnage this to array_filter late // change this to array_filter late
unset($config['options']); unset($config['options']);
$this->assertAttributeEquals($config, '_arguments', $socket); $this->assertAttributeEquals($config, '_arguments', $socket);
} }
public function asArrayProvider() {
return Array(
Array(Array('hello' => 'world'), Array('hello' => 'world'))
, Array(null, null)
, Array(Array('hello' => 'world'), new \ArrayObject(Array('hello' => 'world')))
);
}
/**
* @dataProvider asArrayProvider
*/
public function testMethodMungforselectReturnsExpectedValues($output, $input) {
$method = static::getMethod('mungForSelect');
$return = $method->invokeArgs($this->_socket, Array($input));
$this->assertEquals($return, $output);
}
public function testMethodMungforselectRejectsNonTraversable() {
$this->setExpectedException('\\InvalidArgumentException');
$method = static::getMethod('mungForSelect');
$method->invokeArgs($this->_socket, Array('I am upset with PHP ATM'));
}
} }