PHP – How to find pathnames matching a pattern
First published on Ka of Isis 140420
Note: As github.io
(where this website lives) does not support PHP, the results shown in this article, are simulations.
According to the PHP manual, the glob()
function searches for all the pathnames matching a pattern and returns an array containing the matched files/directories, an empty array if no file matched, or false
on error. As an example, the following code will search for – and build an array of – text files in a given directory and display file names and their corresponding file sizes concatenated on separate lines:
foreach (glob("*.txt") as $filename) {
echo "$filename (" . filesize($filename) . " bytes)<br>";
}
Testing this live with three plain text files stored in the same directory as this article is stored, the result is:
file-1.txt (136 bytes)
file-2.txt (262 bytes)
file-3.txt (1668 bytes)
On some systems, however, it is impossible to distinguish between an empty match and an error. If no matching files are found, either nothing will be displayed or a message will be generated. In a comment to the PHP manual, an anonymous user states that the glob
function result will only be an array if it finds some files, and the foreach
statement requires its argument to be an array. By checking for the possibility that the result of the glob
function may not be an array, the warning can be eliminated.
He/she suggests a modified script:
$matches = glob("*.txt");
if (is_array ($matches)) {
foreach ($matches as $filename) {
echo "$filename (" . filesize($filename) . " bytes)<br>";
}
}
Applying the same test as above, an ideal result is (once more):
file-1.txt (136 bytes)
file-2.txt (262 bytes)
file-3.txt (1668 bytes)
So, how many matching files are there?
$matches = glob("*.txt"); // Assuming the same directory. Otherwise: ("/sub1/sub2/sub3/*.txt")
if (is_array ($matches)) {
echo "There are " . count($matches) . " plain text files in the directory";
} else {
echo 0; // Note that this does not explain possible error messages
}
The script above should echo the number of matching files in the directory:
There are 3 plain text files in the directory
Now, pick a random text file from an array of matching files and display the first 12 characters
$matches = glob("*.txt");
if (is_array ($matches)) {
$rndm = rand(1, count($matches));
$filename = "file-" . $rndm . ".txt";
$handle = fopen($filename, "r");
$text = fread($handle, 12); // 12 bytes equals 12 characters. Note that we assume here that the file is at least that long
fclose($handle);
echo "The randomly selected file is " . $filename . " and the initial text is: " . $text . "…";
}
The randomly selected file is file-3.txt and the initial text is: At vero eos …
Note: This example does not check whether the file is at least 12 characters (bytes) long.
Finally, pick a random text file from an array of matching files and display the whole text
1st Approach
$matches = glob("*.txt");
if (is_array ($matches)) {
$rndm = rand(1, count($matches));
$filename = "file-" . $rndm . ".txt";
$handle = fopen($filename, "r");
$text = fread($handle, filesize($filename)); // This returns ALL of the text if bytes are not specified
fclose($handle);
echo "The randomly selected file is " . $filename . " and the contents are as follows: " . $text;
}
The randomly selected file is file-1.txt and the contents are as follows: Lorem ipsum dolor sit amet, consectetur adipscing elit, sed diam nonnumy tempor incidunt ut labore et dolore magna aliquam erat volupat.
2nd Approach
When the goal is to get the complete contents of a file into a string, file_get_contents()
has a better performance than the 1st approach:
$matches = glob("*.txt");
if (is_array ($matches)) {
$rndm = rand(1, count($matches));
$filename = "file-" . $rndm . ".txt";
$text = file_get_contents($filename);
echo "The randomly selected file is " . $filename . " and the contents are as follows: " . $text;
}
The randomly selected file is file-1.txt and the contents are as follows: Lorem ipsum dolor sit amet, consectetur adipscing elit, sed diam nonnumy tempor incidunt ut labore et dolore magna aliquam erat volupat.