Passed
Push — master ( 031f57...c44613 )
by Moln
01:42 queued 13s
created

Socket::close()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 7
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace MySQLReplication\Socket;
5
6
class Socket implements SocketInterface
7
{
8
    private $socket;
9
10
    public function __destruct()
11
    {
12
        $this->close();
13
    }
14
15
    public function close(): void
16
    {
17
        if ($this->isConnected()) {
18
            socket_shutdown($this->socket);
19
            socket_close($this->socket);
20
        }
21
        $this->socket = null;
22
    }
23
24
    public function isConnected(): bool
25
    {
26
        return is_resource($this->socket) || $this->socket instanceof \Socket;
27
    }
28
29
    public function connectToStream(string $host, int $port): void
30
    {
31
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
32
        if (!$this->socket) {
33
            throw new SocketException(
34
                SocketException::SOCKET_UNABLE_TO_CREATE_MESSAGE . $this->getSocketErrorMessage(),
35
                SocketException::SOCKET_UNABLE_TO_CREATE_CODE
36
            );
37
        }
38
        socket_set_block($this->socket);
39
        socket_set_option($this->socket, SOL_SOCKET, SO_KEEPALIVE, 1);
40
41
        if (!socket_connect($this->socket, $host, $port)) {
42
            throw new SocketException($this->getSocketErrorMessage(), $this->getSocketErrorCode());
43
        }
44
    }
45
46
    private function getSocketErrorMessage(): string
47
    {
48
        return socket_strerror($this->getSocketErrorCode());
49
    }
50
51
    private function getSocketErrorCode(): int
52
    {
53
        return socket_last_error();
54
    }
55
56
    public function readFromSocket(int $length): string
57
    {
58
        $received = socket_recv($this->socket, $buf, $length, MSG_WAITALL);
59
        if ($length === $received) {
60
            return $buf;
61
        }
62
63
        // http://php.net/manual/en/function.socket-recv.php#47182
64
        if (0 === $received) {
65
            throw new SocketException(
66
                SocketException::SOCKET_DISCONNECTED_MESSAGE,
67
                SocketException::SOCKET_DISCONNECTED_CODE
68
            );
69
        }
70
71
        throw new SocketException($this->getSocketErrorMessage(), $this->getSocketErrorCode());
72
    }
73
74
    public function writeToSocket(string $data): void
75
    {
76
        if (!socket_write($this->socket, $data, strlen($data))) {
77
            throw new SocketException(
78
                SocketException::SOCKET_UNABLE_TO_WRITE_MESSAGE . $this->getSocketErrorMessage(),
79
                SocketException::SOCKET_UNABLE_TO_WRITE_CODE
80
            );
81
        }
82
    }
83
}