Passed
Branch master (c44613)
by Moln
05:00
created

Socket::isConnected()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 1
nc 2
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 2
rs 10
c 1
b 0
f 1
1
<?php
2
declare(strict_types=1);
3
4
namespace MySQLReplication\Socket;
5
6
class Socket implements SocketInterface
7
{
8
    private $socket;
9
10 62
    public function __destruct()
11
    {
12 62
        $this->close();
13
    }
14
15 62
    public function close(): void
16
    {
17 62
        if ($this->isConnected()) {
18 62
            socket_shutdown($this->socket);
19 62
            socket_close($this->socket);
20
        }
21 62
        $this->socket = null;
22
    }
23
24 62
    public function isConnected(): bool
25
    {
26 62
        return is_resource($this->socket) || $this->socket instanceof \Socket;
27
    }
28
29 62
    public function connectToStream(string $host, int $port): void
30
    {
31 62
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
32 62
        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 62
        socket_set_block($this->socket);
39 62
        socket_set_option($this->socket, SOL_SOCKET, SO_KEEPALIVE, 1);
40
41 62
        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 62
    public function readFromSocket(int $length): string
57
    {
58 62
        $received = socket_recv($this->socket, $buf, $length, MSG_WAITALL);
59 62
        if ($length === $received) {
60 62
            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 62
    public function writeToSocket(string $data): void
75
    {
76 62
        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
}