Completed
Pull Request — master (#31)
by Eugene
15:31
created

StreamConnection::close()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 0
crap 2
1
<?php
2
3
namespace Tarantool\Client\Connection;
4
5
use Tarantool\Client\Exception\ConnectionException;
6
use Tarantool\Client\IProto;
7
use Tarantool\Client\Packer\PackUtils;
8
9
class StreamConnection implements Connection
10
{
11
    const DEFAULT_URI = 'tcp://127.0.0.1:3301';
12
13
    private $uri;
14
15
    private $options = [
16
        'connect_timeout' => 10.0,
17
        'socket_timeout' => 10.0,
18
    ];
19
20
    private $stream;
21
22 45
    public function __construct($uri = null, array $options = null)
23
    {
24 45
        $this->uri = null === $uri ? self::DEFAULT_URI : $uri;
25
26 45
        if ($options) {
27 5
            $this->options = $options + $this->options;
28
        }
29 45
    }
30
31 60
    public function open()
32
    {
33 60
        $this->close();
34
35 60
        $stream = @stream_socket_client($this->uri, $errorCode, $errorMessage, (float) $this->options['connect_timeout']);
36 60
        if (false === $stream) {
37 3
            throw new ConnectionException(sprintf('Unable to connect to %s: %s.', $this->uri, $errorMessage));
38
        }
39
40 57
        $this->stream = $stream;
41 57
        stream_set_timeout($this->stream, $this->options['socket_timeout']);
42
43
        // TODO
44
        // use stream_context_create() for php 7.1+
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
45
        // https://github.com/php/php-src/blob/6053987bc27e8dede37f437193a5cad448f99bce/ext/standard/tests/streams/stream_context_tcp_nodelay.phpt
46
47 57
        if (isset($this->options['tcp_nodelay']) && function_exists('socket_import_stream')) {
48
            $socket = socket_import_stream($this->stream);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $socket is correct as socket_import_stream($this->stream) (which targets socket_import_stream()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
49
            socket_set_option($socket, SOL_TCP, TCP_NODELAY, (int) $this->options['tcp_nodelay']);
50
        }
51
52 57
        $greeting = $this->read(IProto::GREETING_SIZE, 'Unable to read greeting.');
53
54 54
        return IProto::parseGreeting($greeting);
55
    }
56
57 60
    public function close()
58
    {
59 60
        if ($this->stream) {
60 17
            fclose($this->stream);
61 17
            $this->stream = null;
62
        }
63 60
    }
64
65 107
    public function isClosed()
66
    {
67 107
        return null === $this->stream;
68
    }
69
70 106
    public function send($data)
71
    {
72 106
        if (!fwrite($this->stream, $data)) {
73
            throw new ConnectionException('Unable to write request.');
74
        }
75
76 106
        $length = $this->read(IProto::LENGTH_SIZE, 'Unable to read response length.');
77 104
        $length = PackUtils::unpackLength($length);
78
79 104
        return $this->read($length, 'Unable to read response.');
80
    }
81
82 127
    private function read($length, $errorMessage)
83
    {
84 127
        if ($data = stream_get_contents($this->stream, $length)) {
85 124
            return $data;
86
        }
87
88 8
        $meta = stream_get_meta_data($this->stream);
89 8
        throw new ConnectionException($meta['timed_out'] ? 'Read timed out.' : $errorMessage);
90
    }
91
}
92