I'm trying to delete a given file from a directory using PHP. Here is the code I've tried:
// Get the file name
$id = '61514';
// Get the folder path
$uploads_folder_dir = 'some/dir';
// Check if the directory exists
if ( ! file_exists( $uploads_folder_dir ) )
return false;
// Open the directory
if ( $dir = opendir( $uploads_folder_dir ) ) {
// Loop through each file in the directory
while ( false !== ( $file = readdir( $dir ) ) ) {
// Target the file to be deleted and delete. All files in folder are .png
if ( $file == ( $id . '.png' ) )
#unlink( $uploads_folder_dir . '/' . $file );
}
}
// Housekeeping
closedir( $dir );
#rmdir( $uploads_folder_dir );
Each time I run the code, the particular file I'm trying to delete is not deleted.
My guess is when I'm looping through the directory, my logic to find the file isn't working. I can confirm that file 61514.png is definitely in directory some/dir
Hoping someone can spot where I'm going wrong here?
First debug your file path is ok or not just by printing whole file path like
// Target the file to be deleted and delete. All files in folder are .png
if ( $file == ( $id . '.png' ) ){
echo $uploads_folder_dir . '/' . $file; die;
#unlink( $uploads_folder_dir . '/' . $file );
}
}
Why do you loop through the files? This one would be much easier:
// Get the file name
$id = '61514';
// Get the folder path
$uploads_folder_dir = 'some/dir';
// Check if the directory exists
if ( ! file_exists( $uploads_folder_dir ) )
return false;
unlink("$uploads_folder_dir/$id.png");
// Housekeeping
#rmdir( $uploads_folder_dir );
#unlink -> use unlink and if you don't see permission denied problem, the file and "dir" should be removed.
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 move a file from one directory to another directory using PHP rename() function. But the function is not working. every time it display Not done. Your suggestions please.
Here is my code
<?php
error_reporting(1);
error_reporting('On');
include 'includes/config.php'; // database configuration file
$site_path = "http://www.website.com/";
$file_name = "images800466507.jpg";
$currentPath = 'TempImages/'.$file_name; // ( file permission : 777 )
$newPath = 'ImagesNew/'.$file_name; // ( file permission : 755 )
if( rename($site_path.$currentPath , $site_path.$newPath ) )
echo 'done';
else
echo 'not done';
?>
You need to get your real path, for me real path /Applications/MAMP/htdocs/phptest but you can define ABSPATH like define('ABSPATH', dirname(__FILE__).'/');
Complete code:
error_reporting(1);
error_reporting('On');
define('ABSPATH', dirname(__FILE__).'/');
include 'includes/config.php'; // database configuration file
$file_name = "images800466507.jpg";
$currentPath = ABSPATH.'/TempImages/'.$file_name; // ( file permission : 777 )
$newPath = ABSPATH.'/ImagesNew/'.$file_name; // ( file permission : 755 )
if( rename($currentPath ,$newPath ) )
echo 'done';
else
echo 'not done';
I tested and it worked for me.
Perhaps using the full local path might do the trick
$filename = 'images800466507.jpg';
$currentpath = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'TempImages' . DIRECTORY_SEPARATOR . $filename;
$targetpath = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'ImagesNew' . DIRECTORY_SEPARATOR . $filename;
echo realpath( $currentpath ) && rename($currentpath,$targetpath) ? 'done' : 'not done';
Does the source file exist at the location specified?
if( !file_exists( $currentpath ) ) echo 'Bad Foo - ' . $currentpath . ' not found!';
Add / before TempImages/ and ImagesNew/ directory like /TempImages/ and /ImagesNew/
<?php
error_reporting(1);
error_reporting('On');
include 'includes/config.php'; // database configuration file
//$site_path = "http://www.website.com/";
$file_name = "images800466507.jpg";
$currentPath = '/TempImages/'.$file_name; // ( file permission : 777 )
$newPath = '/ImagesNew/'.$file_name; // ( file permission : 755 )
if( rename($currentPath , $newPath ) )
echo 'done';
else
echo 'not done';
?>
more details rename function http://php.net/manual/en/function.rename.php
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 need to check if a folder exist in an other folder. If not, then a new folder will be created. I canĀ“t seem to get it to work. See code below.
Note: I use TCPDF.
// Create filename
$filnamnet = $id.'_'.$datum.'_'.$fornamn.'_'.$efternamn.'.pdf';
// Folder in iup_pdf
$mapparna_dir = 'iup_pdf/'.$id.'_'.$fornamn.'_'.$efternamn.'_'.$personnummer.'';
// Check if folder exist in iup_pdf
if(!is_dir($mapparna_dir) ) {
mkdir('iup_pdf/'.$id.'_'.$fornamn.'_'.$efternamn.'_'.$personnummer);
}
$pdf->Output(__DIR__ . '/iup_pdf/'.$id.'_'.$fornamn.'_'.$efternamn.'_'.$personnummer.'/'.$filnamnet.'', 'F');
The error states: TCPDF ERROR: Unable to create output file
You might find this of use.
function RecursiveMkdir( $path=NULL, $perm=0644 ) {
if( !file_exists( $path ) ) {
RecursiveMkdir( dirname( $path ) );
mkdir( $path, $perm, TRUE );
clearstatcache();
}
}
I tend to find that the fullpath works best - ie:$_SERVER['DOCUMENT_ROOT'].'/path/elements/to/folder' etc rather than the relative path. Also, is_dir() determines if a file is a directory - perhaps use file_exists as in the function.
if( !file_exists( $mapparna_dir ) ) RecursiveMKdir( $mapparna_dir );
$path = realpath( dirname( __FILE__ ) ) . '/Uploads/'; // Upload directory
// Decode content array.
$ContentArray = json_decode( stripslashes( $_POST['content'] ) );
foreach( $ContentArray as $ContentIndividualFilename )
{
echo $path.$ContentIndividualFilename;
// Move uploaded files.
if( copy( $_FILES["files"]["tmp_name"][$ContentIndividualFilename], $path.$ContentIndividualFilename) )
{
}
}
this is wrong $_FILES["files"]["tmp_name"][$ContentIndividualFilename] because i get here through ajax function without page refresh. $ContentIndividualFilename contains filenames of the files.How do i transfer the file to the required folder?
How to process files inside the folder sub directories using php script.
Actually I want the image files inside each sub directories residing in my server itself to process and save to another location and save the folder name & file name in the database. Can anyone help and give a sample script on how to operate this...
the folder structure may be something like this
parent folder
sub-folder1
img1
img2
img3
.
.
img'n'
sub-folder2
img1
img2
img3
.
.
img'n'
sub-folder3
img1
img2
img3
.
.
img'n'
.
.
.
sub-folder'n'
Also if on the process of copying and writing to database how can show a progress bar
u can use this function to copy a folder including its subfolders from source to target.
function fullCopy( $source, $target ) {
if ( is_dir( $source ) ) {
$d = dir( $source );
while ( FALSE !== ( $entry = $d->read() ) ) {
if ( $entry == '.' || $entry == '..' ) {
continue;
}
$Entry = $source . '/' . $entry;
if ( is_dir( $Entry ) ) {
#mkdir( $Entry );
fullCopy( $Entry, $target . '/' . $entry );
continue;
}
copy( $Entry, $target . '/' . $entry );
}
$d->close();
}else {
copy( $source, $target );
}
}
inside the loop u can execute a query to save file names to the database.
This is described in detail at http://php.net/manual/en/features.file-upload.php. You can store files anywhere you want.
You can use PHP glob() to gather your files. Saving info to the database is pretty straight forward. Moving the files can be done via rename(). The MySQLi documentation is full of examples on how to talk to your database.