sebastianbergmann/phpunit · error · UnsupportedPhptSectionException
PHPUnit does not support PHPT --%s-- sections
Error message
PHPUnit does not support PHPT --%s-- sections
What it means
After section parsing, parse() loops over the UNSUPPORTED_SECTIONS constant (CGI, COOKIE, DEFLATE_POST, EXPECTHEADERS, EXTENSIONS, GET, GZIP_POST, HEADERS, PHPDBG, POST, POST_RAW, PUT, REDIRECTTEST, REQUEST) and throws UnsupportedPhptSectionException('PHPUnit does not support PHPT --%s-- sections') when one is present. These are real php run-tests.php sections that PHPUnit deliberately rejects, mostly because they require a CGI/web harness PHPUnit does not provide.
Source
Thrown at src/Runner/Phpt/Parser.php:170
$sections[$section] .= $line;
}
$codeSection = $this->ensureExactlyOneSectionOf($sections, self::FILE_SECTIONS);
$this->ensureExactlyOneSectionOf($sections, self::EXPECTATION_SECTIONS);
if (isset($sections['FILEEOF'])) {
$sections['FILE'] = rtrim($sections['FILEEOF'], "\r\n");
unset($sections['FILEEOF']);
}
$this->parseExternal($phptFile, $sections);
foreach (self::UNSUPPORTED_SECTIONS as $unsupportedSection) {
if (isset($sections[$unsupportedSection])) {
throw new UnsupportedPhptSectionException($unsupportedSection);
}
}
$this->ensureCodeIsNotEmpty($sections, $codeSection);
return $sections;
}
/**
* @return array<non-empty-string, string>
*/
public function parseEnvSection(string $content): array
{
$env = [];
foreach (explode("\n", trim($content)) as $e) {
$e = explode('=', trim($e), 2);
View on GitHub (pinned to f123cdb2a2)
Solutions
- Remove the unsupported section when the test still makes sense without it (for example drop --EXPECTHEADERS-- and keep --EXPECT--).
- Rewrite the test as a normal PHPUnit TestCase (e.g. using an HTTP client against a running server) when it genuinely depends on request data.
- Leave such tests to php run-tests.php or a harness that supports CGI sections.
Example fix
-- before
--POST--
a=1
--FILE--
<?php echo $_POST['a'];
--EXPECT--
1
-- after (plain PHPUnit test)
public function testPostA(): void
{
$response = $this->client->post('/', ['a' => '1']);
self::assertSame('1', (string) $response->getBody());
} Defensive patterns
Strategy: validation
Validate before calling
function assertNoUnsupportedPhptSections(string $phptFile): void
{
$unsupported = ['CGI','COOKIE','DEFLATE_POST','EXPECTHEADERS','EXTENSIONS','GET',
'GZIP_POST','HEADERS','PHPDBG','POST','POST_RAW','PUT','REDIRECTTEST','REQUEST'];
foreach (file($phptFile) as $line) {
if (preg_match('/^--([_A-Z]+)--/', $line, $m) === 1 && in_array($m[1], $unsupported, true)) {
throw new RuntimeException('PHPUnit cannot run --' . $m[1] . '--; port the test to a TestCase');
}
}
} Try / catch
try {
$sections = (new \PHPUnit\Runner\Phpt\Parser())->parse($phptFile);
} catch (\PHPUnit\Runner\Phpt\UnsupportedPhptSectionException $e) {
// route this file to php run-tests.php or port it; do not retry as-is
} Prevention
- Before importing run-tests.php suites, filter out tests whose headers intersect the CGI/request section list.
- Keep web-request PHPT tests in a separate CI job driven by a harness that supports them.
When it happens
Trigger: Running a .phpt written for php run-tests.php that uses --POST--, --GET--, --COOKIE--, --EXPECTHEADERS--, --POST_RAW-- etc.; copying php-src or extension PHPT suites verbatim into a PHPUnit-driven test run.
Common situations: Porting php-src/PECL tests that exercise the CGI SAPI; reusing upstream PHPT corpora in CI based on PHPUnit; grabbing a run-tests test without checking PHPUnit's support matrix.
Related errors
- --%s-- is not a valid PHPT section
- --%s-- section occurs more than once
- PHPT file must not contain text before its first section (li
- Could not load --%s-- %s for PHPT file
- PHPT file must contain one of the sections --%s--
AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23).
Data as JSON: /api/errors/7c599024c0d321f9.
Report an issue: GitHub.