listing files of subfolder issue - php

i have several millions files in a folder and there are several subfolders in that folder each subfolder consists of thousands of files . i am able to list all files of given folder using glob function but here in this case as its very high i am getting php fatal error . allowed memory size exhaused try to allocate more memory i know that can be done just by keeping one php.ini file in that subfolder but what i exactly want is listing all .txt extension size in descending order so the bigger file will be at the top and smaller file will be at the bottom but as i have said it is not possible to list millions of file so just like mysql can i list them in page wise or something like top 100 files will be listed in descending order when i click on next page it will show next 100-200 items but i dont want to use database if there is no other way how i can store all these details in database without causing heavy load on server.
<?php
foreach (glob("files/*") as $filename) {
echo "uploads/" . "$filename" . "\n</br>";
}
?>

use opendir insteed of glob();
Try something like this:
function printdirs($path) {
if ($handle = opendir($path)) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
if(is_dir($path.'/'.$entry))
printdirs($path.'/'.$entry);
else
echo $path . "/" . $entry . "\n</br>";
}
}
closedir($handle);
}}
printdirs('uploads');

Related

How do I move a specified number of files automatically from one folder to another using PHP? (for use in WordPress plugin)

Using a WordPress plugin, I have an image carousel that displays all files within a specified folder.
I only want to display the last 24 images from that folder. One way I thought I could do this without editing the original plugin is have all files from the previous day move to a new folder when the first photo from the next day arrives. The file names contain a time stamp, because of this, I can't specify actual file names, just the type of file.
Unfortunately, I am completely new to PHP and Server Side Scripting and would appreciate any advice on how to solve this issue.
I believe you don't have to move the files, just read them and sort by date.
here's a conceptual how to, untested.
$files =[];
if ($handle = opendir('.')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
$files[filemtime($file)] = $file;
}
}
closedir($handle);
// sort in reverse order
krsort($files);
for($i =0; $i < 24; $i++) {
$file = $files[$i]
echo "<img src='".$file."' />";
}
}
good luck
Ok, You want to display only last 24 images from that folder.
You can get name of last 24 images by their modification time.
$filelist = glob("/path/to/your_dir/*.{jpg,JPG,PNG,png,jpeg,JPEG}", GLOB_BRACE);
In php run a foreach loop for all the files in that directory, ,
$i = 0;
foreach($filelist as $key => $file){
$temp_arr[$i]['mtime'] = filemtime($file);
$temp[$i]['filename'] = $file;
$i++;
}
Then you can sort $temp_arr to retrive 24 latest images based on mtime.

search and delete unused images in articles with php

I have been working on some project and through time it got messed up with images which I tested it, so now I want to make a script which is going to search in articles img tags and find the img name (artiles are stored in mysql with attribute 'text') after scanning the folder where images are stored if they are not in any article included then to delete those images (unused images). Has anyone done this before so I could see an example or any good approach about this case?
Here's what you'll need to do what you want:
Loop through your directory of files (if they are on the filesystem):
if ($handle = opendir('/path/to/files')) {
echo "Directory handle: $handle\n";
echo "Entries:\n";
/* This is the correct way to loop over the directory. */
while (false !== ($entry = readdir($handle))) {
echo "$entry\n";
}
/* This is the WRONG way to loop over the directory. */
while ($entry = readdir($handle)) {
echo "$entry\n";
}
closedir($handle);
}
Ref. http://php.net/readdir
Loop through your files (if they are on the database):
Ref. http://www.php.net/manual/en/mysqli.query.php
Compare file names (obvious once you are looping through your resource).
Delete unused images like so http://www.php.net/unlink
Approach is simple
Query database and get list of all image URLs - add to an array
Loop through each folder that contains images and make an array of every image on the site/
here is how to find all items that are in one array but not another (may be a better answer more specific to you - array_Intesect is what you need.
with the new array simply loop through the list and delete the files.
All of the above you can search individually and then string them together.
I would recommend backing everything up before trying!!!!
I recently came accross such thing where I wanted to remove unused files that users left behind / change the profile picture but they were stored on the webserver. To fix this I used this :
$images = scandir("uploads", 1);
foreach ($images as $itemlc)
{
$res=mysql_query("SELECT * FROM company WHERE c_logo='$itemlc'");
$count = mysql_num_rows($res);
$res2=mysql_query("SELECT * FROM users WHERE u_logo='$itemlc'");
$count2 = mysql_num_rows($res2);
if($count == 1)
{
echo $itemlc; echo " exists <br><br>";
}
else if ($count2 == 1)
{
echo $itemlc; echo " exists <br><br>";
}
else{ $file_path = 'uploads/'; $src=$file_path.$itemlc; #unlink($src); }
}
Hope this helps if there is someone who needs this!

PHP hidden directories - Windows

I'm attempting to add a feature to our intranet, which will allow users to log onto the intranet, and access documents stored within a Windows network SAN.
At the moment, I've successfully retrieved all the file and folder names within a specified users 'My Documents'.
I'm having difficulty removing hidden files and folders from the array.
At the moment, I can remove all folders and files starting with ..
However on Windows, they're being marked as 'hidden' in the properties. I've googled and found lots of resources about how to mark a file as hidden, and how to hide files that start with a ., but none on how to remove hidden windows files / folders. One post on stackoverflow mentions to use DirectoryIterator, but at the moment, but haven't explained at all how to use it to check if a files marked as hidden.
We have over 1000 users, with approximately 500MB - 1GB of documents, with multiple layers of directories, so It needs to be relatively fast.
For clarification:
During a recursive iteration on a Windows system, how can I find out whether a directory is hidden or not, without relying on a prepended . symbol?
Ok, so worked it out, with help from the exec() function, so use with care!
I'm using CodeIgniter, so I've modified the directory_helper.php function slightly, as its installed on a windows box, it'll always need to check for the hidden files, but it should also work for non-codeigniter sites:
function directory_map($source_dir, $directory_depth = 0, $hidden = FALSE)
{
if ($fp = #opendir($source_dir))
{
if(!$hidden)
{
$exclude = array();
exec('dir "' . $source_dir . '" /ah /B', $exclude);
}
$filedata = array();
$new_depth = $directory_depth - 1;
$source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
while (FALSE !== ($file = readdir($fp)))
{
// Remove '.', '..', and hidden files [optional]
if ( ! trim($file, '.') OR ($hidden == FALSE && $file[0] == '.') OR ($hidden === FALSE && in_array($file, $exclude)))
{
continue;
}
if (($directory_depth < 1 OR $new_depth > 0) && #is_dir($source_dir.$file))
{
$filedata[$file] = directory_map($source_dir.$file.DIRECTORY_SEPARATOR, $new_depth, $hidden);
}
else
{
$filedata[] = $file;
}
}
closedir($fp);
return $filedata;
}
return FALSE;
}
This scanned 2207 files, and 446 folders in approx 11 seconds (Ages I know, but the best I could do). Tested it on 500 folders and 200 files, and did it in around 3 seconds.
Its a recursive function which will scan each non-hidden directory. The first thing it does is scan the current directory for all hidden files and folders using the exec('dir *directory* /ah /B') function.
It will then store the results in an array and make sure that the current file/directory being read isn't in that array.

PHP readir results - trying to sort by date created and also get rid of "." and ".."

I have a double question. Part one: I've pulled a nice list of pdf files from a directory and have appended a file called download.php to the "href" link so the pdf files don't try to open as a web page (they do save/save as instead). Trouble is I need to order the pdf files/links by date created. I've tried lots of variations but nothing seems to work! Script below. I'd also like to get rid of the "." and ".." directory dots! Any ideas on how to achieve all of that. Individually, these problems have been solved before, but not with my appended download.php scenario :)
<?php
$dir="../uploads2"; // Directory where files are stored
if ($dir_list = opendir($dir))
{
while(($filename = readdir($dir_list)) !== false)
{
?>
<p><a href="http://www.duncton.org/download.php?file=login/uploads2/<?php echo $filename; ?>"><?php echo $filename;
?></a></p>
<?php
}
closedir($dir_list);
}
?>
While you can filter them out*, the . and .. handles always come first. So you could just cut them away. In particular if you use the simpler scandir() method:
foreach (array_slice(scandir($dir), 2) as $filename) {
One could also use glob("dir/*") which skips dotfiles implicitly. As it returns the full path sorting by ctime then becomes easier as well:
$files = glob("dir/*");
// make filename->ctime mapping
$files = array_combine($files, array_map("filectime", $files));
// sorts filename list
arsort($files);
$files = array_keys($files);

Multiple Random Includes from Directory with Sub-Directories

I have a directory containing sub directories which each contain a series of files. I'm looking for a script that will look inside the sub directories and randomly return a specified number of files.
There are a few scripts that can search a single directories (not sub folders), and other scripts that can search sub folders but only return one file.
To put a little context on the situation, the returned files will be included as li's in an rotating banner.
Thanks in advance for any help, hopefully this is possible.
I think I've got there, not exactly what I set out to achieve but works good enough, arguably better for the purpose, I'm using the following function:
<?php function RandomFile($folder='', $extensions='.*'){
// fix path:
$folder = trim($folder);
$folder = ($folder == '') ? './' : $folder;
// check folder:
if (!is_dir($folder)){ die('invalid folder given!'); }
// create files array
$files = array();
// open directory
if ($dir = #opendir($folder)){
// go trough all files:
while($file = readdir($dir)){
if (!preg_match('/^\.+$/', $file) and
preg_match('/\.('.$extensions.')$/', $file)){
// feed the array:
$files[] = $file;
}
}
// close directory
closedir($dir);
}
else {
die('Could not open the folder "'.$folder.'"');
}
if (count($files) == 0){
die('No files where found :-(');
}
// seed random function:
mt_srand((double)microtime()*1000000);
// get an random index:
$rand = mt_rand(0, count($files)-1);
// check again:
if (!isset($files[$rand])){
die('Array index was not found! very strange!');
}
// return the random file:
return $folder . "/" . $files[$rand];
}
$random1 = RandomFile('project-banners/website-design');
while (!$random2 || $random2 == $random1) {
$random2 = RandomFile('project-banners/logo-design');
}
while (!$random3 || $random3 == $random1 || $random3 == $random2) {
$random3 = RandomFile('project-banners/design-for-print');
}
?>
And echoing the results into the container (in this case the ul):
<?php include($random1) ;?>
<?php include($random2) ;?>
<?php include($random3) ;?>
Thanks to quickshiftin for his help, however it was a little above my skill level.
For info the original script which I changed an be found at:
http://randaclay.com/tips-tools/multiple-random-image-php-script/
Scrubbing the filesystem every single time to randomly select a file to display will be really slow. You should index the directory structure ahead of time. You can do this many ways, try a simple find command or if you really want to use PHP my favorite choice would be RecursiveDirectoryIterator plus RecursiveIteratorIterator.
Put all the results into one file and just read from there when you select a file to display. You can use the line numbers as an index, and the rand function to pick a line and thus a file to display. You might want to consider something more evenly distributed than rand though, you know to keep the advertisers happy :)
EDIT:
Adding a simple real-world example:
// define the location of the portfolio directory
define('PORTFOLIO_ROOT', '/Users/quickshiftin/junk-php');
// and a place where we'll store the index
define('FILE_INDEX', '/tmp/porfolio-map.txt');
// if the index doesn't exist, build it
// (this doesn't take into account changes to the portfolio files)
if(!file_exists(FILE_INDEX))
shell_exec('find ' . PORTFOLIO_ROOT . ' > ' . FILE_INDEX);
// read the index into memory (very slow but easy way to do this)
$aIndex = file(FILE_INDEX);
// randomly select an index
$iIndex = rand(0, count($aIndex) - 1);
// spit out the filename
var_dump(trim($aIndex[$iIndex]));

Categories