Verzeichnisstruktur phpBB-3.1.0
- Veröffentlicht
- 27.10.2014
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
NativeSessionStorage.php
001 <?php
002
003 /*
004 * This file is part of the Symfony package.
005 *
006 * (c) Fabien Potencier <fabien@symfony.com>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace Symfony\Component\HttpFoundation\Session\Storage;
013
014 use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
015 use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
016 use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
017 use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
018 use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
019
020 /**
021 * This provides a base class for session attribute storage.
022 *
023 * @author Drak <drak@zikula.org>
024 */
025 class NativeSessionStorage implements SessionStorageInterface
026 {
027 /**
028 * Array of SessionBagInterface
029 *
030 * @var SessionBagInterface[]
031 */
032 protected $bags;
033
034 /**
035 * @var bool
036 */
037 protected $started = false;
038
039 /**
040 * @var bool
041 */
042 protected $closed = false;
043
044 /**
045 * @var AbstractProxy
046 */
047 protected $saveHandler;
048
049 /**
050 * @var MetadataBag
051 */
052 protected $metadataBag;
053
054 /**
055 * Constructor.
056 *
057 * Depending on how you want the storage driver to behave you probably
058 * want to override this constructor entirely.
059 *
060 * List of options for $options array with their defaults.
061 * @see http://php.net/session.configuration for options
062 * but we omit 'session.' from the beginning of the keys for convenience.
063 *
064 * ("auto_start", is not supported as it tells PHP to start a session before
065 * PHP starts to execute user-land code. Setting during runtime has no effect).
066 *
067 * cache_limiter, "nocache" (use "0" to prevent headers from being sent entirely).
068 * cookie_domain, ""
069 * cookie_httponly, ""
070 * cookie_lifetime, "0"
071 * cookie_path, "/"
072 * cookie_secure, ""
073 * entropy_file, ""
074 * entropy_length, "0"
075 * gc_divisor, "100"
076 * gc_maxlifetime, "1440"
077 * gc_probability, "1"
078 * hash_bits_per_character, "4"
079 * hash_function, "0"
080 * name, "PHPSESSID"
081 * referer_check, ""
082 * serialize_handler, "php"
083 * use_cookies, "1"
084 * use_only_cookies, "1"
085 * use_trans_sid, "0"
086 * upload_progress.enabled, "1"
087 * upload_progress.cleanup, "1"
088 * upload_progress.prefix, "upload_progress_"
089 * upload_progress.name, "PHP_SESSION_UPLOAD_PROGRESS"
090 * upload_progress.freq, "1%"
091 * upload_progress.min-freq, "1"
092 * url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset="
093 *
094 * @param array $options Session configuration options.
095 * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler
096 * @param MetadataBag $metaBag MetadataBag.
097 */
098 public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null)
099 {
100 session_cache_limiter(''); // disable by default because it's managed by HeaderBag (if used)
101 ini_set('session.use_cookies', 1);
102
103 if (version_compare(phpversion(), '5.4.0', '>=')) {
104 session_register_shutdown();
105 } else {
106 register_shutdown_function('session_write_close');
107 }
108
109 $this->setMetadataBag($metaBag);
110 $this->setOptions($options);
111 $this->setSaveHandler($handler);
112 }
113
114 /**
115 * Gets the save handler instance.
116 *
117 * @return AbstractProxy
118 */
119 public function getSaveHandler()
120 {
121 return $this->saveHandler;
122 }
123
124 /**
125 * {@inheritdoc}
126 */
127 public function start()
128 {
129 if ($this->started && !$this->closed) {
130 return true;
131 }
132
133 if (version_compare(phpversion(), '5.4.0', '>=') && \PHP_SESSION_ACTIVE === session_status()) {
134 throw new \RuntimeException('Failed to start the session: already started by PHP.');
135 }
136
137 if (version_compare(phpversion(), '5.4.0', '<') && isset($_SESSION) && session_id()) {
138 // not 100% fool-proof, but is the most reliable way to determine if a session is active in PHP 5.3
139 throw new \RuntimeException('Failed to start the session: already started by PHP ($_SESSION is set).');
140 }
141
142 if (ini_get('session.use_cookies') && headers_sent($file, $line)) {
143 throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line));
144 }
145
146 // ok to try and start the session
147 if (!session_start()) {
148 throw new \RuntimeException('Failed to start the session');
149 }
150
151 $this->loadSession();
152 if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
153 // This condition matches only PHP 5.3 with internal save handlers
154 $this->saveHandler->setActive(true);
155 }
156
157 return true;
158 }
159
160 /**
161 * {@inheritdoc}
162 */
163 public function getId()
164 {
165 if (!$this->started && !$this->closed) {
166 return ''; // returning empty is consistent with session_id() behaviour
167 }
168
169 return $this->saveHandler->getId();
170 }
171
172 /**
173 * {@inheritdoc}
174 */
175 public function setId($id)
176 {
177 $this->saveHandler->setId($id);
178 }
179
180 /**
181 * {@inheritdoc}
182 */
183 public function getName()
184 {
185 return $this->saveHandler->getName();
186 }
187
188 /**
189 * {@inheritdoc}
190 */
191 public function setName($name)
192 {
193 $this->saveHandler->setName($name);
194 }
195
196 /**
197 * {@inheritdoc}
198 */
199 public function regenerate($destroy = false, $lifetime = null)
200 {
201 if (null !== $lifetime) {
202 ini_set('session.cookie_lifetime', $lifetime);
203 }
204
205 if ($destroy) {
206 $this->metadataBag->stampNew();
207 }
208
209 $ret = session_regenerate_id($destroy);
210
211 // workaround for https://bugs.php.net/bug.php?id=61470 as suggested by David Grudl
212 if ('files' === $this->getSaveHandler()->getSaveHandlerName()) {
213 session_write_close();
214 if (isset($_SESSION)) {
215 $backup = $_SESSION;
216 session_start();
217 $_SESSION = $backup;
218 } else {
219 session_start();
220 }
221
222 $this->loadSession();
223 }
224
225 return $ret;
226 }
227
228 /**
229 * {@inheritdoc}
230 */
231 public function save()
232 {
233 session_write_close();
234
235 if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
236 // This condition matches only PHP 5.3 with internal save handlers
237 $this->saveHandler->setActive(false);
238 }
239
240 $this->closed = true;
241 $this->started = false;
242 }
243
244 /**
245 * {@inheritdoc}
246 */
247 public function clear()
248 {
249 // clear out the bags
250 foreach ($this->bags as $bag) {
251 $bag->clear();
252 }
253
254 // clear out the session
255 $_SESSION = array();
256
257 // reconnect the bags to the session
258 $this->loadSession();
259 }
260
261 /**
262 * {@inheritdoc}
263 */
264 public function registerBag(SessionBagInterface $bag)
265 {
266 $this->bags[$bag->getName()] = $bag;
267 }
268
269 /**
270 * {@inheritdoc}
271 */
272 public function getBag($name)
273 {
274 if (!isset($this->bags[$name])) {
275 throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
276 }
277
278 if ($this->saveHandler->isActive() && !$this->started) {
279 $this->loadSession();
280 } elseif (!$this->started) {
281 $this->start();
282 }
283
284 return $this->bags[$name];
285 }
286
287 /**
288 * Sets the MetadataBag.
289 *
290 * @param MetadataBag $metaBag
291 */
292 public function setMetadataBag(MetadataBag $metaBag = null)
293 {
294 if (null === $metaBag) {
295 $metaBag = new MetadataBag();
296 }
297
298 $this->metadataBag = $metaBag;
299 }
300
301 /**
302 * Gets the MetadataBag.
303 *
304 * @return MetadataBag
305 */
306 public function getMetadataBag()
307 {
308 return $this->metadataBag;
309 }
310
311 /**
312 * {@inheritdoc}
313 */
314 public function isStarted()
315 {
316 return $this->started;
317 }
318
319 /**
320 * Sets session.* ini variables.
321 *
322 * For convenience we omit 'session.' from the beginning of the keys.
323 * Explicitly ignores other ini keys.
324 *
325 * @param array $options Session ini directives array(key => value).
326 *
327 * @see http://php.net/session.configuration
328 */
329 public function setOptions(array $options)
330 {
331 $validOptions = array_flip(array(
332 'cache_limiter', 'cookie_domain', 'cookie_httponly',
333 'cookie_lifetime', 'cookie_path', 'cookie_secure',
334 'entropy_file', 'entropy_length', 'gc_divisor',
335 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character',
336 'hash_function', 'name', 'referer_check',
337 'serialize_handler', 'use_cookies',
338 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
339 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
340 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags',
341 ));
342
343 foreach ($options as $key => $value) {
344 if (isset($validOptions[$key])) {
345 ini_set('session.'.$key, $value);
346 }
347 }
348 }
349
350 /**
351 * Registers session save handler as a PHP session handler.
352 *
353 * To use internal PHP session save handlers, override this method using ini_set with
354 * session.save_handler and session.save_path e.g.
355 *
356 * ini_set('session.save_handler', 'files');
357 * ini_set('session.save_path', /tmp');
358 *
359 * or pass in a NativeSessionHandler instance which configures session.save_handler in the
360 * constructor, for a template see NativeFileSessionHandler or use handlers in
361 * composer package drak/native-session
362 *
363 * @see http://php.net/session-set-save-handler
364 * @see http://php.net/sessionhandlerinterface
365 * @see http://php.net/sessionhandler
366 * @see http://github.com/drak/NativeSession
367 *
368 * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $saveHandler
369 *
370 * @throws \InvalidArgumentException
371 */
372 public function setSaveHandler($saveHandler = null)
373 {
374 if (!$saveHandler instanceof AbstractProxy &&
375 !$saveHandler instanceof NativeSessionHandler &&
376 !$saveHandler instanceof \SessionHandlerInterface &&
377 null !== $saveHandler) {
378 throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \SessionHandlerInterface; or be null.');
379 }
380
381 // Wrap $saveHandler in proxy and prevent double wrapping of proxy
382 if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
383 $saveHandler = new SessionHandlerProxy($saveHandler);
384 } elseif (!$saveHandler instanceof AbstractProxy) {
385 $saveHandler = version_compare(phpversion(), '5.4.0', '>=') ?
386 new SessionHandlerProxy(new \SessionHandler()) : new NativeProxy();
387 }
388 $this->saveHandler = $saveHandler;
389
390 if ($this->saveHandler instanceof \SessionHandlerInterface) {
391 if (version_compare(phpversion(), '5.4.0', '>=')) {
392 session_set_save_handler($this->saveHandler, false);
393 } else {
394 session_set_save_handler(
395 array($this->saveHandler, 'open'),
396 array($this->saveHandler, 'close'),
397 array($this->saveHandler, 'read'),
398 array($this->saveHandler, 'write'),
399 array($this->saveHandler, 'destroy'),
400 array($this->saveHandler, 'gc')
401 );
402 }
403 }
404 }
405
406 /**
407 * Load the session with attributes.
408 *
409 * After starting the session, PHP retrieves the session from whatever handlers
410 * are set to (either PHP's internal, or a custom save handler set with session_set_save_handler()).
411 * PHP takes the return value from the read() handler, unserializes it
412 * and populates $_SESSION with the result automatically.
413 *
414 * @param array|null $session
415 */
416 protected function loadSession(array &$session = null)
417 {
418 if (null === $session) {
419 $session = &$_SESSION;
420 }
421
422 $bags = array_merge($this->bags, array($this->metadataBag));
423
424 foreach ($bags as $bag) {
425 $key = $bag->getStorageKey();
426 $session[$key] = isset($session[$key]) ? $session[$key] : array();
427 $bag->initialize($session[$key]);
428 }
429
430 $this->started = true;
431 $this->closed = false;
432 }
433 }
434