FTP folder to local using PHP - php

I want to make a copy of ftp in a folder of my project(localhost) so I need to specify source_folder and dest_folder. My problem is that my code just save all files in my project's root and I would like to copy my ftp folder "/" into my "./copy_data" folder in my local project.
Here is my code:
function ftp_sync ($dir) {
if ($dir != ".") {
if (ftp_chdir($this->conn, $dir) == false) {
echo ("Change Dir Failed: $dir<BR>\r\n");
return;
}
if (!(is_dir($dir)))
mkdir($dir);
chdir ($dir);
}
$contents = ftp_nlist($this->conn, ".");
foreach ($contents as $file) {
if ($file == '.' || $file == '..')
continue;
if (#ftp_chdir($this->conn, $file)) {
ftp_chdir ($this->conn, "..");
$this->ftp_sync ($file);
}
else{
//ftp_get($this->conn, $file, $file, FTP_BINARY);
ftp_get($this->conn, $file, $file, FTP_BINARY);
}
}
ftp_chdir ($this->conn, "..");
chdir ("..");
}
ftp_sync('.');
Could anyone help me?

You can execute bash command from php to zip, copy and move the target folder is my recommendation
$message=shell_exec("/var/www/scripts/testscript 2>&1");
print_r($message);

Related

Download all contents from FTP server without time limit

I want to download the contents (files, folders, and sub-folders) of a directory from a FTP server using PHP.
I was able to do it using this function:
function ftp_sync ($dir) {
global $conn_id;
if ($dir != ".") {
if (ftp_chdir($conn_id, $dir) == false) {
echo ("Change Dir Failed: $dir<BR>\r\n");
return;
}
if (!(is_dir($dir)))
mkdir($dir);
chdir ($dir);
}
$contents = ftp_nlist($conn_id, ".");
foreach ($contents as $file) {
if ($file == '.' || $file == '..')
continue;
if (#ftp_chdir($conn_id, $file)) {
ftp_chdir ($conn_id, "..");
ftp_sync ($file);
}
else
ftp_get($conn_id, $file, $file, FTP_BINARY);
}
ftp_chdir ($conn_id, "..");
chdir ("..");
}
Source: https://stackoverflow.com/a/5650503/10349407
But after some time; the script times out from the browser because it takes so long time as the contents of the folder are large.
I tried to set:
ini_set('max_execution_time', 0);
set_time_limit(0);
but I still get the error Warning: set_time_limit() has been disabled for security reasons as I am on a shared hosting.
So, my question: Is it possible to do redirects in the above PHP function so it starts a new page for each file that it downloads (this is my suggestion to prevent the timeout limit)
So a line like:
header("Location: " . __FILE__ . "?file=$file");
where it should download the file which is the value of $_GET['file'] then redirect again and so on until it finishes downloading the whole contents.
EDIT: This is my try but it doesn't work :/
function ftp_sync ($dir) {
global $conn_id;
if( isset($_GET['cd']) ) {
$dir = $_GET['cd'];
}
if ($dir != ".") {
if (ftp_chdir($conn_id, $dir) == false) {
echo ("Change Dir Failed: $dir<BR>\r\n");
return;
}
if (!(is_dir($dir)))
mkdir($dir);
chdir ($dir);
}
$contents = ftp_nlist($conn_id, ".");
foreach ($contents as $file) {
if ($file == '.' || $file == '..')
continue;
if (#ftp_chdir($conn_id, $file)) {
ftp_chdir ($conn_id, "..");
ftp_sync ($file);
header("refresh:0.5;url=" . "ftp.php" . "?file=$file&cd=" . ftp_pwd($conn_id));
die();
}
else {
ftp_get($conn_id, $file, $file, FTP_BINARY);
}
}
ftp_chdir ($conn_id, "..");
chdir ("..");
}
I finally did it on my own!
All what I needed was a way to list ALL the contents of the FTP server recursively (files, directories, sub-directories).
And I found this awesome class: https://www.phpclasses.org/package/7707-PHP-List-recursively-all-files-in-a-FTP-server.html
So, all what you've to do is to download this class and write this script which I've spent hours on (although it is simple xD).
<?php
error_reporting(0);
set_time_limit(0);
session_start();
// SETTINGS
$ftp_hostname = "";
$ftp_port = 21;
$ftp_username = "";
$ftp_password = "";
$where_to_download = "."; // Without the last slash!
// ---------------------
// NOTE: If you want to end the current session; go to http://example.com/filename.php?end
if( isset($_GET['end']) ) {
session_unset();
session_destroy();
die("Successfully ended the session.");
}
include("ftpcrawler.php");
$ftpcrawler = new ftpcrawler;
$ftpcrawler->server = "ftp://$ftp_username:$ftp_password#$ftp_hostname:$ftp_port/";
if( !isset($_SESSION['array']) ) {
$_SESSION['array'] = $ftpcrawler->crawl();
}
if( empty($_SESSION['array']) ) {
echo "Finished downloading everything , or theres no files to download.";
session_unset();
session_destroy();
die();
}
foreach($_SESSION['array'] as $item) {
if( $item['type'] == "file" ) {
$ITEM_DIRECTORY = str_replace($item['name'], "", $item['path']);
}
if( $item['type'] == "directory" ) {
$ITEM_DIRECTORY = $item['path'];
}
if (!file_exists($where_to_download . $ITEM_DIRECTORY) && !is_dir($where_to_download . $ITEM_DIRECTORY)) {
mkdir($where_to_download . $ITEM_DIRECTORY, 0777, TRUE);
}
if( $item['type'] == "file" ) {
$data = #file_get_contents("ftp://$ftp_username:$ftp_password#$ftp_hostname:$ftp_port" . $item['path']);
file_put_contents($where_to_download . $item['path'], $data);
}
unset($_SESSION['array'][$item['path']]); // Remove the item from the array.
echo "Downloaded/Created Folder " . $item['path'] . " !";
header( "refresh:0.2;url=" . basename(__FILE__) );
die();
}
?>
Save the file with the name you need and make sure that ftpcrawler.php is in the same directory of the script.

PHP Delete all folder content without deleting root folder

I'm trying to delete the content of a folder with PHP. This folder has subfolders and files. I want to delete all but the root folder.
For example:
FolderFather
--Folderchild1
--FolChild2
----SubFolChild2
------Anotherfile.jpg
--MyFile.jpg
I want remove all folder except root directory Folder.
Something like
function empty_dir($directory, $delete = false)
{
$contents = glob($directory . '*');
foreach($contents as $item)
{
if (is_dir($item))
empty_dir($item . '/', true);
else
unlink($item);
}
if ($delete === true)
rmdir($directory);
}
should work.
E.g. empty_dir('/some/path/'); should empty that directory without removing,
empty_dir('/some/path/', true); should empty and than remove the directory.
Try:
function deleteAll($path)
{
$dir = dir($path);
while ($file = $dir->read())
{
if ($file == '.' || $file == '..') continue;
$file = $path . '/' . $file;
if (is_dir($file))
{
deleteAll($file);
rmdir($file);
}
else
{
unlink($file);
}
}
}
Calling deleteAll('/path/to/FolderFather'); should work as expected.
You can use scandir() for directory contents and unlink() for deleting contents.
<?php
$dir = "/yourfolder";
$dir_contents = scandir($dir);
foreach($dir_contents as $content)
{
unlink($dir.'/'.$content);
}
$contents = glob('path/*'); // to get all the contents
foreach ($contents as $file) { // loop the files
if (is_file($file)) {
unlink($file); //------- delete the file
}
}

Save FTP files in JSON with PHP

I'm trying to make an array of all my ftp files. I thought that would be easy. However, I want to have an array like this:
files = [
"index.html":"_content from index.html_"
"somedir/things/server.txt":"_content from server.txt_"
"process/server.php":"_content from process.php_"
]
Is there any way to do this?
After I have this, I would like to put this array in a JSON file, that doesn't seem so hard. However, then I have things like images, which can't be saved in a JSON file right? So, I want them to download to my hard drive. How do I do that?
Thanks in advance...
UPDATE 1
This is what I just found:
<?php
$ftp_server = "ftp.example.com";
$conn_id = ftp_connect ($ftp_server)
or die("Couldn't connect to $ftp_server");
$login_result = ftp_login($conn_id, "user", "pass");
if ((!$conn_id) || (!$login_result))
die("FTP Connection Failed");
ftp_sync ("."); // Use "." if you are in the current directory
ftp_close($conn_id);
// ftp_sync - Copy directory and file structure
function ftp_sync ($dir) {
global $conn_id;
if ($dir != ".") {
if (ftp_chdir($conn_id, $dir) == false) {
echo ("Change Dir Failed: $dir<BR>\r\n");
return;
}
if (!(is_dir($dir)))
mkdir($dir);
chdir ($dir);
}
$contents = ftp_nlist($conn_id, ".");
foreach ($contents as $file) {
if ($file == '.' || $file == '..')
continue;
if (#ftp_chdir($conn_id, $file)) {
ftp_chdir ($conn_id, "..");
ftp_sync ($file);
}
else
ftp_get($conn_id, $file, $file, FTP_BINARY);
}
ftp_chdir ($conn_id, "..");
chdir ("..");
}
?>
I want to do something like this, but instead of getting the whole file, I want to get the path to the file and the content and save them in an array.

Extracting zip file on host by PHP destroys directory structure

I have a directory structure like this :
members/
login.php
register.php
I zip them by PHP ZipArchive in my windows machine, but when I upload it to linux host and extract there by PHP it gives me these as two files with no directory :
members\login.php
members\register.php
I want to have the complete directory structure on the host after unzipping the file.
Note that this unpacking code runs without any problem in my local machine. Is it something about windows and linux or what? How can I resolve it?
PHP does not actually provide a function that extracts a ZIP including its directory structure. I found the following code in a user comment in the manual:
function unzip($zipfile)
{
$zip = zip_open($zipfile);
while ($zip_entry = zip_read($zip)) {
zip_entry_open($zip, $zip_entry);
if (substr(zip_entry_name($zip_entry), -1) == '/') {
$zdir = substr(zip_entry_name($zip_entry), 0, -1);
if (file_exists($zdir)) {
trigger_error('Directory "<b>' . $zdir . '</b>" exists', E_USER_ERROR);
return false;
}
mkdir($zdir);
}
else {
$name = zip_entry_name($zip_entry);
if (file_exists($name)) {
trigger_error('File "<b>' . $name . '</b>" exists', E_USER_ERROR);
return false;
}
$fopen = fopen($name, "w");
fwrite($fopen, zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)), zip_entry_filesize($zip_entry));
}
zip_entry_close($zip_entry);
}
zip_close($zip);
return true;
}
Source here.
try DIRECTORY_SEPARATOR
instead of using:
$path = $someDirectory.'/'.$someFile;
use:
$path = $someDirectory. DIRECTORY_SEPARATOR .$someFile;
Change your code to this:
$zip = new ZipArchive;
if ($zip->open("module. DIRECTORY_SEPARATOR .$file[name]") === TRUE) {
$zip->extractTo('module. DIRECTORY_SEPARATOR');
}
And it will work for both operating systems.
Good luck,
The problem solved! Here's what I did :
I change the code of creating zip file into this function from php.net user comments :
function addFolderToZip($dir, $zipArchive){
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
//Add the directory
$zipArchive->addEmptyDir($dir);
// Loop through all the files
while (($file = readdir($dh)) !== false) {
//If it's a folder, run the function again!
if(!is_file($dir . $file)){
// Skip parent and root directories
if(($file !== ".") && ($file !== "..")){
addFolderToZip($dir . $file . "/", $zipArchive);
}
}else{
// Add the files
$zipArchive->addFile($dir . $file);
}
}
}
}
}
$zip = new ZipArchive;
$zip->open("$modName.zip", ZipArchive::CREATE);
addFolderToZip("$modName/", $zip);
$zip->close();
And in the host I wrote just this code to extract the zipped file :
copy($file["tmp_name"], "module/$file[name]");
$zip = new ZipArchive;
if ($zip->open("module/$file[name]") === TRUE) {
$zip->extractTo('module/');
}
$zip->close();
It created the folder and sub-folders. The only bug left is that it extracts every file in all subfolders in the main folder too, so there is two versions of each file in subfolders.

PHP Sync over ftp giving errors

So I got this code that's suppose to grab all the contents from /upload/ folder on remote host and copy it into the location where the file is at. Code looks like this:
<?php
$ftp_server = "server";
$conn_id = ftp_connect ($ftp_server)
or die("Couldn't connect to $ftp_server");
$login_result = ftp_login($conn_id, "user", "password");
if ((!$conn_id) || (!$login_result))
die("FTP Connection Failed");
ftp_sync ("/update/");
ftp_close($conn_id);
function ftp_sync ($dir) {
global $conn_id;
if ($dir != ".") {
if (ftp_chdir($conn_id, $dir) == false) {
echo ("Change Dir Failed: $dir<BR>\r\n");
return;
}
if (!(is_dir($dir)))
mkdir($dir);
chdir ($dir);
}
$contents = ftp_nlist($conn_id, ".");
foreach ($contents as $file) {
if ($file == '.' || $file == '..')
continue;
if (#ftp_chdir($conn_id, $file)) {
ftp_chdir ($conn_id, "..");
ftp_sync ($file);
}
else
ftp_get($conn_id, $file, $file, FTP_BINARY);
}
ftp_chdir ($conn_id, "..");
chdir ("..");
}
?>
When I run it in an empty folder it does what it's suppose to. However, if I run it in a folder that contains the files from /update/ it will give me two errors. The errors are listed below
Warning: mkdir() [function.mkdir]: Permission denied in /home/limited/public_html/download.php on line 25
Warning: chdir() [function.chdir]: No such file or directory (errno 2) in /home/limited/public_html/download.php on line 26
It's suppose to just overwrite the files with new ones, not throw errors.
Thank you
Either the script (actually the user running the script) has no permissions to create new folders on the server OR the folder where you are trying to copy the files and create new folders is restricted from your user.
Try with a user that has higher permissions or add write permissions to the folder where you want to sync the files into

Categories