100 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			100 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			PHP
		
	
	
| 
								 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * This file is part of the Symfony package.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * (c) Fabien Potencier <fabien@symfony.com>
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * For the full copyright and license information, please view the LICENSE
							 | 
						||
| 
								 | 
							
								 * file that was distributed with this source code.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace Symfony\Component\Cache\Marshaller;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								use Symfony\Component\Cache\Exception\CacheException;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Serializes/unserializes values using igbinary_serialize() if available, serialize() otherwise.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @author Nicolas Grekas <p@tchwork.com>
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class DefaultMarshaller implements MarshallerInterface
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    private $useIgbinarySerialize = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function __construct(bool $useIgbinarySerialize = null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (null === $useIgbinarySerialize) {
							 | 
						||
| 
								 | 
							
								            $useIgbinarySerialize = \extension_loaded('igbinary') && (\PHP_VERSION_ID < 70400 || version_compare('3.1.6', phpversion('igbinary'), '<='));
							 | 
						||
| 
								 | 
							
								        } elseif ($useIgbinarySerialize && (!\extension_loaded('igbinary') || (\PHP_VERSION_ID >= 70400 && version_compare('3.1.6', phpversion('igbinary'), '>')))) {
							 | 
						||
| 
								 | 
							
								            throw new CacheException(\extension_loaded('igbinary') && \PHP_VERSION_ID >= 70400 ? 'Please upgrade the "igbinary" PHP extension to v3.1.6 or higher.' : 'The "igbinary" PHP extension is not loaded.');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $this->useIgbinarySerialize = $useIgbinarySerialize;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * {@inheritdoc}
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function marshall(array $values, ?array &$failed): array
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $serialized = $failed = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        foreach ($values as $id => $value) {
							 | 
						||
| 
								 | 
							
								            try {
							 | 
						||
| 
								 | 
							
								                if ($this->useIgbinarySerialize) {
							 | 
						||
| 
								 | 
							
								                    $serialized[$id] = igbinary_serialize($value);
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    $serialized[$id] = serialize($value);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            } catch (\Exception $e) {
							 | 
						||
| 
								 | 
							
								                $failed[] = $id;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $serialized;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * {@inheritdoc}
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function unmarshall(string $value)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ('b:0;' === $value) {
							 | 
						||
| 
								 | 
							
								            return false;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if ('N;' === $value) {
							 | 
						||
| 
								 | 
							
								            return null;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        static $igbinaryNull;
							 | 
						||
| 
								 | 
							
								        if ($value === ($igbinaryNull ?? $igbinaryNull = \extension_loaded('igbinary') ? igbinary_serialize(null) : false)) {
							 | 
						||
| 
								 | 
							
								            return null;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
							 | 
						||
| 
								 | 
							
								        try {
							 | 
						||
| 
								 | 
							
								            if (':' === ($value[1] ?? ':')) {
							 | 
						||
| 
								 | 
							
								                if (false !== $value = unserialize($value)) {
							 | 
						||
| 
								 | 
							
								                    return $value;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            } elseif (false === $igbinaryNull) {
							 | 
						||
| 
								 | 
							
								                throw new \RuntimeException('Failed to unserialize values, did you forget to install the "igbinary" extension?');
							 | 
						||
| 
								 | 
							
								            } elseif (null !== $value = igbinary_unserialize($value)) {
							 | 
						||
| 
								 | 
							
								                return $value;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            throw new \DomainException(error_get_last() ? error_get_last()['message'] : 'Failed to unserialize values.');
							 | 
						||
| 
								 | 
							
								        } catch (\Error $e) {
							 | 
						||
| 
								 | 
							
								            throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine());
							 | 
						||
| 
								 | 
							
								        } finally {
							 | 
						||
| 
								 | 
							
								            ini_set('unserialize_callback_func', $unserializeCallbackHandler);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @internal
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static function handleUnserializeCallback($class)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        throw new \DomainException('Class not found: '.$class);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |