I have a simple PHP script with this snippet of code:
$files = scandir($dir);
print_r($files);
And noticed in my array i have:
[0] => .
[1] => ..
[2] => assets.php
[3] => loader.php
Is this a bug on my server or is it expected behavior, what are they? And if it's the latter is there any way to exclude them from the scan? As I wish to only get script files that I made from the directory and nothing else. Is there any way to exclude them from the scan?
No it isn't a bug.... . is the current directory, .. the parent directory
See the PHP Docs
The user-contributed notes show one way of excluding them:
$directory = '/path/to/my/directory';
$scanned_directory = array_diff(scandir($directory), array('..', '.'));
If you use other options besides scandir, such as SPL's DirectoryIterator, there's options to exclude them (such as combining it with a RegexIterator), or to test for them as you're iterating:
$iterator = new DirectoryIterator(dirname(__FILE__));
foreach ($iterator as $fileinfo) {
if (!$fileinfo->isDot()) {
echo $fileinfo->getFilename() . "\n";
}
}
Related
I have a script that scans a folder and put in an array the file names it contains.
Then I shuffle the array and display the file names.
Like this:
$count=0;
$ar=array();
$i=1;
$g=scandir('./images/');
foreach($g as $x)
{
if(is_dir($x))$ar[$x]=scandir($x);
else
{
$count++;
$ar[]=$x;
}
}
shuffle($ar);
while($i <= $count)
{
echo $ar[$i-1];
$i++;
}
?>
It works well but for some reason I get something like this:
fff.jpg
ccc.jpg
Array
nnn.jpg
ttt.jpg
sss.jpg
bbb.jpg
Array
eee.jpg
Of course, the order changes when I refresh the page because of the shuffle I did but among 200 filenames I always get these 2 "Array" somewhere in the list.
What could it be?
Thank you
Just to explain the part wherein it gives you the Array.
First off, scandir returns the following:
Returns an array of files and directories from the directory.
From that return values, it returned this (this is an example, for reference):
Array
(
[0] => . // current directory
[1] => .. // parent directory
[2] => imgo.jpg
[3] => logo.png
[4] => picture1.png
[5] => picture2.png
[6] => picture3.png
[7] => picture4.png
)
Those dots right there are actually folders. Right now in your code logic, when it hits/iterate this spot:
if(is_dir($x))$ar[$x]=scandir($x); // if its a directory
// invoke another set of scandir into this directory, then append it into the array
Thats why your resultant array has mixed strings, and that another extra/unneeded scandir array return values from ..
A dirty quick fix could be used in order to avoid those. Just skip the dots:
foreach($g as $x)
{
// skip the dots
if(in_array($x, array('..', '.'))) continue;
if(is_dir($x))$ar[$x]=scandir($x);
else
{
$count++;
$ar[]=$x;
}
}
Another alternative is to use DirectoryIterator:
$path = './images/';
$files = new DirectoryIterator($path);
$ar = array();
foreach($files as $file) {
if(!$file->isDot()) {
// if its not a directory
$ar[] = $file->getFilename();
}
}
echo '<pre>', print_r($ar, 1);
I need to recursively traverse a certain directory and list all of the files inside of it I have found an example on the PHP website however after further searching I am not able to find a solution to my problem. The problem is that it prints out the entire path but I only want to echo out the first containing folder of the file. So for example as it sits now I get this output:
/var/www/example.com/public_html/images/6.Blah/_Original/DSC_0174.jpg
But I want it to echo:
_Original/DSC_0174.jpg
or
/_Original/DSC_0174.jpg
Here is the code I am using:
<?php
$path = realpath('/etc');
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object){
echo "$name\n";
}
?>
This is a formatting issue, you can approach it in many different ways. One way will be to split the string into an array and grab the last two elements.
foreach($objects as $name => $object){
$pieces = explode("/",$name);
$length = count($pieces);
$result = $pieces[$length-2]."/".$pieces[$length-1];
}
can anyone tell me why my code is only outputting 20 out of 40 files
$Files = array();
$dir = new DirectoryIterator('./images/gallery');
foreach($dir as $fileinfo){
if($fileinfo->isFile()){
$Files[$fileinfo->getMTime()] = $fileinfo->getFilename();
}
}
krsort($Files);
foreach($Files as $file){
echo "<a rel='fancy1' href='/images/gallery/$file'><span><img src='/images/revelsmashy.php?src=/images/gallery/$file&w=128&zc=0&q=100'></span></a>\n";
}
edit:
i am looking to sort images based on the data time they were uploaded with the latest one posted 1st
Your original method of indexing the array by the file's modification time looks to be resulting in files having the same mtime values overwriting previous array keys. In some circumstances, if your whole directory were rewritten at once, all files could have the same modification time so only the last one iterated will be in the resultant array.
If you need to ultimately sort by the time, you can instead build a multidimensional array which holds both filenames and file modification times and then sort it using usort().
$dir = new DirectoryIterator('./images/gallery');
foreach($dir as $fileinfo){
if($fileinfo->isFile()){
// Append each file as an array with filename and filetime keys
$Files[] = array(
'filename' => $fileinfo->getFilename(),
'filetime' => $fileinfo->getMtime()
);
}
}
// Then perform a custom sort:
// (note: this method requires PHP 5.3. For PHP <5.3 the you have to use a named function instead.
// see the usort() docs for examples )
usort($Files, function($a, $b) {
if ($a['filetime'] == $b['filetime']) return 0;
return $a['filetime'] < $b['filetime'] ? -1 : 1;
});
In your output loop, access the filename key:
foreach($Files as $file){
echo "<a rel='fancy1' href='/images/gallery/{$file['filename']}'><span><img src='/images/revelsmashy.php?src=/images/gallery/{$file['filename']}&w=128&zc=0&q=100'></span></a>\n";
//-----------------------------------------^^^^^^^^^^^^^^^^^^^^
}
This question already has answers here:
What is the meaning of [] [closed]
(4 answers)
Closed 8 years ago.
I have been following a tutorial on readdir(), is_dir() etc involved in setting up a small image gallery based on folders and files on my FTP. I was wondering what the $directorys[] = $file; part does specifically?
while( $file= readdir( $dir_handle ) )
{
if( is_dir( $file ) ){
$directorys[] = $file;
}else{
$files[] = $file;
}
}
$directory is an array.
The code
$directory[] = $file
adds $file to the end of $directory array. This is the same as
array_push($directory, $file).
More info at array_push at phpdocs
$file will contain the name of the item that was scanned. In this case, the use of is_dir($file) allows you to check that $file in the current directory is a directory or not.
Then, using the standard array append operator [], the $file name or directory name is added to a $files/$directorys array...
It pushes an item to the array, instead of array_push, it would only push one item to the array.
Using array_push and $array[] = $item works the same, but it's not ideal to use array_push as it's suitable for pushing multiple items in the array.
Example:
Array (
)
After doing this $array[] = 'This works!'; or array_push($array, 'This works!') it will appear as this:
Array (
[0] => This works!
)
Also you can push arrays into an array, like so:
$array[] = array('item', 'item2');
Array (
[0] => Array (
[0] => item
[1] => item2
)
)
It adds the directory to the directory array :)
if( is_dir( $file ) ){
$directorys[] = $file; // current item is a directory so add it to the list of directories
}else{
$files[] = $file; // current item is a file so add it to the list of files
}
However if you use PHP 5 I really suggest using a DirectoryIterator.
BTW naming that $file is really bad, since it isn't always a file.
It creates a new array element at the end of the array and assigns a value to it.
I'm looking for a way to glob a directory and sort the contents by time/date and print it on the PHP page. There must be a way to do this, I've tried the following code but it won't print anything out on the page:
<?php
$files = glob("subdir/*");
$files = array_combine($files, array_map("filemtime", $files));
arsort($files);
?>
print_r wont work because I need just the file name. I'm new to PHP arrays so I need as much help as I can get!
Given your original code:
$files = glob("subdir/*");
$files = array_combine($files, array_map("filemtime", $files));
arsort($files);
From there you could either loop on the array of sorted filename/mtime pairs, or create a new array with just the filenames (in their sorted order).
The first looks like:
foreach ($files as $file => $mtime) {
echo $file . " ";
}
The second could be:
foreach (array_keys($files) as $file) {
echo $file . " ";
}
Depending on your needs, it might also be okay to simply:
echo implode(" ", array_keys($files));
Sounds like you're looking for foreach
foreach($files as $filename=>$mtime){
echo AS INTENDED;
}