Skip to content

Instantly share code, notes, and snippets.

@WinterSilence
Last active October 5, 2021 06:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WinterSilence/51207bffadb8b19c3b4fc6c14c616800 to your computer and use it in GitHub Desktop.
Save WinterSilence/51207bffadb8b19c3b4fc6c14c616800 to your computer and use it in GitHub Desktop.
glob:// stream wrapper
<?php
/**
* Stream wrapper `glob://` to use rich syntax in `GlobIterator`.
*/
class GlobStreamWrapper
{
/**
* @var string
*/
protected const PROTOCOL = 'glob';
/**
* @var Generator|null
*/
protected ?Generator $generator;
public static function register(): bool
{
return \stream_wrapper_unregister(self::PROTOCOL) && \stream_wrapper_register(self::PROTOCOL, self::class);
}
public static function unregister(): bool
{
return \stream_wrapper_unregister(self::PROTOCOL) && \stream_wrapper_restore(self::PROTOCOL);
}
protected function createGenerator(array $paths): \Generator
{
return yield from $paths;
}
public function openDir(string $pattern, int $options = 0): bool
{
$pattern = \str_replace(self::PROTOCOL . '://', '', $pattern);
$pattern = \str_replace(['\\', '/'], \DIRECTORY_SEPARATOR, $pattern);
$options |= \GLOB_BRACE | \GLOB_NOSORT;
$paths = \glob($pattern, $options) ?: [];
$this->generator = $this->createGenerator($paths);
return $this->generator->valid();
}
/**
* @return string|false
*/
public function readDir()
{
if ($this->generator !== null && $this->generator->valid()) {
$path = $this->generator->current();
$this->generator->next();
return $path;
}
return false;
}
public function rewindDir(): bool
{
if ($this->generator === null) {
return false;
}
$this->generator->rewind();
return $this->generator->valid();
}
public function closeDir(): bool
{
$this->generator = null;
return true;
}
/**
* @return mixed
* @throws \BadMethodCallException Call undefined method
*/
public function __call(string $method, array $arguments)
{
$aliases = [
'dir_opendir' => 'openDir',
'dir_readdir' => 'readDir',
'dir_rewinddir' => 'rewindDir',
'dir_closedir' => 'closeDir',
];
if (!isset($aliases[$method])) {
throw new \BadMethodCallException('Call undefined method: ' . $method);
}
return $this->{$aliases[$method]}(...$arguments);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment