I was wondering if it is possible to add timestamp of the file creation/update when using ftp_nlist().
My code right now:
function ftp_get_recursive_paths($conn, $path, $max_level = 0){
$files = array();
if($max_level < 0) return $files;
if($path !== '/' && $path[strlen($path) - 1] !== '/') $path .= '/';
$files_list = ftp_nlist($conn, $path);
foreach($files_list as $f){
if($f !== '.' && $f !== '..' && $f !== $path){
if(strpos($f, '.') === FALSE){
$files[$f] = ftp_get_recursive_paths($conn, $f, $max_level-1);
}else{
$files[] = basename($f);
}
}
}
return $files;
}
And output:
(
[/folder1] => (
[0] => file.php
[1] => file2.php
)
[/folder2] => (
[/folder2/2] => (
)
)
)
Try with the following code:
function ftp_get_recursive_paths($conn, $path, $max_level = 0){
$files = array();
if($max_level < 0) return $files;
if($path !== '/' && $path[strlen($path) - 1] !== '/') $path .= '/';
$files_list = ftp_nlist($conn, $path);
foreach($files_list as $f){
if($f !== '.' && $f !== '..' && $f !== $path){
if(strpos($f, '.') === FALSE){
$files[$f] = ftp_get_recursive_paths($conn, $f, $max_level-1);
}else{
$mdate = ftp_mdtm($conn, $f);
$files[] = basename($f) . " - " . date("m-d-Y H:i:s.", $mdate);
}
}
}
return $files;
}
Related
I am trying to take heavy files backup with PHP but for more then 1 GB files I am getting PHP timeout error how I can resolve this please help me with complete code. below is my complete code.
please check my code and suggest code change that can help me. I have tried number of code and functions but nothing happen. I am very frustrated for this task
#ini_set('max_execution_time', 60000000);
#ini_set('memory_limit', '10000M');
function zipData($source, $destination, $ignores = [])
{
if (extension_loaded('zip') === true) {
if (file_exists($source) === true) {
$zip = new ZipArchive();
if ($zip->open($destination, ZIPARCHIVE::CREATE) === true) {
$source = realpath($source);
if (is_dir($source) === true) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file) {
$file = realpath($file);
$ignored = false;
foreach ($ignores as $ignore) {
if (strpos($file, $ignore)) {
$ignored = true;
break;
}
}
if ($ignored) {
continue;
}
if (is_dir($file) === true) {
$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
} else if (is_file($file) === true) {
// $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
$zip->addFile($file, str_replace($source . DIRECTORY_SEPARATOR, '', $file));
}
}
} else if (is_file($source) === true) {
//$zip->addFromString(basename($source), file_get_contents($source));
$zip->addFile($source, basename($source));
}
}
return $zip->close();
}
}
return false;
}
$backup_path = 'create_backup_site/site_backup_' . date('Y-m-d');
if (!file_exists($backup_path)) {
mkdir($backup_path, 0777, true);
}
$name_zip_file = $backup_path . '/' . date("j-n-Y") . '-backup.zip';
$ignorearray = array('create_backup');
$dir = '../../test/wp-content/uploads';
function listFolderFiles($dir, $backup_path)
{
$fileInfo = scandir($dir);
$allFileLists = [];
$allpathname = [];
foreach ($fileInfo as $folder) {
if ($folder !== '.' && $folder !== '..') {
if (is_dir($dir . DIRECTORY_SEPARATOR . $folder) === true) {
$allFileLists[$folder] = listFolderFiles($dir . DIRECTORY_SEPARATOR . $folder, $backup_path);
//$allFileLists[$folder]['file_path'] = $dir . DIRECTORY_SEPARATOR . $folder;
$allpathname[] = listFolderFiles($dir . DIRECTORY_SEPARATOR . $folder, $backup_path);
} else {
$filesize = filesize($dir . '/' . $folder);
// if ($filesize < 1073741824) {
// if ($filesize < 536870912) { //512 mb size check
if ($filesize < 1048576) { //512 mb size check
$allFileLists[$folder] = array("file_name" => $folder, "file_path" => $dir . DIRECTORY_SEPARATOR);
$allpathname[] = $folder;
}
}
}
}
return $allFileLists;
$dirlist = listFolderFiles($dir, $backup_path);
$final_array = array();
$final_array_path = array();
foreach ($dirlist as $key => $value) {
if (is_array($value)) {
foreach ($value as $newkey => $newvalue) {
foreach ($newvalue as $key2 => $val2) {
if ($val2['file_name'] != '.') {
if (strlen($val2['file_name']) > 2) {
$final_array[] = array('file_name' => $val2['file_name'], 'file_path' => $val2['file_path']);
$filepatrh = str_replace($val2['file_name'],"",$val2['file_path']);
}
}
}
if ($newvalue['file_name'] != '.') {
if (strlen($newvalue['file_name']) > 2) {
$final_array[] = array('file_name' => $newvalue['file_name'], 'file_path' => $newvalue['file_path']);
$filepatrh = str_replace($newvalue['file_name'],"",$newvalue['file_path']);
}
}
}
} else {
}
if ($value['file_name'] != '.') {
if (strlen($value['file_name']) > 2) {
$final_array[] = array('file_name' => $value['file_name'], 'file_path' => $value['file_path']);
$filepatrh = str_replace($value['file_name'],"",$value['file_path']);
}
}
}
foreach ($final_array as $final_key => $final_value) {
zipData($final_value['file_path'], $backup_path . '/uploads.zip', $ignorearray);
echo 'Finished.';
}
}
I am writing a function to recursively copy a specific file type from one folder to the other, but the function copies all the files in the folder.
function recurse_copy($src, $dst) {
$dir = opendir($src);
#mkdir($dst);
while (false !== ( $file = readdir($dir))) {
if (( $file != '.' ) && ( $file != '..' )) {
if (is_dir($src . '/' . $file)) {
if ($file->getExtension() == "pdf") {
recurse_copy($src . '/' . $file, $dst . '/' . $file);
}
} else {
copy($src . '/' . $file, $dst . '/' . $file);
}
}
} closedir($dir);
}
// if statements for
$itp = new RecursiveDirectoryIterator("foldername/", > FilesystemIterator::SKIP_DOTS);
$displayp = Array('pdf');
$i = 0;
foreach (new RecursiveIteratorIterator($itp) as $filepop) {
if (in_array(strtolower(array_pop(explode('.', $filepop))), $displayp))
if ($filepop->getExtension() == "pdf") {
echo >
recurse_copy("a", "b");
}
}
$itcopy = new RecursiveDirectoryIterator("foldername/", FilesystemIterator::SKIP_DOTS);
$displayp = Array ( 'pdf' );
foreach(new RecursiveIteratorIterator($itcopy) as $filecopy)
{
if (in_array(strtolower(array_pop(explode('.', $filecopy))), $displayp))
if ($filecopy->getExtension()=="pdf"){
copy($filecopy->getrealPath(),'pdf_folder/'.$filecopy->getFilename()) ;
}
}
1) how can i make this read only ".txt" files
2) how can i make it show only the file name so i can design it how i'd i like..
(<h1>$file</h1> for example)
$dir = "includes/news";
$dh = opendir($dir);
while (false !== ($filename = readdir($dh)))
{
if ($filename != "." && $filename != ".." && strtolower(substr($filename, strrpos($filename, '.') + 1)) == 'txt')
{
$files[] = $filename;
}
}
sort($files);
echo $files;
what it shows right now is:
Array ( [0] => . [1] => .. [2] => [23.7] Hey.txt [3] => [24.7] New
Website.txt [4] => [25.7] Example.txt )
Now, this is another way i could do it, i like it bit better:
if( $handle = opendir( 'includes/news' ))
{
while( $file = readdir( $handle ))
{
if( strstr( $file, "txt" ) )
{
$addr = strtr($file, array('.txt' => ''));
echo '<h1>» ' . $addr . "</h1>";
}
}
closedir($handle);
}
but the my issue with this one is that there is no Sorting between the files.
everything is ok with the output, just the order of them. so if one of you can figure out how to sort them right, that would be perfect
Okay, try this:
$files = array();
if($handle = opendir( 'includes/news' )) {
while( $file = readdir( $handle )) {
if ($file != '.' && $file != '..') {
// let's check for txt extension
$extension = substr($file, -3);
// filename without '.txt'
$filename = substr($file, 0, -4);
if ($extension == 'txt')
$files[] = $file; // or $filename
}
}
closedir($handle);
}
sort($files);
foreach ($files as $file)
echo '<h1><a href="?module=news&read=' . $file
. '">» ' . $file . "</a></h1>";
I think this should accomplish what you want to do. It uses explode and a negative limit to find only .txt files and returns only the name.
$dir = "includes/news";
$dh = opendir($dir);
while (false !== ($filename = readdir($dh))){
$fileName = explode('.txt', $node, -1)[0];
if(count($fileName) )
$files[] = '<h1>'.$fileName.'</h1>';
}
try to make it as simple as possible
try this
function check_txt($file){
$array = explode(".","$file");
if(count($array)!=1 && $array[count($array)-1]=="txt"){return true;}
return false;
}
if($handle = opendir( 'includes/news' )) {
while( $file = readdir( $handle ))
{
if( check_txt($file) )
{
echo '<h1>» ' . $file . "</h1>";
}
}
closedir($handle);
}
$dir = '/master/files';
$files = scandir($dir);
foreach($files as $file){
if(($file != '.') && ($file != '..')){
if(is_dir($dir.'/'.$file)){
echo '<li class="folder">'.$file.'</li>';
}else{
echo '<li class="file">'.$file.'</li>';
}
}
}
From the script above, I get result:
images (folder)
index.html
javascript (folder)
style.css
How to sort the folder first and then files?
Try this :
$dir = '/master/files';
$directories = array();
$files_list = array();
$files = scandir($dir);
foreach($files as $file){
if(($file != '.') && ($file != '..')){
if(is_dir($dir.'/'.$file)){
$directories[] = $file;
}else{
$files_list[] = $file;
}
}
}
foreach($directories as $directory){
echo '<li class="folder">'.$directory.'</li>';
}
foreach($files_list as $file_list){
echo '<li class="file">'.$file_list.'</li>';
}
You don't need to make 2 loops, you can do the job with this piece of code:
<?php
function scandirSorted($path) {
$sortedData = array();
foreach(scandir($path) as $file) {
// Skip the . and .. folder
if($file == '.' || $file == '..')
continue;
if(is_file($path . $file)) {
// Add entry at the end of the array
array_push($sortedData, '<li class="folder">' . $file . '</li>');
} else {
// Add entry at the begin of the array
array_unshift($sortedData, '<li class="file">' . $file . '</li>');
}
}
return $sortedData;
}
?>
This function will return the list of entries of your path, folders first, then files.
Modifying your code as little as possible:
$folder_list = "";
$file_list = "";
$dir = '/master/files';
$files = scandir($dir);
foreach($files as $file){
if(($file != '.') && ($file != '..')){
if(is_dir($dir.'/'.$file)){
$folder_list .= '<li class="folder">'.$file.'</li>';
}else{
$file_list .= '<li class="file">'.$file.'</li>';
}
}
}
print $folder_list;
print $file_list;
This only loops through everything once, rather than requiring multiple passes.
I have a solution for N deep recursive directory scan:
function scanRecursively($dir = "/") {
$scan = array_diff(scandir($dir), array('.', '..'));
$tree = array();
$queue = array();
foreach ( $scan as $item )
if ( is_file($item) ) $queue[] = $item;
else $tree[] = scanRecursively($dir . '/' . $item);
return array_merge($tree, $queue);
}
Store the output in 2 arrays, then iterate through the arrays to output them in the right order.
$dir = '/master/files';
$contents = scandir($dir);
// create blank arrays to store folders and files
$folders = $files = array();
foreach ($contents as $file) {
if (($file != '.') && ($file != '..')) {
if (is_dir($dir.'/'.$file)) {
// add to folders array
$folders[] = $file;
} else {
// add to files array
$files[] = $file;
}
}
}
// output folders
foreach ($folders as $folder) {
echo '<li class="folder">' . $folder . '</li>';
}
// output files
foreach ($files as $file) {
echo '<li class="file">' . $file . '</li>';
}
Being a CodeIgniter lover, I have in fact modified the core directory_helper from that to include the ability to have certain files exempt from the scanning in addition to setting the depth and choosing if hidden files should be included.
All credit goes to the original authors of CI. I simply added to it
with the exempt array and building in the sorting.
It uses ksort to order the folders, as the folder name is set as the key and natsort to order the files inside each folder.
The only thing you may need to do is define what the DIRECTORY_SEPARATOR is for your environment but I don't think you will need to modify much else.
function directory_map($source_dir, $directory_depth = 0, $hidden = FALSE, $exempt = array())
{
if ($fp = #opendir($source_dir))
{
$folddata = array();
$filedata = array();
$new_depth = $directory_depth - 1;
$source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
while (FALSE !== ($file = readdir($fp)))
{
// Remove '.', '..', and hidden files [optional]
if ($file === '.' OR $file === '..' OR ($hidden === FALSE && $file[0] === '.'))
{
continue;
}
is_dir($source_dir.$file) && $file .= DIRECTORY_SEPARATOR;
if (($directory_depth < 1 OR $new_depth > 0) && is_dir($source_dir.$file))
{
$folddata[$file] = directory_map($source_dir.$file, $new_depth, $hidden, $exempt);
}
elseif(empty($exempt) || !empty($exempt) && !in_array($file, $exempt))
{
$filedata[] = $file;
}
}
!empty($folddata) ? ksort($folddata) : false;
!empty($filedata) ? natsort($filedata) : false;
closedir($fp);
return array_merge($folddata, $filedata);
}
return FALSE;
}
Usage example would be:
$filelist = directory_map('full_server_path');
As mentioned above, it will set the folder name as the key for the child array, so you can expect something along the lines of the following:
Array(
[documents/] => Array(
[0] => 'document_a.pdf',
[1] => 'document_b.pdf'
),
[images/] => Array(
[tn/] = Array(
[0] => 'picture_a.jpg',
[1] => 'picture_b.jpg'
),
[0] => 'picture_a.jpg',
[1] => 'picture_b.jpg'
),
[0] => 'file_a.jpg',
[1] => 'file_b.jpg'
);
Just keep in mind that the exempt will be applied to all folders. This is handy if you want to skip out a index.html file or other file that is used in the directories you don't want included.
Try
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
chdir ($path);
$dir = array_diff (scandir ('.'), array ('.', '..', '.DS_Store', 'Thumbs.db'));
usort ($dir, create_function ('$a,$b', '
return is_dir ($a)
? (is_dir ($b) ? strnatcasecmp ($a, $b) : -1)
: (is_dir ($b) ? 1 : (
strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION)) == 0
? strnatcasecmp ($a, $b)
: strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION))
))
;
'));
header ('content-type: text/plain');
print_r ($dir);
?>
public function sortedScanDir($dir) {
// scan the current folder
$content = scandir($dir);
// create arrays
$folders = [];
$files = [];
// loop through
foreach ($content as $file) {
$fileName = $dir . '/' . $file;
if (is_dir($fileName)) {
$folders[] = $file;
} else {
$files[] = $file;
}
}
// combine
return array_merge($folders, $files);
}
The function below returns an array of XML files from a given directory including all subdirectories. How can I modify this function by passing a second optional parameter which excludes a directory.
E.g:
getDirXmlFiles($config_dir, "example2");
Directory/Files
/file1.xml
/file2.xml
/examples/file3.xml
/examples/file4.xml
/example2/file5.xml
/example2/file5.xml
In the above case the function would return all files except files in the example2 directory.
function getDirXmlFiles($base) {
$files = array();
if(!is_dir($base)) return $files;
if ($handle = opendir($base)) {
while (false !== ($file = readdir($handle))) {
if ($file == "." || $file == "..") continue;
if(is_dir("$base/$file")) {
$subfiles = $this->getDirXmlFiles("$base/$file");
$files = array_merge($files, $subfiles);
} else {
if(Cms_File::type($file,false) == "xml")
$files[] = "$base/$file";
}
}
closedir($handle);
}
return $files;
}
Try this:
function getDirXmlFiles($base, $exclude = NULL) {
$files = array();
if(!is_dir($base)) return $files;
if ($handle = opendir($base)) {
while (false !== ($file = readdir($handle))) {
if ($file == "." || $file == ".." || "$base/$file" == $exclude) continue;
if(is_dir("$base/$file")) {
$subfiles = $this->getDirXmlFiles("$base/$file",$exclude);
$files = array_merge($files, $subfiles);
} else {
if(Cms_File::type($file,false) == "xml")
$files[] = "$base/$file";
}
}
closedir($handle);
}
return $files;
}
Redefine the function inputs:
function getDirXmlFiles($base, $excludeDir) {
Then change this line:
if(is_dir("$base/$file")) {
to this:
if(is_dir("$base/$file") && "$base/$file" != "$base/$excludeDir") {
You can just slightly modify the function to check and see if the current directory is the one you want to exclude or not
function getDirXmlFiles($base,$exclude) {
$files = array();
if(!is_dir($base)) return $files;
if ($handle = opendir($base)) {
while (false !== ($file = readdir($handle))) {
if ($file == "." || $file == "..") continue;
if(is_dir("$base/$file") && $file != $exclude) {
$subfiles = $this->getDirXmlFiles("$base/$file",$exclude);
$files = array_merge($files, $subfiles);
} else {
if(Cms_File::type($file,false) == "xml")
$files[] = "$base/$file";
}
}
closedir($handle);
}
return $files;
}
Smth of the sort ( tested only the syntax validation there might be needed some small debugging ) ( this will allow you to exclude multiple directory names )
function getDirXmlFiles($base, $excludeArray = array()) {
if (!is_array($excludeArray))
throw new Exception(__CLASS__ . "->" . __METHOD__ . " expects second argument to be a valid array");
$files = array();
if(!is_dir($base)) return $files;
if ($handle = opendir($base)) {
while (false !== ($file = readdir($handle))) {
$path = $base . "/" . $file;
$isDir = is_dir($path);
if (
$file == "."
|| $file == ".."
|| (
$isDir
&& count($excludeArray) > 0
&& in_array($file, $excludeArray)
)
)
continue;
if($isDir) {
$subfiles = $this->getDirXmlFiles($path, $excludeArray);
$files = array_merge($files, $subfiles);
} else {
if(Cms_File::type($file,false) == "xml")
$files[] = $path;
}
}
closedir($handle);
}
return $files;
}