Clone/Copy a directory to destination - php

First of all i have searched and tried many functions but all of them works by copying all the contents(not the self source whole folder) of my source directory to destination.
But i want to copy WHOLE DIRECTORY.
WHAT I HAVE TRIED?
This function copies the contents of folder copy of $source to folder New Copy of destination $dest.
$source = 'C:\MAMP\htdocs\projectAuru\our/files/copy';
$dest = 'C:\MAMP\htdocs\projectAuru\our/files/New Copy';
function xcopy($source, $dest, $permissions = 0777)
{
// Check for symlinks
if (is_link($source)) {
return symlink(readlink($source), $dest);
}
// Simple copy for a file
if (is_file($source)) {
return copy($source, $dest);
}
// Make destination directory
if (!is_dir($dest)) {
mkdir($dest, $permissions);
}
// Loop through the folder
$dir = dir($source);
while (false !== $entry = $dir->read()) {
// Skip pointers
if ($entry == '.' || $entry == '..') {
continue;
}
// Deep copy directories
xcopy("$source/$entry", "$dest/$entry", $permissions);
}
// Clean up
$dir->close();
return true;
}
WHAT I AM LOOKING FOR?
It should copy my entire directory copy(along with all of its files and subfolders) to destination folder So finally the destination directory should look like afterwards:
C:\MAMP\htdocs\projectAuru\our/files/New Copy/copy

The solution to this is to get the name of the folder that we are copying and mkdir with that name in the Destination and then copy all files to that mkdir destination.
// Get value after last slash and trim trailing slash if exists
$copyFromFolderName = substr(rtrim($copyFrom, '/'), strrpos(rtrim($copyFrom, '/'), '/') + 1);
if (!is_dir($base.$copyTo.'/'.$copyFromFolderName)) {
mkdir($base.$copyTo.'/'.$copyFromFolderName, 0777, true);
xcopy($base.$copyFrom, $base.$copyTo.'/'.$copyFromFolderName);
}else{
xcopy($base.$copyFrom, $base.$copyTo.'/'.$copyFromFolderName);
}

Related

Preserve the folder structure when creating a Zip archive

I want to create a zip file and copy all the folders and files from a directory to it. It is successfully created and contains the files and folders, but the file tree is not preserved, everything being in the root directory.
My directory:
folder/
test.txt
test2.txt
test.php
The zip archive:
folder/
test.txt
test2.txt
test.php
This is my code:
public function createZipFromDir($dir, $zip_file) {
$zip = new ZipArchive();
if(true !== $zip->open($zip_file, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)) {
return false;
}
$this->zipDir($dir, $zip);
return $zip;
}
public function zipDir($dir, $zip) {
$dir = rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$files = scandir($dir);
foreach($files as $file) {
if(in_array($file, array('.', '..'))) continue;
if(is_dir($dir . $file)) {
$zip->addEmptyDir($file);
$this->zipDir($dir . $file, $zip);
} else {
$zip->addFile($dir . $file, $file);
}
}
}
$zip = $this->createZipFromDir($rootPath, $archiveName);
The issue is that when you create a folder or set the localname (second argument of addFile()) when adding a file to the archive, you only use $file, therefore everything gets put at the root. It is necessary to provide the file hierarchy as well.
Now the obvious solution would be to use $dir.$file instead, but this would only work properly on a folder located in the same directory as the script.
We actually need to keep track of two file trees:
the real tree, as it exists on the machine
the archive tree, relative to the path we want to archive
But since one is just a subset of the other, we can easily keep track of that by splitting the real path in two:
$dir, a prefix pointing to the original path
$subdir, a path relative to $dir
When referring to a file on the machine, we use $dir.$subdir and when referring to a file in the archive we use only $subdir. This requires us to adapt zipDir() to keep track of the prefix by adding a third argument to it and slightly modifying the call to zipDir() in createZipFromDir().
function createZipFromDir($dir, $zip_file) {
$zip = new ZipArchive();
if(true !== $zip->open($zip_file, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)) {
return false;
}
zipDir(
// base dir, note we use a trailing separator from now on
rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR,
// subdir, empty on initial call
null,
// archive ref
$zip
);
return $zip;
}
function zipDir($dir, $subdir, $zip) {
// using real path
$files = scandir($dir.$subdir);
foreach($files as $file) {
if(in_array($file, array('.', '..')))
continue;
// check dir using real path
if(is_dir($dir.$subdir.$file)) {
// create folder using relative path
$zip->addEmptyDir($subdir.$file);
zipDir(
$dir, // remember base dir
$subdir.$file.DIRECTORY_SEPARATOR, // relative path, don't forget separator
$zip // archive
);
}
// file
else {
// get real path, set relative path
$zip->addFile($dir.$subdir.$file, $subdir.$file);
}
}
}
This code has been tested and is working.

foreach loop copy files directories

I'd like to copy files from a remote server with a similar structure to files in my server with the same structure.
include "../arrays.php";
foreach ($citycode as $city) {
$source = "http://www.remoteserver.com/data/{$city}/";
$dest = "/alltxts/{$city}/";
// EVERYTHING FROM HERE ONWARDS RUNS PERFECTLY, THE PROBLEM IS PROBABLY ABOVE.
function copyr($source, $dest)
{
// Simple copy for a file
if (is_file($source)) {
chmod($dest, 777);
return copy($source, $dest);
}
// Make destination directory
if (!is_dir($dest)) {
mkdir($dest);
}
chmod($dest, 777);
// Loop through the folder
$dir = dir($source);
while (false !== $entry = $dir->read()) {
// Skip pointers
if ($entry == '.' || $entry == '..') {
continue;
}
// Deep copy directories
if ($dest !== "$source/$entry") {
copyr("$source/$entry", "$dest/$entry");
}
}
// Clean up
$dir->close();
return true;
}
}
The code to copy the files works just fine when I use a specific $citycode as $city. However, when I use the array to catch all city names with one line, it doesn't work. Any ideas? I'd appreciate any help, thanks!
You are searching for:
$source = "http://www.remoteserver.com/data/{$city}/";
$dest = "/alltxts/{$city}/";
file_put_contents($dest, file_get_contents($source));
Make sure that you have proper permissions to save files in /alltxts/'. Also the leading / looks weird to me. Do you mean something like alltexts/ (relative path) instead?

Retrieving contents of several files in directory PHP

I need to get the contents of several files within a directory but which is the best way of doing this?
I am using
$data = file_get_contents('./files/myfile.txt');
but I want every file without having to specify the file individually as above.
You can use glob to get particular file extention and file_get_contents to get the content
$content = implode(array_map(function ($v) {
return file_get_contents($v);
}, glob(__DIR__ . "/files/*.txt")));
/**
* Change the path to your folder.
* This must be the full path from the root of your
* web space. If you're not sure what it is, ask your host.
*
* Name this file index.php and place in the directory.
*/
// Define the full path to your folder from root
$path = "/home/content/s/h/a/shaileshr21/html/download";
// Open the folder
$dir_handle = #opendir($path) or die("Unable to open $path");
// Loop through the files
while ($file = readdir($dir_handle)) {
$data = file_get_contents('$filet');
}
// Close
closedir($dir_handle);
You can dir the directory and loop through it to get the contents of all files.
<?php
$path = './files';
$d = dir($path);
$contents = '';
while (false !== ($entry = $d->read())) {
if (!($entry == '..' || $entry == '.')) {
$contents .= file_get_contents($path.'/'.$entry);
}
}
$d->close();
?>
If you only want .txt files you can change the if statement of the code above from:
if (!($entry == '..' || $entry == '.')) {
to:
if (substr($entry, -4) == '.txt') {
This will result to a variable $contents that is type string and has all the contents of all the files (or only txt files if you select the 2nd solution) that are in the ./files dir.

ZipArchive - extract folder

I am allowing users to upload portfolios in ZIP archives on my site.
The problem is that most archives have the following folder structure:
zipfile.zip
- zipfile
- file1.ext
- file2.ext
- file3.ext
is there any way to simply put the files (not the directory) onto my site (so the folder structure of their portfolio is like so)
user_name
- portfolio
- file1.ext
- file2.ext
- file3.ext
it currently uploads them like so:
user_name
- portfolio
- zipfile
- file1.ext
- file2.ext
- file3.ext
which creates all kinds of problems!
I have tried doing this:
$zip = new ZipArchive();
$zip->open($_FILES['zip']['tmp_name']);
$folder = explode('.', $_FILES['zip']['name']);
end($folder);
unset($folder[key($folder)]);
$folder = (implode('.', $folder));
$zip->extractTo($root, array($folder));
$zip->close();
to no avail.
You could do something like this:
Extract Zip file to a temp location.
Scan through it and move(copy) all the files to portfolio folder.
Delete the temp folder and its all contents (created in Step 1).
Code:
//Step 01
$zip = new ZipArchive();
$zip->open($_FILES['zip']['tmp_name']);
$zip->extractTo('temp/user');
$zip->close();
//Define directories
$userdir = "user/portfolio"; // Destination
$dir = "temp/user"; //Source
//Step 02
// Get array of all files in the temp folder, recursivly
$files = dirtoarray($dir);
// Cycle through all source files to copy them in Destination
foreach ($files as $file) {
copy($dir.$file, $userdir.$file);
}
//Step 03
//Empty the dir
recursive_directory_delete($dir);
// Functions Code follows..
//to get all the recursive paths in a array
function dirtoarray($dir, $recursive) {
$array_items = array();
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
if (is_dir($dir. "/" . $file)) {
if($recursive) {
$array_items = array_merge($array_items, dirtoarray($dir. "/" . $file, $recursive));
}
} else {
$file = $dir . "/" . $file;
$array_items[] = preg_replace("/\/\//si", "/", $file);
}
}
}
closedir($handle);
}
return $array_items;
}
// Empty the dir
function recursive_directory_delete($dir)
{
// if the path has a slash at the end we remove it here
if(substr($directory,-1) == '/')
{
$directory = substr($directory,0,-1);
}
// if the path is not valid or is not a directory ...
if(!file_exists($directory) || !is_dir($directory))
{
// ... we return false and exit the function
return FALSE;
// ... if the path is not readable
}elseif(!is_readable($directory))
{
// ... we return false and exit the function
return FALSE;
// ... else if the path is readable
}else{
// we open the directory
$handle = opendir($directory);
// and scan through the items inside
while (FALSE !== ($item = readdir($handle)))
{
// if the filepointer is not the current directory
// or the parent directory
if($item != '.' && $item != '..')
{
// we build the new path to delete
$path = $directory.'/'.$item;
// if the new path is a directory
if(is_dir($path))
{
// we call this function with the new path
recursive_directory_delete($path);
// if the new path is a file
}else{
// we remove the file
unlink($path);
}
}
}
// close the directory
closedir($handle);
// return success
return TRUE;
}
}
How if change your zip file to this?
zipfile.zip
- file1.ext
- file2.ext
- file3.ext

Copy entire directory and content from one location to another using PHP

I am trying to copy an entire folder from one location to another using PHP, but it doesn't seem to work:
$username = "peter" //this is just an example.
$userdir = "../Users/".$username."/";
mkdir($userdir);// create folder
// copy image folder
$source = "templates/template1/images/";//copy image folder -source
$dest = $userdir;
function copyr($source, $dest){
// Simple copy for a file
if (is_file($source)) {
$c = copy($source, $dest);
chmod($dest, 0777);
return $c;
}
// Make destination directory
if (!is_dir($dest)) {
$oldumask = umask(0);
mkdir($dest, 0777);
umask($oldumask);
}
// Loop through the folder
$dir = dir($source);
while (false !== $entry = $dir->read()) {
// Skip pointers
if ($entry == "." || $entry == "..") {
continue;
}
}
// Clean up
$dir->close();
return true;
}
I have also tried other solutions I saw online without success. Would appreciate any help possible
I also just tried this script without any luck.
I just tried another script and still no luck :(.
$template_homepage = "templates/template1/index.php";//path to default template homepage
$homepage = file_get_contents($template_homepage);//get default homepage structure
$username = testuser;// folder name for store
if (trim($username) == '') {
die("An error occured.");
} else {
$userdir = "../Users/".$username."/";
mkdir($userdir);// create folder for new website
// copy image folder
$src = 'templates/template1/images';//copy image folder -source
$dst = $userdir;
function rcopy($src, $dst) {
if (file_exists($dst)) rrmdir($dst);
if (is_dir($src)) {
mkdir($dst);
$files = scandir($src);
foreach ($files as $file)
if ($file != "." && $file != "..") rcopy("$src/$file", "$dst/$file");
}
else if (file_exists($src)) copy($src, $dst);
}
$fh = fopen($userdir."index.php", 'w') or die("An error occured. ");// create home page in users folder
// $stringData = $title; //."\n";//
fwrite($fh, $homepage);// write homepage structure into new homepage file.
fclose($fh);// close new homepage file.
$launchpage = "../Users/".$username."/"; // launch new homepage file.
header("Location: $launchpage");
}
Why don't you use exec and use the OS command to copy the folder over?
exec('cp -r sourcedir destdir');

Categories