I'm trying to copy multiple files from one domain on a web server to another using copy() and looping through a list of files, but it's only copying the last file on the list.
Here is the contents of files-list.txt:
/templates/template.php
/admin/admin.css
/admin/codeSnippets.php
/admin/editPage.php
/admin/index.php
/admin/functions.php
/admin/style.php
/admin/editPost.php
/admin/createPage.php
/admin/createPost.php
/admin/configuration.php
This script runs on the website that I'm trying to copy the files to. Here's the script:
$filesList = file_get_contents("http://copyfromhere.com/copythesefiles/files-list.txt");
$filesArray = explode("\n", $filesList);
foreach($filesArray as $file) {
$filename = trim('http://copyfromhere.com/copythesefiles' . $file);
$dest = "destFolder" . $file;
if(!#copy($filename, $dest))
{
$errors= error_get_last();
echo "COPY ERROR: ".$errors['type'];
echo "<br />\n".$errors['message'];
} else {
echo "$filename copied to $dest from remote!<br/>";
}
}
I get the affirmative message for each and every file individually just as I should, but when I check the directory, only the last file from files-list.txt is there. I've tried changing the order, so I know the problem lies with the script, not any individual file.
The output from the echo statements looks something like this:
http://copyfromhere.com/copythesefiles/admin/admin.css copied to updates/admin/editPage.php from remote!
http://copyfromhere.com/copythesefiles/admin/admin.css copied to updates/admin/editPost.php from remote!
http://copyfromhere.com/copythesefiles/admin/admin.css copied to updates/admin/index.php from remote!
Etc
I've modified your code slightly, and tested it on my local dev server. The following seems to work:
$fileURL = 'http://copyfromhere.com/copythesefiles';
$filesArray = file("$fileURL/files-list.txt", FILE_IGNORE_NEW_LINES);
foreach ($filesArray as $file) {
$fileName = "$fileURL/$file";
$dest = str_replace($fileURL, 'destFolder', $fileName);
if (!copy($fileName, $dest)) {
$errors= error_get_last();
echo "COPY ERROR: ".$errors['type'];
echo "<br />\n".$errors['message'];
}
else {
echo "$fileName copied to $dest from remote!<br/>";
}
}
This uses the same fix that Mark B pointed out, but also consolidated the code a little.
Unless the data you're fetching from that remote site has leading/ in the path/filename, you're not generating proper paths:
$file = 'foo.txt'; // example only
$dest = "destFolder" . $file;
produces destFolderfoo.txt, and you end up littering your script's working directory with a bunch of wonky filenames. Perhaps you wanted
$dest = 'destFolder/' . $file;
^----note this
instead.
Related
https://trevim.pt/header-4/
I'm copying this image to this link
https://trevim.pt/anuncios/header.png
When I run the script it always says 'File copied successfully' but some times I only get the top half of the image... it's not at all a large file (22.6KB), is this behavior normal? How can I copy the whole image every time? Any ideas? Here's my code:
foreach($to_activate as $data_row)
{
$template_id = $data_row['template_id'];
$img_url = $data_row['img_url'];
$template = mysqli_query($conn, "SELECT name FROM `wp_ad_templates` WHERE id = '$template_id' limit 1")->fetch_object()->name;
$dst = "../" . $template . ".png";
if(!#copy($img_url, $dst))
{
$errors= error_get_last();
echo "COPY ERROR: ".$errors['type'];
echo "<br>".$errors['message']."<br><br>";
} else {
echo "File copied from remote!";
}
}
By the way I found this similar question Php copy only copies part of file which is solved by using exec() but that solution didn't work for me, I get:
COPY ERROR: 2
exec() has been disabled for security reasons
I am trying to copy a file that I download it. The file name is test1234.txt, but I want to access it using a wildcard like this: test*.txt and after that to move it to another folder (because I don't know how the file name looks like, but I know that the beginning is test and the rest is changing every time I download a new one). I tried some codes:
$myFile = 'C:/Users/Carl/Downloads/'. date("y-m-d") . '/test*.txt';
$myNewFile = 'C:/Users/Carl/Downloads/'. date("y-m-d").'/text.xml';
if(preg_match("([0-9]+)", $myFile)) {
echo 'ok';
copy($myFile, $myNewFile);
}
I am getting an error because of * in $myFile. Any help is very appreciated.
$myFile= 'C:/Users/Carl/Downloads/'. date("y-m-d") . '/test*.txt';
$myNyFile = 'C:/Users/Carl/Downloads/'.date("y-m-d").'/test.txt';
foreach (glob($myFile) as $fileName) {
copy($fileName, $myNyFile);
}
For complete response, if you want to only move *.txt in NewFolder.
$myFiles = 'C:/Users/Carl/Downloads/*.txt';
$myFolderDest = 'C:/Users/Carl/NewFolder/';
foreach (glob($myFiles) as $file) {
copy($file, $myFolderDest . basename($file));
}
I have code which generates a text file on my server. I then need this file uploaded to another server using sftp. To start things off, I do
if(performLdapOperations()) {
sleep(10);
performFtpOperation();
}
performLdapOperations produces the text file and places it on my server, performFtpOperation takes this text file and uploads to another server. This is my function
function performFtpOperation() {
global $config;
$local_directory = getcwd() .'/outputs/';
$remote_directory = '/home/newfolder/';
$sftp = new SFTP($config::FTP_SERVER, 22, 10);
if (!$sftp->login($config::FTP_USER, $config::FTP_PASSWORD)) {
exit('Login Failed');
}
$files_to_upload = array();
/* Open the local directory form where you want to upload the files */
if ($handle = opendir($local_directory))
{
/* This is the correct way to loop over the directory. */
while (false !== ($file = readdir($handle)))
{
if ($file != "." && $file != "..")
{
$files_to_upload[] = $file;
}
}
closedir($handle);
}
if(!empty($files_to_upload))
{
/* Now upload all the files to the remote server */
foreach($files_to_upload as $file)
{
$success = $sftp->put($remote_directory . $file,
$local_directory . $file,
NET_SFTP_LOCAL_FILE);
}
}
}
So the text file that is produces is in my outputs folder. I then want to take this file and upload to a new server to the location /home/newfolder/
Everything seems to work, and the file seems to get uploaded to the new server. However, when I open the file that has been uploaded, all it contains is the path of where the file is, nothing else. The file on my server which is in the outputs folder contains everything, for some reason something is going wrong when sending it over sftp?
Is there anything in my code that may be causing this?
Thanks
It looks like you're using the 2.0 version of phpseclib, which is namespaced. If that's the case then the problem is with this line:
$success = $sftp->put($remote_directory . $file,
$local_directory . $file,
NET_SFTP_LOCAL_FILE);
Try this:
$success = $sftp->put($remote_directory . $file,
$local_directory . $file,
SFTP::SOURCE_LOCAL_FILE);
I have a zip file containing one folder, that contains more folders and files, like this:
myfile.zip
-firstlevel
--folder1
--folder2
--folder3
--file1
--file2
Now, I want to extract this file using PHPs ZipArchive, but without the "firstlevel" folder. At the moment, the results look like this:
destination/firstlevel/folder1
destination/firstlevel/folder2
...
The result I'd like to have would look like this:
destination/folder1
destination/folder2
...
I've tried extractTo, which produces the first mentioned result, and copy(), as suggested here, but this doesn't seem to work at all.
My current code is here:
if($zip->open('myfile.zip') === true) {
$firstlevel = $zip->getNameIndex(0);
for($i = 0; $i < $zip->numFiles; $i++) {
$entry = $zip->getNameIndex($i);
$pos = strpos($entry, $firstlevel);
if ($pos !== false) {
$file = substr($entry, strlen($firstlevel));
if(strlen($file) > 0){
$files[] = $file;
}
}
}
//attempt 1 (extractTo):
//$zip->extractTo('./test', $files);
//attempt 2 (copy):
foreach($files as $filename){
copy('zip://'.$firstlevel.'/'.$filename, 'test/'.$filename);
}
}
How can I achieve the result I'm aiming for?
Take a look at my Quick Unzipper script. I wrote this for personal use a while back when uploading large zip files to a server. It was a backup, and 1,000s of files take forever with FTP so using a zip file was faster. I use Git and everything, but there wasn't another option for me. I place this php file in the directory I want the files to go, and put the zip file in the same directory. For my script, they all have to operate in the same directory. It was an easy way to secure it for my needs, as everything I needed was in the same dir.
Quick Unzipper: https://github.com/incomepitbull/QuickUnzipper/blob/master/unzip.php
I linked the file because I am not showcasing the repo, just the code that makes the unzip tick. With modern versions of PHP, there should't be anything that isn't included on your setup. So you shouldn't need to do any server config changes to use this.
Here is the PHP Doc for the ZipArchive class it uses: http://php.net/manual/en/class.ziparchive.php
There isn't any included way to do what you want, which is a shame. So I would unzip the file to a temp directory, then use another function to copy the contents to where you want. So when using ZipArchive, you will need to return the first item to get the folder name if it is unknown. If the folder is known, ie: the same pesky folder name every time, then you could hard code the name.
I have made it return the first item from the index. So if you ALWAYS have a zip with 1 folder inside it, and everything in that folder, this would work. However, if you have a zip file without everything consolidated inside 1 folder, it would fail. The code I have added will take care of your question. You will need to add further logic to handle alternate cases.
Also, You will still be left with the old directory from when we extract it to the temp directory for "processing". So I included code to delete it too.
NOTE: The code uses a lot of if's to show the processing steps, and print a message for testing purposes. You would need to modify it to your needs.
<?php
public function copyDirectoryContents($source, $destination, $create=false)
{
if ( ! is_dir($source) ) {
return false;
}
if ( ! is_dir($destination) && $create === true ) {
#mkdir($destination);
}
if ( is_dir($destination) ) {
$files = array_diff(scandir($source), array('.','..'));
foreach ($files as $file)
{
if ( is_dir($file) ) {
copyDirectoryContents("$source/$file", "$destination/$file");
} else {
#copy("$source/$file", "$destination/$file");
}
}
return true;
}
return false;
}
public function removeDirectory($directory, $options=array())
{
if(!isset($options['traverseSymlinks']))
$options['traverseSymlinks']=false;
$files = array_diff(scandir($directory), array('.','..'));
foreach ($files as $file)
{
if (is_dir("$directory/$file"))
{
if(!$options['traverseSymlinks'] && is_link(rtrim($file,DIRECTORY_SEPARATOR))) {
unlink("$directory/$file");
} else {
removeDirectory("$directory/$file",$options);
}
} else {
unlink("$directory/$file");
}
}
return rmdir($directory);
}
$file = dirname(__FILE__) . '/file.zip'; // full path to zip file needing extracted
$temp = dirname(__FILE__) . '/zip-temp'; // full path to temp dir to process extractions
$path = dirname(__FILE__) . '/extracted'; // full path to final destination to put the files (not the folder)
$firstDir = null; // holds the name of the first directory
$zip = new ZipArchive;
$res = $zip->open($file);
if ($res === TRUE) {
$firstDir = $zip->getNameIndex(0);
$zip->extractTo($temp);
$zip->close();
$status = "<strong>Success:</strong> '$file' extracted to '$temp'.";
} else {
$status = "<strong>Error:</strong> Could not extract '$file'.";
}
echo $status . '<br />';
if ( empty($firstDir) ) {
echo 'Error: first directory was empty!';
} else {
$firstDir = realpath($temp . '/' . $firstDir);
echo "First Directory: $firstDir <br />";
if ( is_dir($firstDir) ) {
if ( copyDirectoryContents($firstDir, $path) ) {
echo 'Directory contents copied!<br />';
if ( removeDirectory($directory) ) {
echo 'Temp directory deleted!<br />';
echo 'Done!<br />';
} else {
echo 'Error deleting temp directory!<br />';
}
} else {
echo 'Error copying directory contents!<br />';
}
} else {
echo 'Error: Could not find first directory';
}
}
I have this code to read a file for preview, but the downside is I have to download the file first from cloud and read from it, but it's a waste of space so I want to delete it after viewing a certain file. Is there an automatic way of doing this? Or do I have to integrate it to a close button?
// Get the container we want to use
$container = $conn->get_container('mailtemplate');
//$filename = 'template1.zip';
// upload file to Rackspace
$object = $container->get_object($filename);
//var_dump($object);
//echo '<pre>' . print_r($object,true) . '</pre>';
$localfile = $dir.$filename;
//echo $localfile;
$object->save_to_filename($localfile);
if($_GET['preview'] == "true")
{
$dir = "../mailtemplates/";
$file1 = $_GET['tfilename'];
$file = $dir.$file1;
$file2 = "index.html";
$info = pathinfo($file);
$file_name = basename($file,'.'.$info['extension']);
$path = $file_name.'/'.$file2;
$zip = new ZipArchive();
$zip->open($file);
$fp = $zip->getStream($path);
if(!$fp)
{
exit("faileds\n");
$zip->close();
unlink($dir.$filename);
}
else
{
$stuff = stream_get_contents($fp);
echo $stuff;
$zip->close();
if($stuff != null)
{
unlink($dir.$filename);
}
}
}
else
{
unlink($dir.$filename);
}
You didn't google this did ya?
Try Unlink
Edit:
Taking a look at this code, $zip->open($file); <-- is where you open the file. The file variable is set by:
"../mailtemplates/" . basename($_GET['tfilename'], '.' . $info['extension']) . '/' . "index.html"
So you're grabbing a relative directory and grabbing a filename as a folder, and going to that folder /index.html. Here's an example:
if you're in c:\ testing and you go to ../mailtemplates/ you'll be in c:\mailtemplates and then you're looking at file test.php but you're removing the file extension, so you'll be opening the location c:\mailtemplates\test\index.html so you open up that html file and read it. Then, you're trying to delete c:\mailtemplates\test.php
can you explain how any of that makes sense to you? 'cause that seems very odd to me.