PHP - Make dirs and copy files from a URL - php

I have an array filled with paths looking like this:
library/main/single/list.php
library/article/grid/thumbs.php
library/footer/tiny.php
These files and folders exists on my http://localhost/test/
I also have path that is http://localhost/new/
What I want to do
What I need to do is move the files while keeping the current file structure (with directories intact) to the new location.
The result should be like this
http://localhost/new/library/main/single/list.php
http://localhost/new/library/article/grid/thumbs.php
http://localhost/new/library/footer/tiny.php
Is there an easy way to do it or do I have to cut every string by its slash?

You could try:
$from = './test/'; //replace with absolute path if better
$to = './new/';
$paths = array('library/main/single/list.php', 'library/article/grid/thumbs.php', 'library/footer/tiny.php');
$dirs = array();
foreach( $paths as $path ) {
$pathinfo = pathinfo($to.$path);
if (!in_array($pathinfo['dirname'], $dirs) && !file_exists($pathinfo['dirname']) && mkdir($pathinfo['dirname'], 0777, true))
$dirs[] = $pathinfo['dirname'];
copy($from.$path, $to.$path);
}

Related

PHP File count inside a folder

I'm using bootstrap tables and rows to count how much files are in a folder, but the destination is pointing to a different server the code below does not work.
As i'm using localhost (xampp) trying to do this don't know if its possible.
<?php
// integer starts at 0 before counting
$i = 0;
$dir = 'uploads/'; <!--\\189.207.00.122\folder1\folder2\folder3\test-->
if ($handle = opendir($dir)) {
while (($file = readdir($handle)) !== false){
if (!in_array($file, array('.', '..')) && !is_dir($dir.$file))
$i++;
}
}
// prints out how many were in the directory
echo "There were $i files";
?>
Here is a handy little function you might want to try out. Just pass the path to the Directory as the first argument to it and you'd get your result.
NOTE: This Function is RECURSIVE, which means: it will traverse all sub-directories... to disable this behaviour, simply comment out or delete the following lines towards the end of the Funciton:
<?php
}else if(is_dir($temp_file_or_dir) && !preg_match('/^\..*/', $val) ){
getFilesInFolder($temp_file_or_dir);
}
THE CODE:
<?php
$folder = dirname(__FILE__).'/uploads'; // ASSUMES YOUR uploads DIRECTORY
// IS IN THE SAME DIRECTORY AS index.php
// (/htdocs/php/pages)
// OR
$folder = dirname(__FILE__).'/../uploads'; // ASSUMES YOUR uploads DIRECTORY
// IS ONE DIRECTORY ABOVE
// THE CURRENT DIRECTORY (/htdocs/php)
// THIS IS MOST LIKELY RIGHT
// OR
$folder = dirname(__FILE__).'/../../uploads';// ASSUMES YOUR uploads DIRECTORY
// IS TWO DIRECTORIES ABOVE
// THE CURRENT DIRECTORY (/htdocs)
// MAKE SURE THE FOLDER IN QUESTION HAS THE RIGHT PERMISSIONS
// OR RATHER CHANGE PERMISSIONS ON THE FOLDER TO BE ABLE TO WORK WITH IT
chmod($folder, 0777);
var_dump(getFilesInFolder($folder));
// IF YOU PASS false AS THE THE 2ND ARGUMENT TO THIS FUNCTION
// YOU'D GET AN ARRAY OF ALL FILES IN THE $path2Folder DIRECTORY
// AS WELL AS IN SUB-DIRECTORIES WITHIN IT...
function getFilesInFolder($path2Folder, $countOnly=true){
$files_in_dir = scandir($path2Folder);
$returnable = array();
foreach($files_in_dir as $key=>$val){
$temp_file_or_dir = $path2Folder . DIRECTORY_SEPARATOR . $val;
if(is_file($temp_file_or_dir) && !preg_match("#^\..*#", $temp_file_or_dir)){
$arrRX = array('#\.{2,4}$#', '#\.#');
$arrReplace = array("", "_");
$returnVal = preg_replace($arrRX, $arrReplace, $val);
$returnable[$returnVal] = $temp_file_or_dir;
}else if(is_dir($temp_file_or_dir) && !preg_match('/^\..*/', $val) ){
getFilesInFolder($temp_file_or_dir);
}
}
return ($countOnly) ? count($returnable) : $returnable;
}
Use $_SERVER['DOCUMENT_ROOT'] to get your root directory.
$dir = $_SERVER['DOCUMENT_ROOT'].'/uploads/';

Move file to directory

So with your help I have been able to assemble the below.
$dir = "./reporting/live-metrics/";
$des = "./reporting/historic-metrics/";
$ctime = time();
foreach (glob($dir."*") as $file) {
$live = file_get_contents($file);
if (strpos($live, 'CORO') === false && filemtime($file) < time() - 1 * 10) {
$exclude[] = $live;
$lines = file( $file , FILE_IGNORE_NEW_LINES );
$lines[3] = 'Taken Down';
$lines[5] = $ctime;
file_put_contents( $file , implode( "\n", $lines ) );
if (!file_exists($des.basename($file).PHP_EOL)) {
mkdir($des.basename($file), 0777, true);
}
rename($file,$des.$ctime);
}
}
My issue is that I am attempting to move the file to the new directory created but I am having a little issue with it. No matter what I do I can only get it to move to $des, i cant seem to get ti to move to the dynamicaly created directory for each specific file. I am assuming it has to do with the fact I am not using rename to its correct params. Below are the some of the combinations I have tried to get it to rename and move.
rename($file,$des.basename($file).PHP_EOL.$ctime); //doesn't move or rename
rename($file,$des.basename($file).$ctime); //adds to historic-metrics/ as jason1465519298
I also tried creating a function and setting the rename to call on that. eg.
$path = $des.basename($file).PHP_EOL;
rename($file,$path.$ctime);
Currently the script is great up until the moving the file. It will move it to ./reporting/historic-metrics/ but I would like it to move to the directory just created. EG, if the file it is currently handeling is called 'Jason' then it will create ./reporting/historic-metrics/Jason but move the file to ./reporting/historic-metrics/
There seems to be two possibilities:
Source or destination file paths may be wrong, you can print and check
The newly created destination directory is getting the
correct permission & ownership.
Otherwise your script looks OK.
I finally got it. My main issue was trying to get the filepath to send the file to. After a few interruptions and rethinking my approach I came up with the below. I know it isn't pretty or as slim as could be made but it does the job perfectly.
$dir = "./reporting/live-metrics/";
$des = "./reporting/historic-metrics/";
$ctime = time();
foreach (glob($dir."*") as $file) {
$live = file_get_contents($file);
if (strpos($live, 'CORO') === false && filemtime($file) < time() - 1 * 10) {
$exclude[] = $live;
$lines = file( $file , FILE_IGNORE_NEW_LINES );
$lines[3] = 'Taken Down';
$lines[5] = $ctime;
file_put_contents( $file , implode( "\n", $lines ) );
if (!file_exists($des.basename($file).PHP_EOL)) {
mkdir($des.basename($file), 0777, true);
}
$user = basename($file); //Gets file name that was used in mkdir
$path = (String) $des.$user."/"; //Compiles variables into string
rename($file,$path.$ctime);
}
}

return all unique directories within a hierarchy

I'm using RecursiveDirectoryIterator to scan for all files and folders within a given root dir. This works fine, but I'd like to keep track of all of the unique directories in that list, so I'm not sure that RecursiveDirectoryIterator is the way to go.
I have a directory structure of
-a
->b
->c
-one
->two
->three
Here is my code:
<?php
function test($dir){
$in_dir = 'none';
$currdir = 'none';
$thisdir = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($thisdir, RecursiveIteratorIterator::SELF_FIRST);
foreach($files as $object){
//if this is a directory... find out which one it is.
if($object->isDir()){
//figure out if we have changed directories...
$currdir = realpath($object->getPath());
if(strpos($currdir, '.') == false){
$test = strcmp($currdir, $prevdir);
if($test){
echo "current dir changing: ", $currdir, "\n";
$prevdir = $currdir;
}
}
}
}
}
test('fold');
?>
What I get from that is the following:
current dir changing: /Users/<usr>/Desktop/test/fold
current dir changing: /Users/<usr>/Desktop/test/fold/a
current dir changing: /Users/<usr>/Desktop/test/fold/a/b
current dir changing: /Users/<usr>/Desktop/test/fold
current dir changing: /Users/<usr>/Desktop/test/fold/one
current dir changing: /Users/<usr>/Desktop/test/fold/one/two
...But I only want the unique directories.
It's perhaps the method of object comparison in the loop that returns duplicates, as the iterator moves up and down the directory tree as it parses through folders.
The following worked for me. I also use array_unique() confirm no dupes as a redundancy.
$dirArray = []; // the array to store dirs
$path = realpath('/some/folder/location');
$objects = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path),
RecursiveIteratorIterator::SELF_FIRST
);
// loop through all objects and store names in dirArray[]
foreach($objects as $name => $object){
if ($object->isDir()) {
$dirArray[] = $name;
}
}
// make sure there are no dupes
$result = array_unique($dirArray);
// print array out
print_r($result);

PHP Get file name starting with prefix

This is a custom function. At the moment, this function get all the file in the default directory, strip ".php" and list them.
The problem is that I want to only get files from the directory which has starting prefix "tpl-" Example : tpl-login-page.php
/* Get template name of the file */
function get_template_name (){
$files = preg_grep('~\.(php)$~', scandir(admin . "templates/default/"));
foreach($files as $file){
$file = str_replace('.php','',$file);
echo $file . "<br/>";
}
}
You need to change the regular expression in preg_grep:
$files = preg_grep('~^tpl-.*\.php$~', scandir(admin . "templates/default/"));
Explanation:
^tpl- - starting with "tpl-"
.* - any characters
\.php$ - ending with ".php"
I like another, simple way:
1. get all files in folder
$path = './images';
$files = glob($path.'/*');
2. get all files having extension .jpg
$path = './images';
$files = glob($path.'/*.jpg');
3. get all files having prefix myprefix_
$path = './images';
$files = glob($path.'/myprefix_*');
$target_file_png = glob($target_dir.'/group_'.$groupId.'*.png');
$target_file_png will return an array containing all the files in folder specified in the path $target_dir starting with '/group_'.$groupId.' and specify the file format as *.png

Is there an easy way to read filenames in a directory and add to an array?

I have a directory: Audio/ and in that will be mp3 files only. I'm wanting to automate the process of creating links to those files. Is there a way to read a directory and add filenames within that directory to an array?
It'd be doubly cool if we could do an associative array, and have the key be the file name minus the .mp3 tag.
Any ideas?
To elaborate: I actual have several Audio/ folders and each folder contains mp3s of a different event. The event details are being pulled from a database and populating a table. That's why I'm duplicating code, because right now in each Audio/ folder, I'm having to define the filenames for the download links and define the filenames for the mp3 player.
Thank you! This will greatly simplify my code as right now I'm repeating tons of code over and over!
The SPL way is with DirectoryIterator:
$files = array();
foreach (new DirectoryIterator('/path/to/files/') as $fileInfo) {
if($fileInfo->isDot() || !$fileInfo->isFile()) continue;
$files[] = $fileInfo->getFilename();
}
And for completeness : you could use glob as well :
$files = array_filter(glob('/path/to/files/*'), 'is_file');
This will return all files (but not the folders), you can adapt it as needed.
To get just the filenames (instead of files with complete path), just add :
$files = array_map('basename', $files);
Yes: use scandir(). If you just want the name of the file without the extension, use basename() on each element in the array you received from scandir().
This should be able to do what you're looking for:
// Read files
$files = scandir($dirName);
// Filter out non-files ('.' or '..')
$files = array_filter($files, 'is_file');
// Create associative array ('filename' => 'filename.mp3')
$files = array_combine(array_map('basename', $files), $files);
Sure...I think this should work...
$files[] = array();
$dir = opendir("/path/to/Audio") or die("Unable to open folder");
while ($file = readdir($dir)) {
$cleanfile = basename($file);
$files[$cleanfile] = $file;
}
closedir($dir);
I imagine that should work...
$results = array();
$handler = opendir($directory);
while ($file = readdir($handler)) {
if ($file != "." && $file != "..") {
$results[] = $file;
}
}
closedir($handler);
this should work, if you want any files to be excluded from the array, just add them to the if statement, same for file extensions

Categories