Response   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 218
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 73.26%

Importance

Changes 0
Metric Value
dl 0
loc 218
ccs 63
cts 86
cp 0.7326
rs 10
c 0
b 0
f 0
wmc 26
lcom 1
cbo 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A status() 0 4 1
A header() 0 4 1
A addHeaders() 0 4 1
A noCache() 0 5 1
A gzip() 0 4 1
A __construct() 0 9 1
A rawcookie() 0 8 2
C getHeader() 0 54 15
A getRawContent() 0 16 3
1
<?php
2
namespace Laravoole;
3
4
class Response
5
{
6
    public $http_protocol = 'HTTP/1.1';
7
    public $http_status = 200;
8
9
    public $header;
10
    public $cookie;
11
    public $content = '';
12
13
    public $isFastCgi = false;
14
15
    static $HTTP_HEADERS = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $HTTP_HEADERS.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
16
        100 => 'Continue',
17
        101 => 'Switching Protocols',
18
        102 => 'Processing', // RFC2518
19
        200 => 'OK',
20
        201 => 'Created',
21
        202 => 'Accepted',
22
        203 => 'Non-Authoritative Information',
23
        204 => 'No Content',
24
        205 => 'Reset Content',
25
        206 => 'Partial Content',
26
        207 => 'Multi-Status', // RFC4918
27
        208 => 'Already Reported', // RFC5842
28
        226 => 'IM Used', // RFC3229
29
        300 => 'Multiple Choices',
30
        301 => 'Moved Permanently',
31
        302 => 'Found',
32
        303 => 'See Other',
33
        304 => 'Not Modified',
34
        305 => 'Use Proxy',
35
        306 => 'Reserved',
36
        307 => 'Temporary Redirect',
37
        308 => 'Permanent Redirect', // RFC7238
38
        400 => 'Bad Request',
39
        401 => 'Unauthorized',
40
        402 => 'Payment Required',
41
        403 => 'Forbidden',
42
        404 => 'Not Found',
43
        405 => 'Method Not Allowed',
44
        406 => 'Not Acceptable',
45
        407 => 'Proxy Authentication Required',
46
        408 => 'Request Timeout',
47
        409 => 'Conflict',
48
        410 => 'Gone',
49
        411 => 'Length Required',
50
        412 => 'Precondition Failed',
51
        413 => 'Request Entity Too Large',
52
        414 => 'Request-URI Too Long',
53
        415 => 'Unsupported Media Type',
54
        416 => 'Requested Range Not Satisfiable',
55
        417 => 'Expectation Failed',
56
        418 => 'I\'m a teapot', // RFC2324
57
        422 => 'Unprocessable Entity', // RFC4918
58
        423 => 'Locked', // RFC4918
59
        424 => 'Failed Dependency', // RFC4918
60
        425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817
61
        426 => 'Upgrade Required', // RFC2817
62
        428 => 'Precondition Required', // RFC6585
63
        429 => 'Too Many Requests', // RFC6585
64
        431 => 'Request Header Fields Too Large', // RFC6585
65
        500 => 'Internal Server Error',
66
        501 => 'Not Implemented',
67
        502 => 'Bad Gateway',
68
        503 => 'Service Unavailable',
69
        504 => 'Gateway Timeout',
70
        505 => 'HTTP Version Not Supported',
71
        506 => 'Variant Also Negotiates (Experimental)', // RFC2295
72
        507 => 'Insufficient Storage', // RFC4918
73
        508 => 'Loop Detected', // RFC5842
74
        510 => 'Not Extended', // RFC2774
75
        511 => 'Network Authentication Required', // RFC6585
76
    );
77
78
    protected $protocol;
79
    public $request;
80
    protected $gzip_level = false;
81
82 8
    public function __construct($protocol, $request, $isFastCgi = false)
0 ignored issues
show
Unused Code introduced by
The parameter $isFastCgi is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
83
    {
84 8
        $this->protocol = $protocol;
85 8
        $this->request = $request;
86 8
        $this->request->response = $this;
87 8
        $this->header = [
88 4
            'Content-Type' => 'text/html',
89
        ];
90 8
    }
91
92
    /**
93
     * 设置Http状态
94
     * @param $code
95
     */
96 8
    public function status($code)
97
    {
98 8
        $this->http_status = $code;
99 8
    }
100
101
    /**
102
     * 设置Http头信息
103
     * @param $key
104
     * @param $value
105
     */
106 8
    public function header($key, $value)
107
    {
108 8
        $this->header[ucwords($key, '-')] = $value;
109 8
    }
110
111
    /**
112
     * 设置COOKIE
113
     * @param $name
114
     * @param null $value
115
     * @param null $expire
116
     * @param string $path
117
     * @param null $domain
118
     * @param null $secure
119
     * @param null $httponly
120
     */
121 4
    public function rawcookie($name, $value = null, $expire = null, $path = '/', $domain = null, $secure = null, $httponly = null)
122
    {
123 4
        $cookie = [];
124 4
        foreach (['name', 'value', 'expire', 'path', 'domain', 'secure', 'httponly'] as $key) {
125 4
            $cookie[$key] = $$key;
126 2
        }
127 4
        $this->cookie[] = $cookie;
128 4
    }
129
130
    /**
131
     * 添加http header
132
     * @param $header
133
     */
134
    public function addHeaders(array $header)
135
    {
136
        $this->header = array_merge($this->header, $header);
137
    }
138
139 4
    public function getHeader()
140
    {
141 4
        $out = '';
142 4
        if ($this->isFastCgi) {
143
            $status = isset(static::$HTTP_HEADERS[$this->http_status]) ? static::$HTTP_HEADERS[$this->http_status] : 'Undefined Status Code';
0 ignored issues
show
Bug introduced by
Since $HTTP_HEADERS is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $HTTP_HEADERS to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
144
            $out .= 'Status: ' . $this->http_status . ' ' . $status . "\r\n";
145
        } else {
146
            //Protocol
147 4
            if (isset($this->header[0])) {
148
                $out .= $this->header[0] . "\r\n";
149
                unset($this->header[0]);
150
            } else {
151 4
                $out = "HTTP/1.1 200 OK\r\n";
152
            }
153
        }
154 4
        if (!isset($this->header['Content-Length'])) {
155
            $this->header['Content-Length'] = strlen($this->content);
156
        }
157
158
        //Headers
159 4
        foreach ($this->header as $k => $v) {
160 4
            $out .= $k . ': ' . $v . "\r\n";
161 2
        }
162
        //Cookies
163 4
        if (!empty($this->cookie) and is_array($this->cookie)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
164 4
            foreach ($this->cookie as $cookie) {
165
166 4
                if ($cookie['value'] == null) {
167
                    $cookie['value'] = 'deleted';
168
                }
169 4
                $value = "{$cookie['name']}={$cookie['value']}";
170 4
                if ($cookie['expire']) {
171 4
                    $value .= "; expires=" . date("D, d-M-Y H:i:s T", $cookie['expire']);
172 2
                }
173 4
                if ($cookie['path']) {
174 4
                    $value .= "; path={$cookie['path']}";
175 2
                }
176 4
                if ($cookie['secure']) {
177
                    $value .= "; secure";
178
                }
179 4
                if ($cookie['domain']) {
180
                    $value .= "; domain={$cookie['domain']}";
181
                }
182 4
                if ($cookie['httponly']) {
183 4
                    $value .= '; httponly';
184 2
                }
185
186 4
                $out .= "Set-Cookie: $value\r\n";
187 2
            }
188 2
        }
189
        //End
190 4
        $out .= "\r\n";
191 4
        return $out;
192
    }
193
194
    public function noCache()
195
    {
196
        $this->header['Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0';
197
        $this->header['Pragma'] = 'no-cache';
198
    }
199
200 4
    public function gzip($level)
201
    {
202 4
        $this->gzip_level = $level;
203 4
    }
204
205 4
    public function getRawContent($content = '')
206
    {
207 4
        if($content) {
208
            $this->content = $content;
209
        } else {
210 4
            $content = $this->content;
211
        }
212 4
        if ($this->gzip_level) {
213 4
            $content = gzencode($content, $this->gzip_level);
214 4
            $this->header('Content-Encoding', 'gzip');
215 2
        }
216 4
        $this->header('Content-Length', strlen($content));
217 4
        $out = $this->getHeader();
218 4
        $out .= $content;
219 4
        return $out;
220
    }
221
}
222