Multi   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 156
Duplicated Lines 14.1 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 68.54%

Importance

Changes 6
Bugs 1 Features 2
Metric Value
wmc 28
c 6
b 1
f 2
lcom 1
cbo 3
dl 22
loc 156
ccs 61
cts 89
cp 0.6854
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
A __destruct() 0 5 1
A setTimeout() 0 5 1
A attach() 7 7 1
A detach() 7 7 1
A start() 0 8 2
C getFinishedResponses() 4 36 7
C waitResponse() 4 29 8
A send() 0 5 1
A detachAll() 0 8 2
A getIterator() 0 4 1
A count() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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