This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
get last modified file in a dir?
I have a folder which contents more than 30000 subfolders in it. How can I get a list of subfolders with last modification date >= one hour ago? Is it possible to do that without getting a list of all files in an array and sorting it? I cannot use a readdir function because it returns files in the order in which they are stored by the filesystem and exhaustive search of the list of files will take a very long time.
Use GNU Find - it is simpler and faster!
find [path] -type d -mmin +60
The linux "find" command is pretty powerful.
$cmd = "find ".$path." type -d -mmin +60";
$out=`$cmd`;
$files=explode("\n",$out);
Give this a try:
<?php
$path = 'path/to/dir';
if (is_dir($path)) {
$contents = scandir($path);
foreach ($contents as $file) {
$full_path = $path . DIRECTORY_SEPARATOR . $file;
if ($file != '.' && $file != '..') {
if (is_dir($full_path)) {
$dirs[filemtime($full_path)] = $file;
}
}
}
// Sort in reverse order to put newest modification at the top
krsort($dirs);
$iteration = 0;
foreach ($dirs as $mtime => $name) {
if ($iteration != 5) {
echo $name . '<br />';
}
$iteration++;
}
}
?>
Related
This question already has answers here:
How to get the newest file in a directory in php
(4 answers)
Closed 8 years ago.
I created a PHP script to find the latest XML file in a directory, and it worked great, but today is May 1st and my latest file is from April 30th. Today the result shows "file not found", but it is there. There is something wrong with my method of finding the last file and it having a date stamp that is not the current month.
Here is my code:
// Initialize list arrays, files and array counters for them
$t = 0;
$f = 0;
$files_arr['name'] = array();
$files_arr['time'] = array();
if (#$handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
$fName = $file;
$file = $path . '/' . $file;
if (is_file($file)) {
/* here is the sorting by date, just a seperate key
in the array to store filetimes */
$files_arr['time'][$t++] = filemtime($file);
$files_arr['name'][$f++] = $file;
}
;
}
;
}
;
closedir($handle);
asort($files_arr['time']);
asort($files_arr['name']);
}
//test
foreach ($files_arr['time'] as $key => $ftime) {
$fname = $files_arr['name'][$key];
}
// End Finding Latest File in Dir
// $source = file_get_contents('data/201404.xml');
// echo $fname;exit;
$fname = $path . "/" . date('Y') . date('m') . ".xml";
Can anyone help me just get the latest file and not have it dependent on the current date?
I assume the filenames are of the format "201404.xml" where the filename is the year+month?
If so, can't you read the files into an array and sort it, or even better if you just want the latest, read all the files and compare the current name to the highest, if it's greater then set the highest to the current name and get the next file, looping until you get to the end of the list. You need to set highest to blanks (or null before you start.
I was able to add a variable with the help a a programmer:
if(date('m')-1>9)
$ss=date('m')-1;
else
$ss="0".(date('m')-1);
$filee=$path."/".date('Y').date('m').".xml";
if(file_exists($filee))
$fname=$path."/".date('Y').date('m').".xml";
else
$fname=$path."/".date('Y').($ss).".xml";
Seems to work now!
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Does glob() have negation?
I want to delete all files from a directory (could be any number of file extentions) apart from the single index.html in there.
I'm using:
$path = "/assets/cache/";
foreach(glob($path ."*.*") as $file) {
unlink($file);
}
But can't for the life of me how to say unlink, if not .html!
Thanks!
Try this here...
$path = "/assets/cache/";
foreach(glob($path ."*.*") as $file) {
$pathPart = explode(".",$file);
$fileEx = $pathPart[count($pathPart)-1];
if($fileEx != "html" && $fileEx != "htm"){
unlink($file);
}
}
try
$path = "/assets/cache/";
foreach(glob($path ."*.*") as $file) {
if(pathinfo($file, PATHINFO_EXTENSION) != 'html') {
unlink($file);
}
}
if you want to delete other html files also (apart from "index.html"):
$path = "/assets/cache/";
foreach(glob($path ."*.*") as $file) {
if(pathinfo($file, PATHINFO_BASENAME) != 'index.html') {
unlink($file);
}
}
The php function glob has no negation, however PHP can give you the difference between two globs via array_diff:
$all = glob("*.*");
$not = glob("php_errors.log");
var_dump(
$all,
$not,
array_diff($all, $not)
);
See the demo: http://codepad.org/RBFwPUWm
If you do not want to use arrays, I highly suggest to take a look into PHPs directory iterators.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Finding a file with a specific name with any extension
i've this code for put into an array all the files contained into a directory
$directory = "./";
$ourDirList = scandir($directory);
$arraylistafiles=array();
foreach($ourDirList as $ourItem)
{
if (is_file($ourDir . $ourItem))
{$arraylistafiles[]=$ourItem;}
}
but if i want to put only the file that have ".jpg" extension, what i can do?
Using PHP's glob() you can avoid the is_file() call because glob will only return files that actually exist in the directory. There is no need to create a UDF (user defined function) in your case.
$dir = './';
foreach(glob($dir.'*.jpg') as $file) {
print $file . "\n";
}
UPDATE
From your comment it's clear that you don't understand how glob() works. You can achieve what you're trying to do like this:
$arraylistafiles = glob($dir.'*.jpg');
if(is_file($ourDir.$ourItem) && substr($ourItem,-4) == '.jpg') {
//
}
You can use bellow function.
public function getFileList($dirpath,$list_ignore,$list_allowed_ext)
{
$filelist = array();
if ($handle = opendir(dirname ($dirpath)))
{
while (false !== ($file = readdir($handle)))
{
if (!is_dir($file) && !in_array($file,$list_ignore) && in_array(strtolower(end(explode('.',$file))),$list_allowed_ext))
{
$filelist[] = $file;
}
}
closedir($handle);
}
return $filelist;
}
Implementation will be looks like..
$fileTypes = array ("jpg");
$list_ignore = array ('.','..');
$fileList = getFileList("./",$list_ignore,$fileTypes);
Cheers!
First you have to check for the file extension for the file in foreach array. . If the extension is jpg then add that item into the new array. . . Hope you understand. .
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Get the Files inside a directory
Is there a function that can be used to get the contents of a directory (a photo gallery directory for example) ?
I'm trying to save time on a project by automating a photo gallery based on which files are available.
Thanks
Shane
You can either use the DirectoryIterator:
$dir = new DirectoryIterator('path/to/images');
foreach ($dir as $fileinfo) {
echo $fileinfo->getFilename() . "\n";
}
or alternatively glob():
$filenames = glob('path/to/images/*.jpg');
foreach ($filenames as $filename) {
echo $filename ."\n";
}
glob()
scandir()
I use a while loop to grab a list of files, omit the 2nd if statement if you want to grab a all files.
if ($handle = opendir('/photos/')) {
while(false !== ($sFile = readdir($handle))) {
if (strrpos($sFile, ".jpg") === strlen($sFile)-strlen(".jpg")) {
$fileList[] = $sfile;
}
}
}
I want something (final) like this :
<?php
//named as config.php
$fn[0]["long"] = "file name"; $fn[0]["short"] = "file-name.txt";
$fn[1]["long"] = "file name 1"; $fn[1]["short"] = "file-name_1.txt";
?>
What that I want to?:
1. $fn[0], $fn[1], etc.., as auto increasing
2. "file-name.txt", "file-name_1.txt", etc.., as file name from a directory, i want it auto insert.
3. "file name", "file name 1", etc.., is auto split from "file-name.txt", "file-name_1.txt", etc..,
and config.php above needed in another file e.g.
<? //named as form.php
include "config.php";
for($tint = 0;isset($text_index[$tint]);$tint++)
{
if($allok === TRUE && $tint === $index) echo("<option VALUE=\"" . $text_index[$tint]["short"] . "\" SELECTED>" . $text_index[$tint]["long"] . "</option>\n");
else echo("<option VALUE=\"" . $text_index[$tint]["short"] . "\">" . $text_index[$tint]["long"] . "</option>\n");
} ?>
so i try to search and put php code and hope it can handling at all :
e.g.
<?php
$path = ".";
$dh = opendir($path);
//$i=0;
$i= 1;
while (($file = readdir($dh)) !== false) {
if($file != "." && $file != "..") {
echo "\$fn[$i]['short'] = '$file'; $fn[$i]['long'] = '$file(splited)';<br />"; // Test
$i++;
}
}
closedir($dh);
?>
but i'm wrong, the output is not similar to what i want, e.g.
$fn[0]['short'] = 'file-name.txt'; ['long'] = 'file-name.txt'; //<--not splitted
$fn[1]['short'] = 'file-name_1.txt'; ['long'] = 'file-name_1.txt'; //<--not splitted
because i am little known with php so i don't know how to improve code more, there are any good tips of you guys could help me, Please
New answer after OP edited his question
From your edited question, I understand you want to dynamically populate a SelectBox element on an HTML webpage with the files found in a certain directory for option value. The values are supposed to be split by dash, underscore and number to provide the option name, e.g.
Directory with Files > SelectBox Options
filename1.txt > value: filename1.txt, text: Filename 1
file_name2.txt > value: filename1.txt, text: File Name 2
file-name3.txt > value: filename1.txt, text: File Name 3
Based from the code I gave in my other answer, you could achieve this with the DirectoryIterator like this:
$config = array();
$dir = new DirectoryIterator('.');
foreach($dir as $item) {
if($item->isFile()) {
$fileName = $item->getFilename();
// turn dashes and underscores to spaces
$longFileName = str_replace(array('-', '_'), ' ', $fileName);
// prefix numbers with space
$longFileName = preg_replace('/(\d+)/', ' $1', $fileName);
// add to array
$config[] = array('short' => $filename,
'long' => $longFilename);
}
}
However, since filenames in a directory are unique, you could also use this as an array:
$config[$filename] => $longFilename;
when building the config array. The short filename will form the key of the array then and then you can build your selectbox like this:
foreach($config as $short => $long)
{
printf( '<option value="%s">%s</option>' , $short, $long);
}
Alternatively, use the Iterator to just create an array of filenames and do the conversion to long file names when creating the Selectbox options, e.g. in the foreach loop above. In fact, you could build the entire SelectBox right from the iterator instead of building the array first, e.g.
$dir = new DirectoryIterator('.');
foreach($dir as $item) {
if($item->isFile()) {
$fileName = $item->getFilename();
$longFileName = str_replace(array('-', '_'), ' ', $fileName);
$longFileName = preg_replace('/(\d+)/', ' $1', $fileName);
printf( '<option value="%s">%s</option>' , $fileName, $longFileName);
}
}
Hope that's what your're looking for. I strongly suggest having a look at the chapter titled Language Reference in the PHP Manual if you got no or very little experience with PHP so far. There is also a free online book at http://www.tuxradar.com/practicalphp
Use this as the if condition to avoid the '..' from appearing in the result.
if($file != "." && $file != "..")
Change
if($file != "." ) {
to
if($file != "." and $file !== "..") {
and you get the behaviour you want.
If you read all the files from a linux environment you always get . and .. as files, which represent the current directory (.) and the parent directory (..). In your code you only ignore '.', while you also want to ignore '..'.
Edit:
If you want to print out what you wrote change the code in the inner loop to this:
if($file != "." ) {
echo "\$fn[\$i]['long'] = '$file'<br />"; // Test
$i++;
}
If you want to fill an array called $fn:
if($file != "." ) {
$fn[]['long'] = $file;
}
(You can remove the $i, because php auto increments arrays). Make sure you initialize $fn before the while loop:
$fn = array();
Have a look at the following functions:
glob — Find pathnames matching a pattern
scandir — List files and directories inside the specified path
DirectoryIterator — provides a simple interface for viewing the contents of filesystem directories
So, with the DirectoryIterator you simply would do:
$dir = new DirectoryIterator('.');
foreach($dir as $item) {
if($item->isFile()) {
echo $file;
}
}
Notice how every $item in $dir is an SplFileInfo instance and provides access to a number of useful other functions, e.g. isFile().
Doing a recursive directory traversal is equally easy. Just use a RecursiveDirectoryIterator with a RecursiveIteratorIterator and do:
$dir = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('.'));
foreach($dir as $item) {
echo $file;
}
NOTE I am afraid I do not understand what the following line from your question is supposed to mean:
echo "$fn[$i]['long'] = '$file'<br />"; // Test
But with the functions and example code given above, you should be able to do everything you ever wanted to do with files inside directories.
I've had the same thing happen. I've just used array_shift() to trim off the top of the array
check out the documentation. http://ca.php.net/manual/en/function.array-shift.php