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.
Related
I'm using a php video gallery from codeboxx in an attempt to see all the videos my security camera is uploading to my hosting. My camera makes many subfolders for dates and hours which I can't keep anticipating. What I've been trying to get is for this script to include subfolders:
<body>
<div id="vid-gallery"><?php
// (A) GET ALL VIDEO FILES FROM THE GALLERY FOLDER
$dir = __DIR__ . DIRECTORY_SEPARATOR . "gallery" . DIRECTORY_SEPARATOR;
$videos = glob($dir . "*.{webm,mp4,ogg}", GLOB_BRACE);
// (B) OUTPUT ALL VIDEOS
if (count($videos) > 0) { foreach ($videos as $vid) {
printf("<video src='gallery/%s'></video>", rawurlencode(basename($vid)));
}}
?></div>
</body>
I think I can get the first part to work in scanning 4 subfolders deep by me doing this:
$dir = __DIR__ . DIRECTORY_SEPARATOR . "{gallery,gallery/**,gallery/**/**,gallery/**/**/**,gallery/**/**/**/**}" . DIRECTORY_SEPARATOR;
Now I think this line is giving me a problem as I can't seem to get this src get videos in the subdirectories and wildcards don't seem to work:
printf("<video src='gallery/%s'></video>", rawurlencode(basename($vid)));
I've tried to look up how to do it and I've seen array/echo/recursive functions, but I don't know how to implement anything. I appreciate any help.
Untested but along the right lines - a combination of recursiveIterator & recursiveDirectoryIterator ought to be enough to list all the files - when combined further with pathinfo to find the file extension you can do away with the glob or preg_match
$dir=sprintf('%s/gallery',__DIR__);
$exts=array('webm','ogg','mp4');
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir ), RecursiveIteratorIterator::SELF_FIRST );
if( is_object( $files ) ){
foreach( $files as $name => $file ){
if( !$file->isDir() && !in_array( $file->getFileName(), array('.','..') ) ){
if( in_array( pathinfo( $file->getFileName(), PATHINFO_EXTENSION ),$exts ) ){
echo $file->getFileName() . '<br />';
}
}
}
}
An update that loads the videos as per the request
$dir=sprintf('%s/gallery', __DIR__ );
$exts=array('webm','ogg','mp4');
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir ), RecursiveIteratorIterator::SELF_FIRST );
if( is_object( $files ) ){
foreach( $files as $name => $file ){
if( !$file->isDir() && !in_array( $file->getFileName(), array( '.', '..' ) ) ){
if( in_array( pathinfo( $file->getFileName(), PATHINFO_EXTENSION ),$exts ) ){
/*
For my test the script is running within an `aliased` folder
outside of the directory root. The gallery folder and it's
sub-folders are within this alised directory.
Roughly the structure is:
c:\wwwroot\sites\myWebsite ~ this is the directory root
The aliased folder - as `demo`:
c:\wwwroot\content\
The working directory:
c:\wwwroot\content\stack
with the gallery
c:\wwwroot\content\stack\gallery etc
So - I needed to remove the absolute portion of the returned filepaths
c:\wwwroot\content
*/
$rel_filepath=str_replace(
array( realpath( getcwd() ), '\\' ),
array( '', '/' ),
$file->getPathName()
);
$rel_filepath=ltrim( $rel_filepath, '/' );
printf( '<h5>%1$s</h5><video src="%1$s" controls></video>', $rel_filepath );
}
}
}
}
Which resulted in the following display:
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 );
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.
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>
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.