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

  1. Remove the unsupported section when the test still makes sense without it (for example drop --EXPECTHEADERS-- and keep --EXPECT--).
  2. 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.
  3. 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

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


AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23). Data as JSON: /api/errors/7c599024c0d321f9. Report an issue: GitHub.