Skip to content

Instantly share code, notes, and snippets.

@trk
Created February 18, 2021 12:17
Show Gist options
  • Save trk/934aa6a2c0cf0a9d30f6c9c12057df0f to your computer and use it in GitHub Desktop.
Save trk/934aa6a2c0cf0a9d30f6c9c12057df0f to your computer and use it in GitHub Desktop.
PHP FileFinder
<?php
class FileFinder
{
/**
* Glob files with braces support.
*
* @param string $pattern
* @param int $flags
*
* @return array
*
* @example
* FileFinder::glob('/path/{*.ext,*.php'});
* // => ['/path/file.ext', '/path/file.php']
*/
public static function glob(string $pattern, int $flags = 0): array
{
if (defined('GLOB_BRACE') && !static::startsWith($pattern, '{')) {
return glob($pattern, $flags | GLOB_BRACE | GLOB_NOSORT);
}
$files = [];
foreach (static::expandBraces($pattern) as $file) {
$files = array_merge($files, glob($file, $flags | GLOB_NOSORT) ?: []);
}
return $files;
}
/**
* Checks if string starts with a given substring.
*
* @param string $haystack
* @param string|array $needles
*
* @return bool
*
* @example
* FileFinder::startsWith('jason', 'jas');
* // => true
*/
public static function startsWith(string $haystack, $needles): bool
{
foreach ((array) $needles as $needle) {
if ($needle !== '' && (string) $needle === substr($haystack, 0, strlen($needle))) {
return true;
}
}
return false;
}
/**
* Expand a glob braces to array.
*
* @param string $pattern
*
* @return array
*
* @example
* FileFinder::expandBraces('foo/{2,3}/bar');
* // => ['foo/2/bar', 'foo/3/bar']
*/
public static function expandBraces(string $pattern): array
{
$braces = [];
$expanded = [];
$callback = function ($matches) use (&$braces) {
$index = '{' . count($braces) . '}';
$braces[$index] = $matches[0];
return $index;
};
if (preg_match($regex = '/{((?:[^{}]+|(?R))*)}/', $pattern, $matches, PREG_OFFSET_CAPTURE)) {
list($matches, $replaces) = $matches;
foreach (explode(',', preg_replace_callback($regex, $callback, $replaces[0])) as $replace) {
$expand = substr_replace($pattern, strtr($replace, $braces), $matches[1], strlen($matches[0]));
$expanded = array_merge($expanded, static::expandBraces($expand));
}
}
return $expanded ?: [$pattern];
}
}
@trk
Copy link
Author

trk commented Feb 18, 2021

Example usages

<?php

$path = join(',', array_filter([
    'path/to/dir',
    'path/to/another/dir/*'
]));

$locale = 'en';

$files = FileFinder::glob('{' . $path . '}/translations/' . $locale . '.php');

echo '<pre>' . print_r($files, true) . '</pre>';
<?php

$path = join(',', array_filter([
    'path/to/theme',
    'path/to/modules/*'
]));

$locale = 'en';

$files = FileFinder::glob('{' . $path . '}/translations/' . $locale . '.php');

echo '<pre>' . print_r($files, true) . '</pre>';
<?php

$files = FileFinder::glob('path/to/dir/*/*.json');

echo '<pre>' . print_r($files, true) . '</pre>';
<?php

$files = FileFinder::glob('my/path/{*.json,*.php}');

echo '<pre>' . print_r($files, true) . '</pre>';

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment