I am looking for a way to list the names of every folder in a directory and their path in PHP
Thank you
What you are referring to is not a page from WAMPP, it is a default setting to show files and folders on any (if not most) web servers... This is usually switched off by the web server config, or .htaccess files
You are looking for some PHP code to do a similar thing, the following PHP functions are what you will need to look into, read the pages and view the examples to understand how to use them... Do not ignore "Warning" or "Important" messages on these pages from php.net:
opendir - Creates a handle to a directory for reading
readdir - Reads files/folders inside a dir
rmdir - Deletes a folder (must be empty)
mkdir - Creates a folder
Here is an example:
<?php
$folder = "myfolder";
if ($dhandle = opendir($folder)) {
while ($file = readdir($dhandle)) {
// Ignore . and ..
if ($file<>'.' && $file<>'..')
// if it's a folder, echo [F]
if (is_dir("$folder/$file")) echo "[F] $file<br>"; else
echo "$file<br>";
}
closedir($dhandle);
}
?>
Important
Remember that on a linux OS, your Apache/PHP must have access to the folder in question before it can write/delete files and folders... Read up on chmod, chown and chgrp
use the following function to get the path of the files/folders
<?php
function getDirectory( $path = '.', $level = 0 ){
$ignore = array( 'cgi-bin', '.', '..' );
// Directories to ignore when listing output. Many hosts
// will deny PHP access to the cgi-bin.
$dh = #opendir( $path );
// Open the directory to the handle $dh
while( false !== ( $file = readdir( $dh ) ) ){
// Loop through the directory
if( !in_array( $file, $ignore ) ){
// Check that this file is not to be ignored
$spaces = str_repeat( ' ', ( $level * 4 ) );
// Just to add spacing to the list, to better
// show the directory tree.
if( is_dir( "$path/$file" ) ){
// Its a directory, so we need to keep reading down...
echo "<strong>$spaces $file</strong><br />";
getDirectory( "$path/$file", ($level+1) );
// Re-call this same function but on a new directory.
// this is what makes function recursive.
} else {
echo "$spaces $file<br />";
// Just print out the filename
}
}
}
closedir( $dh );
// Close the directory handle
}
getDirectory( "." );
?>
There is an simple solution to this problem :(if you are using linux only )
you want list the names of every folder in a directory and their path in PHP .
you can use
find
command in conjuction with PHP's
exec();
function
the following snippet shows this
<?php
$startdir = "Some Directory" ; // the start directory whose sub directories along with path is needed
exec("find " . $startdir . " -type d " , $directories); // executes the command and stores the result in array $directory line by line
while(list($index,$dir) = each($directories) ) {
echo $dir."<br/>"; //lists directories one by one
}
?>
foot notes:
command ,
find dirname -type d
lists all the directories and subdirectories under folder startdir
This is a php code save this as index.php and put it in your web root directory.
<?php
$pngFolder = <<< EOFILE
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAA3NCSVQICAjb4U/gAAABhlBMVEX//v7//v3///7//fr//fj+/v3//fb+/fT+/Pf//PX+/Pb+/PP+/PL+/PH+/PD+++/+++7++u/9+vL9+vH79+r79+n79uj89tj89Nf889D88sj78sz78sr58N3u7u7u7ev777j67bL67Kv46sHt6uP26cns6d356aP56aD56Jv45pT45pP45ZD45I324av344r344T14J734oT34YD13pD24Hv03af13pP233X025303JL23nX23nHz2pX23Gvn2a7122fz2I3122T12mLz14Xv1JPy1YD12Vz02Fvy1H7v04T011Py03j011b01k7v0n/x0nHz1Ejv0Hnuz3Xx0Gvz00buzofz00Pxz2juz3Hy0TrmznzmzoHy0Djqy2vtymnxzS3xzi/kyG3jyG7wyyXkwJjpwHLiw2Liw2HhwmDdvlXevVPduVThsX7btDrbsj/gq3DbsDzbrT7brDvaqzjapjrbpTraojnboTrbmzrbmjrbl0Tbljrakz3ajzzZjTfZijLZiTJdVmhqAAAAgnRSTlP///////////////////////////////////////8A////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9XzUpQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAB90RVh0U29mdHdhcmUATWFjcm9tZWRpYSBGaXJld29ya3MgOLVo0ngAAACqSURBVBiVY5BDAwxECGRlpgNBtpoKCMjLM8jnsYKASFJycnJ0tD1QRT6HromhHj8YMOcABYqEzc3d4uO9vIKCIkULgQIlYq5haao8YMBUDBQoZWIBAnFtAwsHD4kyoEA5l5SCkqa+qZ27X7hkBVCgUkhRXcvI2sk3MCpRugooUCOooWNs4+wdGpuQIlMDFKiWNbO0dXTx9AwICVGuBQqkFtQ1wEB9LhGeAwDSdzMEmZfC0wAAAABJRU5ErkJggg==
EOFILE;
if (isset($_GET['img']))
{
header("Content-type: image/png");
echo base64_decode($pngFolder);
exit();
}
$projectsListIgnore = array ('.','..');
$handle=opendir(".");
$projectContents = '';
while ($file = readdir($handle))
{
if (is_dir($file) && !in_array($file,$projectsListIgnore))
{
$projectContents .= '<li>'.$file.'</li>';
}
}
closedir($handle);
?>
<ul class="projects">
<?php $projectContents ?>
</ul>
Related
I keep having - I think permission issues - with unzipping a file (this part goes OK) and moving content to write folder.
I am running simple code:
$zip = new ZipArchive( );
$x = $zip->open( $file );
if ( $x === true ) {
$zip->extractTo( $target );
$zip->close( );
unlink( $file );
rmove( __DIR__ . '/' . $target . '/dist', __DIR__ );
} else {
die( "There was a problem. Please try again!" );
}
where rmove() is a simple recursive function that iterates thru content and applies rename() to each file.
Problem is that unzipping goes well, files are copied, but not moved - delete from a temporary folder. I read so far that could be caused by not having a write permission to unzipped files at the time of renaming.
How to control those permissions at the time of unzipping?
Update: content of rmove():
function rmove( $src, $dest ) {
// If source is not a directory stop processing
if ( ! is_dir( $src ) ) return false;
// If the destination directory does not exist create it
if ( ! is_dir( $dest ) ) {
if ( ! mkdir( $dest ) ) {
// If the destination directory could not be created stop processing
return false;
}
}
// Open the source directory to read in files
$i = new DirectoryIterator( $src );
foreach( $i as $f ) {
if ( $f->isFile( ) ) {
echo $f->getRealPath( ) . '<br/>';
rename( $f->getRealPath( ), "$dest/" . $f->getFilename( ) );
} else if ( ! $f->isDot( ) && $f->isDir( ) ) {
rmove( $f->getRealPath( ), "$dest/$f" );
unlink( $f->getRealPath( ) );
}
}
unlink( $src );
}
As far as I'm aware ZipArchive::extractTo doesn't set any special write/delete permissions, so you should have full access to the extracted files.
The issue with your code is the rmove function. You're trying to remove directories with unlink, but unlink removes files. You should use rmdir to remove directories.
If we fix that issue, your rmove function works fine.
function rmove($src, $dest) {
// If source is not a directory stop processing
if (!is_dir($src)) {
return false;
}
// If the destination directory does not exist create it
if (!is_dir($dest) && !mkdir($dest)) {
return false;
}
// Open the source directory to read in files
$contents = new DirectoryIterator($src);
foreach ($contents as $f) {
if ($f->isFile()) {
echo $f->getRealPath() . '<br/>';
rename($f->getRealPath(), "$dest/" . $f->getFilename());
} else if (!$f->isDot() && $f->isDir()) {
rmove($f->getRealPath(), "$dest/$f");
}
}
rmdir($src);
}
You don't have to remove every subfolder in the loop, the rmdir at the end will remove all folders, since this is a recursive function.
If you still can't remove the contents of the folder, then you may not have sufficient permissions. I don't think that's very likely, but in that case you could try chmod.
I just wonder about the $target.'/dist' directory. I assume that the 'dist' directory is coming from the archive. Having pointed out that I can see the 'rmove' function is prone to copy a file to a destination directory before it is created. Your code assumes that the directory will supersede the files in the iterator. If the file path supersedes the directory the destination directory won't exist to copy the file.
I would suggest you an alternative function to your custom written recursive 'rmove' function, which is the RecursiveDirectoryIterator.
http://php.net/manual/en/class.recursivedirectoryiterator.php
Let me simplify your code with RecursiveDirectoryIterator as follows
$directory = new \RecursiveDirectoryIterator( __DIR__ . '/' . $target . '/dist', RecursiveDirectoryIterator::SKIP_DOTS);
$iterator = new \RecursiveIteratorIterator($directory);
foreach ($iterator as $f) {
if($f->isFile()){
if(!empty($iterator->getSubpath()))
#mkdir(__DIR__."/" . $iterator->getSubpath(),0755,true);
rename($f->getPathname(), __DIR__."/" . $iterator->getSubPathName());
}
}
Please check to see whether you still get the permission error.
I want to be able to list all the directories, subdirectories and files in the "./" folder ie the project folder called fileSystem which contains this php file scanDir.php.
You can view the directory system I've got here:
At the minute it will only return the subdirectory folders/files in the root of the mkdir directory but not any folders inside that subdirectory.
How do I modify the code so that it demonstrates all the files, directories, subdirectories and their files and subdirectories within the fileSystem folder given that the php file being run is called scanDir.php and the code for that is provided below.
Here is the php code:
$path = "./";
if(is_dir($path))
{
$dir_handle = opendir($path);
//extra check to see if it's a directory handle.
//loop round one directory and read all it's content.
//readdir takes optional parameter of directory handle.
//if you only scan one single directory then no need to passs in argument.
//if you are then going to scan into sub-directories the argument needs
//to be passed into readdir.
while (($dir = readdir($dir_handle))!== false)
{
if(is_dir($dir))
{
echo "is dir: " . $dir . "<br>";
if($dir == "mkdir")
{
$sub_dir_handle = opendir($dir);
while(($sub_dir = readdir($sub_dir_handle))!== false)
{
echo "--> --> contents=$sub_dir <br>";
}
}
}
elseif(is_file($dir))
{
echo "is file: " . $dir . "<br>" ;
}
}
closedir($dir_handle); //will close the automatically open dir.
}
else {
echo "is not a directory";
}
Use scandir to see all stuff in the directory and is_file to check if the item is file or next directory, if it is directory, repeat the same thing over and over.
So, this is completely new code.
function listIt($path) {
$items = scandir($path);
foreach($items as $item) {
// Ignore the . and .. folders
if($item != "." AND $item != "..") {
if (is_file($path . $item)) {
// this is the file
echo "-> " . $item . "<br>";
} else {
// this is the directory
// do the list it again!
echo "---> " . $item;
echo "<div style='padding-left: 10px'>";
listIt($path . $item . "/");
echo "</div>";
}
}
}
}
echo "<div style='padding-left: 10px'>";
listIt("/");
echo "</div>";
You can see the live demo here in my webserver, btw, I will keep this link just for a second
When you see the "->" it's an file and "-->" is a directory
The pure code with no HTML:
function listIt($path) {
$items = scandir($path);
foreach($items as $item) {
// Ignore the . and .. folders
if($item != "." AND $item != "..") {
if (is_file($path . $item)) {
// this is the file
// Code for file
} else {
// this is the directory
// do the list it again!
// Code for directory
listIt($path . $item . "/");
}
}
}
}
listIt("/");
the demo can take a while to load, it's a lot of items.
There are some powerful builtin functions for PHP to find files and folders, personally I like the recursiveIterator family of classes.
$startfolder=$_SERVER['DOCUMENT_ROOT'];
$files=array();
foreach( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $startfolder, RecursiveDirectoryIterator::KEY_AS_PATHNAME ), RecursiveIteratorIterator::CHILD_FIRST ) as $file => $info ) {
if( $info->isFile() && $info->isReadable() ){
$files[]=array('filename'=>$info->getFilename(),'path'=>realpath( $info->getPathname() ) );
}
}
echo '<pre>',print_r($files,true),'</pre>';
Hi i have problem with this code
with the code i can change whole my folder file to number like 1.mp4 2.mp4 ect...
i test the code and i print the name of the file from it and every thing is right
but rename function is not working
this is my code
$dir = opendir('.');
$i = 1;
// loop through all the files in the directory
while (false !== ($file = readdir($dir)))
{
// if the extension is '.mp4'
if (strtolower(pathinfo($file, PATHINFO_EXTENSION)) == 'mp4')
{
echo $file ;
// do the rename based on the current iteration
$newName = $i . '.mp4';
rename($file, $newName);
// increase for the next loop
$i++;
}
}
// close the directory handle
closedir($dir);
?>
what is the problem now ?
NEW iNFO
i tried the code inside my localhost and it's work but it's not working inside the server
It's more efficient to use glob()
foreach(glob(__DIR__ . '/*.mp4') as $key => $file) {
if(!rename($file, __DIR__ . '/' . ($key + 1) . '.mp4')) {
throw new Exception('Unable to write to '. $file);
}
}
I'll hazard a guess it's a write permissions issue though - I don't see anything directly wrong with the script.
Getting the real path can help:
$file = realpath($filename);
but it sounds like it could be a permissions issue or an SELinux issue also. You will need apache to be the group on the files in question, and the files should be writeable by the group.
Also, if you have SELinux enabled, you will need to use
semanage fcontext -a -t httpd_sys_rw_content_t "/path/to/images/folder(/.*)?"
and
restorecon -R -v /path/to/images/folder
I am working on a website with a lot of images and PDF files that are updated regularly, but the old files are not deleted after the new ones are uploaded. Therefor I have a lot of files that are just sitting on the server without being used.
Is there a script or whatever else that I can run and will search for files that nothing is linking to?
EDIT :
I am not asking how to upload new files and delete the old ones in the future. I have already taken care of that.
I just want to know how to get rid of the files that are not in use any more.
Does that make sense?
Try this, just don't forget to change your directory $dir = "/Your/directory/here";
<?
$findex = array();
$findex[path] = array();
$findex[file] = array();
$extensions = array('.cfm','.html','.htm','.css','.php','.gif','.jpg','.png','.jpeg','.dwt');
$excludes = array('.svn');
function rec_scandir($dir)
{
$files = array();
global $findex;
global $extensions;
global $excludes;
if ( $handle = opendir($dir) )
{
while ( ($file = readdir($handle)) !== false )
{
if ( $file != ".." && $file != "." )
{
if ( is_dir($dir . "/" . $file) )
{
$files[$file] = rec_scandir($dir . "/" . $file);
}
else
{
for ($i=0;$i<sizeof($extensions);$i++)
{
if (strpos(strtolower($file),strtolower($extensions[$i])) > 0)
{
$found = true;
}
}
for ($i=0;$i<sizeof($excludes);$i++)
{
if (strpos(strtolower($file),strtolower($excludes[$i])) > 0)
{
$found = false;
}
}
if ($found)
{
$files[] = $file;
$dirlink = $dir . "/" . $file;
array_push($findex[path],$dirlink);
array_push($findex[file],$file);
}
$found = false;
}
}
}
closedir($handle);
return $findex;
}
}
$dir = "/Your/directory/here";
echo "\n";
echo " Searching ". $dir ." for matching files\n";
$files = rec_scandir($dir);
echo " Found " . sizeof($files[file]) . " matching extensions\n";
echo " Scanning for orphaned files....\n";
$findex[found] = array();
for ($i=0;$i<sizeof($findex[path]);$i++)
{
echo $i . " ";
$contents = file_get_contents($findex[path][$i]);
for ($j=0;$j<sizeof($findex[file]);$j++)
{
if (strpos($contents,$findex[file][$j]) > 0)
{
$findex[found][$j] = 1;
}
}
}
echo "\n";
$counter=1;
for ($i=0;$i<sizeof($findex[path]);$i++)
{
if ($findex[found][$i] != 1)
{
echo " " . $counter . ") " . substr($findex[path][$i],0,1000) . " is orphaned\n";
$counter++;
}
}
?>
Source: http://sun3.org/archives/297
If there is no probability that you will need those files again after updating the link and you have no files that have multiple links to them, i'd suggest you delete the files at the time of updating a link. Ie:
Link1 points to File1
Update Link1 to point to File2
Delete File1 immediately.
If in your scenario you might have multiple links to same file or files that might be relinked in a short period, i'd suggest setting up a cron job that will execute for a example once every week and will check all files in your files/ directory against the links table in your database and delete them if there are no links referencing that particular file.
There are many free link checker tools that you can use. After running it against your site (filtering for image/pdf files), you can then take that generated list and programmatically check it against your images/pdf directory to find out what's not in the list. Keep in mind that this can be difficult to determine with certainty as dynamically generated src/href's (based on user input/settings, apache rewrites, files returned via code) may not be included.
if it is a unix server, use the find command with something like this:
find /tmp/web_tmp \( \( \( -type f -amin +120 \) -or \( -type f -amin +30 -size 20480k \) \) -exec rm {} \; \) -or \( -depth -type d -empty -exec rmdir {} \; \)
In this case I am looking into the /tmp/web_tmp folder for empty folders as well as files that haven't been accessed in 120 minutes or haven't been accessed in 30 minutes and are over 20Mb. Once founded it will delete the found entry
Maybe in the find command you will find something that will allow you to delete files that haven't been accessed/modified/edited in a long time.
I've been trying to get this done with no luck. I've got a php script that downloads and UNZIPS a file. No problem here.
After that, I need to get the unzipped files and replace all the files of the root directory with the files on this folder. Problem is, the folder is in the root directory.
Eg.: my directory is something like this
/
/folder 1
/folder 2
/folder 3
/file.php
/file2.php
etc...
After I run my download script I unzip the archive to a folder called update in the root of the dir
/update/--UNZIPED STUFF--
I need to delete virtually all files/dirs from the root DIR excluding the update folder I guess and a couple of other files and then move the files/folders inside the update folder to the root of the dir.
Any ideas?
UPDATE
Ok, so I've made a code that seems to be right but I get a lot of file permission to when using unlink or rename. How can I go about that?
Here is the bit of code I've made
echo '<table>';
$updateContents = scandir('./');
foreach($updateContents as $number=>$fileName){
if($fileName != 'update' && $fileName != 'config.ini' && $fileName != 'layout.php' && $fileName != '..' && $fileName != '.' && $fileName != '.git' && $fileName != '.gitignore'){
if(is_dir($fileName)){
moveDownload($fileName, 'old/'.$fileName);
} else {
if(rename($fileName, 'old/'.$fileName)){
echo '<tr><td>'.$fileName.' moved successfully </td><td><font color="green">OK</font></td></tr>';
} else {
echo '<tr><td>Could not move file '.$fileName.'</td><td><font color="red">ERROR</font></td></tr>';
}
}
}
}
echo '</table>';
and the moveDownload function is one I found here somewhere. It moves a non empty folder and it was slightly modified by me.
function moveDownload($src,$dst){
$dir = opendir($src);
while(false !== ($file = readdir($dir))){
if (($file != '.') && ($file != '..') && ($file != 'config.ini') && ($file != 'layout.php') && ($file != 'sbpcache') && ($file !='update')){
if (is_dir($src.'/'.$file)){
if(file_exists($dst.'/'.$file)){
rrmdir($dst.'/'.$file);
}
}
if(#rename($src . '/' . $file, $dst . '/' . $file)){
echo '<tr><td>'.$file.' moved successfully </td><td><font color="green">OK</font></td></tr>';
} else {
if(#chmod($src.'/'.$file, 0777)){
if(#rename($src . '/' . $file, $dst . '/' . $file)){
echo '<tr><td>'.$file.' moved successfully </td><td><font color="green">OK</font></td></tr>';
} else {
echo '<tr><td>Could not move file '.$file.'</td><td><font color="red">ERROR RENAME</font></td></tr>';
}
} else {
echo '<tr><td>Could not move file '.$file.'</td><td><font color="red">ERROR CHMOD</font></td></tr>';
}
}
}
}
closedir($dir);
}
I also do the same in the again but moving from the update folder.
So basically, first instead of deleting things I am just moving them to a folder called old and then I try to move the new things in, but I get permission problems everywhere. Some files move, some don't, even if I have ' sudo chmod 777 -R'. Any ideas?
PHP's opendir will allow you to iterate along all the files and directories inside the root directory. You can use unlink to delete the files or folders and add an if clause to check if the item is to be deleted or not.
Why don't you just get a list of all directories / files under root and then loop through them, delete them (using unlink) while ignoring the "backup" directory.
Next you can either run a php copy OR shell_exec mv * command to move the files from backup to root.
what for to use root folder. use /tmp
what the problem with unlink / rmdir