Passed
Push — master ( a91d54...875978 )
by y
02:08
created

SocketError   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 25
dl 0
loc 77
rs 10
c 0
b 0
f 0
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getExtra() 0 2 1
A getLast() 0 15 4
A setExtra() 0 3 1
A __construct() 0 15 3
1
<?php
2
3
namespace Helix\Socket;
4
5
use RuntimeException;
6
7
/**
8
 * A socket error.
9
 *
10
 * @link https://php.net/sockets.constants
11
 */
12
class SocketError extends RuntimeException {
13
14
    /**
15
     * Extra data, if any. The specific contents are documented where the error is thrown.
16
     *
17
     * @var mixed
18
     */
19
    protected $extra;
20
21
    /**
22
     * Retrieves and clears the socket error.
23
     * For resources, this favors `SO_ERROR`, then falls back to the error number set by PHP.
24
     * Both error codes are cleared.
25
     *
26
     * @link https://php.net/socket_last_error
27
     * @link https://php.net/socket_clear_error
28
     *
29
     * @param resource $resource PHP socket resource, or `null` for the global error.
30
     * @return int If the resource is closed or not a socket, `SOCKET_EBADF` is returned.
31
     */
32
    public static function getLast ($resource = null) {
33
        if (isset($resource)) {
34
            if (@get_resource_type($resource) !== 'Socket') {
35
                return SOCKET_EBADF;
36
            }
37
            // fetching SO_ERROR also clears it
38
            elseif (!$errno = socket_get_option($resource, SOL_SOCKET, SO_ERROR)) {
39
                $errno = socket_last_error($resource);
40
            }
41
            socket_clear_error($resource);
42
            return $errno;
43
        }
44
        $errno = socket_last_error();
45
        socket_clear_error();
46
        return $errno;
47
    }
48
49
    /**
50
     * Initializes the error based on a mixed subject.
51
     *
52
     * @param int|resource|null $subject Error constant, or resource, or `NULL` to use the most recent global error.
53
     * @param int $fallback Code to assume if one can't be found via the subject. This is because PHP likes to return
54
     *     `false` without setting the error number in some places, all of which are accounted for in this library.
55
     *     PHP's last suppressed warning is used for the message.
56
     *
57
     */
58
    public function __construct ($subject = null, $fallback = 0) {
59
        if (is_int($subject)) {
60
            $errno = $subject;
61
        }
62
        else {
63
            $errno = static::getLast($subject);
64
        }
65
        if ($errno) {
66
            $message = socket_strerror($errno);
67
        }
68
        else {
69
            $errno = $fallback;
70
            $message = error_get_last()['message'];
71
        }
72
        parent::__construct($message, $errno);
73
    }
74
75
    /**
76
     * @return mixed
77
     */
78
    public function getExtra () {
79
        return $this->extra;
80
    }
81
82
    /**
83
     * @param mixed $extra
84
     * @return $this
85
     */
86
    public function setExtra ($extra) {
87
        $this->extra = $extra;
88
        return $this;
89
    }
90
91
}
92