CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.3 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.3
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
      • Validator
    • Network
      • Email
      • Http
    • Routing
      • Filter
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper

Classes

  • CakeRequest
  • CakeResponse
  • CakeSocket
  1: <?php
  2: /**
  3:  * CakeRequest
  4:  *
  5:  * PHP 5
  6:  *
  7:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8:  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  9:  *
 10:  * Licensed under The MIT License
 11:  * For full copyright and license information, please see the LICENSE.txt
 12:  * Redistributions of files must retain the above copyright notice.
 13:  *
 14:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 15:  * @link          http://cakephp.org CakePHP(tm) Project
 16:  * @since         CakePHP(tm) v 2.0
 17:  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 18:  */
 19: 
 20: App::uses('Hash', 'Utility');
 21: 
 22: /**
 23:  * A class that helps wrap Request information and particulars about a single request.
 24:  * Provides methods commonly used to introspect on the request headers and request body.
 25:  *
 26:  * Has both an Array and Object interface. You can access framework parameters using indexes:
 27:  *
 28:  * `$request['controller']` or `$request->controller`.
 29:  *
 30:  * @package       Cake.Network
 31:  */
 32: class CakeRequest implements ArrayAccess {
 33: 
 34: /**
 35:  * Array of parameters parsed from the url.
 36:  *
 37:  * @var array
 38:  */
 39:     public $params = array(
 40:         'plugin' => null,
 41:         'controller' => null,
 42:         'action' => null,
 43:         'named' => array(),
 44:         'pass' => array(),
 45:     );
 46: 
 47: /**
 48:  * Array of POST data. Will contain form data as well as uploaded files.
 49:  * Inputs prefixed with 'data' will have the data prefix removed. If there is
 50:  * overlap between an input prefixed with data and one without, the 'data' prefixed
 51:  * value will take precedence.
 52:  *
 53:  * @var array
 54:  */
 55:     public $data = array();
 56: 
 57: /**
 58:  * Array of querystring arguments
 59:  *
 60:  * @var array
 61:  */
 62:     public $query = array();
 63: 
 64: /**
 65:  * The url string used for the request.
 66:  *
 67:  * @var string
 68:  */
 69:     public $url;
 70: 
 71: /**
 72:  * Base url path.
 73:  *
 74:  * @var string
 75:  */
 76:     public $base = false;
 77: 
 78: /**
 79:  * webroot path segment for the request.
 80:  *
 81:  * @var string
 82:  */
 83:     public $webroot = '/';
 84: 
 85: /**
 86:  * The full address to the current request
 87:  *
 88:  * @var string
 89:  */
 90:     public $here = null;
 91: 
 92: /**
 93:  * The built in detectors used with `is()` can be modified with `addDetector()`.
 94:  *
 95:  * There are several ways to specify a detector, see CakeRequest::addDetector() for the
 96:  * various formats and ways to define detectors.
 97:  *
 98:  * @var array
 99:  */
100:     protected $_detectors = array(
101:         'get' => array('env' => 'REQUEST_METHOD', 'value' => 'GET'),
102:         'post' => array('env' => 'REQUEST_METHOD', 'value' => 'POST'),
103:         'put' => array('env' => 'REQUEST_METHOD', 'value' => 'PUT'),
104:         'delete' => array('env' => 'REQUEST_METHOD', 'value' => 'DELETE'),
105:         'head' => array('env' => 'REQUEST_METHOD', 'value' => 'HEAD'),
106:         'options' => array('env' => 'REQUEST_METHOD', 'value' => 'OPTIONS'),
107:         'ssl' => array('env' => 'HTTPS', 'value' => 1),
108:         'ajax' => array('env' => 'HTTP_X_REQUESTED_WITH', 'value' => 'XMLHttpRequest'),
109:         'flash' => array('env' => 'HTTP_USER_AGENT', 'pattern' => '/^(Shockwave|Adobe) Flash/'),
110:         'mobile' => array('env' => 'HTTP_USER_AGENT', 'options' => array(
111:             'Android', 'AvantGo', 'BlackBerry', 'DoCoMo', 'Fennec', 'iPod', 'iPhone', 'iPad',
112:             'J2ME', 'MIDP', 'NetFront', 'Nokia', 'Opera Mini', 'Opera Mobi', 'PalmOS', 'PalmSource',
113:             'portalmmm', 'Plucker', 'ReqwirelessWeb', 'SonyEricsson', 'Symbian', 'UP\\.Browser',
114:             'webOS', 'Windows CE', 'Windows Phone OS', 'Xiino'
115:         )),
116:         'requested' => array('param' => 'requested', 'value' => 1)
117:     );
118: 
119: /**
120:  * Copy of php://input. Since this stream can only be read once in most SAPI's
121:  * keep a copy of it so users don't need to know about that detail.
122:  *
123:  * @var string
124:  */
125:     protected $_input = '';
126: 
127: /**
128:  * Constructor
129:  *
130:  * @param string $url Trimmed url string to use. Should not contain the application base path.
131:  * @param boolean $parseEnvironment Set to false to not auto parse the environment. ie. GET, POST and FILES.
132:  */
133:     public function __construct($url = null, $parseEnvironment = true) {
134:         $this->_base();
135:         if (empty($url)) {
136:             $url = $this->_url();
137:         }
138:         if ($url[0] === '/') {
139:             $url = substr($url, 1);
140:         }
141:         $this->url = $url;
142: 
143:         if ($parseEnvironment) {
144:             $this->_processPost();
145:             $this->_processGet();
146:             $this->_processFiles();
147:         }
148:         $this->here = $this->base . '/' . $this->url;
149:     }
150: 
151: /**
152:  * process the post data and set what is there into the object.
153:  * processed data is available at `$this->data`
154:  *
155:  * Will merge POST vars prefixed with `data`, and ones without
156:  * into a single array. Variables prefixed with `data` will overwrite those without.
157:  *
158:  * If you have mixed POST values be careful not to make any top level keys numeric
159:  * containing arrays. Hash::merge() is used to merge data, and it has possibly
160:  * unexpected behavior in this situation.
161:  *
162:  * @return void
163:  */
164:     protected function _processPost() {
165:         if ($_POST) {
166:             $this->data = $_POST;
167:         } elseif (
168:             ($this->is('put') || $this->is('delete')) &&
169:             strpos(env('CONTENT_TYPE'), 'application/x-www-form-urlencoded') === 0
170:         ) {
171:                 $data = $this->_readInput();
172:                 parse_str($data, $this->data);
173:         }
174:         if (ini_get('magic_quotes_gpc') === '1') {
175:             $this->data = stripslashes_deep($this->data);
176:         }
177:         if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) {
178:             $this->data['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE');
179:         }
180:         $isArray = is_array($this->data);
181:         if ($isArray && isset($this->data['_method'])) {
182:             if (!empty($_SERVER)) {
183:                 $_SERVER['REQUEST_METHOD'] = $this->data['_method'];
184:             } else {
185:                 $_ENV['REQUEST_METHOD'] = $this->data['_method'];
186:             }
187:             unset($this->data['_method']);
188:         }
189:         if ($isArray && isset($this->data['data'])) {
190:             $data = $this->data['data'];
191:             if (count($this->data) <= 1) {
192:                 $this->data = $data;
193:             } else {
194:                 unset($this->data['data']);
195:                 $this->data = Hash::merge($this->data, $data);
196:             }
197:         }
198:     }
199: 
200: /**
201:  * Process the GET parameters and move things into the object.
202:  *
203:  * @return void
204:  */
205:     protected function _processGet() {
206:         if (ini_get('magic_quotes_gpc') === '1') {
207:             $query = stripslashes_deep($_GET);
208:         } else {
209:             $query = $_GET;
210:         }
211: 
212:         unset($query['/' . str_replace('.', '_', urldecode($this->url))]);
213:         if (strpos($this->url, '?') !== false) {
214:             list(, $querystr) = explode('?', $this->url);
215:             parse_str($querystr, $queryArgs);
216:             $query += $queryArgs;
217:         }
218:         if (isset($this->params['url'])) {
219:             $query = array_merge($this->params['url'], $query);
220:         }
221:         $this->query = $query;
222:     }
223: 
224: /**
225:  * Get the request uri. Looks in PATH_INFO first, as this is the exact value we need prepared
226:  * by PHP. Following that, REQUEST_URI, PHP_SELF, HTTP_X_REWRITE_URL and argv are checked in that order.
227:  * Each of these server variables have the base path, and query strings stripped off
228:  *
229:  * @return string URI The CakePHP request path that is being accessed.
230:  */
231:     protected function _url() {
232:         if (!empty($_SERVER['PATH_INFO'])) {
233:             return $_SERVER['PATH_INFO'];
234:         } elseif (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '://') === false) {
235:             $uri = $_SERVER['REQUEST_URI'];
236:         } elseif (isset($_SERVER['REQUEST_URI'])) {
237:             $qPosition = strpos($_SERVER['REQUEST_URI'], '?');
238:             if ($qPosition !== false && strpos($_SERVER['REQUEST_URI'], '://') > $qPosition) {
239:                 $uri = $_SERVER['REQUEST_URI'];
240:             } else {
241:                 $uri = substr($_SERVER['REQUEST_URI'], strlen(FULL_BASE_URL));
242:             }
243:         } elseif (isset($_SERVER['PHP_SELF']) && isset($_SERVER['SCRIPT_NAME'])) {
244:             $uri = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['PHP_SELF']);
245:         } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
246:             $uri = $_SERVER['HTTP_X_REWRITE_URL'];
247:         } elseif ($var = env('argv')) {
248:             $uri = $var[0];
249:         }
250: 
251:         $base = $this->base;
252: 
253:         if (strlen($base) > 0 && strpos($uri, $base) === 0) {
254:             $uri = substr($uri, strlen($base));
255:         }
256:         if (strpos($uri, '?') !== false) {
257:             list($uri) = explode('?', $uri, 2);
258:         }
259:         if (empty($uri) || $uri === '/' || $uri === '//' || $uri === '/index.php') {
260:             $uri = '/';
261:         }
262:         $endsWithIndex = '/webroot/index.php';
263:         $endsWithLength = strlen($endsWithIndex);
264:         if (
265:             strlen($uri) >= $endsWithLength &&
266:             substr($uri, -$endsWithLength) === $endsWithIndex
267:         ) {
268:             $uri = '/';
269:         }
270:         return $uri;
271:     }
272: 
273: /**
274:  * Returns a base URL and sets the proper webroot
275:  *
276:  * If CakePHP is called with index.php in the URL even though
277:  * URL Rewriting is activated (and thus not needed) it swallows
278:  * the unnecessary part from $base to prevent issue #3318.
279:  *
280:  * @return string Base URL
281:  * @link https://cakephp.lighthouseapp.com/projects/42648-cakephp/tickets/3318
282:  */
283:     protected function _base() {
284:         $dir = $webroot = null;
285:         $config = Configure::read('App');
286:         extract($config);
287: 
288:         if (!isset($base)) {
289:             $base = $this->base;
290:         }
291:         if ($base !== false) {
292:             $this->webroot = $base . '/';
293:             return $this->base = $base;
294:         }
295: 
296:         if (!$baseUrl) {
297:             $base = dirname(env('PHP_SELF'));
298: 
299:             $indexPos = strpos($base, '/webroot/index.php');
300:             if ($indexPos !== false) {
301:                 $base = substr($base, 0, $indexPos) . '/webroot';
302:             }
303:             if ($webroot === 'webroot' && $webroot === basename($base)) {
304:                 $base = dirname($base);
305:             }
306:             if ($dir === 'app' && $dir === basename($base)) {
307:                 $base = dirname($base);
308:             }
309: 
310:             if ($base === DS || $base === '.') {
311:                 $base = '';
312:             }
313:             $base = implode('/', array_map('rawurlencode', explode('/', $base)));
314:             $this->webroot = $base . '/';
315: 
316:             return $this->base = $base;
317:         }
318: 
319:         $file = '/' . basename($baseUrl);
320:         $base = dirname($baseUrl);
321: 
322:         if ($base === DS || $base === '.') {
323:             $base = '';
324:         }
325:         $this->webroot = $base . '/';
326: 
327:         $docRoot = env('DOCUMENT_ROOT');
328:         $docRootContainsWebroot = strpos($docRoot, $dir . DS . $webroot);
329: 
330:         if (!empty($base) || !$docRootContainsWebroot) {
331:             if (strpos($this->webroot, '/' . $dir . '/') === false) {
332:                 $this->webroot .= $dir . '/';
333:             }
334:             if (strpos($this->webroot, '/' . $webroot . '/') === false) {
335:                 $this->webroot .= $webroot . '/';
336:             }
337:         }
338:         return $this->base = $base . $file;
339:     }
340: 
341: /**
342:  * Process $_FILES and move things into the object.
343:  *
344:  * @return void
345:  */
346:     protected function _processFiles() {
347:         if (isset($_FILES) && is_array($_FILES)) {
348:             foreach ($_FILES as $name => $data) {
349:                 if ($name !== 'data') {
350:                     $this->params['form'][$name] = $data;
351:                 }
352:             }
353:         }
354: 
355:         if (isset($_FILES['data'])) {
356:             foreach ($_FILES['data'] as $key => $data) {
357:                 $this->_processFileData('', $data, $key);
358:             }
359:         }
360:     }
361: 
362: /**
363:  * Recursively walks the FILES array restructuring the data
364:  * into something sane and useable.
365:  *
366:  * @param string $path The dot separated path to insert $data into.
367:  * @param array $data The data to traverse/insert.
368:  * @param string $field The terminal field name, which is the top level key in $_FILES.
369:  * @return void
370:  */
371:     protected function _processFileData($path, $data, $field) {
372:         foreach ($data as $key => $fields) {
373:             $newPath = $key;
374:             if (!empty($path)) {
375:                 $newPath = $path . '.' . $key;
376:             }
377:             if (is_array($fields)) {
378:                 $this->_processFileData($newPath, $fields, $field);
379:             } else {
380:                 $newPath .= '.' . $field;
381:                 $this->data = Hash::insert($this->data, $newPath, $fields);
382:             }
383:         }
384:     }
385: 
386: /**
387:  * Get the IP the client is using, or says they are using.
388:  *
389:  * @param boolean $safe Use safe = false when you think the user might manipulate their HTTP_CLIENT_IP
390:  *   header. Setting $safe = false will will also look at HTTP_X_FORWARDED_FOR
391:  * @return string The client IP.
392:  */
393:     public function clientIp($safe = true) {
394:         if (!$safe && env('HTTP_X_FORWARDED_FOR')) {
395:             $ipaddr = preg_replace('/(?:,.*)/', '', env('HTTP_X_FORWARDED_FOR'));
396:         } else {
397:             if (env('HTTP_CLIENT_IP')) {
398:                 $ipaddr = env('HTTP_CLIENT_IP');
399:             } else {
400:                 $ipaddr = env('REMOTE_ADDR');
401:             }
402:         }
403: 
404:         if (env('HTTP_CLIENTADDRESS')) {
405:             $tmpipaddr = env('HTTP_CLIENTADDRESS');
406: 
407:             if (!empty($tmpipaddr)) {
408:                 $ipaddr = preg_replace('/(?:,.*)/', '', $tmpipaddr);
409:             }
410:         }
411:         return trim($ipaddr);
412:     }
413: 
414: /**
415:  * Returns the referer that referred this request.
416:  *
417:  * @param boolean $local Attempt to return a local address. Local addresses do not contain hostnames.
418:  * @return string The referring address for this request.
419:  */
420:     public function referer($local = false) {
421:         $ref = env('HTTP_REFERER');
422:         $forwarded = env('HTTP_X_FORWARDED_HOST');
423:         if ($forwarded) {
424:             $ref = $forwarded;
425:         }
426: 
427:         $base = '';
428:         if (defined('FULL_BASE_URL')) {
429:             $base = FULL_BASE_URL . $this->webroot;
430:         }
431:         if (!empty($ref) && !empty($base)) {
432:             if ($local && strpos($ref, $base) === 0) {
433:                 $ref = substr($ref, strlen($base));
434:                 if ($ref[0] !== '/') {
435:                     $ref = '/' . $ref;
436:                 }
437:                 return $ref;
438:             } elseif (!$local) {
439:                 return $ref;
440:             }
441:         }
442:         return '/';
443:     }
444: 
445: /**
446:  * Missing method handler, handles wrapping older style isAjax() type methods
447:  *
448:  * @param string $name The method called
449:  * @param array $params Array of parameters for the method call
450:  * @return mixed
451:  * @throws CakeException when an invalid method is called.
452:  */
453:     public function __call($name, $params) {
454:         if (strpos($name, 'is') === 0) {
455:             $type = strtolower(substr($name, 2));
456:             return $this->is($type);
457:         }
458:         throw new CakeException(__d('cake_dev', 'Method %s does not exist', $name));
459:     }
460: 
461: /**
462:  * Magic get method allows access to parsed routing parameters directly on the object.
463:  *
464:  * Allows access to `$this->params['controller']` via `$this->controller`
465:  *
466:  * @param string $name The property being accessed.
467:  * @return mixed Either the value of the parameter or null.
468:  */
469:     public function __get($name) {
470:         if (isset($this->params[$name])) {
471:             return $this->params[$name];
472:         }
473:         return null;
474:     }
475: 
476: /**
477:  * Magic isset method allows isset/empty checks
478:  * on routing parameters.
479:  *
480:  * @param string $name The property being accessed.
481:  * @return boolean Existence
482:  */
483:     public function __isset($name) {
484:         return isset($this->params[$name]);
485:     }
486: 
487: /**
488:  * Check whether or not a Request is a certain type. Uses the built in detection rules
489:  * as well as additional rules defined with CakeRequest::addDetector(). Any detector can be called
490:  * as `is($type)` or `is$Type()`.
491:  *
492:  * @param string $type The type of request you want to check.
493:  * @return boolean Whether or not the request is the type you are checking.
494:  */
495:     public function is($type) {
496:         $type = strtolower($type);
497:         if (!isset($this->_detectors[$type])) {
498:             return false;
499:         }
500:         $detect = $this->_detectors[$type];
501:         if (isset($detect['env'])) {
502:             if (isset($detect['value'])) {
503:                 return env($detect['env']) == $detect['value'];
504:             }
505:             if (isset($detect['pattern'])) {
506:                 return (bool)preg_match($detect['pattern'], env($detect['env']));
507:             }
508:             if (isset($detect['options'])) {
509:                 $pattern = '/' . implode('|', $detect['options']) . '/i';
510:                 return (bool)preg_match($pattern, env($detect['env']));
511:             }
512:         }
513:         if (isset($detect['param'])) {
514:             $key = $detect['param'];
515:             $value = $detect['value'];
516:             return isset($this->params[$key]) ? $this->params[$key] == $value : false;
517:         }
518:         if (isset($detect['callback']) && is_callable($detect['callback'])) {
519:             return call_user_func($detect['callback'], $this);
520:         }
521:         return false;
522:     }
523: 
524: /**
525:  * Add a new detector to the list of detectors that a request can use.
526:  * There are several different formats and types of detectors that can be set.
527:  *
528:  * ### Environment value comparison
529:  *
530:  * An environment value comparison, compares a value fetched from `env()` to a known value
531:  * the environment value is equality checked against the provided value.
532:  *
533:  * e.g `addDetector('post', array('env' => 'REQUEST_METHOD', 'value' => 'POST'))`
534:  *
535:  * ### Pattern value comparison
536:  *
537:  * Pattern value comparison allows you to compare a value fetched from `env()` to a regular expression.
538:  *
539:  * e.g `addDetector('iphone', array('env' => 'HTTP_USER_AGENT', 'pattern' => '/iPhone/i'));`
540:  *
541:  * ### Option based comparison
542:  *
543:  * Option based comparisons use a list of options to create a regular expression. Subsequent calls
544:  * to add an already defined options detector will merge the options.
545:  *
546:  * e.g `addDetector('mobile', array('env' => 'HTTP_USER_AGENT', 'options' => array('Fennec')));`
547:  *
548:  * ### Callback detectors
549:  *
550:  * Callback detectors allow you to provide a 'callback' type to handle the check. The callback will
551:  * receive the request object as its only parameter.
552:  *
553:  * e.g `addDetector('custom', array('callback' => array('SomeClass', 'somemethod')));`
554:  *
555:  * ### Request parameter detectors
556:  *
557:  * Allows for custom detectors on the request parameters.
558:  *
559:  * e.g `addDetector('post', array('param' => 'requested', 'value' => 1)`
560:  *
561:  * @param string $name The name of the detector.
562:  * @param array $options The options for the detector definition. See above.
563:  * @return void
564:  */
565:     public function addDetector($name, $options) {
566:         $name = strtolower($name);
567:         if (isset($this->_detectors[$name]) && isset($options['options'])) {
568:             $options = Hash::merge($this->_detectors[$name], $options);
569:         }
570:         $this->_detectors[$name] = $options;
571:     }
572: 
573: /**
574:  * Add parameters to the request's parsed parameter set. This will overwrite any existing parameters.
575:  * This modifies the parameters available through `$request->params`.
576:  *
577:  * @param array $params Array of parameters to merge in
578:  * @return The current object, you can chain this method.
579:  */
580:     public function addParams($params) {
581:         $this->params = array_merge($this->params, (array)$params);
582:         return $this;
583:     }
584: 
585: /**
586:  * Add paths to the requests' paths vars. This will overwrite any existing paths.
587:  * Provides an easy way to modify, here, webroot and base.
588:  *
589:  * @param array $paths Array of paths to merge in
590:  * @return CakeRequest the current object, you can chain this method.
591:  */
592:     public function addPaths($paths) {
593:         foreach (array('webroot', 'here', 'base') as $element) {
594:             if (isset($paths[$element])) {
595:                 $this->{$element} = $paths[$element];
596:             }
597:         }
598:         return $this;
599:     }
600: 
601: /**
602:  * Get the value of the current requests URL. Will include named parameters and querystring arguments.
603:  *
604:  * @param boolean $base Include the base path, set to false to trim the base path off.
605:  * @return string the current request URL including query string args.
606:  */
607:     public function here($base = true) {
608:         $url = $this->here;
609:         if (!empty($this->query)) {
610:             $url .= '?' . http_build_query($this->query, null, '&');
611:         }
612:         if (!$base) {
613:             $url = preg_replace('/^' . preg_quote($this->base, '/') . '/', '', $url, 1);
614:         }
615:         return $url;
616:     }
617: 
618: /**
619:  * Read an HTTP header from the Request information.
620:  *
621:  * @param string $name Name of the header you want.
622:  * @return mixed Either false on no header being set or the value of the header.
623:  */
624:     public static function header($name) {
625:         $name = 'HTTP_' . strtoupper(str_replace('-', '_', $name));
626:         if (!empty($_SERVER[$name])) {
627:             return $_SERVER[$name];
628:         }
629:         return false;
630:     }
631: 
632: /**
633:  * Get the HTTP method used for this request.
634:  * There are a few ways to specify a method.
635:  *
636:  * - If your client supports it you can use native HTTP methods.
637:  * - You can set the HTTP-X-Method-Override header.
638:  * - You can submit an input with the name `_method`
639:  *
640:  * Any of these 3 approaches can be used to set the HTTP method used
641:  * by CakePHP internally, and will effect the result of this method.
642:  *
643:  * @return string The name of the HTTP method used.
644:  */
645:     public function method() {
646:         return env('REQUEST_METHOD');
647:     }
648: 
649: /**
650:  * Get the host that the request was handled on.
651:  *
652:  * @return string
653:  */
654:     public function host() {
655:         return env('HTTP_HOST');
656:     }
657: 
658: /**
659:  * Get the domain name and include $tldLength segments of the tld.
660:  *
661:  * @param integer $tldLength Number of segments your tld contains. For example: `example.com` contains 1 tld.
662:  *   While `example.co.uk` contains 2.
663:  * @return string Domain name without subdomains.
664:  */
665:     public function domain($tldLength = 1) {
666:         $segments = explode('.', $this->host());
667:         $domain = array_slice($segments, -1 * ($tldLength + 1));
668:         return implode('.', $domain);
669:     }
670: 
671: /**
672:  * Get the subdomains for a host.
673:  *
674:  * @param integer $tldLength Number of segments your tld contains. For example: `example.com` contains 1 tld.
675:  *   While `example.co.uk` contains 2.
676:  * @return array An array of subdomains.
677:  */
678:     public function subdomains($tldLength = 1) {
679:         $segments = explode('.', $this->host());
680:         return array_slice($segments, 0, -1 * ($tldLength + 1));
681:     }
682: 
683: /**
684:  * Find out which content types the client accepts or check if they accept a
685:  * particular type of content.
686:  *
687:  * #### Get all types:
688:  *
689:  * `$this->request->accepts();`
690:  *
691:  * #### Check for a single type:
692:  *
693:  * `$this->request->accepts('application/json');`
694:  *
695:  * This method will order the returned content types by the preference values indicated
696:  * by the client.
697:  *
698:  * @param string $type The content type to check for. Leave null to get all types a client accepts.
699:  * @return mixed Either an array of all the types the client accepts or a boolean if they accept the
700:  *   provided type.
701:  */
702:     public function accepts($type = null) {
703:         $raw = $this->parseAccept();
704:         $accept = array();
705:         foreach ($raw as $types) {
706:             $accept = array_merge($accept, $types);
707:         }
708:         if ($type === null) {
709:             return $accept;
710:         }
711:         return in_array($type, $accept);
712:     }
713: 
714: /**
715:  * Parse the HTTP_ACCEPT header and return a sorted array with content types
716:  * as the keys, and pref values as the values.
717:  *
718:  * Generally you want to use CakeRequest::accept() to get a simple list
719:  * of the accepted content types.
720:  *
721:  * @return array An array of prefValue => array(content/types)
722:  */
723:     public function parseAccept() {
724:         return $this->_parseAcceptWithQualifier($this->header('accept'));
725:     }
726: 
727: /**
728:  * Get the languages accepted by the client, or check if a specific language is accepted.
729:  *
730:  * Get the list of accepted languages:
731:  *
732:  * {{{ CakeRequest::acceptLanguage(); }}}
733:  *
734:  * Check if a specific language is accepted:
735:  *
736:  * {{{ CakeRequest::acceptLanguage('es-es'); }}}
737:  *
738:  * @param string $language The language to test.
739:  * @return If a $language is provided, a boolean. Otherwise the array of accepted languages.
740:  */
741:     public static function acceptLanguage($language = null) {
742:         $raw = self::_parseAcceptWithQualifier(self::header('Accept-Language'));
743:         $accept = array();
744:         foreach ($raw as $languages) {
745:             foreach ($languages as &$lang) {
746:                 if (strpos($lang, '_')) {
747:                     $lang = str_replace('_', '-', $lang);
748:                 }
749:                 $lang = strtolower($lang);
750:             }
751:             $accept = array_merge($accept, $languages);
752:         }
753:         if ($language === null) {
754:             return $accept;
755:         }
756:         return in_array(strtolower($language), $accept);
757:     }
758: 
759: /**
760:  * Parse Accept* headers with qualifier options
761:  *
762:  * @param string $header
763:  * @return array
764:  */
765:     protected static function _parseAcceptWithQualifier($header) {
766:         $accept = array();
767:         $header = explode(',', $header);
768:         foreach (array_filter($header) as $value) {
769:             $prefPos = strpos($value, ';');
770:             if ($prefPos !== false) {
771:                 $prefValue = substr($value, strpos($value, '=') + 1);
772:                 $value = trim(substr($value, 0, $prefPos));
773:             } else {
774:                 $prefValue = '1.0';
775:                 $value = trim($value);
776:             }
777:             if (!isset($accept[$prefValue])) {
778:                 $accept[$prefValue] = array();
779:             }
780:             if ($prefValue) {
781:                 $accept[$prefValue][] = $value;
782:             }
783:         }
784:         krsort($accept);
785:         return $accept;
786:     }
787: 
788: /**
789:  * Provides a read accessor for `$this->query`. Allows you
790:  * to use a syntax similar to `CakeSession` for reading url query data.
791:  *
792:  * @param string $name Query string variable name
793:  * @return mixed The value being read
794:  */
795:     public function query($name) {
796:         return Hash::get($this->query, $name);
797:     }
798: 
799: /**
800:  * Provides a read/write accessor for `$this->data`. Allows you
801:  * to use a syntax similar to `CakeSession` for reading post data.
802:  *
803:  * ## Reading values.
804:  *
805:  * `$request->data('Post.title');`
806:  *
807:  * When reading values you will get `null` for keys/values that do not exist.
808:  *
809:  * ## Writing values
810:  *
811:  * `$request->data('Post.title', 'New post!');`
812:  *
813:  * You can write to any value, even paths/keys that do not exist, and the arrays
814:  * will be created for you.
815:  *
816:  * @param string $name,... Dot separated name of the value to read/write
817:  * @return mixed Either the value being read, or this so you can chain consecutive writes.
818:  */
819:     public function data($name) {
820:         $args = func_get_args();
821:         if (count($args) == 2) {
822:             $this->data = Hash::insert($this->data, $name, $args[1]);
823:             return $this;
824:         }
825:         return Hash::get($this->data, $name);
826:     }
827: 
828: /**
829:  * Read data from `php://input`. Useful when interacting with XML or JSON
830:  * request body content.
831:  *
832:  * Getting input with a decoding function:
833:  *
834:  * `$this->request->input('json_decode');`
835:  *
836:  * Getting input using a decoding function, and additional params:
837:  *
838:  * `$this->request->input('Xml::build', array('return' => 'DOMDocument'));`
839:  *
840:  * Any additional parameters are applied to the callback in the order they are given.
841:  *
842:  * @param string $callback A decoding callback that will convert the string data to another
843:  *     representation. Leave empty to access the raw input data. You can also
844:  *     supply additional parameters for the decoding callback using var args, see above.
845:  * @return The decoded/processed request data.
846:  */
847:     public function input($callback = null) {
848:         $input = $this->_readInput();
849:         $args = func_get_args();
850:         if (!empty($args)) {
851:             $callback = array_shift($args);
852:             array_unshift($args, $input);
853:             return call_user_func_array($callback, $args);
854:         }
855:         return $input;
856:     }
857: 
858: /**
859:  * Only allow certain HTTP request methods, if the request method does not match
860:  * a 405 error will be shown and the required "Allow" response header will be set.
861:  *
862:  * Example:
863:  *
864:  * $this->request->onlyAllow('post', 'delete');
865:  * or
866:  * $this->request->onlyAllow(array('post', 'delete'));
867:  *
868:  * If the request would be GET, response header "Allow: POST, DELETE" will be set
869:  * and a 405 error will be returned
870:  *
871:  * @param string|array $methods Allowed HTTP request methods
872:  * @return boolean true
873:  * @throws MethodNotAllowedException
874:  */
875:     public function onlyAllow($methods) {
876:         if (!is_array($methods)) {
877:             $methods = func_get_args();
878:         }
879:         foreach ($methods as $method) {
880:             if ($this->is($method)) {
881:                 return true;
882:             }
883:         }
884:         $allowed = strtoupper(implode(', ', $methods));
885:         $e = new MethodNotAllowedException();
886:         $e->responseHeader('Allow', $allowed);
887:         throw $e;
888:     }
889: 
890: /**
891:  * Read data from php://input, mocked in tests.
892:  *
893:  * @return string contents of php://input
894:  */
895:     protected function _readInput() {
896:         if (empty($this->_input)) {
897:             $fh = fopen('php://input', 'r');
898:             $content = stream_get_contents($fh);
899:             fclose($fh);
900:             $this->_input = $content;
901:         }
902:         return $this->_input;
903:     }
904: 
905: /**
906:  * Array access read implementation
907:  *
908:  * @param string $name Name of the key being accessed.
909:  * @return mixed
910:  */
911:     public function offsetGet($name) {
912:         if (isset($this->params[$name])) {
913:             return $this->params[$name];
914:         }
915:         if ($name === 'url') {
916:             return $this->query;
917:         }
918:         if ($name === 'data') {
919:             return $this->data;
920:         }
921:         return null;
922:     }
923: 
924: /**
925:  * Array access write implementation
926:  *
927:  * @param string $name Name of the key being written
928:  * @param mixed $value The value being written.
929:  * @return void
930:  */
931:     public function offsetSet($name, $value) {
932:         $this->params[$name] = $value;
933:     }
934: 
935: /**
936:  * Array access isset() implementation
937:  *
938:  * @param string $name thing to check.
939:  * @return boolean
940:  */
941:     public function offsetExists($name) {
942:         return isset($this->params[$name]);
943:     }
944: 
945: /**
946:  * Array access unset() implementation
947:  *
948:  * @param string $name Name to unset.
949:  * @return void
950:  */
951:     public function offsetUnset($name) {
952:         unset($this->params[$name]);
953:     }
954: 
955: }
956: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs