Multi::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
ccs 6
cts 6
cp 1
rs 9.4286
cc 2
eloc 4
nc 2
nop 0
crap 2
1
<?php
2
/**
3
 * spindle/httpclient
4
 * @license CC0-1.0 (Public Domain) https://creativecommons.org/publicdomain/zero/1.0/
5
 * @see https://github.com/spindle/spindle-httpclient
6
 */
7
namespace Spindle\HttpClient;
8
9
class Multi implements \IteratorAggregate, \Countable
10
{
11
    protected
12
        $mh
13
      , $timeout = 10
14
      , $pool = array()
15
    ;
16
17 2
    function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
18 2
        $this->mh = curl_multi_init();
19 2
        foreach (func_get_args() as $req) {
20 1
            $this->attach($req);
21 2
        }
22 2
    }
23
24 2
    function __destruct()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
25
    {
26 2
        $this->detachAll();
27 2
        curl_multi_close($this->mh);
28 2
    }
29
30 1
    function setTimeout($num)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
31
    {
32 1
        $this->timeout = $num;
33 1
        return $this;
34
    }
35
36 2 View Code Duplication
    function attach(Request $req)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
37
    {
38 2
        $handle = $req->getHandle();
39 2
        $this->pool[(int)$handle] = $req;
40
41 2
        curl_multi_add_handle($this->mh, $handle);
42 2
    }
43
44 1 View Code Duplication
    function detach(Request $req)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
45
    {
46 1
        $handle = $req->getHandle();
47 1
        unset($this->pool[(int)$handle]);
48
49 1
        curl_multi_remove_handle($this->mh, $handle);
50 1
    }
51
52 2
    function start()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
53
    {
54 2
        $mh = $this->mh;
55
56 2
        do $stat = curl_multi_exec($mh, $running);
57 2
        while ($stat === \CURLM_CALL_MULTI_PERFORM);
58 2
        return curl_multi_select($mh, 0);
59
    }
60
61
    /**
62
     * イベントが発生するのを待って、何かレスポンスが得られればその配列を返す。
63
     * これを実行すると、不要になったrequestオブジェクトはdetachします
64
     *
65
     * @return Request[]
66
     */
67
    function getFinishedResponses()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
68
    {
69
        $mh = $this->mh;
70
        $requests = array();
71
72
        switch (curl_multi_select($mh, $this->timeout)) {
73
            case 0:
74
                throw new \RuntimeException('timeout?');
75
76
            case -1:
77
            default:
78
                do $stat = curl_multi_exec($mh, $running);
79
                while ($stat === \CURLM_CALL_MULTI_PERFORM);
80
81
                do if ($raised = curl_multi_info_read($mh, $remains)) {
82
                    $info = curl_getinfo($raised['handle']);
83
                    $body = curl_multi_getcontent($raised['handle']);
84
85
                    $response = new Response($body, $info);
86
                    $request = $this->pool[(int)$raised['handle']];
87
88
                    $request->setResponse($response);
89
                    $this->detach($request);
90
91 View Code Duplication
                    if (CURLE_OK !== $raised['result']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
92
                        $error = new CurlException(curl_error($raised['handle']), $raised['result']);
93
                        $request->setError($error);
94
                    }
95
96
                    $requests[] = $request;
97
98
                } while ($remains);
0 ignored issues
show
Bug Best Practice introduced by
The expression $remains of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
99
        }
100
101
        return $requests;
102
    }
103
104 2
    function waitResponse()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
105
    {
106 2
        $mh = $this->mh;
107
108 2
        do switch (curl_multi_select($mh, $this->timeout)) {
109 2
            case 0:
110 1
                throw new \RuntimeException('timeout.');
111
112 1
            case -1:
113 1
            default:
114 1
                do $stat = curl_multi_exec($mh, $running);
115 1
                while ($stat === \CURLM_CALL_MULTI_PERFORM);
116
117 1
                do if ($raised = curl_multi_info_read($mh, $remains)) {
118 1
                    $info = curl_getinfo($raised['handle']);
119 1
                    $body = curl_multi_getcontent($raised['handle']);
120
121 1
                    $response = new Response($body, $info);
122 1
                    $request = $this->pool[(int)$raised['handle']];
123
124 1
                    $request->setResponse($response);
125 1 View Code Duplication
                    if (CURLE_OK !== $raised['result']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
126
                        $error = new CurlException(curl_error($raised['handle']), $raised['result']);
127
                        $request->setError($error);
128
                    }
129
130 1
                } while ($remains);
0 ignored issues
show
Bug Best Practice introduced by
The expression $remains of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
131 1
        } while ($running);
132 1
    }
133
134 2
    function send()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
135
    {
136 2
        $this->start();
137 2
        $this->waitResponse();
138 1
    }
139
140 2
    function detachAll()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
141
    {
142 2
        foreach ($this->pool as $request) {
143 2
            curl_multi_remove_handle($this->mh, $request->getHandle());
144 2
        }
145
146 2
        $this->pool = array();
147 2
    }
148
149
    /**
150
     * @override IteratorAggregate::getIterator
151
     */
152 1
    function getIterator()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
153
    {
154 1
        return new \ArrayIterator($this->pool);
155
    }
156
157
    /**
158
     * @override Countable::count
159
     */
160 1
    function count()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
161
    {
162 1
        return count($this->pool);
163
    }
164
}
165