SimpleHttpTrait::httpGet()   D
last analyzed

Complexity

Conditions 18
Paths 62

Size

Total Lines 72
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 18
eloc 53
c 1
b 0
f 0
nc 62
nop 2
dl 0
loc 72
rs 4.8666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
0 ignored issues
show
Coding Style introduced by
Missing file doc comment
Loading history...
3
namespace Hhxsv5\LaravelS\Components\HttpClient;
4
5
use Hhxsv5\LaravelS\Swoole\Coroutine\Context;
6
use Swoole\Coroutine\Http\Client as CoroutineClient;
7
8
trait SimpleHttpTrait
0 ignored issues
show
Coding Style introduced by
Missing doc comment for trait SimpleHttpTrait
Loading history...
9
{
10
    protected $curlOptions = [
11
        //bool
12
        CURLOPT_HEADER         => true,
13
        CURLOPT_FOLLOWLOCATION => true,
14
        CURLOPT_RETURNTRANSFER => true,
15
16
        //int
17
        CURLOPT_MAXREDIRS      => 3,
18
        CURLOPT_TIMEOUT        => 5,
19
        CURLOPT_CONNECTTIMEOUT => 3,
20
    ];
21
22
    /**
23
     * Sends a GET request and returns a array response.
24
     * @param string $url
0 ignored issues
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
25
     * @param array $options
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
26
     * @return array
0 ignored issues
show
Coding Style introduced by
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
27
     */
28
    public function httpGet($url, array $options)
29
    {
30
        if (Context::inCoroutine()) {
31
            $parts = parse_url($url);
32
            $path = isset($parts['path']) ? $parts['path'] : '/';
33
            if (isset($parts['query'])) {
34
                $path .= '?' . $parts['query'];
35
            }
36
            if (isset($parts['fragment'])) {
37
                $path .= '#' . $parts['fragment'];
38
            }
39
            $client = new CoroutineClient($parts['host'], isset($parts['port']) ? $parts['port'] : 80, isset($parts['scheme']) && $parts['scheme'] === 'https');
40
            if (isset($options['timeout'])) {
41
                $client->set([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
42
                    'timeout' => $options['timeout'],
43
                ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
44
            }
45
            $client->get($path);
46
            $client->close();
47
            if ($client->errCode === 110) {
48
                return ['statusCode' => 0, 'headers' => [], 'body' => ''];
49
            }
50
            if ($client->errCode !== 0) {
51
                $msg = sprintf('Failed to send Http request(%s), errcode=%d, errmsg=%s', $url, $client->errCode, $client->errMsg);
52
                throw new \RuntimeException($msg, $client->errCode);
53
            }
54
            return ['statusCode' => $client->statusCode, 'headers' => $client->headers, 'body' => $client->body];
55
        }
56
57
        $handle = curl_init();
58
        $finalOptions = [
59
                CURLOPT_URL     => $url,
60
                CURLOPT_HTTPGET => true,
61
            ] + $this->curlOptions;
62
        if (isset($options['timeout'])) {
63
            $finalOptions[CURLOPT_TIMEOUT] = $options['timeout'];
64
        }
65
        curl_setopt_array($handle, $finalOptions);
66
        $responseStr = curl_exec($handle);
67
        $errno = curl_errno($handle);
68
        $errmsg = curl_error($handle);
69
        // Fix: curl_errno() always return 0 when fail
70
        if ($errno !== 0 || $errmsg !== '') {
71
            curl_close($handle);
72
            $msg = sprintf('Failed to send Http request(%s), errcode=%d, errmsg=%s', $url, $errno, $errmsg);
73
            throw new \RuntimeException($msg, $errno);
74
        }
75
76
        $headerSize = curl_getinfo($handle, CURLINFO_HEADER_SIZE);
77
        $statusCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
78
        curl_close($handle);
79
80
        $header = substr($responseStr, 0, $headerSize);
0 ignored issues
show
Bug introduced by
It seems like $responseStr can also be of type true; however, parameter $string of substr() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

80
        $header = substr(/** @scrutinizer ignore-type */ $responseStr, 0, $headerSize);
Loading history...
81
        $body = substr($responseStr, $headerSize);
82
        $lines = explode("\n", $header);
83
        array_shift($lines); // Remove status
84
85
        $headers = [];
86
        foreach ($lines as $part) {
87
            $middle = explode(':', $part);
88
            $key = trim($middle[0]);
89
            if ($key === '') {
90
                continue;
91
            }
92
            if (isset($headers[$key])) {
93
                $headers[$key] = (array)$headers[$key];
94
                $headers[$key][] = isset($middle[1]) ? trim($middle[1]) : '';
95
            } else {
96
                $headers[$key] = isset($middle[1]) ? trim($middle[1]) : '';
97
            }
98
        }
99
        return ['statusCode' => $statusCode, 'headers' => $headers, 'body' => $body];
100
    }
101
}