PHP dynamic gallery problem - php

I'm trying to create a dynamic image gallery script, so that a client, once I'm done with the site, can upload images via FTP and the site will update automatically. I'm using a script I found on here, but I cannot get it to work for the life of me. The PHP writes information, but will never actually write out the images it's supposed to find in the directory. Not sure why. Demo here and you can see the working code (without PHP) here.
<?php
function getDirTree($dir,$p=true) {
$d = dir($dir);$x=array();
while (false !== ($r = $d->read())) {
if($r!="."&&$r!=".."&&(($p==false&&is_dir($dir.$r))||$p==true)) {
$x[$r] = (is_dir($dir.$r)?array():(is_file($dir.$r)?true:false));
}
}
foreach ($x as $key => $value) {
if (is_dir($dir.$key."/")) {
$x[$key] = getDirTree($dir.$key."/",$p);
}
}
ksort($x);
return $x;
}
$path = "../images/bettydew/";
$tree = getDirTree($path);
echo '<ul class="gallery">';
foreach($tree as $element => $eval) {
if (is_array($eval)) {
foreach($eval as $file => $value) {
if (strstr($file, "png")||strstr($file, "jpg")||strstr($file, "bmp")||strstr($file, "gif")) {
$item = $path.$file;
echo '<img src="'.$item.'" alt="'.$item.'"/>';
}
}
}
}
echo '</ul>';
?>

path problem and a recursion problem in the sub-directories.
perhaps try this:
<?php
$path = "./images/bettydew/";
$file_array = array ();
readThisDir ( $path, &$file_array );
echo '<ul class="gallery">';
foreach ( $file_array as $file )
{
if (strstr($file, "png")||strstr($file, "jpg")||strstr($file, "bmp")||strstr($file, "gif"))
{
list($width, $height) = getimagesize($file);
echo '<li><img src="'.$file.'" width="'.$width.'" height="'.$height.'" alt="'.$file.'"/></li>';
}
}
echo '</ul>';
function readThisDir ( $path, $arr )
{
if ($handle = opendir($path))
{
while (false !== ($file = readdir($handle)))
{
if ($file != "." && $file != "..")
{
if (is_dir ( $path."/".$file ))
{
readThisDir ($path."/".$file, &$arr);
} else {
$arr[] = $path."/".$file;
}
}
}
closedir($handle);
}
}
?>

Either Your path is mistake... it caused me similar error when i feed wrong path to the $path variable.
Or you do not have read permission on that directory... check the permissions too
And remember to check '/' at the end of your path as without it your code cannot do recursive search inside the child directory...
And finally your code will not give the correct file path of the files of sub-directory while writing output... so check it too...

Related

how to search for a file with php

First thing is first. I am not a php developer this is something that is needed for my job so I took it on and I am learning as i go
Right now we have an excel sheet that holds links for a manuals for the items we make and these have to be updated manually. It can take hours to do. so I am trying to find a way to do this to cut the time.
I can read the excel file to get the info I need using javascript and then I send that to php with an ajax call.
I have made sure I get the data I need and make it look how they do on the server.
I have been googling all day trying to get it to work but I just keep coming up empty.
Here is my code in the php file.
<?php
$search = isset($_POST['urlData']) ? rawurldecode($_POST['urlData']) : "Nope Still not set";
$path = $_SERVER['DOCUMENT_ROOT'];
$it = new RecursiveDirectoryIterator( $path );
foreach (new RecursiveIteratorIterator($it) as $file){
$pathfile = str_replace($path,'',$file);
if (strpos($pathfile, $search) !== false) {
echo " pathFile var => ". $pathfile . "| Search var => " . $search;
$encodedUrl = rawurlencode($pathfile .$search);
echo 'link = http://manuals.myCompany.com/'. $doneUrl .'<br>';
}else{
echo "File does not exist => ";
echo $path. "<= Path " . $search."<= Search ". $pathfile . "<= Pathfile";
}
break;
}
So I need to give the php file the name of a manual and see if it is in the directory somewhere.
this file is searchManuals.php stored in the manuals folder (manuals/searchManuals.php).The files I look for are in folders in the same directory with it (manuals/english/jdv0/pdf/manual.pdf).
Try this:
$file_to_search = "abc.pdf";
search_file('.',$file_to_search);
function search_file($dir,$file_to_search){
$files = scandir($dir);
foreach($files as $key => $value){
$path = realpath($dir.DIRECTORY_SEPARATOR.$value);
if(!is_dir($path)) {
if($file_to_search == $value){
echo "file found<br>";
echo $path;
break;
}
} else if($value != "." && $value != "..") {
search_file($path, $file_to_search);
}
}
}
Inspired by VK321's answer, here is another version with early termination:
class Test
{
public static function find($dir, $targetFile)
{
$filePath = null;
// pass function ref &$search so we can make recursive call
// pass &$filePath ref so we can get rid of it as class param
$search = function ($dir, $targetFile) use (&$search, &$filePath) {
if (null !== $filePath) return; // early termination
$files = scandir($dir);
foreach ($files as $key => $file) {
if ($file == "." || $file == "..") continue;
$path = realpath($dir . DIRECTORY_SEPARATOR . $file);
if (is_file($path)) {
if ($file === $targetFile) {
$filePath = $path;
break;
}
} else {
$search($path, $targetFile);
}
}
};
$search($dir, $targetFile); // invoke the function
return $filePath;
}
}
// $dir = './', $targetFile = "Foo.php";
echo Test::find($dir, $targetFile);
How about glob() function?
PHP Docs

PHP Sort Files In Directory by Type

I wrote the following PHP code to display files in a directory. It uses JQuery to expand folders. Everything works fine but right now it displays all files in alphabetical order mixing file types.
I'd like to keep the alphabetical order but display folders and files separately. How can I sort the displayed files so Folders are displayed on top and other files are displayed bellow.
In other words, how do I sort the files by file type?
Thank you very much!
<?php
$path = ROOT_PATH;
$dir_handle = #opendir($path) or die("Unable to open $path");
list_dir($dir_handle,$path);
function list_dir($dir_handle,$path)
{
echo "<ul class='treeview'>";
while (false !== ($file = readdir($dir_handle)))
{
$dir =$path.'/'.$file;
if(is_dir($dir) && $file != '.' && $file !='..' )
{
$handle = #opendir($dir) or die("undable to open file $file");
echo '<li class="folder">'.$file.'</li>';
list_dir($handle, $dir);
}
elseif($file != '.' && $file !='..')
{
echo '<li class="file">'.$file.'</li>';
}
}
echo "</ul>";
closedir($dir_handle);
}
?>
First thing you should do is separate the logic of getting/sorting the files and displaying them, that'll make customisation easier..
Here's a working solution (had some spare time this morning :)
list_dir(ROOT_PATH);
/* Rendering */
function list_dir($path)
{
$items = get_sorted_entries($path);
if (!$items)
return;
echo "<ul class='treeview'>";
foreach($items as $item)
{
if ($item->type=='dir')
{
echo '<li class="folder">'.$item->entry.'</li>';
list_dir($item->full_path);
}
else
{
echo '<li class="file">'.$item->entry.'</li>';
}
}
echo "</ul>";
}
/* Finding */
function get_sorted_entries($path)
{
$dir_handle = #opendir($path) ;
$items = array();
while (false !== ($item = readdir($dir_handle)))
{
$dir =$path.'/'.$item;
if ( $item == '.' || $item =='..' )
continue;
if(is_dir($dir))
{
$items[] = (object) array('type'=>'dir','entry'=>$item, 'full_path'=>$dir);
}
else
{
$items[] = (object) array('type'=>'file','entry'=>$item, 'full_path'=>$dir);
}
}
closedir($dir_handle);
usort($items,'_sort_entries');
return $items;
}
/* Sorting */
function _sort_entries($a, $b)
{
return strcmp($a->entry,$b->entry);
}
Edit: And if you want to show the directories first, change the sort function to this:
function _sort_entries($a, $b)
{
if ($a->type!=$b->type)
return strcmp($a->type,$b->type);
return strcmp($a->entry,$b->entry);
}
That will put the directories at the top (Windows style)

Delete directory with files in it?

I wonder, what's the easiest way to delete a directory with all its files in it?
I'm using rmdir(PATH . '/' . $value); to delete a folder, however, if there are files inside of it, I simply can't delete it.
There are at least two options available nowadays.
Before deleting the folder, delete all its files and folders (and this means recursion!). Here is an example:
public static function deleteDir($dirPath) {
if (! is_dir($dirPath)) {
throw new InvalidArgumentException("$dirPath must be a directory");
}
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
$dirPath .= '/';
}
$files = glob($dirPath . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
self::deleteDir($file);
} else {
unlink($file);
}
}
rmdir($dirPath);
}
And if you are using 5.2+ you can use a RecursiveIterator to do it without implementing the recursion yourself:
$dir = 'samples' . DIRECTORY_SEPARATOR . 'sampledirtree';
$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($it,
RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file) {
if ($file->isDir()){
rmdir($file->getRealPath());
} else {
unlink($file->getRealPath());
}
}
rmdir($dir);
I generally use this to delete all files in a folder:
array_map('unlink', glob("$dirname/*.*"));
And then you can do
rmdir($dirname);
what's the easiest way to delete a directory with all its files in it?
system("rm -rf ".escapeshellarg($dir));
Short function that does the job:
function deleteDir($path) {
return is_file($path) ?
#unlink($path) :
array_map(__FUNCTION__, glob($path.'/*')) == #rmdir($path);
}
I use it in a Utils class like this:
class Utils {
public static function deleteDir($path) {
$class_func = array(__CLASS__, __FUNCTION__);
return is_file($path) ?
#unlink($path) :
array_map($class_func, glob($path.'/*')) == #rmdir($path);
}
}
With great power comes great responsibility: When you call this function with an empty value, it will delete files starting in root (/). As a safeguard you can check if path is empty:
function deleteDir($path) {
if (empty($path)) {
return false;
}
return is_file($path) ?
#unlink($path) :
array_map(__FUNCTION__, glob($path.'/*')) == #rmdir($path);
}
As seen in most voted comment on PHP manual page about rmdir() (see http://php.net/manual/es/function.rmdir.php), glob() function does not return hidden files. scandir() is provided as an alternative that solves that issue.
Algorithm described there (which worked like a charm in my case) is:
<?php
function delTree($dir)
{
$files = array_diff(scandir($dir), array('.', '..'));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
?>
You may use Symfony's Filesystem (code):
// composer require symfony/filesystem
use Symfony\Component\Filesystem\Filesystem;
(new Filesystem)->remove($dir);
However I couldn't delete some complex directory structures with this method, so first you should try it to ensure it's working properly.
I could delete the said directory structure using a Windows specific implementation:
$dir = strtr($dir, '/', '\\');
// quotes are important, otherwise one could
// delete "foo" instead of "foo bar"
system('RMDIR /S /Q "'.$dir.'"');
And just for the sake of completeness, here is an old code of mine:
function xrmdir($dir) {
$items = scandir($dir);
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $dir.'/'.$item;
if (is_dir($path)) {
xrmdir($path);
} else {
unlink($path);
}
}
rmdir($dir);
}
This is a shorter Version works great to me
function deleteDirectory($dirPath) {
if (is_dir($dirPath)) {
$objects = scandir($dirPath);
foreach ($objects as $object) {
if ($object != "." && $object !="..") {
if (filetype($dirPath . DIRECTORY_SEPARATOR . $object) == "dir") {
deleteDirectory($dirPath . DIRECTORY_SEPARATOR . $object);
} else {
unlink($dirPath . DIRECTORY_SEPARATOR . $object);
}
}
}
reset($objects);
rmdir($dirPath);
}
}
You can try as follows:
/*
* Remove the directory and its content (all files and subdirectories).
* #param string $dir the directory name
*/
function rmrf($dir) {
foreach (glob($dir) as $file) {
if (is_dir($file)) {
rmrf("$file/*");
rmdir($file);
} else {
unlink($file);
}
}
}
I can't believe there are 30+ answers for this. Recursively deleting a folder in PHP could take minutes depending on the depth of the directory and the number of files in it! You can do this with one line of code ...
shell_exec("rm -rf " . $dir);
If you're concerned with deleting the entire filesystem, make sure your $dir path is exactly what you want first. NEVER allow a user to input something that can directly delete files without first heavily validating the input. That's essential coding practice.
This one works for me:
function removeDirectory($path) {
$files = glob($path . '/*');
foreach ($files as $file) {
is_dir($file) ? removeDirectory($file) : unlink($file);
}
rmdir($path);
return;
}
Here you have one nice and simple recursion for deleting all files in source directory including that directory:
function delete_dir($src) {
$dir = opendir($src);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
delete_dir($src . '/' . $file);
}
else {
unlink($src . '/' . $file);
}
}
}
closedir($dir);
rmdir($src);
}
Function is based on recursion made for copying directory. You can find that function here:
Copy entire contents of a directory to another using php
Glob function doesn't return the hidden files, therefore scandir can be more useful, when trying to delete recursively a tree.
<?php
public static function delTree($dir) {
$files = array_diff(scandir($dir), array('.','..'));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
?>
Example for the Linux server: exec('rm -f -r ' . $cache_folder . '/*');
Litle bit modify of alcuadrado's code - glob don't see files with name from points like .htaccess so I use scandir and script deletes itself - check __FILE__.
function deleteDir($dirPath) {
if (!is_dir($dirPath)) {
throw new InvalidArgumentException("$dirPath must be a directory");
}
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
$dirPath .= '/';
}
$files = scandir($dirPath);
foreach ($files as $file) {
if ($file === '.' || $file === '..') continue;
if (is_dir($dirPath.$file)) {
deleteDir($dirPath.$file);
} else {
if ($dirPath.$file !== __FILE__) {
unlink($dirPath.$file);
}
}
}
rmdir($dirPath);
}
The Best Solution for me
my_folder_delete("../path/folder");
code:
function my_folder_delete($path) {
if(!empty($path) && is_dir($path) ){
$dir = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS); //upper dirs are not included,otherwise DISASTER HAPPENS :)
$files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($files as $f) {if (is_file($f)) {unlink($f);} else {$empty_dirs[] = $f;} } if (!empty($empty_dirs)) {foreach ($empty_dirs as $eachDir) {rmdir($eachDir);}} rmdir($path);
}
}
p.s. REMEMBER! dont pass EMPTY VALUES to any Directory deleting functions!!! (backup them always, otherwise one day you might get DISASTER!!)
I want to expand on the answer by #alcuadrado with the comment by #Vijit for handling symlinks. Firstly, use getRealPath(). But then, if you have any symlinks that are folders it will fail as it will try and call rmdir on a link - so you need an extra check.
$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file) {
if ($file->isLink()) {
unlink($file->getPathname());
} else if ($file->isDir()){
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}
rmdir($dir);
I prefer this because it still returns TRUE when it succeeds and FALSE when it fails, and it also prevents a bug where an empty path might try and delete everything from '/*' !!:
function deleteDir($path)
{
return !empty($path) && is_file($path) ?
#unlink($path) :
(array_reduce(glob($path.'/*'), function ($r, $i) { return $r && deleteDir($i); }, TRUE)) && #rmdir($path);
}
What about this:
function recursiveDelete($dirPath, $deleteParent = true){
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) {
$path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname());
}
if($deleteParent) rmdir($dirPath);
}
Using DirectoryIterator an equivalent of a previous answer…
function deleteFolder($rootPath)
{
foreach(new DirectoryIterator($rootPath) as $fileToDelete)
{
if($fileToDelete->isDot()) continue;
if ($fileToDelete->isFile())
unlink($fileToDelete->getPathName());
if ($fileToDelete->isDir())
deleteFolder($fileToDelete->getPathName());
}
rmdir($rootPath);
}
you can try this simple 12 line of code for delete folder or folder files...
happy coding... ;) :)
function deleteAll($str) {
if (is_file($str)) {
return unlink($str);
}
elseif (is_dir($str)) {
$scan = glob(rtrim($str,'/').'/*');
foreach($scan as $index=>$path) {
$this->deleteAll($path);
}
return #rmdir($str);
}
}
Something like this?
function delete_folder($folder) {
$glob = glob($folder);
foreach ($glob as $g) {
if (!is_dir($g)) {
unlink($g);
} else {
delete_folder("$g/*");
rmdir($g);
}
}
}
Delete all files in Folder
array_map('unlink', glob("$directory/*.*"));
Delete all .*-Files in Folder (without: "." and "..")
array_map('unlink', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
Now delete the Folder itself
rmdir($directory)
2 cents to add to THIS answer above, which is great BTW
After your glob (or similar) function has scanned/read the directory, add a conditional to check the response is not empty, or an invalid argument supplied for foreach() warning will be thrown. So...
if( ! empty( $files ) )
{
foreach( $files as $file )
{
// do your stuff here...
}
}
My full function (as an object method):
private function recursiveRemoveDirectory( $directory )
{
if( ! is_dir( $directory ) )
{
throw new InvalidArgumentException( "$directory must be a directory" );
}
if( substr( $directory, strlen( $directory ) - 1, 1 ) != '/' )
{
$directory .= '/';
}
$files = glob( $directory . "*" );
if( ! empty( $files ) )
{
foreach( $files as $file )
{
if( is_dir( $file ) )
{
$this->recursiveRemoveDirectory( $file );
}
else
{
unlink( $file );
}
}
}
rmdir( $directory );
} // END recursiveRemoveDirectory()
Here is the solution that works perfect:
function unlink_r($from) {
if (!file_exists($from)) {return false;}
$dir = opendir($from);
while (false !== ($file = readdir($dir))) {
if ($file == '.' OR $file == '..') {continue;}
if (is_dir($from . DIRECTORY_SEPARATOR . $file)) {
unlink_r($from . DIRECTORY_SEPARATOR . $file);
}
else {
unlink($from . DIRECTORY_SEPARATOR . $file);
}
}
rmdir($from);
closedir($dir);
return true;
}
What about this?
function Delete_Directory($Dir)
{
if(is_dir($Dir))
{
$files = glob( $Dir . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned
foreach( $files as $file )
{
Delete_Directory( $file );
}
if(file_exists($Dir))
{
rmdir($Dir);
}
}
elseif(is_file($Dir))
{
unlink( $Dir );
}
}
Refrence:
https://paulund.co.uk/php-delete-directory-and-files-in-directory
You could copy the YII helpers
$directory (string) - to be deleted recursively.
$options (array) - for the directory removal.
Valid options are:
traverseSymlinks: boolean, whether symlinks to the directories should be traversed too. Defaults to false, meaning that the content of the symlinked directory would not be deleted. Only symlink would be removed in that default case.
public static function removeDirectory($directory,$options=array())
{
if(!isset($options['traverseSymlinks']))
$options['traverseSymlinks']=false;
$items=glob($directory.DIRECTORY_SEPARATOR.'{,.}*',GLOB_MARK | GLOB_BRACE);
foreach($items as $item)
{
if(basename($item)=='.' || basename($item)=='..')
continue;
if(substr($item,-1)==DIRECTORY_SEPARATOR)
{
if(!$options['traverseSymlinks'] && is_link(rtrim($item,DIRECTORY_SEPARATOR)))
unlink(rtrim($item,DIRECTORY_SEPARATOR));
else
self::removeDirectory($item,$options);
}
else
unlink($item);
}
if(is_dir($directory=rtrim($directory,'\\/')))
{
if(is_link($directory))
unlink($directory);
else
rmdir($directory);
}
}
<?php
function rrmdir($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($dir."/".$object) == "dir")
rrmdir($dir."/".$object);
else unlink ($dir."/".$object);
}
}
reset($objects);
rmdir($dir);
}
}
?>
Have your tryed out the obove code from php.net
Work for me fine
For windows:
system("rmdir ".escapeshellarg($path) . " /s /q");
Like Playnox's solution, but with the elegant built-in DirectoryIterator:
function delete_directory($dirPath){
if(is_dir($dirPath)){
$objects=new DirectoryIterator($dirPath);
foreach ($objects as $object){
if(!$object->isDot()){
if($object->isDir()){
delete_directory($object->getPathname());
}else{
unlink($object->getPathname());
}
}
}
rmdir($dirPath);
}else{
throw new Exception(__FUNCTION__.'(dirPath): dirPath is not a directory!');
}
}
I do not remember from where I copied this function, but it looks like it is not listed and it is working for me
function rm_rf($path) {
if (#is_dir($path) && is_writable($path)) {
$dp = opendir($path);
while ($ent = readdir($dp)) {
if ($ent == '.' || $ent == '..') {
continue;
}
$file = $path . DIRECTORY_SEPARATOR . $ent;
if (#is_dir($file)) {
rm_rf($file);
} elseif (is_writable($file)) {
unlink($file);
} else {
echo $file . "is not writable and cannot be removed. Please fix the permission or select a new path.\n";
}
}
closedir($dp);
return rmdir($path);
} else {
return #unlink($path);
}
}

Delete the unwanted files and folders from destination folder as compared to source folder

I am using PHP and I need to script something like below:
I have to compare two folder structure
and with reference of source folder I
want to delete all the files/folders
present in other destination folder
which do not exist in reference source
folder, how could i do this?
EDITED:
$original = scan_dir_recursive('/var/www/html/copy2');
$mirror = scan_dir_recursive('/var/www/html/copy1');
function scan_dir_recursive($dir) {
$all_paths = array();
$new_paths = scandir($dir);
foreach ($new_paths as $path) {
if ($path == '.' || $path == '..') {
continue;
}
$path = $dir . DIRECTORY_SEPARATOR . $path;
if (is_dir($path)) {
$all_paths = array_merge($all_paths, scan_dir_recursive($path));
} else {
$all_paths[] = $path;
}
}
return $all_paths;
}
foreach($mirror as $mirr)
{
if($mirr != '.' && $mirr != '..')
{
if(!in_array($mirr, $original))
{
unlink($mirr);
// delete the file
}
}
}
The above code shows what i did..
Here My copy1 folder contains extra files than copy2 folders hence i need these extra files to be deleted.
EDITED:
Below given output is are arrays of original Mirror and of difference of both..
Original Array
(
[0] => /var/www/html/copy2/Copy (5) of New Text Document.txt
[1] => /var/www/html/copy2/Copy of New Text Document.txt
)
Mirror Array
(
[0] => /var/www/html/copy1/Copy (2) of New Text Document.txt
[1] => /var/www/html/copy1/Copy (3) of New Text Document.txt
[2] => /var/www/html/copy1/Copy (5) of New Text Document.txt
)
Difference Array
(
[0] => /var/www/html/copy1/Copy (2) of New Text Document.txt
[1] => /var/www/html/copy1/Copy (3) of New Text Document.txt
[2] => /var/www/html/copy1/Copy (5) of New Text Document.txt
)
when i iterate a loop to delete on difference array all files has to be deleted as per displayed output.. how can i rectify this.. the loop for deletion is given below.
$dirs_to_delete = array();
foreach ($diff_path as $path) {
if (is_dir($path)) {
$dirs_to_delete[] = $path;
} else {
unlink($path);
}
}
while ($dir = array_pop($dirs_to_delete)) {
rmdir($dir);
}
First you need a recursive listing of both directories. A simple function like this will work:
function scan_dir_recursive($dir, $rel = null) {
$all_paths = array();
$new_paths = scandir($dir);
foreach ($new_paths as $path) {
if ($path == '.' || $path == '..') {
continue;
}
if ($rel === null) {
$path_with_rel = $path;
} else {
$path_with_rel = $rel . DIRECTORY_SEPARATOR . $path;
}
$full_path = $dir . DIRECTORY_SEPARATOR . $path;
$all_paths[] = $path_with_rel;
if (is_dir($full_path)) {
$all_paths = array_merge(
$all_paths, scan_dir_recursive($full_path, $path_with_rel)
);
}
}
return $all_paths;
}
Then you can compute their difference with array_diff.
$diff_paths = array_diff(
scan_dir_recursive('/foo/bar/mirror'),
scan_dir_recursive('/qux/baz/source')
);
Iterating over this array, you will be able to start deleting files. Directories are a bit trickier because they must be empty first.
// warning: test this code yourself before using on real data!
$dirs_to_delete = array();
foreach ($diff_paths as $path) {
if (is_dir($path)) {
$dirs_to_delete[] = $path;
} else {
unlink($path);
}
}
while ($dir = array_pop($dirs_to_delete)) {
rmdir($dir);
}
I've tested things and it should be working well now. Of course, don't take my word for it. Make sure to setup your own safe test before deleting real data.
For recursive directories please use:
$modified_directory = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('path/to/modified'), true
);
$modified_files = array();
foreach ($modified_directory as $file)
{
$modified_files []= $file->getPathname();
}
You can do other things like $file->isDot(), or $file->isFile(). For more file commands with SPLFileInfo visit http://www.php.net/manual/en/class.splfileinfo.php
Thanks all for the precious time given to my work, Special Thanks to erisco for his dedication for my problem, Below Code is the perfect code to acomplish the task I was supposed to do, with a little change in the erisco's last edited reply...
$source = '/var/www/html/copy1';
$mirror = '/var/www/html/copy2';
function scan_dir_recursive($dir, $rel = null) {
$all_paths = array();
$new_paths = scandir($dir);
foreach ($new_paths as $path) {
if ($path == '.' || $path == '..') {
continue;
}
if ($rel === null) {
$path_with_rel = $path;
} else {
$path_with_rel = $rel . DIRECTORY_SEPARATOR . $path;
}
$full_path = $dir . DIRECTORY_SEPARATOR . $path;
$all_paths[] = $path_with_rel;
if (is_dir($full_path)) {
$all_paths = array_merge(
$all_paths, scan_dir_recursive($full_path, $path_with_rel)
);
}
}
return $all_paths;
}
$diff_paths = array_diff(
scan_dir_recursive($mirror),
scan_dir_recursive($source)
);
echo "<pre>Difference ";print_r($diff_paths);
$dirs_to_delete = array();
foreach ($diff_paths as $path) {
$path = $mirror."/".$path;//added code to unlink.
if (is_dir($path)) {
$dirs_to_delete[] = $path;
} else {
if(unlink($path))
{
echo "File ".$path. "Deleted.";
}
}
}
while ($dir = array_pop($dirs_to_delete)) {
rmdir($dir);
}
First do a scandir() of the original folder, then do a scandir on mirror folder. start traversing the mirror folder array and check if that file is present in the scandir() of original folder. something like this
$original = scandir('path/to/original/folder');
$mirror = scandir('path/to/mirror/folder');
foreach($mirror as $mirr)
{
if($mirr != '.' && $mirr != '..')
{
if(in_array($mirr, $original))
{
// do not delete the file
}
else
{
// delete the file
unlink($mirr);
}
}
}
this should solve your problem. you will need to modify the above code accordingly (include some recursion in the above code to check if the folder that you are trying to delete is empty or not, if it is not empty then you will first need to delete all the file/folders in it and then delete the parent folder).

Dynamically pulling images and creating links

Is there a way to pull images from a directory and place them on a webpage and have links attached to those images that would take a person to a specific webpage associated with that image using PHP?
Thanks
something like this should do it :
if ($handle = opendir('/path/to/files')) {
    echo "Directory handle: $handle\n";
    echo "Files:\n";
    /* This is the correct way to loop over the directory. */
    while (false !== ($file = readdir($handle))) {
if(substr($file, -3) == 'jpg'){ //modify to handle filetypes you want
        echo "<a href='/path/to/files/".$file."'>".$file."</a>";
}
    }
    closedir($handle);
}
are you asking how to scan the directory or how to associate a list of images with urls?
the answer to the first question is glob() function
the second answer is to use an assoc array
$list = array('foo.gif' => 'bar.php', 'blah.gif' => 'quux.php');
and a foreach loop to output images and links
foreach($list as $src => $href) echo "<a href='$href'><img src='$src'></a>";
#ricebowl:
using PHP Version 5.2.9/apache 2.0/windows vista - I'm getting Parse error.
anyway, there is working solution:
$dir = "./imageDirectory";
$ext = array('.jpg','.png','.gif');
$dh = opendir($dir);
while (false !== ($filename = readdir($dh))) {
print '<ul>';
if(strpos($filename, '.') > 3)
{
print '<li>'.str_replace($ext, '', $filename).'</li>';
}
print '</ul>';
}
<?php
$directory = "imageDirectory"; // assuming that imageDirectory is in the same folder as the script/page executing the script
$contents = scandir($directory);
if ($contents) {
foreach($contents as $key => $value) {
if ($value == "." || $value == "..") {
unset($key);
}
}
}
echo "<ul>";
foreach($contents as $k => $v) {
echo "<li>link text</li>";
}
echo "</ul>";
?>
This should work, though foreach() can be -computationally- expensive. And I'm sure there must be a better/more-economical way of removing the relative-file-paths of . and .. in the first foreach()

Categories