SocketError::setExtra()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Helix\Socket;
4
5
use RuntimeException;
6
7
/**
8
 * A socket error.
9
 *
10
 * @see 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
     * @see https://php.net/socket_last_error
27
     * @see 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; // Bad file descriptor
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
     * PHP's core socket functions like to return `false` without setting `errno` in some places.
53
     *
54
     * To account for that scenario, a fallback code can be given.
55
     *
56
     * When the fallback code is used, PHP's last suppressed warning message is used.
57
     *
58
     * All scenarios within this library have been meticulously cross-checked with the PHP C source code
59
     * for cases where a fallback code is necessary.
60
     *
61
     * @param int|resource|null $subject Error constant, resource to check, or `NULL` to use the global socket error.
62
     * @param int $fallback Code to assume if one can't be found via the subject.
63
     * @param SocketError|null $previous Slippage of a prior error.
64
     */
65
    public function __construct ($subject = null, $fallback = 0, SocketError $previous = null) {
66
        if ($errno = is_int($subject) ? $subject : static::getLast($subject)) {
67
            $message = socket_strerror($errno);
68
        }
69
        else {
70
            $errno = $fallback;
71
            $last = error_get_last();
72
            $message = "{$last['message']} in {$last['file']}:{$last['line']}";
73
        }
74
        parent::__construct($message, $errno, $previous);
75
    }
76
77
    /**
78
     * @return mixed
79
     */
80
    public function getExtra () {
81
        return $this->extra;
82
    }
83
84
    /**
85
     * @param mixed $extra
86
     * @return $this
87
     */
88
    public function setExtra ($extra) {
89
        $this->extra = $extra;
90
        return $this;
91
    }
92
93
}
94