Seditio Source
Root |
./othercms/dotclear-2.22/inc/libs/clearbricks/net/class.net.socket.php
<?php
/**
 * @class netSocket
 * @brief Network base
 *
 * This class handles network socket through an iterator.
 *
 * @package Clearbricks
 * @subpackage Network
 *
 * @copyright Olivier Meunier & Association Dotclear
 * @copyright GPL-2.0-only
 */
class netSocket
{
    protected
$_host;           ///< string: Server host
   
protected $_port;           ///< integer: Server port
   
protected $_transport = ''; ///< string: Server transport
   
protected $_timeout;        ///< integer: Connection timeout
   
protected $_handle;         ///< resource: Resource handler

    /**
     * Class constructor
     *
     * @param string        $host        Server host
     * @param string         $port        Server port
     * @param int        $timeout        Connection timeout
     */
   
public function __construct($host, $port, $timeout = 10)
    {
       
$this->_host    = $host;
       
$this->_port    = abs((int) $port);
       
$this->_timeout = abs((int) $timeout);
    }

   
/**
     * Object destructor
     *
     * Calls {@link close()} method
     */
   
public function __destruct()
    {
       
$this->close();
    }

   
/**
     * Get / Set host
     *
     * If <var>$host</var> is set, set {@link $_host} and returns true.
     * Otherwise, returns {@link $_host} value.
     *
     * @param string    $host            Server host
     * @return string|true
     */
   
public function host($host = null)
    {
        if (
$host) {
           
$this->_host = $host;

            return
true;
        }

        return
$this->_host;
    }

   
/**
     * Get / Set port
     *
     * If <var>$port</var> is set, set {@link $_port} and returns true.
     * Otherwise, returns {@link $_port} value.
     *
     * @param integer    $port            Server port
     * @return integer|true
     */
   
public function port($port = null)
    {
        if (
$port) {
           
$this->_port = abs((int) $port);

            return
true;
        }

        return
$this->_port;
    }

   
/**
     * Get / Set timeout
     *
     * If <var>$timeout</var> is set, set {@link $_timeout} and returns true.
     * Otherwise, returns {@link $_timeout} value.
     *
     * @param integer    $timeout            Connection timeout
     * @return string|true
     */
   
public function timeout($timeout = null)
    {
        if (
$timeout) {
           
$this->_timeout = abs((int) $timeout);

            return
true;
        }

        return
$this->_timeout;
    }

   
/**
     * Set blocking
     *
     * Sets blocking or non-blocking mode on the socket.
     *
     * @param integer    $i        1 for yes, 0 for no
     * @return    boolean
     */
   
public function setBlocking($i)
    {
        if (!
$this->isOpen()) {
            return
false;
        }

        return
stream_set_blocking($this->_handle, (bool) $i);
    }

   
/**
     * Open connection.
     *
     * Opens socket connection and Returns an object of type {@link netSocketIterator}
     * which can be iterate with a simple foreach loop.
     *
     * @return    netSocketIterator|bool
     */
   
public function open()
    {
       
$handle = @fsockopen($this->_transport . $this->_host, $this->_port, $errno, $errstr, $this->_timeout);
        if (!
$handle) {
            throw new
Exception('Socket error: ' . $errstr . ' (' . $errno . ')');
        }
       
$this->_handle = $handle;

        return
$this->iterator();
    }

   
/**
     * Closes socket connection
     */
   
public function close()
    {
        if (
$this->isOpen()) {
           
fclose($this->_handle);
           
$this->_handle = null;
        }
    }

   
/**
     * Send data
     *
     * Sends data to current socket and returns an object of type
     * {@link netSocketIterator} which can be iterate with a simple foreach loop.
     *
     * <var>$data</var> can be a string or an array of lines.
     *
     * Example:
     *
     * <code>
     * <?php
     * $s = new netSocket('www.google.com',80,2);
     * $s->open();
     * $data = [
     *     'GET / HTTP/1.0'
     * ];
     * foreach($s->write($data) as $v) {
     *     echo $v."\n";
     * }
     * $s->close();
     * ?>
     * </code>
     *
     * @param string|array    $data        Data to send
     * @return    netSocketIterator|false
     */
   
public function write($data)
    {
        if (!
$this->isOpen()) {
            return
false;
        }

        if (
is_array($data)) {
           
$data = implode("\r\n", $data) . "\r\n\r\n";
        }

       
fwrite($this->_handle, $data);

        return
$this->iterator();
    }

   
/**
     * Flush buffer
     *
     * Flushes socket write buffer.
     */
   
public function flush()
    {
        if (!
$this->isOpen()) {
            return
false;
        }

       
fflush($this->_handle);
    }

   
/**
     * Iterator
     *
     * @return    netSocketIterator|false
     */
   
protected function iterator()
    {
        if (!
$this->isOpen()) {
            return
false;
        }

        return new
netSocketIterator($this->_handle);
    }

   
/**
     * Is open
     *
     * Returns true if socket connection is open.
     *
     * @return    boolean
     */
   
public function isOpen()
    {
        return
is_resource($this->_handle);
    }
}

/**
 * @class netSocketIterator
 * @brief Network socket iterator
 *
 * This class offers an iterator for network operations made with
 * {@link netSocket}.
 *
 * @see netSocket::write()
 */
class netSocketIterator implements Iterator
{
    protected
$_handle; ///< resource: Socket resource handler
   
protected $_index;  ///< integer: Current index position

    /**
     * Constructor
     *
     * @param resource    $handle        Socket resource handler
     */
   
public function __construct(&$handle)
    {
        if (!
is_resource($handle)) {
            throw new
Exception('Handle is not a resource');
        }
       
$this->_handle = &$handle;
       
$this->_index  = 0;
    }

   
/* Iterator methods
    --------------------------------------------------- */
    /**
     * Rewind
     */
    #[\ReturnTypeWillChange]
   
public function rewind()
    {
       
# Nothing
   
}

   
/**
     * Valid
     *
     * @return boolean    True if EOF of handler
     */
    #[\ReturnTypeWillChange]
   
public function valid()
    {
        return !
feof($this->_handle);
    }

   
/**
     * Move index forward
     */
    #[\ReturnTypeWillChange]
   
public function next()
    {
       
$this->_index++;
    }

   
/**
     * Current index
     *
     * @return integer    Current index
     */
    #[\ReturnTypeWillChange]
   
public function key()
    {
        return
$this->_index;
    }

   
/**
     * Current value
     *
     * @return string    Current socket response line
     */
    #[\ReturnTypeWillChange]
   
public function current()
    {
        return
fgets($this->_handle, 4096);
    }
}