Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions ext/standard/VmDir.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,36 @@ public static function isValidHandle(int $handle): bool
return null !== $slot && isset(self::$handles[$slot]);
}

/**
* scandir() for VM — opendir/readdir/closedir stack, no host \\scandir() (#5048, php-src dir.c).
*
* @return list<string>|false
*/
public static function scandir(string $path, int $sortingOrder = \SCANDIR_SORT_ASCENDING)
{
$handle = self::opendir($path);
if (false === $handle) {
return false;
}
$names = [];
while (true) {
$entry = self::readdir($handle);
if (false === $entry) {
break;
}
$names[] = $entry;
}
self::closedir($handle);
if (\SCANDIR_SORT_NONE !== $sortingOrder) {
\sort($names, \SORT_STRING);
if (\SCANDIR_SORT_DESCENDING === $sortingOrder) {
$names = \array_reverse($names, false);
}
}

return $names;
}

/** @return int|null */
private static function slot(int $handle): ?int
{
Expand Down
4 changes: 2 additions & 2 deletions ext/standard/scandir.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use PHPCompiler\VM\Variable;
use PHPLLVM\Value;

/** scandir() — list directory entries (VM via host PHP; JIT defers to VM). */
/** scandir() — list directory entries (VM via VmDir; JIT via __phpc_scandir_vec). */
final class scandir extends Internal
{
public function execute(Frame $frame): void
Expand All @@ -37,7 +37,7 @@ public function execute(Frame $frame): void
return;
}

$result = \scandir($pathVar->toString(), $sortingOrder);
$result = VmDir::scandir($pathVar->toString(), $sortingOrder);
if (false === $result) {
$frame->returnVar->bool(false);

Expand Down
17 changes: 17 additions & 0 deletions test/unit/VmFsGlobTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,23 @@ public function testGlobBuiltinDoesNotCallHostGlob(): void
$this->assertStringContainsString('VmFsGlob::glob', $source);
}

public function testScandirBuiltinDoesNotCallHostScandir(): void
{
$source = (string) file_get_contents(self::$root.'/ext/standard/scandir.php');
$this->assertStringNotContainsString('\\scandir(', $source);
$this->assertStringContainsString('VmDir::scandir', $source);
}

public function testVmDirScandirMatchesFixture(): void
{
$dir = self::$root.'/test/compliance/cases/stdlib/glob_scandir_fixture';
$entries = \PHPCompiler\ext\standard\VmDir::scandir($dir);
$this->assertIsArray($entries);
$this->assertTrue(\in_array('a.php', $entries, true));
$this->assertTrue(\in_array('readme.txt', $entries, true));
$this->assertFalse(\PHPCompiler\ext\standard\VmDir::scandir('/nonexistent/path/for/php-compiler'));
}

public function testVmFsGlobMatchesFixturePhpFiles(): void
{
$dir = self::$root.'/test/compliance/cases/stdlib/glob_scandir_fixture';
Expand Down