Passed
Pull Request — master (#4)
by Moln
03:27
created

Socket   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 31
c 1
b 0
f 1
dl 0
loc 74
rs 10
wmc 15

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getSocketErrorCode() 0 3 1
A __destruct() 0 3 1
A readFromSocket() 0 16 3
A writeToSocket() 0 6 2
A isConnected() 0 3 2
A getSocketErrorMessage() 0 3 1
A close() 0 7 2
A connectToStream() 0 14 3
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
}