diff --git a/.travis.yml b/.travis.yml index 561157b13f..c60334e874 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,9 +25,10 @@ matrix: group: edge - php: 5.5 - php: 5.6 + - php: 7.0 - php: 7.1 env: deps=high - - php: 7.0 + - php: 7.2 env: deps=low fast_finish: true diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig index b89a788041..07ca81f506 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig @@ -50,10 +50,14 @@ {% endblock %} {% block checkbox_label -%} + {%- set label_attr = label_attr|merge({'for': id}) -%} + {{- block('checkbox_radio_label') -}} {%- endblock checkbox_label %} {% block radio_label -%} + {%- set label_attr = label_attr|merge({'for': id}) -%} + {{- block('checkbox_radio_label') -}} {%- endblock radio_label %} diff --git a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php index c258ad41a1..f6c678a918 100644 --- a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php +++ b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php @@ -45,6 +45,9 @@ class AppVariableTest extends TestCase $this->assertEquals('dev', $this->appVariable->getEnvironment()); } + /** + * @runInSeparateProcess + */ public function testGetSession() { $session = $this->getMockBuilder(Session::class)->disableOriginalConstructor()->getMock(); @@ -166,6 +169,9 @@ class AppVariableTest extends TestCase $this->assertEquals(array(), $this->appVariable->getFlashes()); } + /** + * @runInSeparateProcess + */ public function testGetFlashesWithNoSessionStarted() { $session = $this->getMockBuilder(Session::class)->disableOriginalConstructor()->getMock(); @@ -177,6 +183,9 @@ class AppVariableTest extends TestCase $this->assertEquals(array(), $this->appVariable->getFlashes()); } + /** + * @runInSeparateProcess + */ public function testGetFlashes() { $flashMessages = $this->setFlashMessages(); diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index bf4deb3f6e..e7e7e4889f 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -24,6 +24,7 @@ "symfony/asset": "~2.8|~3.0|~4.0", "symfony/finder": "~2.8|~3.0|~4.0", "symfony/form": "~3.4|~4.0", + "symfony/http-foundation": "^3.3.11|~4.0", "symfony/http-kernel": "~3.2|~4.0", "symfony/polyfill-intl-icu": "~1.0", "symfony/routing": "~2.8|~3.0|~4.0", diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php index 2fe2eb5c9a..e4f3f084d2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php @@ -55,7 +55,7 @@ class CacheClearCommandTest extends TestCase $finder = new Finder(); $metaFiles = $finder->files()->in($this->kernel->getCacheDir())->name('*.php.meta'); // simply check that cache is warmed up - $this->assertGreaterThanOrEqual(1, count($metaFiles)); + $this->assertNotEmpty($metaFiles); $configCacheFactory = new ConfigCacheFactory(true); foreach ($metaFiles as $file) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php index eff76f4f92..8d5a6e710d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php @@ -373,6 +373,9 @@ abstract class ControllerTraitTest extends TestCase $this->assertSame(302, $response->getStatusCode()); } + /** + * @runInSeparateProcess + */ public function testAddFlash() { $flashBag = new FlashBag(); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php index a1ecee6d0b..5f28d0648f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php @@ -2,7 +2,9 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Validation; -class Article implements NotExistingInterface -{ - public $category; +if (!function_exists('__phpunit_run_isolated_test')) { + class Article implements NotExistingInterface + { + public $category; + } } diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 18065e6782..a8cd62ab08 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -23,7 +23,7 @@ "symfony/dependency-injection": "~3.4|~4.0", "symfony/config": "~3.4|~4.0", "symfony/event-dispatcher": "^3.3.1|~4.0", - "symfony/http-foundation": "~3.3|~4.0", + "symfony/http-foundation": "^3.3.11|~4.0", "symfony/http-kernel": "~3.4|~4.0", "symfony/polyfill-mbstring": "~1.0", "symfony/filesystem": "~2.8|~3.0|~4.0", diff --git a/src/Symfony/Component/Config/Tests/Fixtures/BadParent.php b/src/Symfony/Component/Config/Tests/Fixtures/BadParent.php index 68d7296ed8..3f9720bb8a 100644 --- a/src/Symfony/Component/Config/Tests/Fixtures/BadParent.php +++ b/src/Symfony/Component/Config/Tests/Fixtures/BadParent.php @@ -2,6 +2,8 @@ namespace Symfony\Component\Config\Tests\Fixtures; -class BadParent extends MissingParent -{ +if (!function_exists('__phpunit_run_isolated_test')) { + class BadParent extends MissingParent + { + } } diff --git a/src/Symfony/Component/Console/Descriptor/TextDescriptor.php b/src/Symfony/Component/Console/Descriptor/TextDescriptor.php index ddb97b60e2..ffcc224a30 100644 --- a/src/Symfony/Component/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Component/Console/Descriptor/TextDescriptor.php @@ -143,7 +143,7 @@ class TextDescriptor extends Descriptor $this->writeText('Usage:', $options); foreach (array_merge(array($command->getSynopsis(true)), $command->getAliases(), $command->getUsages()) as $usage) { $this->writeText("\n"); - $this->writeText(' '.$usage, $options); + $this->writeText(' '.OutputFormatter::escape($usage), $options); } $this->writeText("\n"); diff --git a/src/Symfony/Component/Console/Tests/Fixtures/command_2.txt b/src/Symfony/Component/Console/Tests/Fixtures/command_2.txt index cad9cb45f2..2864c7bdc3 100644 --- a/src/Symfony/Component/Console/Tests/Fixtures/command_2.txt +++ b/src/Symfony/Component/Console/Tests/Fixtures/command_2.txt @@ -1,7 +1,7 @@ Usage: - descriptor:command2 [options] [--] - descriptor:command2 -o|--option_name - descriptor:command2 + descriptor:command2 [options] [--] \ + descriptor:command2 -o|--option_name \ + descriptor:command2 \ Arguments: argument_name diff --git a/src/Symfony/Component/Console/Tests/Fixtures/command_mbstring.txt b/src/Symfony/Component/Console/Tests/Fixtures/command_mbstring.txt index 969a065242..cde457dcab 100644 --- a/src/Symfony/Component/Console/Tests/Fixtures/command_mbstring.txt +++ b/src/Symfony/Component/Console/Tests/Fixtures/command_mbstring.txt @@ -1,7 +1,7 @@ Usage: - descriptor:åèä [options] [--] - descriptor:åèä -o|--option_name - descriptor:åèä + descriptor:åèä [options] [--] \ + descriptor:åèä -o|--option_name \ + descriptor:åèä \ Arguments: argument_åèä diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/Throwing.php b/src/Symfony/Component/Debug/Tests/Fixtures/Throwing.php index 21e0aba17d..d338ca9d57 100644 --- a/src/Symfony/Component/Debug/Tests/Fixtures/Throwing.php +++ b/src/Symfony/Component/Debug/Tests/Fixtures/Throwing.php @@ -1,3 +1,5 @@ markTestSkipped('To run this test, add "phar" to the "suhosin.executor.include.whitelist" settings in your php.ini file.'); } + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('HHVM makes this test conflict with those run in separate processes.'); + } require_once self::$fixturesPath.'/includes/ProjectWithXsdExtensionInPhar.phar'; diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php index ad8baeb7c9..fdb142f84e 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php @@ -116,6 +116,7 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface return; } + $position = 0; $formatter = $this->getNumberFormatter(); $groupSep = $formatter->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL); $decSep = $formatter->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL); @@ -129,18 +130,44 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface $value = str_replace(',', $decSep, $value); } + if (false !== strpos($value, $decSep)) { + $type = \NumberFormatter::TYPE_DOUBLE; + } else { + $type = \PHP_INT_SIZE === 8 ? \NumberFormatter::TYPE_INT64 : \NumberFormatter::TYPE_INT32; + } + // replace normal spaces so that the formatter can read them - $value = $formatter->parse(str_replace(' ', "\xc2\xa0", $value)); + $result = $formatter->parse(str_replace(' ', "\xc2\xa0", $value), $type, $position); if (intl_is_failure($formatter->getErrorCode())) { throw new TransformationFailedException($formatter->getErrorMessage()); } if (self::FRACTIONAL == $this->type) { - $value /= 100; + $result /= 100; } - return $value; + if (\function_exists('mb_detect_encoding') && false !== $encoding = mb_detect_encoding($value, null, true)) { + $length = mb_strlen($value, $encoding); + $remainder = mb_substr($value, $position, $length, $encoding); + } else { + $length = \strlen($value); + $remainder = substr($value, $position, $length); + } + + // After parsing, position holds the index of the character where the + // parsing stopped + if ($position < $length) { + // Check if there are unrecognized characters at the end of the + // number (excluding whitespace characters) + $remainder = trim($remainder, " \t\n\r\0\x0b\xc2\xa0"); + + if ('' !== $remainder) { + throw new TransformationFailedException(sprintf('The number contains unrecognized characters: "%s"', $remainder)); + } + } + + return $result; } /** diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php index 24cef424d1..3467e891c9 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php @@ -141,10 +141,10 @@ class PercentToLocalizedStringTransformerTest extends TestCase */ public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDot() { - // Since we test against "de_AT", we need the full implementation + // Since we test against "de_DE", we need the full implementation IntlTestHelper::requireFullIntl($this, '4.8.1.1'); - \Locale::setDefault('de_AT'); + \Locale::setDefault('de_DE'); $transformer = new PercentToLocalizedStringTransformer(1, 'integer'); @@ -236,4 +236,70 @@ class PercentToLocalizedStringTransformerTest extends TestCase $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5')); $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5')); } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformDisallowsLeadingExtraCharacters() + { + $transformer = new PercentToLocalizedStringTransformer(); + + $transformer->reverseTransform('foo123'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + * @expectedExceptionMessage The number contains unrecognized characters: "foo3" + */ + public function testReverseTransformDisallowsCenteredExtraCharacters() + { + $transformer = new PercentToLocalizedStringTransformer(); + + $transformer->reverseTransform('12foo3'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + * @expectedExceptionMessage The number contains unrecognized characters: "foo8" + * @requires extension mbstring + */ + public function testReverseTransformDisallowsCenteredExtraCharactersMultibyte() + { + // Since we test against other locales, we need the full implementation + IntlTestHelper::requireFullIntl($this, false); + + \Locale::setDefault('ru'); + + $transformer = new PercentToLocalizedStringTransformer(); + + $transformer->reverseTransform("12\xc2\xa0345,67foo8"); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + * @expectedExceptionMessage The number contains unrecognized characters: "foo" + */ + public function testReverseTransformDisallowsTrailingExtraCharacters() + { + $transformer = new PercentToLocalizedStringTransformer(); + + $transformer->reverseTransform('123foo'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + * @expectedExceptionMessage The number contains unrecognized characters: "foo" + * @requires extension mbstring + */ + public function testReverseTransformDisallowsTrailingExtraCharactersMultibyte() + { + // Since we test against other locales, we need the full implementation + IntlTestHelper::requireFullIntl($this, false); + + \Locale::setDefault('ru'); + + $transformer = new PercentToLocalizedStringTransformer(); + + $transformer->reverseTransform("12\xc2\xa0345,678foo"); + } } diff --git a/src/Symfony/Component/HttpFoundation/HeaderBag.php b/src/Symfony/Component/HttpFoundation/HeaderBag.php index e0b51ad125..e06713f39e 100644 --- a/src/Symfony/Component/HttpFoundation/HeaderBag.php +++ b/src/Symfony/Component/HttpFoundation/HeaderBag.php @@ -147,7 +147,7 @@ class HeaderBag implements \IteratorAggregate, \Countable } if ('cache-control' === $key) { - $this->cacheControl = $this->parseCacheControl($values[0]); + $this->cacheControl = $this->parseCacheControl(implode(', ', $this->headers[$key])); } } diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php index 48bef335ba..623d38721b 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -73,6 +73,7 @@ class NativeSessionStorage implements SessionStorageInterface * gc_probability, "1" * hash_bits_per_character, "4" * hash_function, "0" + * lazy_write, "1" * name, "PHPSESSID" * referer_check, "" * serialize_handler, "php" @@ -98,8 +99,11 @@ class NativeSessionStorage implements SessionStorageInterface */ public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null) { - session_cache_limiter(''); // disable by default because it's managed by HeaderBag (if used) - ini_set('session.use_cookies', 1); + $options += array( + // disable by default because it's managed by HeaderBag (if used) + 'cache_limiter' => '', + 'use_cookies' => 1, + ); session_register_shutdown(); @@ -187,6 +191,10 @@ class NativeSessionStorage implements SessionStorageInterface return false; } + if (headers_sent()) { + return false; + } + if (null !== $lifetime) { ini_set('session.cookie_lifetime', $lifetime); } @@ -324,12 +332,16 @@ class NativeSessionStorage implements SessionStorageInterface */ public function setOptions(array $options) { + if (headers_sent()) { + return; + } + $validOptions = array_flip(array( 'cache_limiter', 'cookie_domain', 'cookie_httponly', 'cookie_lifetime', 'cookie_path', 'cookie_secure', 'entropy_file', 'entropy_length', 'gc_divisor', 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', - 'hash_function', 'name', 'referer_check', + 'hash_function', 'lazy_write', 'name', 'referer_check', 'serialize_handler', 'use_strict_mode', 'use_cookies', 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', @@ -381,6 +393,10 @@ class NativeSessionStorage implements SessionStorageInterface ); } + if (headers_sent($file, $line)) { + throw new \RuntimeException(sprintf('Failed to set the session handler because headers have already been sent by "%s" at line %d.', $file, $line)); + } + // Wrap $saveHandler in proxy and prevent double wrapping of proxy if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { $saveHandler = new SessionHandlerProxy($saveHandler); diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php index 22df9481dc..7ed6ccc070 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php @@ -86,6 +86,17 @@ class ResponseHeaderBagTest extends TestCase $bag = new ResponseHeaderBag(); $bag->set('Last-Modified', 'abcde'); $this->assertEquals('private, must-revalidate', $bag->get('Cache-Control')); + + $bag = new ResponseHeaderBag(); + $bag->set('Cache-Control', array('public', 'must-revalidate')); + $this->assertCount(1, $bag->get('Cache-Control', null, false)); + $this->assertEquals('must-revalidate, public', $bag->get('Cache-Control')); + + $bag = new ResponseHeaderBag(); + $bag->set('Cache-Control', 'public'); + $bag->set('Cache-Control', 'must-revalidate', false); + $this->assertCount(1, $bag->get('Cache-Control', null, false)); + $this->assertEquals('must-revalidate, public', $bag->get('Cache-Control')); } public function testCacheControlClone() diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php index a47120f180..a9884c1c92 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php @@ -269,6 +269,9 @@ class PdoSessionHandlerTest extends TestCase $this->assertSame('', $data, 'Destroyed session returns empty string'); } + /** + * @runInSeparateProcess + */ public function testSessionGC() { $previousLifeTime = ini_set('session.gc_maxlifetime', 1000); diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php index 2ce32819e1..332393eead 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php @@ -38,8 +38,7 @@ class LocaleListenerTest extends TestCase public function testLocaleFromRequestAttribute() { $request = Request::create('/'); - session_name('foo'); - $request->cookies->set('foo', 'value'); + $request->cookies->set(session_name(), 'value'); $request->attributes->set('_locale', 'es'); $listener = new LocaleListener($this->requestStack, 'fr'); diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php index 8ada8e7dd8..124bd64d84 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php @@ -65,8 +65,7 @@ class TestSessionListenerTest extends TestCase { $this->sessionHasBeenStarted(); - $params = session_get_cookie_params(); - session_set_cookie_params(0, $params['path'], $params['domain'], $params['secure'], $params['httponly']); + @ini_set('session.cookie_lifetime', 0); $response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST); $cookies = $response->headers->getCookies(); diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index 888cd3f238..2d134e5b14 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -18,7 +18,7 @@ "require": { "php": "^5.5.9|>=7.0.8", "symfony/event-dispatcher": "~2.8|~3.0|~4.0", - "symfony/http-foundation": "~3.3|~4.0", + "symfony/http-foundation": "^3.3.11|~4.0", "symfony/debug": "~2.8|~3.0|~4.0", "psr/log": "~1.0" }, diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/validresource.php b/src/Symfony/Component/Routing/Tests/Fixtures/validresource.php index 482c80b29e..f59a234d65 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/validresource.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/validresource.php @@ -1,5 +1,8 @@ import('validpattern.php'); diff --git a/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php b/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php index 8347585a46..66197c95ac 100644 --- a/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php +++ b/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php @@ -29,14 +29,6 @@ class NativeSessionTokenStorageTest extends TestCase */ private $storage; - public static function setUpBeforeClass() - { - ini_set('session.save_handler', 'files'); - ini_set('session.save_path', sys_get_temp_dir()); - - parent::setUpBeforeClass(); - } - protected function setUp() { $_SESSION = array();