GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 54e37b...ab3bfb )
by やかみ
01:37
created

Request::session()   C

Complexity

Conditions 7
Paths 10

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 8.1426

Importance

Changes 0
Metric Value
cc 7
eloc 15
nc 10
nop 2
dl 0
loc 25
ccs 10
cts 14
cp 0.7143
crap 8.1426
rs 6.7272
c 0
b 0
f 0
1
<?php
2
/**
3
 * Kotori.php
4
 *
5
 * A Tiny Model-View-Controller PHP Framework
6
 *
7
 * This content is released under the Apache 2 License
8
 *
9
 * Copyright (c) 2015-2017 Kotori Technology. All rights reserved.
10
 *
11
 * Licensed under the Apache License, Version 2.0 (the "License");
12
 * you may not use this file except in compliance with the License.
13
 * You may obtain a copy of the License at
14
 *
15
 *     http://www.apache.org/licenses/LICENSE-2.0
16
 *
17
 * Unless required by applicable law or agreed to in writing, software
18
 * distributed under the License is distributed on an "AS IS" BASIS,
19
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
 * See the License for the specific language governing permissions and
21
 * limitations under the License.
22
 */
23
24
/**
25
 * Request Class
26
 *
27
 * @package     Kotori
28
 * @subpackage  Http
29
 * @author      Kokororin
30
 * @link        https://kotori.love
31
 */
32
namespace Kotori\Http;
33
34
use Kotori\Debug\Hook;
35
use Kotori\Interfaces\SoulInterface;
36
use Kotori\Traits\SoulTrait;
37
38
class Request implements SoulInterface
39
{
40
    use SoulTrait;
41
42
    /**
43
     * Ip address
44
     *
45
     * @var mixed
46
     */
47
    protected $_ip = null;
48
49
    /**
50
     * Class constructor
51
     *
52
     * Initialize Request.
53
     *
54
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
55
     */
56 9
    public function __construct()
57
    {
58 9
        Hook::listen(__CLASS__);
59 9
    }
60
61
    /**
62
     * Internal method used to retrieve values from given arrays.
63
     *
64
     * @param  array $source $_GET, $_POST, $_COOKIE, $_SERVER, etc.
65
     * @param  mixed $key Index for item to be fetched from $source
66
     * @param  mixed $default Default value for item
67
     * @return mixed
68
     */
69
    protected function getRequestParams(&$source, $key = null, $default = null)
70
    {
71
        // If $key is NULL, it means that the whole $source is requested
72
        if (!isset($key) || $key == null) {
73
            $key = array_keys($source);
74
        }
75
76
        if (is_array($key)) {
77
            $output = [];
78
            foreach ($key as $k) {
79
                $output[$k] = $this->getRequestParams($source, $k);
80
            }
81
82
            return $output;
83
        }
84
85
        if (isset($source[$key])) {
86
            $value = $source[$key];
87
        } else {
88
            return $default;
89
        }
90
91
        return $value;
92
93
    }
94
95
    /**
96
     * Fetch an item from the GET array
97
     *
98
     * @param  mixed $key Index for item to be fetched from $_GET
99
     * @return mixed
100
     */
101
    public function get($key = null, $default = null)
0 ignored issues
show
Coding Style introduced by
get uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
102
    {
103
        return $this->getRequestParams($_GET, $key, $default);
104
    }
105
106
    /**
107
     * Fetch an item from the POST array
108
     *
109
     * @param  mixed $key Index for item to be fetched from $_POST
110
     * @param  mixed $default Default value for item
111
     * @return mixed
112
     */
113
    public function post($key = null, $default = null)
0 ignored issues
show
Coding Style introduced by
post uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
114
    {
115
        $rawPostData = file_get_contents('php://input');
116
        $source = json_decode($rawPostData, true);
117
        if (json_last_error() != JSON_ERROR_NONE) {
118
            $source = $_POST;
119
        }
120
121
        return $this->getRequestParams($source, $key, $default);
122
    }
123
124
    /**
125
     * Fetch an item from the SERVER array
126
     *
127
     * @param  mixed $key Index for item to be fetched from $_SERVER
128
     * @param  mixed $default Default value for item
129
     * @return mixed
130
     */
131
    public function server($key = null, $default = null)
0 ignored issues
show
Coding Style introduced by
server uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
132
    {
133
        return $this->getRequestParams($_SERVER, $key, $default);
134
    }
135
136
    /**
137
     * Set or Get cookie
138
     *
139
     * @param  mixed $key Index for item for cookie
140
     * @param  string $value cookie value
141
     * @param  mixed  options for cookie setting
142
     * @return mixed
143
     */
144 2
    public function cookie($key = '', $value = '', $options = null)
0 ignored issues
show
Coding Style introduced by
cookie uses the super-global variable $_COOKIE which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
145
    {
146
        $defaultOptions = [
147 2
            'prefix' => '',
148 2
            'expire' => 86400,
149 2
            'path' => '/',
150 2
            'secure' => false,
151 2
            'httponly' => false,
152 2
        ];
153
154 2
        if (!is_null($options)) {
155
            if (is_numeric($options)) {
156
                $options = ['expire' => $options];
157
            } elseif (is_string($options)) {
158
                parse_str($options, $options);
159
            }
160
161
            $options = array_merge($defaultOptions, array_change_key_case($options));
162
        }
163
164 2
        if (!empty($options['httponly'])) {
165
            ini_set('session.cookie_httponly', 1);
166
        }
167
168 2
        if (is_null($key)) {
169
            if (empty($_COOKIE)) {
170
                return null;
171
            }
172
173
            $prefix = empty($value) ? $options['prefix'] : $value;
174
            if (!empty($prefix)) {
175
                foreach ($_COOKIE as $key => $val) {
176
                    if (0 === stripos($key, $prefix)) {
177
                        setcookie($key, '', time() - 3600, $options['path'], $options['domain'], $options['secure'], $options['httponly']);
178
                        unset($_COOKIE[$key]);
179
                    }
180
                }
181
            }
182
183
            return null;
184 2
        } elseif ('' === $key) {
185
            // Get All Cookie
186
            return $_COOKIE;
187
        }
188
189 2
        $key = $options['prefix'] . str_replace('.', '_', $key);
190 2
        if ('' === $value) {
191 2
            if (isset($_COOKIE[$key])) {
192 1
                $value = $_COOKIE[$key];
193 1
                if (0 === strpos($value, 'kotori:')) {
194
                    $value = substr($value, 6);
195
                    return array_map('urldecode', json_decode(MAGIC_QUOTES_GPC ? stripslashes($value) : $value, true));
196
                } else {
197 1
                    return $value;
198
                }
199
            } else {
200 1
                return null;
201
            }
202
        } else {
203 2
            if (is_null($value)) {
204 1
                setcookie($key, '', time() - 3600, $options['path'], $options['domain'], $options['secure'], $options['httponly']);
205 1
                unset($_COOKIE[$key]); // Delete Cookie
206 1
            } else {
207
                // Set Cookie
208 2
                if (is_array($value)) {
209
                    $value = 'kotori:' . json_encode(array_map('urlencode', $value));
210
                }
211
212 2
                $expire = !empty($options['expire']) ? time() + intval($options['expire']) : 0;
213 2
                setcookie($key, $value, $expire, $options['path'], $options['domain'], $options['secure'], $options['httponly']);
214 2
                $_COOKIE[$key] = $value;
215
            }
216
        }
217
218 2
        return null;
219
    }
220
221
    /**
222
     * Set or Get session
223
     *
224
     * @param  mixed $key Index for item for session
225
     * @param  string $value session value
226
     * @return mixed
227
     */
228 2
    public function session($key = '', $value = '')
0 ignored issues
show
Coding Style introduced by
session uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
229
    {
230 2
        if (is_null($key)) {
231
            if (empty($_SESSION)) {
232
                return null;
233
            }
234
235
            unset($_SESSION);
236 2
        } elseif ('' === $key) {
237
            // Get All Session
238
            return $_SESSION;
239
        }
240
241 2
        if ('' === $value) {
242 2
            return isset($_SESSION[$key]) ? $_SESSION[$key] : null;
243
        } else {
244 2
            if (is_null($value)) {
245 1
                unset($_SESSION[$key]);
246 1
            } else {
247 2
                $_SESSION[$key] = $value;
248
            }
249
        }
250
251 2
        return null;
252
    }
253
254
    /**
255
     * Is HTTPS?
256
     *
257
     * Determines if the application is accessed via an encrypted
258
     * (HTTPS) connection.
259
     *
260
     * @return  boolean
261
     */
262 2
    public function isSecure()
0 ignored issues
show
Coding Style introduced by
isSecure uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
263
    {
264 2
        if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
265
            return true;
266 2
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO']) {
267
            return true;
268 2
        } elseif (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') {
269
            return true;
270
        }
271
272 2
        return false;
273
    }
274
275
    /**
276
     * Base URL
277
     *
278
     * Returns base url
279
     *
280
     * @return string
281
     */
282 1
    public function getBaseUrl()
0 ignored issues
show
Coding Style introduced by
getBaseUrl uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
283
    {
284 1
        if (isset($_SERVER['HTTP_HOST']) && preg_match('/^((\[[0-9a-f:]+\])|(\d{1,3}(\.\d{1,3}){3})|[a-z0-9\-\.]+)(:\d+)?$/i', $_SERVER['HTTP_HOST'])) {
285 1
            $base_url = (Request::getSoul()->isSecure() ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST']
286 1
            . substr($_SERVER['SCRIPT_NAME'], 0, strpos($_SERVER['SCRIPT_NAME'], basename($_SERVER['SCRIPT_FILENAME'])));
287 1
        } else {
288
            $base_url = 'http://localhost/';
289
        }
290
291 1
        return rtrim($base_url, '/') . '/';
292
    }
293
294
    /**
295
     * Returns Client Ip Address
296
     *
297
     * @param  integer $type Ip address or ipv4 address
298
     * @return string
299
     */
300 1
    public function getClientIp($type = 0)
0 ignored issues
show
Coding Style introduced by
getClientIp uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
301
    {
302 1
        $type = $type ? 1 : 0;
303
304 1
        if ($this->_ip !== null) {
305
            return $this->_ip[$type];
306
        }
307
308 1
        if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
309
            $this->_ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
310 1
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
311
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
312
            $pos = array_search('unknown', $arr);
313
            if (false !== $pos) {
314
                unset($arr[$pos]);
315
            }
316
317
            $this->_ip = trim($arr[0]);
318 1
        } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
319
            $this->_ip = $_SERVER['HTTP_CLIENT_IP'];
320 1
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
321 1
            $this->_ip = $_SERVER['REMOTE_ADDR'];
322 1
        }
323
324
        // Check ip
325 1
        $long = sprintf("%u", ip2long($this->_ip));
326 1
        $this->_ip = $long ? [$this->_ip, $long] : ['0.0.0.0', 0];
327 1
        return $this->_ip[$type];
328
    }
329
330
    /**
331
     * Returns Http Host
332
     *
333
     * @return string
334
     */
335 1
    public function getHostName()
0 ignored issues
show
Coding Style introduced by
getHostName uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
336
    {
337 1
        $possibleHostSources = ['HTTP_X_FORWARDED_HOST', 'HTTP_HOST', 'SERVER_NAME', 'SERVER_ADDR'];
338
        $sourceTransformations = [
339 1
            "HTTP_X_FORWARDED_HOST" => function ($value) {
340
                $elements = explode(',', $value);
341
                return trim(end($elements));
342 1
            },
343 1
        ];
344 1
        $host = '';
345 1
        foreach ($possibleHostSources as $source) {
346 1
            if (!empty($host)) {
347 1
                break;
348
            }
349
350 1
            if (empty($_SERVER[$source])) {
351 1
                continue;
352
            }
353
354 1
            $host = $_SERVER[$source];
355 1
            if (array_key_exists($source, $sourceTransformations)) {
356
                $host = $sourceTransformations[$source]($host);
357
            }
358 1
        }
359
360
        // Remove port number from host
361 1
        $host = preg_replace('/:\d+$/', '', $host);
362
363 1
        return trim($host);
364
    }
365
366
    /**
367
     * Detect whether request method is GET
368
     *
369
     * @return boolean
370
     */
371
    public function isGet()
0 ignored issues
show
Coding Style introduced by
isGet uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
372
    {
373
        return 'GET' == $_SERVER['REQUEST_METHOD'];
374
    }
375
376
    /**
377
     * Detect whether request method is POST
378
     *
379
     * @return boolean
380
     */
381
    public function isPost()
0 ignored issues
show
Coding Style introduced by
isPost uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
382
    {
383
        return 'POST' == $_SERVER['REQUEST_METHOD'];
384
    }
385
386
    /**
387
     * Detect whether request method is PUT
388
     *
389
     * @return boolean
390
     */
391
    public function isPut()
0 ignored issues
show
Coding Style introduced by
isPut uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
392
    {
393
        return 'PUT' == $_SERVER['REQUEST_METHOD'];
394
    }
395
396
    /**
397
     * Detect whether request method is AJAX
398
     *
399
     * @return boolean
400
     */
401
    public function isAjax()
0 ignored issues
show
Coding Style introduced by
isAjax uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
402
    {
403
        return ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')) ? true : false;
404
    }
405
406
    /**
407
     * Is CLI?
408
     *
409
     * Test to see if a request was made from the command line.
410
     *
411
     * @return  boolean
412
     */
413 3
    public function isCli()
414
    {
415 3
        return PHP_SAPI === 'cli';
416
    }
417
418
    /**
419
     * Detect whether user agent is Mobile
420
     *
421
     * @return boolean
422
     */
423 1
    public function isMobile()
0 ignored issues
show
Coding Style introduced by
isMobile uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
424
    {
425 1
        $userAgent = isset($_SERVER['USER_AGENT']) ? $_SERVER['USER_AGENT'] : null;
426 1
        if ($userAgent == null) {
427 1
            return false;
428
        }
429
430
        return preg_match('/android.+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i', $userAgent) || preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', substr($userAgent, 0, 4));
431
    }
432
}
433