_socket = $this->_wrapper() ->pfsockopen($host, $port, $errno, $errstr, $connectTimeout, $connectPersistent); } else { $this->_socket = $this->_wrapper() ->fsockopen($host, $port, $errno, $errstr, $connectTimeout, $connectPersistent); } if (!$this->_socket) { throw new Exception\ConnectionException($errno, $errstr . " (connecting to $host:$port)"); } $this->_wrapper() ->stream_set_timeout($this->_socket, self::SOCKET_TIMEOUT); } /* (non-phpdoc) * @see Socket::write() */ public function write($data) { $history = new WriteHistory(self::WRITE_RETRIES); for ($written = 0, $fwrite = 0; $written < strlen($data); $written += $fwrite) { $fwrite = $this->_wrapper() ->fwrite($this->_socket, substr($data, $written)); $history->log($fwrite); if ($history->isFullWithNoWrites()) { throw new Exception\SocketException(sprintf( 'fwrite() failed to write data after %u tries', self::WRITE_RETRIES )); } } } /* (non-phpdoc) * @see Socket::write() */ public function read($length) { $read = 0; $parts = ''; while ($read < $length && !$this->_wrapper()->feof($this->_socket)) { $data = $this->_wrapper() ->fread($this->_socket, $length - $read); if ($data === false) { throw new Exception\SocketException('fread() returned false'); } $read += strlen($data); $parts .= $data; } return $parts; } /* (non-phpdoc) * @see Socket::write() */ public function getLine($length = null) { do { $data = isset($length) ? $this->_wrapper()->fgets($this->_socket, $length) : $this->_wrapper()->fgets($this->_socket); if ($this->_wrapper()->feof($this->_socket)) { throw new Exception\SocketException("Socket closed by server!"); } } while ($data === false); return rtrim($data); } public function disconnect() { $this->_wrapper()->fclose($this->_socket); } // ---------------------------------------- /** * Wrapper class for all stream functions. * Facilitates mocking/stubbing stream operations in unit tests. */ private function _wrapper() { return StreamFunctions::instance(); } }