source: Dev/branches/cakephp/cake/libs/cake_socket.php @ 126

Last change on this file since 126 was 126, checked in by fpvanagthoven, 14 years ago

Cakephp branch.

File size: 6.6 KB
Line 
1<?php
2/**
3 * Cake Socket connection class.
4 *
5 * PHP versions 4 and 5
6 *
7 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8 * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
9 *
10 * Licensed under The MIT License
11 * Redistributions of files must retain the above copyright notice.
12 *
13 * @copyright     Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
14 * @link          http://cakephp.org CakePHP(tm) Project
15 * @package       cake
16 * @subpackage    cake.cake.libs
17 * @since         CakePHP(tm) v 1.2.0
18 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
19 */
20App::import('Core', 'Validation');
21
22/**
23 * Cake network socket connection class.
24 *
25 * Core base class for network communication.
26 *
27 * @package       cake
28 * @subpackage    cake.cake.libs
29 */
30class CakeSocket extends Object {
31
32/**
33 * Object description
34 *
35 * @var string
36 * @access public
37 */
38        var $description = 'Remote DataSource Network Socket Interface';
39
40/**
41 * Base configuration settings for the socket connection
42 *
43 * @var array
44 * @access protected
45 */
46        var $_baseConfig = array(
47                'persistent'    => false,
48                'host'                  => 'localhost',
49                'protocol'              => 'tcp',
50                'port'                  => 80,
51                'timeout'               => 30
52        );
53
54/**
55 * Configuration settings for the socket connection
56 *
57 * @var array
58 * @access public
59 */
60        var $config = array();
61
62/**
63 * Reference to socket connection resource
64 *
65 * @var resource
66 * @access public
67 */
68        var $connection = null;
69
70/**
71 * This boolean contains the current state of the CakeSocket class
72 *
73 * @var boolean
74 * @access public
75 */
76        var $connected = false;
77
78/**
79 * This variable contains an array with the last error number (num) and string (str)
80 *
81 * @var array
82 * @access public
83 */
84        var $lastError = array();
85
86/**
87 * Constructor.
88 *
89 * @param array $config Socket configuration, which will be merged with the base configuration
90 * @see CakeSocket::$_baseConfig
91 */
92        function __construct($config = array()) {
93                parent::__construct();
94
95                $this->config = array_merge($this->_baseConfig, $config);
96                if (!is_numeric($this->config['protocol'])) {
97                        $this->config['protocol'] = getprotobyname($this->config['protocol']);
98                }
99        }
100
101/**
102 * Connect the socket to the given host and port.
103 *
104 * @return boolean Success
105 * @access public
106 */
107        function connect() {
108                if ($this->connection != null) {
109                        $this->disconnect();
110                }
111
112                $scheme = null;
113                if (isset($this->config['request']) && $this->config['request']['uri']['scheme'] == 'https') {
114                        $scheme = 'ssl://';
115                }
116
117                if ($this->config['persistent'] == true) {
118                        $tmp = null;
119                        $this->connection = @pfsockopen($scheme.$this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
120                } else {
121                        $this->connection = @fsockopen($scheme.$this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
122                }
123
124                if (!empty($errNum) || !empty($errStr)) {
125                        $this->setLastError($errNum, $errStr);
126                }
127
128                $this->connected = is_resource($this->connection);
129                if ($this->connected) {
130                        stream_set_timeout($this->connection, $this->config['timeout']);
131                }
132                return $this->connected;
133        }
134
135/**
136 * Get the host name of the current connection.
137 *
138 * @return string Host name
139 * @access public
140 */
141        function host() {
142                if (Validation::ip($this->config['host'])) {
143                        return gethostbyaddr($this->config['host']);
144                } else {
145                        return gethostbyaddr($this->address());
146                }
147        }
148
149/**
150 * Get the IP address of the current connection.
151 *
152 * @return string IP address
153 * @access public
154 */
155        function address() {
156                if (Validation::ip($this->config['host'])) {
157                        return $this->config['host'];
158                } else {
159                        return gethostbyname($this->config['host']);
160                }
161        }
162
163/**
164 * Get all IP addresses associated with the current connection.
165 *
166 * @return array IP addresses
167 * @access public
168 */
169        function addresses() {
170                if (Validation::ip($this->config['host'])) {
171                        return array($this->config['host']);
172                } else {
173                        return gethostbynamel($this->config['host']);
174                }
175        }
176
177/**
178 * Get the last error as a string.
179 *
180 * @return string Last error
181 * @access public
182 */
183        function lastError() {
184                if (!empty($this->lastError)) {
185                        return $this->lastError['num'] . ': ' . $this->lastError['str'];
186                } else {
187                        return null;
188                }
189        }
190
191/**
192 * Set the last error.
193 *
194 * @param integer $errNum Error code
195 * @param string $errStr Error string
196 * @access public
197 */
198        function setLastError($errNum, $errStr) {
199                $this->lastError = array('num' => $errNum, 'str' => $errStr);
200        }
201
202/**
203 * Write data to the socket.
204 *
205 * @param string $data The data to write to the socket
206 * @return boolean Success
207 * @access public
208 */
209        function write($data) {
210                if (!$this->connected) {
211                        if (!$this->connect()) {
212                                return false;
213                        }
214                }
215                $totalBytes = strlen($data);
216                for ($written = 0, $rv = 0; $written < $totalBytes; $written += $rv) {
217                        $rv = fwrite($this->connection, substr($data, $written));
218                        if ($rv === false || $rv === 0) {
219                                return $written;
220                        }
221                }
222                return $written;
223        }
224
225/**
226 * Read data from the socket. Returns false if no data is available or no connection could be
227 * established.
228 *
229 * @param integer $length Optional buffer length to read; defaults to 1024
230 * @return mixed Socket data
231 * @access public
232 */
233        function read($length = 1024) {
234                if (!$this->connected) {
235                        if (!$this->connect()) {
236                                return false;
237                        }
238                }
239
240                if (!feof($this->connection)) {
241                        $buffer = fread($this->connection, $length);
242                        $info = stream_get_meta_data($this->connection);
243                        if ($info['timed_out']) {
244                                $this->setLastError(E_WARNING, __('Connection timed out', true));
245                                return false;
246                        }
247                        return $buffer;
248                } else {
249                        return false;
250                }
251        }
252
253/**
254 * Abort socket operation.
255 *
256 * @return boolean Success
257 * @access public
258 */
259        function abort() {
260        }
261
262/**
263 * Disconnect the socket from the current connection.
264 *
265 * @return boolean Success
266 * @access public
267 */
268        function disconnect() {
269                if (!is_resource($this->connection)) {
270                        $this->connected = false;
271                        return true;
272                }
273                $this->connected = !fclose($this->connection);
274
275                if (!$this->connected) {
276                        $this->connection = null;
277                }
278                return !$this->connected;
279        }
280
281/**
282 * Destructor, used to disconnect from current connection.
283 *
284 * @access private
285 */
286        function __destruct() {
287                $this->disconnect();
288        }
289
290/**
291 * Resets the state of this Socket instance to it's initial state (before Object::__construct got executed)
292 *
293 * @return boolean True on success
294 * @access public
295 */
296        function reset($state = null) {
297                if (empty($state)) {
298                        static $initalState = array();
299                        if (empty($initalState)) {
300                                $initalState = get_class_vars(__CLASS__);
301                        }
302                        $state = $initalState;
303                }
304
305                foreach ($state as $property => $value) {
306                        $this->{$property} = $value;
307                }
308                return true;
309        }
310}
Note: See TracBrowser for help on using the repository browser.