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.7 Red Velvet API

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