CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Team
    • Issues (Github)
    • YouTube Channel
    • Get Involved
    • Bakery
    • Featured Resources
    • Newsletter
    • Certification
    • My CakePHP
    • CakeFest
    • Facebook
    • Twitter
    • Help & Support
    • Forum
    • Stack Overflow
    • IRC
    • Slack
    • Paid Support
CakePHP

C CakePHP 3.8 Red Velvet API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 3.8
      • 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

Namespaces

  • Cake
    • Auth
      • Storage
    • Cache
      • Engine
    • Collection
      • Iterator
    • Command
    • Console
      • Exception
    • Controller
      • Component
      • Exception
    • Core
      • Configure
        • Engine
      • Exception
      • Retry
    • Database
      • Driver
      • Exception
      • Expression
      • Schema
      • Statement
      • Type
    • Datasource
      • Exception
    • Error
      • Middleware
    • Event
      • Decorator
    • Filesystem
    • Form
    • Http
      • Client
        • Adapter
        • Auth
      • Cookie
      • Exception
      • Middleware
      • Session
    • I18n
      • Formatter
      • Middleware
      • Parser
    • Log
      • Engine
    • Mailer
      • Exception
      • Transport
    • Network
      • Exception
    • ORM
      • Association
      • Behavior
        • Translate
      • Exception
      • Locator
      • Rule
    • Routing
      • Exception
      • Filter
      • Middleware
      • Route
    • Shell
      • Helper
      • Task
    • TestSuite
      • Fixture
      • Stub
    • Utility
      • Exception
    • Validation
    • View
      • Exception
      • Form
      • Helper
      • Widget
  • None

Classes

  • ActionDispatcher
  • BaseApplication
  • Client
  • ControllerFactory
  • CorsBuilder
  • MiddlewareQueue
  • Response
  • ResponseEmitter
  • Runner
  • Server
  • ServerRequest
  • ServerRequestFactory
  • Session
  1: <?php
  2: /**
  3:  * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4:  * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5:  *
  6:  * Licensed under The MIT License
  7:  * For full copyright and license information, please see the LICENSE.txt
  8:  * Redistributions of files must retain the above copyright notice.
  9:  *
 10:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 11:  * @link          https://cakephp.org CakePHP(tm) Project
 12:  * @since         0.10.0
 13:  * @license       https://opensource.org/licenses/mit-license.php MIT License
 14:  */
 15: namespace Cake\Http;
 16: 
 17: use Cake\Core\App;
 18: use Cake\Utility\Hash;
 19: use InvalidArgumentException;
 20: use RuntimeException;
 21: use SessionHandlerInterface;
 22: 
 23: /**
 24:  * This class is a wrapper for the native PHP session functions. It provides
 25:  * several defaults for the most common session configuration
 26:  * via external handlers and helps with using session in cli without any warnings.
 27:  *
 28:  * Sessions can be created from the defaults using `Session::create()` or you can get
 29:  * an instance of a new session by just instantiating this class and passing the complete
 30:  * options you want to use.
 31:  *
 32:  * When specific options are omitted, this class will take its defaults from the configuration
 33:  * values from the `session.*` directives in php.ini. This class will also alter such
 34:  * directives when configuration values are provided.
 35:  */
 36: class Session
 37: {
 38:     /**
 39:      * The Session handler instance used as an engine for persisting the session data.
 40:      *
 41:      * @var \SessionHandlerInterface
 42:      */
 43:     protected $_engine;
 44: 
 45:     /**
 46:      * Indicates whether the sessions has already started
 47:      *
 48:      * @var bool
 49:      */
 50:     protected $_started;
 51: 
 52:     /**
 53:      * The time in seconds the session will be valid for
 54:      *
 55:      * @var int
 56:      */
 57:     protected $_lifetime;
 58: 
 59:     /**
 60:      * Whether this session is running under a CLI environment
 61:      *
 62:      * @var bool
 63:      */
 64:     protected $_isCLI = false;
 65: 
 66:     /**
 67:      * Returns a new instance of a session after building a configuration bundle for it.
 68:      * This function allows an options array which will be used for configuring the session
 69:      * and the handler to be used. The most important key in the configuration array is
 70:      * `defaults`, which indicates the set of configurations to inherit from, the possible
 71:      * defaults are:
 72:      *
 73:      * - php: just use session as configured in php.ini
 74:      * - cache: Use the CakePHP caching system as an storage for the session, you will need
 75:      *   to pass the `config` key with the name of an already configured Cache engine.
 76:      * - database: Use the CakePHP ORM to persist and manage sessions. By default this requires
 77:      *   a table in your database named `sessions` or a `model` key in the configuration
 78:      *   to indicate which Table object to use.
 79:      * - cake: Use files for storing the sessions, but let CakePHP manage them and decide
 80:      *   where to store them.
 81:      *
 82:      * The full list of options follows:
 83:      *
 84:      * - defaults: either 'php', 'database', 'cache' or 'cake' as explained above.
 85:      * - handler: An array containing the handler configuration
 86:      * - ini: A list of php.ini directives to set before the session starts.
 87:      * - timeout: The time in minutes the session should stay active
 88:      *
 89:      * @param array $sessionConfig Session config.
 90:      * @return static
 91:      * @see \Cake\Http\Session::__construct()
 92:      */
 93:     public static function create($sessionConfig = [])
 94:     {
 95:         if (isset($sessionConfig['defaults'])) {
 96:             $defaults = static::_defaultConfig($sessionConfig['defaults']);
 97:             if ($defaults) {
 98:                 $sessionConfig = Hash::merge($defaults, $sessionConfig);
 99:             }
100:         }
101: 
102:         if (!isset($sessionConfig['ini']['session.cookie_secure']) && env('HTTPS') && ini_get('session.cookie_secure') != 1) {
103:             $sessionConfig['ini']['session.cookie_secure'] = 1;
104:         }
105: 
106:         if (!isset($sessionConfig['ini']['session.name'])) {
107:             $sessionConfig['ini']['session.name'] = $sessionConfig['cookie'];
108:         }
109: 
110:         if (!empty($sessionConfig['handler'])) {
111:             $sessionConfig['ini']['session.save_handler'] = 'user';
112:         }
113: 
114:         // In PHP7.2.0+ session.save_handler can't be set to user by the user.
115:         // https://github.com/php/php-src/commit/a93a51c3bf4ea1638ce0adc4a899cb93531b9f0d
116:         if (version_compare(PHP_VERSION, '7.2.0', '>=')) {
117:             unset($sessionConfig['ini']['session.save_handler']);
118:         }
119: 
120:         if (!isset($sessionConfig['ini']['session.use_strict_mode']) && ini_get('session.use_strict_mode') != 1) {
121:             $sessionConfig['ini']['session.use_strict_mode'] = 1;
122:         }
123: 
124:         if (!isset($sessionConfig['ini']['session.cookie_httponly']) && ini_get('session.cookie_httponly') != 1) {
125:             $sessionConfig['ini']['session.cookie_httponly'] = 1;
126:         }
127: 
128:         return new static($sessionConfig);
129:     }
130: 
131:     /**
132:      * Get one of the prebaked default session configurations.
133:      *
134:      * @param string $name Config name.
135:      * @return bool|array
136:      */
137:     protected static function _defaultConfig($name)
138:     {
139:         $defaults = [
140:             'php' => [
141:                 'cookie' => 'CAKEPHP',
142:                 'ini' => [
143:                     'session.use_trans_sid' => 0,
144:                 ]
145:             ],
146:             'cake' => [
147:                 'cookie' => 'CAKEPHP',
148:                 'ini' => [
149:                     'session.use_trans_sid' => 0,
150:                     'session.serialize_handler' => 'php',
151:                     'session.use_cookies' => 1,
152:                     'session.save_path' => TMP . 'sessions',
153:                     'session.save_handler' => 'files'
154:                 ]
155:             ],
156:             'cache' => [
157:                 'cookie' => 'CAKEPHP',
158:                 'ini' => [
159:                     'session.use_trans_sid' => 0,
160:                     'session.use_cookies' => 1,
161:                     'session.save_handler' => 'user',
162:                 ],
163:                 'handler' => [
164:                     'engine' => 'CacheSession',
165:                     'config' => 'default'
166:                 ]
167:             ],
168:             'database' => [
169:                 'cookie' => 'CAKEPHP',
170:                 'ini' => [
171:                     'session.use_trans_sid' => 0,
172:                     'session.use_cookies' => 1,
173:                     'session.save_handler' => 'user',
174:                     'session.serialize_handler' => 'php',
175:                 ],
176:                 'handler' => [
177:                     'engine' => 'DatabaseSession'
178:                 ]
179:             ]
180:         ];
181: 
182:         if (isset($defaults[$name])) {
183:             return $defaults[$name];
184:         }
185: 
186:         return false;
187:     }
188: 
189:     /**
190:      * Constructor.
191:      *
192:      * ### Configuration:
193:      *
194:      * - timeout: The time in minutes the session should be valid for.
195:      * - cookiePath: The url path for which session cookie is set. Maps to the
196:      *   `session.cookie_path` php.ini config. Defaults to base path of app.
197:      * - ini: A list of php.ini directives to change before the session start.
198:      * - handler: An array containing at least the `class` key. To be used as the session
199:      *   engine for persisting data. The rest of the keys in the array will be passed as
200:      *   the configuration array for the engine. You can set the `class` key to an already
201:      *   instantiated session handler object.
202:      *
203:      * @param array $config The Configuration to apply to this session object
204:      */
205:     public function __construct(array $config = [])
206:     {
207:         if (isset($config['timeout'])) {
208:             $config['ini']['session.gc_maxlifetime'] = 60 * $config['timeout'];
209:         }
210: 
211:         if (!empty($config['cookie'])) {
212:             $config['ini']['session.name'] = $config['cookie'];
213:         }
214: 
215:         if (!isset($config['ini']['session.cookie_path'])) {
216:             $cookiePath = empty($config['cookiePath']) ? '/' : $config['cookiePath'];
217:             $config['ini']['session.cookie_path'] = $cookiePath;
218:         }
219: 
220:         if (!empty($config['ini']) && is_array($config['ini'])) {
221:             $this->options($config['ini']);
222:         }
223: 
224:         if (!empty($config['handler']['engine'])) {
225:             $class = $config['handler']['engine'];
226:             unset($config['handler']['engine']);
227:             $this->engine($class, $config['handler']);
228:         }
229: 
230:         $this->_lifetime = (int)ini_get('session.gc_maxlifetime');
231:         $this->_isCLI = (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg');
232:         session_register_shutdown();
233:     }
234: 
235:     /**
236:      * Sets the session handler instance to use for this session.
237:      * If a string is passed for the first argument, it will be treated as the
238:      * class name and the second argument will be passed as the first argument
239:      * in the constructor.
240:      *
241:      * If an instance of a SessionHandlerInterface is provided as the first argument,
242:      * the handler will be set to it.
243:      *
244:      * If no arguments are passed it will return the currently configured handler instance
245:      * or null if none exists.
246:      *
247:      * @param string|\SessionHandlerInterface|null $class The session handler to use
248:      * @param array $options the options to pass to the SessionHandler constructor
249:      * @return \SessionHandlerInterface|null
250:      * @throws \InvalidArgumentException
251:      */
252:     public function engine($class = null, array $options = [])
253:     {
254:         if ($class === null) {
255:             return $this->_engine;
256:         }
257:         if ($class instanceof SessionHandlerInterface) {
258:             return $this->setEngine($class);
259:         }
260:         $className = App::className($class, 'Http/Session');
261: 
262:         if (!$className) {
263:             $className = App::className($class, 'Network/Session');
264:             if ($className) {
265:                 deprecationWarning('Session adapters should be moved to the Http/Session namespace.');
266:             }
267:         }
268:         if (!$className) {
269:             throw new InvalidArgumentException(
270:                 sprintf('The class "%s" does not exist and cannot be used as a session engine', $class)
271:             );
272:         }
273: 
274:         $handler = new $className($options);
275:         if (!($handler instanceof SessionHandlerInterface)) {
276:             throw new InvalidArgumentException(
277:                 'The chosen SessionHandler does not implement SessionHandlerInterface, it cannot be used as an engine.'
278:             );
279:         }
280: 
281:         return $this->setEngine($handler);
282:     }
283: 
284:     /**
285:      * Set the engine property and update the session handler in PHP.
286:      *
287:      * @param \SessionHandlerInterface $handler The handler to set
288:      * @return \SessionHandlerInterface
289:      */
290:     protected function setEngine(SessionHandlerInterface $handler)
291:     {
292:         if (!headers_sent() && session_status() !== \PHP_SESSION_ACTIVE) {
293:             session_set_save_handler($handler, false);
294:         }
295: 
296:         return $this->_engine = $handler;
297:     }
298: 
299:     /**
300:      * Calls ini_set for each of the keys in `$options` and set them
301:      * to the respective value in the passed array.
302:      *
303:      * ### Example:
304:      *
305:      * ```
306:      * $session->options(['session.use_cookies' => 1]);
307:      * ```
308:      *
309:      * @param array $options Ini options to set.
310:      * @return void
311:      * @throws \RuntimeException if any directive could not be set
312:      */
313:     public function options(array $options)
314:     {
315:         if (session_status() === \PHP_SESSION_ACTIVE || headers_sent()) {
316:             return;
317:         }
318: 
319:         foreach ($options as $setting => $value) {
320:             if (ini_set($setting, (string)$value) === false) {
321:                 throw new RuntimeException(
322:                     sprintf('Unable to configure the session, setting %s failed.', $setting)
323:                 );
324:             }
325:         }
326:     }
327: 
328:     /**
329:      * Starts the Session.
330:      *
331:      * @return bool True if session was started
332:      * @throws \RuntimeException if the session was already started
333:      */
334:     public function start()
335:     {
336:         if ($this->_started) {
337:             return true;
338:         }
339: 
340:         if ($this->_isCLI) {
341:             $_SESSION = [];
342:             $this->id('cli');
343: 
344:             return $this->_started = true;
345:         }
346: 
347:         if (session_status() === \PHP_SESSION_ACTIVE) {
348:             throw new RuntimeException('Session was already started');
349:         }
350: 
351:         if (ini_get('session.use_cookies') && headers_sent($file, $line)) {
352:             return false;
353:         }
354: 
355:         if (!session_start()) {
356:             throw new RuntimeException('Could not start the session');
357:         }
358: 
359:         $this->_started = true;
360: 
361:         if ($this->_timedOut()) {
362:             $this->destroy();
363: 
364:             return $this->start();
365:         }
366: 
367:         return $this->_started;
368:     }
369: 
370:     /**
371:      * Write data and close the session
372:      *
373:      * @return bool True if session was started
374:      */
375:     public function close()
376:     {
377:         if (!$this->_started) {
378:             return true;
379:         }
380: 
381:         if (!session_write_close()) {
382:             throw new RuntimeException('Could not close the session');
383:         }
384: 
385:         $this->_started = false;
386: 
387:         return true;
388:     }
389: 
390:     /**
391:      * Determine if Session has already been started.
392:      *
393:      * @return bool True if session has been started.
394:      */
395:     public function started()
396:     {
397:         return $this->_started || session_status() === \PHP_SESSION_ACTIVE;
398:     }
399: 
400:     /**
401:      * Returns true if given variable name is set in session.
402:      *
403:      * @param string|null $name Variable name to check for
404:      * @return bool True if variable is there
405:      */
406:     public function check($name = null)
407:     {
408:         if ($this->_hasSession() && !$this->started()) {
409:             $this->start();
410:         }
411: 
412:         if (!isset($_SESSION)) {
413:             return false;
414:         }
415: 
416:         return Hash::get($_SESSION, $name) !== null;
417:     }
418: 
419:     /**
420:      * Returns given session variable, or all of them, if no parameters given.
421:      *
422:      * @param string|null $name The name of the session variable (or a path as sent to Hash.extract)
423:      * @return string|array|null The value of the session variable, null if session not available,
424:      *   session not started, or provided name not found in the session.
425:      */
426:     public function read($name = null)
427:     {
428:         if ($this->_hasSession() && !$this->started()) {
429:             $this->start();
430:         }
431: 
432:         if (!isset($_SESSION)) {
433:             return null;
434:         }
435: 
436:         if ($name === null) {
437:             return isset($_SESSION) ? $_SESSION : [];
438:         }
439: 
440:         return Hash::get($_SESSION, $name);
441:     }
442: 
443:     /**
444:      * Reads and deletes a variable from session.
445:      *
446:      * @param string $name The key to read and remove (or a path as sent to Hash.extract).
447:      * @return mixed The value of the session variable, null if session not available,
448:      *   session not started, or provided name not found in the session.
449:      */
450:     public function consume($name)
451:     {
452:         if (empty($name)) {
453:             return null;
454:         }
455:         $value = $this->read($name);
456:         if ($value !== null) {
457:             $this->_overwrite($_SESSION, Hash::remove($_SESSION, $name));
458:         }
459: 
460:         return $value;
461:     }
462: 
463:     /**
464:      * Writes value to given session variable name.
465:      *
466:      * @param string|array $name Name of variable
467:      * @param mixed $value Value to write
468:      * @return void
469:      */
470:     public function write($name, $value = null)
471:     {
472:         if (!$this->started()) {
473:             $this->start();
474:         }
475: 
476:         $write = $name;
477:         if (!is_array($name)) {
478:             $write = [$name => $value];
479:         }
480: 
481:         $data = isset($_SESSION) ? $_SESSION : [];
482:         foreach ($write as $key => $val) {
483:             $data = Hash::insert($data, $key, $val);
484:         }
485: 
486:         $this->_overwrite($_SESSION, $data);
487:     }
488: 
489:     /**
490:      * Returns the session id.
491:      * Calling this method will not auto start the session. You might have to manually
492:      * assert a started session.
493:      *
494:      * Passing an id into it, you can also replace the session id if the session
495:      * has not already been started.
496:      * Note that depending on the session handler, not all characters are allowed
497:      * within the session id. For example, the file session handler only allows
498:      * characters in the range a-z A-Z 0-9 , (comma) and - (minus).
499:      *
500:      * @param string|null $id Id to replace the current session id
501:      * @return string Session id
502:      */
503:     public function id($id = null)
504:     {
505:         if ($id !== null && !headers_sent()) {
506:             session_id($id);
507:         }
508: 
509:         return session_id();
510:     }
511: 
512:     /**
513:      * Removes a variable from session.
514:      *
515:      * @param string $name Session variable to remove
516:      * @return void
517:      */
518:     public function delete($name)
519:     {
520:         if ($this->check($name)) {
521:             $this->_overwrite($_SESSION, Hash::remove($_SESSION, $name));
522:         }
523:     }
524: 
525:     /**
526:      * Used to write new data to _SESSION, since PHP doesn't like us setting the _SESSION var itself.
527:      *
528:      * @param array $old Set of old variables => values
529:      * @param array $new New set of variable => value
530:      * @return void
531:      */
532:     protected function _overwrite(&$old, $new)
533:     {
534:         if (!empty($old)) {
535:             foreach ($old as $key => $var) {
536:                 if (!isset($new[$key])) {
537:                     unset($old[$key]);
538:                 }
539:             }
540:         }
541:         foreach ($new as $key => $var) {
542:             $old[$key] = $var;
543:         }
544:     }
545: 
546:     /**
547:      * Helper method to destroy invalid sessions.
548:      *
549:      * @return void
550:      */
551:     public function destroy()
552:     {
553:         if ($this->_hasSession() && !$this->started()) {
554:             $this->start();
555:         }
556: 
557:         if (!$this->_isCLI && session_status() === \PHP_SESSION_ACTIVE) {
558:             session_destroy();
559:         }
560: 
561:         $_SESSION = [];
562:         $this->_started = false;
563:     }
564: 
565:     /**
566:      * Clears the session.
567:      *
568:      * Optionally it also clears the session id and renews the session.
569:      *
570:      * @param bool $renew If session should be renewed, as well. Defaults to false.
571:      * @return void
572:      */
573:     public function clear($renew = false)
574:     {
575:         $_SESSION = [];
576:         if ($renew) {
577:             $this->renew();
578:         }
579:     }
580: 
581:     /**
582:      * Returns whether a session exists
583:      *
584:      * @return bool
585:      */
586:     protected function _hasSession()
587:     {
588:         return !ini_get('session.use_cookies')
589:             || isset($_COOKIE[session_name()])
590:             || $this->_isCLI
591:             || (ini_get('session.use_trans_sid') && isset($_GET[session_name()]));
592:     }
593: 
594:     /**
595:      * Restarts this session.
596:      *
597:      * @return void
598:      */
599:     public function renew()
600:     {
601:         if (!$this->_hasSession() || $this->_isCLI) {
602:             return;
603:         }
604: 
605:         $this->start();
606:         $params = session_get_cookie_params();
607:         setcookie(
608:             session_name(),
609:             '',
610:             time() - 42000,
611:             $params['path'],
612:             $params['domain'],
613:             $params['secure'],
614:             $params['httponly']
615:         );
616: 
617:         if (session_id()) {
618:             session_regenerate_id(true);
619:         }
620:     }
621: 
622:     /**
623:      * Returns true if the session is no longer valid because the last time it was
624:      * accessed was after the configured timeout.
625:      *
626:      * @return bool
627:      */
628:     protected function _timedOut()
629:     {
630:         $time = $this->read('Config.time');
631:         $result = false;
632: 
633:         $checkTime = $time !== null && $this->_lifetime > 0;
634:         if ($checkTime && (time() - (int)$time > $this->_lifetime)) {
635:             $result = true;
636:         }
637: 
638:         $this->write('Config.time', time());
639: 
640:         return $result;
641:     }
642: }
643: 
Follow @CakePHP
#IRC
OpenHub
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Logos & Trademarks
  • Community
  • Team
  • Issues (Github)
  • YouTube Channel
  • Get Involved
  • Bakery
  • Featured Resources
  • Newsletter
  • Certification
  • My CakePHP
  • CakeFest
  • Facebook
  • Twitter
  • Help & Support
  • Forum
  • Stack Overflow
  • IRC
  • Slack
  • Paid Support

Generated using CakePHP API Docs