I've been working with a handy php script, which scans my site and spits out links to all the pages it finds. The problem is, it's also scanning my 'includes' folder, which contains all my .inc.php files.
Obviously I'd rather it ignore this folder when scanning the site, but for the life of me I can't see how to edit the script to tell it to do so.
The script is:
<?php
// starting directory. Dot means current directory
$basedir = ".";
// function to count depth of directory
function getdepth($fn){
return (($p = strpos($fn, "/")) === false) ? 0 : (1 + getdepth(substr($fn, $p+1)));
}
// function to print a line of html for the indented hyperlink
function printlink($fn){
$indent = getdepth($fn); // get indent value
echo "<li class=\"$indent\"><a href=\"$fn\">"; //print url
$handle = fopen($fn, "r"); //open web page file
$filestr = fread($handle, 1024); //read top part of html
fclose($handle); //clos web page file
if (preg_match("/<title>.+<\/title>/i",$filestr,$title)) { //get page title
echo substr($title[0], 7, strpos($title[0], '/')-8); //print title
} else {
echo "No title";
}
echo "</a></li><br>\n"; //finish html
}
// main function that scans the directory tree for web pages
function listdir($basedir){
if ($handle = #opendir($basedir)) {
while (false !== ($fn = readdir($handle))){
if ($fn != '.' && $fn != '..'){ // ignore these
$dir = $basedir."/".$fn;
if (is_dir($dir)){
listdir($dir); // recursive call to this function
} else { //only consider .html etc. files
if (preg_match("/[^.\/].+\.(htm|html|php)$/",$dir,$fname)) {
printlink($fname[0]); //generate the html code
}
}
}
}
closedir($handle);
}
}
// function call
listdir($basedir); //this line starts the ball rolling
?>
Now I can see where the script is told to ignore certain files, and I've tried appending:
&& $dir != 'includes'
...to it in numerous places, but my php knowledge is simply too shaky to know exactly how to integrate that code into the script.
If anyone can help, then you'd be saving me an awfully large headache. Cheers.
Add it this line:
if ($fn != '.' && $fn != '..'){ // ignore these
so it's
if ($fn != '.' && $fn != '..' && $fn != 'includes'){ // ignore these
Your path needs to be absolute. Add it at the top of listdir
function listdir($basedir){
if($basedir == '/path/to/includes') {
return;
} [...]
This also makes sure that only one includes folder will be ignored.
I have a script that gets a string from a config file and based on that string grabs the file names of a folder.
I now only need the iso files. Not sure if the best way is to check for the .iso string or is there another method?
<?php
// Grab the contents of the "current.conf" file, removing any linebreaks.
$dirPath = trim(file_get_contents('current.conf')).'/';
$fileList = scandir($dirPath);
if(is_array($fileList)) {
foreach($fileList as $file) {
//could replace the below if statement to only proceed if the .iso string is present. But I am worried there could be issues with this.
if ($file != "." and $file != ".." and $file != "index.php")
{
echo "<br/><a href='". $dirPath.$file."'>" .$file."</a>\n";
}
}
}
else echo $dirPath.' cound not be scanned.';
?>
If you only need the files with an extension of .iso, then why not use:
glob($dirPath.'/*.iso');
rather than scandir()
try this:
if(is_array($fileList)) {
foreach($fileList as $file) {
$fileSplode = explode('.',$file); //split by '.'
//this means that u now have an array with the 1st element being the
//filename and the 2nd being the extension
echo (isset($fileSplode[1]) && $fileSplode[1]=='iso')?
"<br/><a href='". $dirPath.$file."'>" .$file."</a>\n":'');
}
}
If you want it in an OOP style you could use:
<?php
foreach (new DirectoryIterator($dirPath) as $fileInfo) {
if($fileInfo->getExtension() == 'iso') {
// do something with it
}
}
?>
I have created this php script which displays the contents of a designated directory and allows users to download each file. Here is the code:
<?php
if ($handle = opendir('test')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
echo "<a href='test/$file'>$file\n</a><br/>";
}
}
closedir($handle);
}
?>
This script also displays folders, but when I click a folder, it does display the contents of the folder, but in the default Apache autoindex view.
What I would like the script to do when a folder is clicked, is display the contents, but in the same fashion as the original script does (as this is more editable with css and the like).
Would you know how to achieve this?
Don't create a link to the directory itself, but to a php page which displays the contents.
Change your php code to somthing like:
if(isset($_REQUEST['dir'])) {
$current_dir = $_REQUEST['dir'];
} else {
$current_dir = 'test';
}
if ($handle = opendir($current_dir)) {
while (false !== ($file_or_dir = readdir($handle))) {
if(in_array($file_or_dir, array('.', '..'))) continue;
$path = $current_dir.'/'.$file_or_dir;
if(is_file($path)) {
echo ''.$file_or_dir."\n<br/>";
} else {
echo ''.$file_or_dir."\n<br/>";
}
}
closedir($handle);
}
PS write you html code with double quotes.
You need your HREF to point back to your PHP script, and not the directory. You will then need to update your PHP script to now which directory it needs to read.
when moving one file from one location to another i use
rename('path/filename', 'newpath/filename');
how do you move all files in a folder to another folder? tried this one without result:
rename('path/*', 'newpath/*');
A slightly verbose solution:
// Get array of all source files
$files = scandir("source");
// Identify directories
$source = "source/";
$destination = "destination/";
// Cycle through all source files
foreach ($files as $file) {
if (in_array($file, array(".",".."))) continue;
// If we copied this successfully, mark it for deletion
if (copy($source.$file, $destination.$file)) {
$delete[] = $source.$file;
}
}
// Delete all successfully-copied files
foreach ($delete as $file) {
unlink($file);
}
Please try this solution, it's tested successfully ::
<?php
$files = scandir("f1");
$oldfolder = "f1/";
$newfolder = "f2/";
foreach($files as $fname) {
if($fname != '.' && $fname != '..') {
rename($oldfolder.$fname, $newfolder.$fname);
}
}
?>
An alternate using rename() and with some error checking:
$srcDir = 'dir1';
$destDir = 'dir2';
if (file_exists($destDir)) {
if (is_dir($destDir)) {
if (is_writable($destDir)) {
if ($handle = opendir($srcDir)) {
while (false !== ($file = readdir($handle))) {
if (is_file($srcDir . '/' . $file)) {
rename($srcDir . '/' . $file, $destDir . '/' . $file);
}
}
closedir($handle);
} else {
echo "$srcDir could not be opened.\n";
}
} else {
echo "$destDir is not writable!\n";
}
} else {
echo "$destDir is not a directory!\n";
}
} else {
echo "$destDir does not exist\n";
}
tried this one?:
<?php
$oldfolderpath = "old/folder";
$newfolderpath = "new/folder";
rename($oldfolderpath,$newfolderpath);
?>
So I tried to use the rename() function as described and I kept getting the error back that there was no such file or directory. I placed the code within an if else statement in order to ensure that I really did have the directories created. It looked like this:
$tempDir = '/home/site/images/tmp/';
$permanentDir = '/home/site/images/' . $claimid; // this was stored above
mkdir($permanentDir,0775);
if(is_dir($permanentDir)){
echo $permanentDir . ' is a directory';
if(is_dir($tempDir)){
echo $tempDir . ' is a directory';
}else{
echo $tempDir . ' is not a directory';
}
}else{
echo $permanentDir . ' is not a directory';
}
rename($tempDir . "*", $permanentDir);
So when I ran the code again, it spit out that both paths were directories. I was stumped. I talked with a coworker and he suggested, "Why not just rename the temp directory to the new directory, since you want to move all the files anyway?"
Turns out, this is what I ended up doing. I gave up trying to use the wildcard with the rename() function and instead just use the rename() to rename the temp directory to the permanent one.
so it looks like this.
$tempDir = '/home/site/images/tmp/';
$permanentDir = '/home/site/images/' . $claimid; // this was stored above
mkdir($permanentDir,0775);
rename($tempDir, $permanentDir);
This worked beautifully for my purposes since I don't need the old tmp directory to remain there after the files have been uploaded and "moved".
Hope this helps. If anyone knows why the wildcard doesn't work in the rename() function and why I was getting the error stating above, please, let me know.
Move or copy the way I use it
function copyfiles($source_folder, $target_folder, $move=false) {
$source_folder=trim($source_folder, '/').'/';
$target_folder=trim($target_folder, '/').'/';
$files = scandir($source_folder);
foreach($files as $file) {
if($file != '.' && $file != '..') {
if ($move) {
rename($source_folder.$file, $target_folder.$file);
} else {
copy($source_folder.$file, $target_folder.$file);
}
}
}
}
function movefiles($source_folder, $target_folder) {
copyfiles($source_folder, $target_folder, $move=true);
}
try this:
rename('path/*', 'newpath/');
I do not see a point in having an asterisk in the destination
If the target directory doesn't exist, you'll need to create it first:
mkdir('newpath');
rename('path/*', 'newpath/');
As a side note; when you copy files to another folder, their last changed time becomes current timestamp. So you should touch() the new files.
... (some codes for directory looping) ...
if (copy($source.$file, $destination.$file)) {
$delete[] = $source.$file;
$filetimestamp = filemtime($source.$file);
touch($destination.$file,$filetimestamp);
}
... (some codes) ...
Not sure if this helps anyone or not, but thought I'd post anyway. Had a challenge where I has heaps of movies I'd purchased and downloaded through various online stores all stored in one folder, but all in their own subfolders and all with different naming conventions. I wanted to move all of them into the parent folder and rename them all to look pretty. all of the subfolders I'd managed to rename with a bulk renaming tool and conditional name formatting. the subfolders had other files in them i didn't want. so i wrote the following php script to, 1. rename/move all files with extension mp4 to their parent directory while giving them the same name as their containing folder, 2. delete contents of subfolders and look for directories inside them to empty and then rmdir, 3. rmdir the subfolders.
$handle = opendir("D:/Movies/");
while ($file = readdir($handle)) {
if ($file != "." && $file != ".." && is_dir($file)) {
$newhandle = opendir("D:/Movies/".$file);
while($newfile = readdir($newhandle)) {
if ($newfile != "." && $newfile != ".." && is_file("D:/Movies/".$file."/".$newfile)) {
$parts = explode(".",$newfile);
if (end($parts) == "mp4") {
if (!file_exists("D:/Movies/".$file.".mp4")) {
rename("D:/Movies/".$file."/".$newfile,"D:/Movies/".$file.".mp4");
}
else {
unlink("D:/Movies/".$file."/".$newfile);
}
}
else { unlink("D:/Movies/".$file."/".$newfile); }
}
else if ($newfile != "." && $newfile != ".." && is_dir("D:/Movies/".$file."/".$newfile)) {
$dirhandle = opendir("D:/Movies/".$file."/".$newfile);
while ($dirfile = readdir($dirhandle)){
if ($dirfile != "." && $dirfile != ".."){
unlink("D:/Movies/".$file."/".$newfile."/".$dirfile);
}
}
rmdir("D:/Movies/".$file."/".$newfile);
}
}
unlink("D:/Movies/".$file);
}
}
i move all my .json files from root folder to json folder with this
foreach (glob("*.json") as $filename) {
rename($filename,"json/".$filename);
}
pd: someone 2020?
I tried to write a script to list all files in directories and subdirectories and so on.. The script works fine if I don't include the check to see whether any of the files are directories. The code doesn't generate errors but it generates a hundred lines of text saying "Directory Listing of ." instead of what I was expecting. Any idea why this isn't working?
<?php
//define the path as relative
$path = "./";
function listagain($pth)
{
//using the opendir function
$dir_handle = #opendir($pth) or die("Unable to open $pth");
echo "Directory Listing of $pth<br/>";
//running the while loop
while ($file = readdir($dir_handle))
{
//check whether file is directory
if(is_dir($file))
{
//if it is, generate it's list of files
listagain($file);
}
else
{
if($file!="." && $file!="..")
echo "<a href='$file'>$file</a><br/>";
}
}
//closing the directory
closedir($dir_handle);
}
listagain($path)
?>
The first enties . and .. refer to the current and parent directory respectivly. So you get a infinite recursion.
You should first check for that before checking the file type:
if ($file!="." && $file!="..") {
if (is_dir($file)) {
listagain($file);
} else {
echo ''.htmlspecialchars($file).'<br/>';
}
}
The problem is, variable $file contains only basename of path. So, you need to use $pth.$file.