Hoa central
Socket.php
Go to the documentation of this file.
1 <?php
2 
37 namespace Hoa\Socket;
38 
39 use Hoa\Core;
40 
49 class Socket
50 {
56  const ADDRESS_IPV6 = 0;
57 
63  const ADDRESS_IPV4 = 1;
64 
70  const ADDRESS_DOMAIN = 2;
71 
77  const ADDRESS_PATH = 3;
78 
84  protected $_address = null;
85 
91  protected $_addressType = 0;
92 
98  protected $_port = -1;
99 
105  protected $_transport = null;
106 
107 
108 
115  public function __construct($uri)
116  {
117  $this->setURI($uri);
118 
119  return;
120  }
121 
129  public function setURI($uri)
130  {
131  $m = preg_match(
132  '#(?<scheme>[^:]+)://' .
133  '(?:\[(?<ipv6_>[^\]]+)\]:(?<ipv6_port>\d+)$|' .
134  '(?<ipv4>(\*|\d+(?:\.\d+){3}))(?::(?<ipv4_port>\d+))?$|' .
135  '(?<domain>[^:]+)(?::(?<domain_port>\d+))?$|' .
136  '(?<ipv6>.+)$)#',
137  $uri,
138  $matches);
139 
140  if (0 === $m) {
141  throw new Exception(
142  'URI %s is not recognized (it is not an IPv6, IPv4 nor ' .
143  'domain name).',
144  0,
145  $uri
146  );
147  }
148 
149  $this->setTransport($matches['scheme']);
150 
151  if (isset($matches['ipv6_']) && !empty($matches['ipv6_'])) {
152  $this->_address = $matches['ipv6_'];
153  $this->_addressType = self::ADDRESS_IPV6;
154  $this->setPort($matches['ipv6_port']);
155  } elseif (isset($matches['ipv6']) && !empty($matches['ipv6'])) {
156  $this->_address = $matches['ipv6'];
157  $this->_addressType = self::ADDRESS_IPV6;
158  } elseif (isset($matches['ipv4']) && !empty($matches['ipv4'])) {
159  $this->_address = $matches['ipv4'];
160  $this->_addressType = self::ADDRESS_IPV4;
161 
162  if ('*' === $this->_address) {
163  $this->_address = '0.0.0.0';
164  }
165 
166  if (isset($matches['ipv4_port'])) {
167  $this->setPort($matches['ipv4_port']);
168  }
169  } elseif (isset($matches['domain'])) {
170  $this->_address = $matches['domain'];
171 
172  if (false !== strpos($this->_address, '/')) {
173  $this->_addressType = self::ADDRESS_PATH;
174  } else {
175  $this->_addressType = self::ADDRESS_DOMAIN;
176  }
177 
178  if (isset($matches['domain_port'])) {
179  $this->setPort($matches['domain_port']);
180  }
181  }
182 
183  if (self::ADDRESS_IPV6 == $this->_addressType &&
184  (
185  !defined('STREAM_PF_INET6') ||
186  (function_exists('socket_create') && !defined('AF_INET6'))
187  )
188  ) {
189  throw new Exception(
190  'IPv6 support has been disabled from PHP, we cannot use ' .
191  'the %s URI.',
192  1,
193  $uri
194  );
195  }
196 
197  return;
198  }
199 
207  protected function setPort($port)
208  {
209  if ($port < 0) {
210  throw new Exception(
211  'Port must be greater or equal than zero, given %d.',
212  2,
213  $port
214  );
215  }
216 
217  $old = $this->_port;
218  $this->_port = $port;
219 
220  return $old;
221  }
222 
230  protected function setTransport($transport)
231  {
232  $transport = strtolower($transport);
233 
234  if (false === Transport::exists($transport)) {
235  throw new Exception(
236  'Transport %s is not enabled on this machin.',
237  3,
238  $transport
239  );
240  }
241 
242  $old = $this->_transport;
243  $this->_transport = $transport;
244 
245  return $old;
246  }
247 
253  public function getAddress()
254  {
255  return $this->_address;
256  }
257 
263  public function getAddressType()
264  {
265  return $this->_addressType;
266  }
267 
273  public function hasPort()
274  {
275  return -1 != $this->getPort();
276  }
277 
283  public function getPort()
284  {
285  return $this->_port;
286  }
287 
293  public function hasTransport()
294  {
295  return null !== $this->getTransport();
296  }
297 
303  public function getTransport()
304  {
305  return $this->_transport;
306  }
307 
313  public function __toString()
314  {
315  $out = null;
316 
317  if (true === $this->hasTransport()) {
318  $out .= $this->getTransport() . '://';
319  }
320 
321  if (true === $this->hasPort()) {
322  if (self::ADDRESS_IPV6 === $this->getAddressType()) {
323  $out .= '[' . $this->getAddress() . ']';
324  } else {
325  $out .= $this->getAddress();
326  }
327 
328  return $out . ':' . $this->getPort();
329  }
330 
331  return $out . $this->getAddress();
332  }
333 }
334 
338 Core\Consistency::flexEntity('Hoa\Socket\Socket');
setPort($port)
Definition: Socket.php:207
const ADDRESS_IPV6
Definition: Socket.php:56
setTransport($transport)
Definition: Socket.php:230
__construct($uri)
Definition: Socket.php:115
static exists($transport)
Definition: Transport.php:71
const ADDRESS_PATH
Definition: Socket.php:77
const ADDRESS_IPV4
Definition: Socket.php:63
const ADDRESS_DOMAIN
Definition: Socket.php:70