ZipArchive zip in linux corrupt in windows - php

I use ziparchive to zip my files in linux, and can't open in windows
default zip uploader, I suspect it is caused by the file path during addfile
e.g.
$zip-addFile(‘/home/userName/public_html/gallery/license.txt’, ‘gallery/license.txt’);
Suggestion from links below mention that I coudl remove the local path(as this can't be understood by windows), which becomes becomes
$zip-addFile(‘/home/userName/public_html/gallery/license.txt’, ‘license.txt’);
http://www.jacobbates.com/blog/2012/04/24/corrupt-zip-files-in-windows-from-phps-ziparchive/
PHP ZipArchive Corrupt in Windows
But I need to maintain the directory structure, how should I address this problem?

maybe first add the target directory with addEmptyDir see the code below this create different files:
<?php
error_reporting(E_ALL);
ini_set('display_errors','on');
$zip = new ZipArchive;
if ($zip->open('tmp/test.zip',ZipArchive::CREATE) === TRUE) {
$zip->addFile('data.php', 'data/data.php');
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
$zip = new ZipArchive;
if ($zip->open('tmp/testdata.zip',ZipArchive::CREATE) === TRUE) {
if($zip->addEmptyDir('data')) {
echo 'Created a new root directory';
} else {
echo 'Could not create the directory';
}
$zip->addFile('data.php', 'data/data.php');
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
The files got different file sizes:
-rw-r--r-- 1 www-data www-data 633 Apr 29 12:10 testdata.zip
-rw-r--r-- 1 www-data www-data 545 Apr 29 12:10 test.zip
unzip test.zip no empty dir added:
unzip test.zip
Archive: test.zip
inflating: data/data.php
unzip testdata.zip with an empty dir added:
Archive: testdata.zip
creating: data/
inflating: data/data.php
does creating: data/ first

Had the same problem with a structure similar to yours on a Drupal context. I solved this by setting the Content-disposition filename with my uri
file_transfer($archive_uri, array(
'Content-Disposition' => 'attachment; filename="' . $archive_uri . '"',
'Content-Length' => filesize($archive_uri))
);

Related

mkdir(): Permission denied in codeigniter

I´ve just moved my CI application to a real server, there, the user finds three optional file uploads, two for regular documents and images, and the third exclusively for a csv file, weird thing is that the first 2 uploads work Ok without warnings, the files upload with no problem, but the 3rd file, the csv file, keeps sending me a warning and avoids any file to be uploaded and the directory where it is supposed to upload is not created either, the code for the 1st file is this:
if (isset($_POST['save'])){
$this->load->library('upload');
$field = "file1";
$nombreCarpeta = preg_replace('/\s+/', '.', $this->session->userdata("username"));
$path = $this->config->item('server_root')."/codeigniter/uploads/".$nombreCarpeta."/";
if(!file_exists($path)){
mkdir($path, 0766);
}
$config["upload_path"] = $path;
$config["overwrite"] = "TRUE";
$config["remove_spaces"] = "TRUE";
$config["allowed_types"] = "txt|pdf|gif|jpg|png|tiff|doc|docx|rtf|jpeg";
$config["max_size"] = "1024*2048";
$config["max_width"] = "1024";
$config["max_height"] = "768";
$config["xss_clean"] = "FALSE";
$this->upload->initialize($config);
$this->upload->do_upload($field);
if($_FILES["file1"]['error'] == 0){
if ($this->upload->do_upload($field)){
$data = $this->upload->data();
array_push($arreglo, $data['file_name']);
}else{
$errors = $this->upload->display_errors();
}
}
.... same code, this time for file2
$field = "file3";
$pathDos = $this->config->item('server_root')."/codeigniter/listas/".$nombreCarpeta."/";
if(!file_exists($pathDos)){
mkdir($pathDos, 0777);
}
$config["upload_path"] = $pathDos;
$config["overwrite"] = "TRUE";
$config["remove_spaces"] = "TRUE";
$config["allowed_types"] = "csv";
$config["max_size"] = "1024*512";
$config["xss_clean"] = "FALSE";
$this->upload->initialize($config);
$this->upload->do_upload($field);
if($_FILES["file3"]['error'] == 0){
if ($this->upload->do_upload($field)){
$data = $this->upload->data();
array_push($arregloDos, $data['file_name']);
}else{
$errors = $this->upload->display_errors();
}
}
}
As you can see, the procedure is the same, except for some upload config, the files need to be uploaded in two previously created folders with 777 permissions, uploads and listas, inside of them, individual folders will be dynamically created and named as the user´s name, in order to distinguish between users files, as I said, no problem with the docs and images directory (uploads), the ls -l looks like this:
drwxrwxrwx. 2 root root 4096 Jan 14 05:59 listas
drwxrwxrwx. 3 root root 4096 Jan 13 11:18 uploads
ls -l inside uploads looks like this:
drwxr-xr-x. 2 apache apache 4096 Jan 13 13:29 administrator
the user administrator uploaded a couple of images, so, a folder named administrator was successfully created inside uploads before uploading his files, but no success when trying to upload a csv file, even when the folder listas has 777 permissions, no folder inside listas was created and no file uploaded, because a "mkdir(): Permission denied" warning!, as you can see the directories have proper permissions, I made a test creating the folder administrator inside of listas and giving it 777 permissions and chown-ing/chgrp-ing it to apache, and no results... any idea? am working on CentOS... thanx i.a.
It may be happening because of csv uploading problem which is a codeigniter bug.
Fix
Open application/config/mimes.php & update line 13 (probably)
'csv' => array('application/vnd.ms-excel', 'text/anytext', 'text/plain', 'text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'),

Unzip file skipping folder

I am creating a php file that will update my site after pulling it off of BitBucket (Git repo). It downloads a zip file of the entire master or a commit, then unzips it in the website's folder.
The problem I am having is there is a randomly named folder that contains all the files in the zip file.
My zip file's contents is similar:
master.php
- (bitbucketusername)-(reponame)-(commitnumber)
- folder1
- index.php
- test.php
- index.php
- config.php
- etc...
but how can I "bypass" the "randomly" named folder and extract the contents of the folder to the website's root?
echo "Unzipping update...<br>" . PHP_EOL;
$zip = new ZipArchive;
$res = $zip->open($filename);
if ($res === TRUE) {
$zip->extractTo('/path/to/www');
$zip->close();
} else {
echo 'Error: The zip file could not be opened...<br>' . PHP_EOL;
}
Found a related question here:
Operating with zip file in PHP
But how can I make it get the "randomly" named folder's name?
Unzip the files to a tmp directory and then mv the files out from the "randomly" named parent folder to the folder that you want to.
echo "Unzipping update...<br>" . PHP_EOL;
$zip = new ZipArchive;
$res = $zip->open($filename);
if ($res === TRUE) {
$zip->extractTo('/tmp/unzip');
$directories = scandir('/tmp/unzip');
foreach($directories as $directory){
if($directory!='.' and $directory!='..' ){
if(is_dir($directory)){
// rcopy from http://ben.lobaugh.net/blog/864/php-5-recursively-move-or-copy-files
rcopy('/tmp/unzip/'.$directory,'/path/to/www');
// rm /tmp/unzip here
}
}
}
$zip->close();
} else {
echo 'Error: The zip file could not be opened...<br>' . PHP_EOL;
}

ftp zip files from one server to another

I am attempting to transfer a zip file via ftp from one server to mine, so that I can use the data in the file to update my database table. Here is my ftp.php file:
<?php
header('Content-type: text/html; charset=utf-8');
$date = "2013-05-21-11-19-40";
$ftp_server="ftp.server.com";
$ftp_user_name="BookCellar";
$ftp_user_pass="*****";
$file = "/reports/other/compreport_abebooks_" .$date. ".zip";//tobe uploaded
$remote_file = "/chroot/home/bookcellaronline.com/html/testbcos/accounting/compreport_abebooks_" .$date. ".zip";
?>
and my ftpUpload.php file is:
<?php
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($file));
header('Content-Type: application/zip');
require_once('ftp.php');
// set up basic connection
$conn_id = ftp_ssl_connect($ftp_server);//ftp_connect
// login with username and password
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);
ftp_pasv($conn_id, true);
// check connection
if ((! $conn_id ) || (! $login_result )) {
echo "FTP connection has failed!" ;
exit;
} else {
echo "Connected for user $ftp_user_name" ;
}
ftp_chdir($conn_id, '/home/bookcell/bookcellaronline.com/html/testbcos/accounting/');
// upload a file
if (ftp_put($conn_id, $remote_file, $file, FTP_BINARY)) {
echo "successfully uploaded $file\n";
exit;
} else {
echo "There was a problem while uploading $file\n";
exit;
}
echo $php_errormsg;
// close the connection
ftp_close($conn_id);
?>
When I run these I get the error messge:
[<a href='function.ftp-put'>function.ftp-put</a>]: failed to open stream: No such file or directory in /chroot/home/bookcell/bookcellaronline.com/html/testbcos/accounting/ftpUpload.php on line 25
Line 25 is:
if (ftp_put($conn_id, $remote_file, $file, FTP_BINARY)) {
I have researched a bunch of other posts on SO and have not found a solution. My connection works, but I can't get the file to transfer.
How do I (if even possible) get this to transfer to my server?
EDIT: Am I missing the fact that I need to connect not only to their server($file) AND my server ($remote_file)????
You can't put a path to the destination file
$remote_file = "/chroot/home/bookcellaronline.com/html/testbcos/accounting/compreport_abebooks_" .$date. ".zip";
e.g. - this doesn't work
ftp_put($conn, '/www/site/file.html','c:/wamp/www/site/file.html',FTP_BINARY);
you have to put
<?php
ftp_chdir($conn, '/www/site/');
ftp_put($conn,'file.html', 'c:/wamp/www/site/file.html', FTP_BINARY );
A FTP server hides his absolute path /home/bookcell/bookcellaronline.com/html/
All folders must be relative to the root
ftp_chdir($conn_id, '/testbcos/accounting/');
test the result of ftp_chdir ! Are your in the right directory ?
echo ftp_pwd($conn_id);
Try to connect to the FTP server via a browser.
ftp://BookCellar#ftp.server.com
What you get is / the root. Folders and files that you see in the browser, are below the root directory.
Update : A working out of the box example.
the $password = line must be replaced with Download pass
ftp.php
<?php
$password = "????";
$resource = ftp_connect('ftp.strato.com');
$login = ftp_login($resource, 'ftp_mx_all#moskito-x.de', $password);
$list = ftp_rawlist($resource, '/');
print_r($list);
?>
You will get with print_r
Array ( [0] => drwxr-xr-x 2 ftp ftp 4096 May 23 20:15 aFolder [1] => -rw-r--r-- 1 ftp ftp 167 May 23 20:25 tutorial.txt )
we can see there is a folder aFolder and a file tutorial.txt.
We are interest what files are in the folder aFolder ?
So replace the $list = with
$list = ftp_rawlist($resource, '/aFolder');
and run the php script again. The output :
Array ( [0] => drwxr-xr-x 3 ftp ftp 4096 May 23 19:24 .. [1] => -rw-r--r-- 1 ftp ftp 167 May 23 20:25 tutorial.txt [2] => -rw-r--r-- 1 ftp ftp 271 May 23 21:16 tutorial.zip )
Now we want to download aFolder/tutorial.txt .
Add following below print_r($list); .
echo "<br />\n";
$local_file = "tmp.txt" ;
$file = ftp_get($resource, $local_file, '/aFolder/tutorial.txt',FTP_ASCII);
if ($file) {
echo "$local_file has been successfully written\n";
} else {
echo "An error has occurred\n";
}
The Output :
The folder where the php script is has changed.
now there is a new file tmp.txt !
If you bring this little script to run. We can go further.
From our chat :
Your server does not allow a ftp call to a url.
look allow_url_fopen = ON
echo ini_get('allow_url_fopen');
if (!ini_get('allow_url_fopen')) {
ini_set('allow_url_fopen', 1);
}
echo ini_get('allow_url_fopen');
Then try it again.
set_time_limit(0);
exec("wget --continue http://example.com/site.zip");
exit;
In the first excerpt change the remote tile to be
`$remote_file = "compreport_abebooks_" .$date. ".zip";`
prior to the put you are changing into the directory.
Also note that the directory that you reference in the ftp_chdir call differs from the one in the $remote_file referenced at the top.
/home/bookcell/bookcellaronline.com/html/testbcos/accounting/
vs
/chroot/home/bookcellaronline.com/html/testbcos/accounting/

File upload / move temp not working on nginx

So, i've read this question about move_uploaded_file() problems. However, on my apache-powered localhost lamp stack, its working just fine. So i think it may be a filesystem / path thing, and not a code thing.
when uploading files to my site locally, it works.
but when I'm on the QA server (which is nginx powered), i get this error:
2012/09/08 15:34:21 [error] 11794#0: *5187 FastCGI sent in stderr: "files not empty
PHP Warning: move_uploaded_file(/var/www/qa.mysite.com/mysite/app/files/maps-aprilfools.tiff): failed to open stream: No such file or directory in /var/www/qa.mysite.com/mysite/app/models/files.php on line 516
PHP Warning: move_uploaded_file(): Unable to move '/tmp/phpvdtznP' to '/var/www/qa.mysite.com/mysite/app/files/maps-aprilfools.tiff' in /var/www/qa.mysite.com/mysite/app/models/files.php on line 516" while reading response header from upstream, client: 72.xxx.xxx.xxx, server: qa.mysite.com, request: "POST /projects/3/files HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "qa.mysite.com", referrer: "http://qa.mysite.com/projects/3/files"
and this is the code that I wrote to handle uploading a file:
public function fileUploadToProject( $project_id ) {
if ($_FILES["upload-file"]["error"] > 0) {
echo "Error: " . $_FILES["file"]["error"] . "<br />";
} else {
$dbSuccess = false;
$tmp_name = $_FILES["upload-file"]["tmp_name"];
$name = $_FILES["upload-file"]["name"]; // someFile.ext
$size = $_FILES['upload-file']['size']; //size in bytes
$mime = $_FILES['upload-file']['type']; //size in bytes
$destination = __FILES__.'/'.$name;
$uploaded = move_uploaded_file( $tmp_name, $destination );
// add entry to database.
/*
* null because there is no container yet.
* We're only uploading to local
*/
$user_container_name = null;
$uploaded_by = LoggedInUser::get_user_id();
/*
* Set this 1 when we're not dealing with our external fileserver
*/
$isLocal = 1;
/*
* Probably shouldn't do this forever for storage size reasons, but for now its useful.
*/
$localPath = $destination;
$task_id = null;
if( $uploaded ) {
$dbSuccess = $this->insertFileRefService( $task_id,
$project_id,
$user_container_name,
$name,
$mime,
$size,
$uploaded_by,
$isLocal,
$localPath
);
if($dbSuccess) {
return true;
} else {
// should I rollback / delete that file?
return false;
}
} else {
return false;
}
}
}
So, is there anything I should know about moving temp files to my filesystem with on nginx? or do you think it is simply a path problem? code problem?
Also, please note that line 516 is this: $uploaded = move_uploaded_file( $tmp_name, $destination );
The folder had problems with permissions, among other things.
the /files directory in that path actually doesn't exist. I somehow never realized that the folder simply wasn't there. Whoops.
then, i had to determine what user was used by nginx to execute php:
ps aux | grep "nginx"
then i had to chown the files directory:
chown -R root:userFromStep1 files
then i had to chmod the directory:
chmod g+w files
that worked like a charm.
Can please try with giving the exact path instead of using the __FILES__. Because it'll not be nginx problem. it will be path problem only

Write binary file in PHP

I have wrote a PHP file which will save a JPEG file in the server and part of the code is listed as follow:
//create folder if folder not exist
if (!is_dir($save_path)){
$old = umask(0);
$flag = #mkdir($save_path,0777);
umask($old);
if(isset($flag)){
$string = 'Folder Create Success!'."\n";
}else{
$string= 'Folder Create Fail!'."\n";
}
echo $string;
}else{
echo "Folder exist!!!!";
}
//write the content to the server
$base=$_REQUEST['image'];
$binary=base64_decode($base);
header('Content-Type: image/jpg; charset=utf-8');
if(!$file = fopen($path, 'wb')){
echo 'Image upload Fail!'."\n";
return;
}
else
{
fwrite($file, $binary);
fclose($file);
}
The problem is when I run the code, if the folder does not exist, it create the folder only but the content can't save in the folder. The error message is :
[Thu Jul 05 16:59:06 2012] [error] [client 10.95.61.220] PHP Warning: fopen(/mnt/csis/upload/newphoto/others/12346_test/12346_test_2012-07-05_others_abc.jpg): failed to open stream: Permission denied in /var/www/html/upload_image.php on line 57
However, if I run the code again, since the folder was created in the past, it work properly. The content can save in the folder......
Anything I get wrong? I try to find the answer on the web but still can't solve the problem.
Anyone can help, many thanks!
I would try changing the creation of the folder to use the recursive flag:
$flag = #mkdir($save_path . "/" . $file,0777,true);

Categories