ZIP archive cannot close after new zip in foreach (PHP) - php

PHP-Version: 8
My script gets pathes to adding the files in a zip. After an individual size, the zip closed and a new one opened for adding files. All works, but when the second file should closed, i'll get an error:
Fatal error: Uncaught ValueError: Invalid or uninitialized Zip object in...
Everything is ok in my log file. The first ZIP is created, files are added and closed. Then the 2nd ZIP is created, files are added and then the ZIP should be closed again. The error comes when closing the second file.
Thats my script:
/**
* check and process file list
**/
## log
$log->logging($lf, "Check backuppathes list.");
## check file list
if(!empty($fullfilelist)) {
## log
$log->logging($lf, "Setting zip parameter.");
## zip counter
$zc = 0;
## zip size
$zs = 0;
## zip path
$zp = (addslashes(__DIR__))."\\zip\\";
## zipfile
$zipfile = $zp.date("Y-m-d")."-".str_pad($zc, 3, "0", STR_PAD_LEFT).".zip";
## log
$log->logging($lf, "Create zip file: ".$zipfile);
## start zip file
$myzip[$zc] = new mfzip;
$myzip[$zc]->newzip($zipfile);
## check new zip file
if($myzip[$zc]->result == 200) {
## log
$log->logging($lf, "Zip ".$zipfile." starts! Set password...");
## set zip password
$myzip[$zc]->passzip($CFG['zippass']);
## check setting
if($myzip[$zc]->result == 200) {
## log
$log->logging($lf, "Password set! Process pathes...");
## process file list
foreach($fullfilelist as $ffl) {
## local file
$l = $ffl;
## log
$log->logging($lf, "Add local file: ".$l);
## file in zip
$r = substr($ffl, 3, 10000000000);
## checking file reading
if(is_readable($l)) {
## add file
$myzip[$zc]->add($l, $r);
## check adding
if($myzip[$zc]->result == 200) {
## log
$log->logging($lf, "Adding successful! Crypt file...");
## crypt file
$myzip[$zc]->cf($r);
## check crypt
if($myzip[$zc]->result == 200) {
## log
$log->logging($lf, "Crypting successful! Get stats of file...");
## get file stats
$myzip[$zc]->stats($r);
## check stats
if($myzip[$zc]->result == 200 && is_array($myzip[$zc]->fstats)) {
## log
$log->logging($lf, "Get stats successful! Checking zip size...");
## filesize
$rfs = $myzip[$zc]->fstats['size'];
## new zip size
$zs = $zs + $rfs;
## log
$log->logging($lf, "File in zip: ".$rfs." bytes | current zip size: ".$zs." bytes");
## check zip size with configured size
if($zs > $CFG['zipsize']) {
## log
$log->logging($lf, "Close zip and start new file (".$zc.")!");
## close zip
$myzip[$zc]->cz();
## check closing
if($myzip[$zc]->result == 200) {
## log
$log->logging($lf, "Closing successfully: ".$zipfile);
## counting up
$zc++;
## zipfile
$zipfile = $zp.date("Y-m-d")."-".str_pad($zc, 3, "0", STR_PAD_LEFT).".zip";
## start new zip file
$myzip[$zc] = new mfzip;
$myzip[$zc]->newzip($zipfile);
## check new file
if($myzip[$zc]->result == 200) {
## log
$log->logging($lf, "Create new zip file: ".$zipfile);
}
## set zip size to 0
$zs = 0;
} else {
## log
$log->logging($lf, "ERROR: Closing error: ".$zipfile);
break;
}
}
} else {
## log
$log->logging($lf, "ERROR: Can't get stats of file ".$r);
}
} else {
## log
$log->logging($lf, "ERROR: Can't crypt file: ".$r);
}
} else {
## log
$log->logging($lf, "ERROR: Can't adding file: ".$r);
}
} else {
## log
$log->logging($lf, "ERROR: Can't read file: ".$l);
}
}
} else {
## log
$log->logging($lf, "ERROR: Can't set password for zip file: ".$zipfile);
}
## log
$log->logging($lf, "Last closing file: ".$zipfile);
## close zip
$myzip[$zc]->cz();
## check closing
if($myzip[$zc]->result == 200) {
## log
$log->logging($lf, "Closing successfully!");
} else {
## log
$log->logging($lf, "ERROR: Closing error: ".$zipfile);
}
} else {
## log
$log->logging($lf, "ERROR: Creating zip file: ".$zipfile);
}
} else {
## log
$log->logging($lf, "ERROR: No backup pathes!");
}
Thats my zip class:
/**
* marcfunk zipping class
**/
class mfzip {
## vars
public $fstats;
public $result;
public $zip;
/**
* create zip archive
* #param: string, filename of zipfile
**/
public function newzip($filename = "") {
## check filename
if($filename !== "") {
## start zip class
$newzip = new ZipArchive();
## create archive
if($newzip->open($filename, ZipArchive::CREATE) === TRUE) {
## status code
$this->result = 200;
## zip class
$this->zip = $newzip;
} else {
$this->result = 900;
}
} else {
$this->result = 900;
}
}
/**
* set zip password
* #param: string, password for zip
**/
public function passzip($hash) {
$setpass = $this->zip;
if($setpass->setPassword($hash)) {
$this->result = 200;
} else {
$this->result = 900;
}
}
/**
* add file to archive
* #param: string, path to local file
* #param: string, path in zip file
**/
public function add($local = "", $remote = "") {
$addfile = $this->zip;
## check local
if($local !== "" && file_exists($local)) {
## check remote
if($remote !== "") {
## add file
if($addfile->addFile($local, $remote)) {
$this->result = 200;
} else {
$this->result = 900;
}
} else {
$this->result = 900;
}
} else {
$this->result = 900;
}
}
/**
* crypt file
* #param: string, path in zip file
**/
public function cf($remote = "") {
$encr = $this->zip;
## check remote
if($remote !== "") {
## crypt file
if($encr->setEncryptionName($remote, ZipArchive::EM_AES_256)) {
$this->result = 200;
} else {
$this->result = 900;
}
} else {
$this->result = 900;
}
}
/**
* stats of file
* #param: string, path in zip file
**/
public function stats($remote = "") {
$stats = $this->zip;
## check remote
if($remote !== "") {
## stats of file
if($this->fstats = $stats->statName($remote)) {
## result
$this->result = 200;
} else {
$this->result = 900;
}
} else {
$this->result = 900;
}
}
/**
* close zip
**/
public function cz() {
if($this->zip->close() === TRUE) {
$this->result = 200;
} else {
$this->result = 900;
}
}
}
I checked up, that the files are available and readable. I have also code a pause after the first close and before starting the second file. The first zip is okay and can extract, but he won't create the second file.

Related

Cannot create large zip file on GAE / Cloud Storage / PHP

I've read similar posts on ZipArchive and GAE but they do not solve my problem. Creating the .zip to the GAE tmp folder exhausts memory as the zip may be 1G or more. Therefore, I'm trying to write directly to a storage bucket.
The output below shows the results of running my zip function. I'm sort of new to GAE/Storage so hoping some more eyes could help me out!
One thing I notice is that $zip->filename = /workspace/gs:/X... Why is "workspace" there and why only one "/" after gs:?
If there is some other method to achieve this, I'm open to suggestions!
I have this working in LAMP, but need to move to GAE. Here's my code of the function that does the zipping:
<?php
function create_zip($files = array(),$fileDestinations = array(),$destination='',$overwrite = false) {
$valid_files = array();
if(is_array($files)) {
//cycle through each file
foreach($files as $file) {
//make sure the file exists OR THE ZIP WON'T BE CREATED
if(file_exists($_SESSION['devStorage'].$file)) {
$valid_files[] = $_SESSION['devStorage'].$file;
}else{
$valid_files[] = $_SERVER['DOCUMENT_ROOT']."/images/default.jpg";
}
}
}
//if we have good files...
if(count($valid_files)) {
if (is_writable(str_replace("https://storage.googleapis.com/","gs://",$_SESSION['devStorage']))) {
echo '<br>'.str_replace("https://storage.googleapis.com/","gs://",$_SESSION['devStorage']).' Folder is writable<br>';
} else {
echo '<br>'.str_replace("https://storage.googleapis.com/","gs://",$_SESSION['devStorage']).' Folder not writable<br>';
}
//create the archive
$zip = new ZipArchive();
if($zip->open($destination, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) {
return "<br>can't open ".$destination;
}
//add the files
foreach($valid_files as $file) {
$zip->addFile($file,current($fileDestinations));
next($fileDestinations);
}
//debug
echo '<br>The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status;
echo '<br>zip->filename = '.$zip->filename;
//close the zip -- done!
if($zip->close()!==true) {
echo '<br>zip->close error';
}
//check to make sure the file exists
if (!file_exists($destination)) {
return "<br>File does not exist at ".$destination;
}else{
return true;
}
} else {
return "no valid files";
}
}
?>
The resulting output:
gs://X.appspot.com/uploads/ Folder is writable
The zip archive contains 139 files with a status of 0
zip->filename = /workspace/gs:/X.appspot.com/uploads/XSpring2021asof122920_06-03-2021_11-18-45
zip->close error
File does not exist at gs://X.appspot.com/uploads/XSpring2021asof122920_06-03-2021_11-18-45
Thanks for any help offered!
Ended up using ZipStream. My function for zipping is below:
/* creates a compressed zip file */
function create_zip($files = array(),$fileDestinations = array(),$destination='') {
// Autoload the dependencies
require 'vendor/autoload.php';
// enable output of HTTP headers
$options = new ZipStream\Option\Archive();
$options->setSendHttpHeaders(true);
$options->setFlushOutput(true);
$options->setZeroHeader(true);
$options->setStatFiles(true);
// create a new zipstream object
$zip = new ZipStream\ZipStream($destination, $options);
$valid_files = array();
if(is_array($files)) {
//cycle through each file
foreach($files as $file) {
if (($_SERVER["REMOTE_ADDR"]=="127.0.0.1") || ($_SESSION["LAMP"]==1)) {
// //make sure the file exists OR THE ZIP WON'T BE CREATED
//if(file_exists($_SERVER["REQUEST_SCHEME"]."://".$_SERVER['HTTP_HOST'].$file)) {
$valid_files[] = $_SERVER["REQUEST_SCHEME"]."://".$_SERVER['HTTP_HOST'].$file;
//}else{
// $valid_files[] = $_SERVER["REQUEST_SCHEME"]."://".$_SERVER['HTTP_HOST']."/images/default.jpg";
//}
}else{
// //make sure the file exists OR THE ZIP WON'T BE CREATED
//if(file_exists($file)) {
$valid_files[] = $file;
//}else{
// $valid_files[] = $_SERVER["REQUEST_SCHEME"]."://".$_SERVER['HTTP_HOST']."/images/default.jpg";
//}
}
}
}
//if we have good files...
if(count($valid_files)) {
foreach($valid_files as $url) {
// Create Temp File
$fp = tmpfile();
// Download File
$ch = curl_init();
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_URL, $url);
curl_exec($ch);
// Force to write all data
fflush($fp);
// Rewind to the beginning, otherwise the stream is at the end from the start
rewind($fp);
// Add File
$zip->addFileFromStream(current($fileDestinations), $fp);
next($fileDestinations);
// Close the Temp File
curl_close($ch);
fclose($fp);
}
// Finish ZIP
$zip->finish();
return true;
}else{
return "no valid files";
}
}

Uploading files in Fine-Uploader, fail to combine/merge chunks after successful upload

So I've been trying to get Chunked uploading working for a project I've been working on, I'm pretty new to things, in fact for all intensive purposes you can consider me a complete noob who is teaching himself, I'm using the Manual Upload Template from the website, and the Traditional Server Side Example files to gain an understanding of how the code works and trying to piece them together into a fully functional example for me to build from. I've been able to get most things working.
I've managed to get it uploading regular files into the files folder successfully if I upload a file without chunking it goes into my files directory, however if I use chunking it works to chunk up the file and upload it into a folder in my Chunks directory, but i cant seem to figure out how to get it to put the chunks back together and place it in the Files directory
My Firefox console gives me this response and stops after finishing uploading a file in chunks regardless of if I have my chunking success endpoint included in my code or not which makes me think it's got something to do with my chunking success endpoint not being set up correctly or something along those lines.
[Fine Uploader 5.11.8] All chunks have been uploaded for 0 - finalizing....fine-uploader.js:162:21
[Fine Uploader 5.11.8] Received response status 200 with body: {"success":true,"uuid":"79e7db33-9609-49cd-bcb1-2606bea6abd7","uploadName":null}fine-uploader.js:162:21
[Fine Uploader 5.11.8] Finalize successful for 0
I've spent about 2 days researching this with no avail, I don't seem to be getting errors, but as I said I'm pretty much a Noob when it comes to understanding this on my own. Any help is Greatly Appreciated.
Here Is my Uploader Code Body
<body>
<!-- Fine Uploader DOM Element
====================================================================== -->
<div id="fine-uploader-manual-trigger"></div>
<!-- Your code to create an instance of Fine Uploader and bind to the DOM/template
====================================================================== -->
<script>
var manualUploader = new qq.FineUploader({
debug: true,
element: document.getElementById('fine-uploader-manual-trigger'),
template: 'qq-template-manual-trigger',
request: {
endpoint: 'endpoint.php'
},
chunking: {
enabled: true
},
success: {
endpoint: "endpoint.php?done"
},
resume: {
enabled: true
},
thumbnails: {
placeholders: {
waitingPath: 'images/waiting-generic.png',
notAvailablePath: 'images/not_available-generic.png'
}
},
autoUpload: false,
showMessage: function(message) { //show message if any error occur during upload process
alert(message);
}
});
qq(document.getElementById("trigger-upload")).attach("click", function() {
manualUploader.uploadStoredFiles();
});
</script>
</body>
</html>
Here Is my Endpoint.php File
require_once "handler.php";
$uploader = new UploadHandler();
// Specify the list of valid extensions, ex. array("jpeg", "xml", "bmp")
$uploader->allowedExtensions = array(); // all files types allowed by default
// Specify max file size in bytes.
$uploader->sizeLimit = null;
// Specify the input name set in the javascript.
$uploader->inputName = "qqfile"; // matches Fine Uploader's default inputName value by default
// If you want to use the chunking/resume feature, specify the folder to temporarily save parts.
$uploader->chunksFolder = "chunks";
$method = $_SERVER["REQUEST_METHOD"];
if ($method == "POST") {
header("Content-Type: text/plain");
// Assumes you have a chunking.success.endpoint set to point here with a query parameter of "done".
// For example: /myserver/handlers/endpoint.php?done
if (isset($_GET["done"])) {
$result = $uploader->combineChunks("files");
}
// Handles upload requests
else {
// Call handleUpload() with the name of the folder, relative to PHP's getcwd()
$result = $uploader->handleUpload("files");
// To return a name used for uploaded file you can use the following line.
$result["uploadName"] = $uploader->getUploadName();
}
echo json_encode($result);
}
// for delete file requests
else if ($method == "DELETE") {
$result = $uploader->handleDelete("files");
echo json_encode($result);
}
else {
header("HTTP/1.0 405 Method Not Allowed");
}
?>
Here is my handler.php file, I'm just using the default traditional server side example.
class UploadHandler {
public $allowedExtensions = array();
public $sizeLimit = null;
public $inputName = 'qqfile';
public $chunksFolder = 'chunks';
public $chunksCleanupProbability = 0.001; // Once in 1000 requests on avg
public $chunksExpireIn = 604800; // One week
protected $uploadName;
/**
* Get the original filename
*/
public function getName(){
if (isset($_REQUEST['qqfilename']))
return $_REQUEST['qqfilename'];
if (isset($_FILES[$this->inputName]))
return $_FILES[$this->inputName]['name'];
}
public function getInitialFiles() {
$initialFiles = array();
for ($i = 0; $i < 5000; $i++) {
array_push($initialFiles, array("name" => "name" + $i, uuid => "uuid" + $i, thumbnailUrl => ""));
}
return $initialFiles;
}
/**
* Get the name of the uploaded file
*/
public function getUploadName(){
return $this->uploadName;
}
public function combineChunks($uploadDirectory, $name = null) {
$uuid = $_POST['qquuid'];
if ($name === null){
$name = $this->getName();
}
$targetFolder = $this->chunksFolder.DIRECTORY_SEPARATOR.$uuid;
$totalParts = isset($_REQUEST['qqtotalparts']) ? (int)$_REQUEST['qqtotalparts'] : 1;
$targetPath = join(DIRECTORY_SEPARATOR, array($uploadDirectory, $uuid, $name));
$this->uploadName = $name;
if (!file_exists($targetPath)){
mkdir(dirname($targetPath), 0777, true);
}
$target = fopen($targetPath, 'wb');
for ($i=0; $i<$totalParts; $i++){
$chunk = fopen($targetFolder.DIRECTORY_SEPARATOR.$i, "rb");
stream_copy_to_stream($chunk, $target);
fclose($chunk);
}
// Success
fclose($target);
for ($i=0; $i<$totalParts; $i++){
unlink($targetFolder.DIRECTORY_SEPARATOR.$i);
}
rmdir($targetFolder);
if (!is_null($this->sizeLimit) && filesize($targetPath) > $this->sizeLimit) {
unlink($targetPath);
http_response_code(413);
return array("success" => false, "uuid" => $uuid, "preventRetry" => true);
}
return array("success" => true, "uuid" => $uuid);
}
/**
* Process the upload.
* #param string $uploadDirectory Target directory.
* #param string $name Overwrites the name of the file.
*/
public function handleUpload($uploadDirectory, $name = null){
if (is_writable($this->chunksFolder) &&
1 == mt_rand(1, 1/$this->chunksCleanupProbability)){
// Run garbage collection
$this->cleanupChunks();
}
// Check that the max upload size specified in class configuration does not
// exceed size allowed by server config
if ($this->toBytes(ini_get('post_max_size')) < $this->sizeLimit ||
$this->toBytes(ini_get('upload_max_filesize')) < $this->sizeLimit){
$neededRequestSize = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
return array('error'=>"Server error. Increase post_max_size and upload_max_filesize to ".$neededRequestSize);
}
if ($this->isInaccessible($uploadDirectory)){
return array('error' => "Server error. Uploads directory isn't writable");
}
$type = $_SERVER['CONTENT_TYPE'];
if (isset($_SERVER['HTTP_CONTENT_TYPE'])) {
$type = $_SERVER['HTTP_CONTENT_TYPE'];
}
if(!isset($type)) {
return array('error' => "No files were uploaded.");
} else if (strpos(strtolower($type), 'multipart/') !== 0){
return array('error' => "Server error. Not a multipart request. Please set forceMultipart to default value (true).");
}
// Get size and name
$file = $_FILES[$this->inputName];
$size = $file['size'];
if (isset($_REQUEST['qqtotalfilesize'])) {
$size = $_REQUEST['qqtotalfilesize'];
}
if ($name === null){
$name = $this->getName();
}
// check file error
if($file['error']) {
return array('error' => 'Upload Error #'.$file['error']);
}
// Validate name
if ($name === null || $name === ''){
return array('error' => 'File name empty.');
}
// Validate file size
if ($size == 0){
return array('error' => 'File is empty.');
}
if (!is_null($this->sizeLimit) && $size > $this->sizeLimit) {
return array('error' => 'File is too large.', 'preventRetry' => true);
}
// Validate file extension
$pathinfo = pathinfo($name);
$ext = isset($pathinfo['extension']) ? $pathinfo['extension'] : '';
if($this->allowedExtensions && !in_array(strtolower($ext), array_map("strtolower", $this->allowedExtensions))){
$these = implode(', ', $this->allowedExtensions);
return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
}
// Save a chunk
$totalParts = isset($_REQUEST['qqtotalparts']) ? (int)$_REQUEST['qqtotalparts'] : 1;
$uuid = $_REQUEST['qquuid'];
if ($totalParts > 1){
# chunked upload
$chunksFolder = $this->chunksFolder;
$partIndex = (int)$_REQUEST['qqpartindex'];
if (!is_writable($chunksFolder) && !is_executable($uploadDirectory)){
return array('error' => "Server error. Chunks directory isn't writable or executable.");
}
$targetFolder = $this->chunksFolder.DIRECTORY_SEPARATOR.$uuid;
if (!file_exists($targetFolder)){
mkdir($targetFolder, 0777, true);
}
$target = $targetFolder.'/'.$partIndex;
$success = move_uploaded_file($_FILES[$this->inputName]['tmp_name'], $target);
return array("success" => true, "uuid" => $uuid);
}
else {
# non-chunked upload
$target = join(DIRECTORY_SEPARATOR, array($uploadDirectory, $uuid, $name));
if ($target){
$this->uploadName = basename($target);
if (!is_dir(dirname($target))){
mkdir(dirname($target), 0777, true);
}
if (move_uploaded_file($file['tmp_name'], $target)){
return array('success'=> true, "uuid" => $uuid);
}
}
return array('error'=> 'Could not save uploaded file.' .
'The upload was cancelled, or server error encountered');
}
}
/**
* Process a delete.
* #param string $uploadDirectory Target directory.
* #params string $name Overwrites the name of the file.
*
*/
public function handleDelete($uploadDirectory, $name=null)
{
if ($this->isInaccessible($uploadDirectory)) {
return array('error' => "Server error. Uploads directory isn't writable" . ((!$this->isWindows()) ? " or executable." : "."));
}
$targetFolder = $uploadDirectory;
$url = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$tokens = explode('/', $url);
$uuid = $tokens[sizeof($tokens)-1];
$target = join(DIRECTORY_SEPARATOR, array($targetFolder, $uuid));
if (is_dir($target)){
$this->removeDir($target);
return array("success" => true, "uuid" => $uuid);
} else {
return array("success" => false,
"error" => "File not found! Unable to delete.".$url,
"path" => $uuid
);
}
}
/**
* Returns a path to use with this upload. Check that the name does not exist,
* and appends a suffix otherwise.
* #param string $uploadDirectory Target directory
* #param string $filename The name of the file to use.
*/
protected function getUniqueTargetPath($uploadDirectory, $filename)
{
// Allow only one process at the time to get a unique file name, otherwise
// if multiple people would upload a file with the same name at the same time
// only the latest would be saved.
if (function_exists('sem_acquire')){
$lock = sem_get(ftok(__FILE__, 'u'));
sem_acquire($lock);
}
$pathinfo = pathinfo($filename);
$base = $pathinfo['filename'];
$ext = isset($pathinfo['extension']) ? $pathinfo['extension'] : '';
$ext = $ext == '' ? $ext : '.' . $ext;
$unique = $base;
$suffix = 0;
// Get unique file name for the file, by appending random suffix.
while (file_exists($uploadDirectory . DIRECTORY_SEPARATOR . $unique . $ext)){
$suffix += rand(1, 999);
$unique = $base.'-'.$suffix;
}
$result = $uploadDirectory . DIRECTORY_SEPARATOR . $unique . $ext;
// Create an empty target file
if (!touch($result)){
// Failed
$result = false;
}
if (function_exists('sem_acquire')){
sem_release($lock);
}
return $result;
}
/**
* Deletes all file parts in the chunks folder for files uploaded
* more than chunksExpireIn seconds ago
*/
protected function cleanupChunks(){
foreach (scandir($this->chunksFolder) as $item){
if ($item == "." || $item == "..")
continue;
$path = $this->chunksFolder.DIRECTORY_SEPARATOR.$item;
if (!is_dir($path))
continue;
if (time() - filemtime($path) > $this->chunksExpireIn){
$this->removeDir($path);
}
}
}
/**
* Removes a directory and all files contained inside
* #param string $dir
*/
protected function removeDir($dir){
foreach (scandir($dir) as $item){
if ($item == "." || $item == "..")
continue;
if (is_dir($item)){
$this->removeDir($item);
} else {
unlink(join(DIRECTORY_SEPARATOR, array($dir, $item)));
}
}
rmdir($dir);
}
/**
* Converts a given size with units to bytes.
* #param string $str
*/
protected function toBytes($str){
$val = trim($str);
$last = strtolower($str[strlen($str)-1]);
switch($last) {
case 'g': $val *= 1024;
case 'm': $val *= 1024;
case 'k': $val *= 1024;
}
return $val;
}
/**
* Determines whether a directory can be accessed.
*
* is_executable() is not reliable on Windows prior PHP 5.0.0
* (http://www.php.net/manual/en/function.is-executable.php)
* The following tests if the current OS is Windows and if so, merely
* checks if the folder is writable;
* otherwise, it checks additionally for executable status (like before).
*
* #param string $directory The target directory to test access
*/
protected function isInaccessible($directory) {
$isWin = $this->isWindows();
$folderInaccessible = ($isWin) ? !is_writable($directory) : ( !is_writable($directory) && !is_executable($directory) );
return $folderInaccessible;
}
/**
* Determines is the OS is Windows or not
*
* #return boolean
*/
protected function isWindows() {
$isWin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
return $isWin;
}
}
Thanks for the help in making sure my code was correct, Kicked myself in the face for this one! As I was thinking for the longest time a incorrectly setup Apache Environment has been the root of all my problems.
I did not have .htaccess setup which seemed to fix all of my problems.
Here are the steps I followed to resolve my problem.
First Step
Open apache.conf file as
sudo vim /etc/apache2/apache2.conf
Second Step
remove comment sign (#) if you find it before this line ( line number 187 approx.)
AccessFileName .htaccess
Third Step
Then find the line where there is
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
replace "None" with "All"
AllowOverride All
Step Four
Activate ModRewrite:
sudo a2enmod rewrite
sudo service apache2 restart
Everything should be Good from here.

How to compress a file say xxx.xml of 6MB into xxx.xml.gz using php program

How to compress a file say xxx.xml of 6MB into xxx.xml.gz using php program.
How do you create a .gz file using PHP?
This solution doesn't work for me. it produce one .gz file which cant be open. it should be not just .gz it should be xxx.xml.gz
$source='xxx.xml';
function gzCompressFile($source, $level = 9){
$dest = $source . '.gz';
$mode = 'wb' . $level;
$error = false;
if ($fp_out = gzopen($dest, $mode)) {
if ($fp_in = fopen($source,'rb')) {
while (!feof($fp_in))
gzwrite($fp_out, fread($fp_in, 1024 * 512));
fclose($fp_in);
} else {
$error = true;
}
gzclose($fp_out);
} else {
$error = true;
}
if ($error)
return false;
else
return $dest;
}
/////////////////////////////////////////////////////////////compresion of output file ends here
//call gzCompressFile function starts
gzCompressFile();
// call gzCompressFile function ends
The other solution below is only for string not for file.
<?php
$string = 'Some information to compress';
$gz = gzopen('somefile.gz','w9');
gzwrite($gz, $string);
gzclose($gz);
?>
Above one is for only string compression not for file compression
Kindly help me to fix it.

Forcefully destroy PHP FTP Connection

I am downloading zip files from FTP server using PHP ftp function.I used binary and passive mode to get file.
The problem is that when I stopped the ftp operation before the completion of ftp operation(ie ftp_close() was not called) and when it was started again it shows the following Warning-
ftp_login() [http://php.net/function.ftp-login]: service unavailable
FTP connection has failed!
And the FTP operation was failed.I have written the following code for FTP operation.
$connId = ftp_connect($host);
$loginResult = ftp_login($connId, $user, $password);
if ((!$connId) || (!$loginResult)) {
echo "FTP connection has failed!";
exit;
}
ftp_pasv($connId, true);
if (!ftp_chdir($connId, $remoteDir))
return false;
if (!ftp_get($connId, $localDir.$localFile,$remoteFile,FTP_BINARY))
return false;
ftp_close($connId);
How to forcefully destroy ftp connection which has started getting files in binary mode and the connection is in passive mode?
Rebooting the machine or deleting the session cookies did not help me.What might be the possible solution for it?
Rebooting a machine always closes all connections made by or to that machine.
ftp_login() [http://php.net/function.ftp-login]: service unavailable
FTP connection has failed!
It looks like the remote FTP server is terminating the connection before you ever get to the login step. Check that your credentials are correct and check to make sure the FTP server is operating correctly.
This question is way old, but one I had some issues with recently. I put together a quick FTP helper class that will automatically and cleanly close connections. Hope this helps others looking for a simpler way to perform basic FTP operations.
//
define("SMOKE_TEST", TRUE);
//
// Define main FTP class.
//
class C_FTP {
// Connection handle.
//
public $h = FALSE;
// Close connection.
//
public function _Close() {
if ($this->h) {
ftp_close($this->h);
$this->h = FALSE;
}
}
// Connect.
//
public function __construct($sDNSName) {
$this->_Close();
$this->h = ftp_connect($sDNSName);
}
// Destructor.
//
public function __destruct() {
$this->_Close();
}
// Authenticate.
//
public function login($sUsername = "", $sPassword = "") {
$sError = "";
do {
//
if (!$this->h) {
$sError = "Not connected";
break;
}
if (!ftp_login($this->h, $sUsername, $sPassword)) {
$sError = "Unrecognized username or password";
break;
}
ftp_pasv($this->h, TRUE);
//
} while (0);
return ($sError);
}
// Change directory.
//
public function cd($sFolder) {
$sError = "";
do {
if (!ftp_chdir($this->h, $sFolder)) {
$sError = "Unable to change directory";
break;
}
} while (0);
return ($sError);
}
// List files in current directory.
//
public function dir(&$aFiles) {
$sError = "";
do {
if (($aFiles = ftp_nlist($this->h, ".")) === FALSE) {
$sError = "Unable to list files in current directory";
break;
}
} while (0);
return ($sError);
}
// Get file from remote site into specified local file.
//
public function get($sLocalFile, $sRemoteFilename) {
$sError = "";
do {
if (!ftp_get($this->h, $sLocalFile, $sRemoteFilename, FTP_BINARY)) {
$sError = "Could not perform file get";
break;
}
} while (0);
return ($sError);
}
// Put file from remote site into current directory.
//
public function put($sLocalFile, $sRemoteFilename) {
$sError = "";
do {
if (!ftp_put($this->h, $sRemoteFilename, $sLocalFile, FTP_BINARY)) {
$sError = "Could not perform file put";
break;
}
} while (0);
return ($sError);
}
// ...end FTP class.
//
}
// If we are running a stand-alone test of this class,
// set SMOKE_TEST to TRUE and invoke from CLI.
// For example: c:\php\php C_FTP.php
//
if (SMOKE_TEST) {
//
function IsError($sMessage) {
if (strlen($sMessage)) {
echo("Error: ".$sMessage);
return (true);
} else {
return (false);
}
}
//
do {
//
$aFiles = array();
//
$cFTP = new C_FTP(FTP_DNS_NAME);
if (IsError($cFTP->login(FTP_USER, FTP_PASSWORD))) { break; }
if (IsError($cFTP->cd("Env"))) { break; }
if (IsError($cFTP->get("foo.txt", "SomeRemoteFile.txt"))) { break; }
if (IsError($cFTP->dir($aFiles))) { break; }
var_dump($aFiles);
//
} while (0);
//
}
?>
Please note that this forces passive mode for data transfer, so if you need active, you'll need to adjust accordingly.

PHP Error only present in Internet Explorer

Okay this has baffled me. My script works in Mozilla but not IE. I get this error in IE:
Warning: move_uploaded_file(uploads/properties/yh96gapdna8amyhhmgcniskcvk9p0u37/) [function.move-uploaded-file]: failed to open stream: Is a directory in /homepages/19/d375499187/htdocs/sitename/include/session.php on line 602
Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move '/tmp/phpJkiaF3' to 'uploads/properties/yh96gapdna8amyhhmgcniskcvk9p0u37/' in /homepages/19/d375499187/htdocs/sitename/include/session.php on line 602
my code at Session.php is:
function addPhoto($subphotoSize,$subphotoType,$subphotoTmpname,$subphotoDesc,$subfieldID,$subsessionid){
global $database, $form;
/* Get random string for directory name */
$randNum = $this->generateRandStr(10);
$maxFileSize = 2500000; // bytes (2 MB)
$filerootpath = PHOTOS_DIR.$subsessionid."/";
if($subphotoType == "image/png"){
$filename = $randNum.".png";
} else if ($subphotoType == "image/jpeg"){
$filename = $randNum.".jpg";
}
$fullURL = $filerootpath.$filename;
/* Image error checking */
$field = "photo";
if(!$subphotoTmpname){
$form->setError($field, "* No file selected");
} else {
if($subphotoSize > $maxFileSize) {
$form->setError($field, "* Your photo is above the maximum of ".$maxFileSize."Kb");
} else if (!is_dir($filerootpath)){
mkdir($filerootpath,0777);
chmod($filerootpath,0777);
}
move_uploaded_file($subphotoTmpname, "$fullURL");
}
/* Errors exist, have user correct them */
if($form->num_errors > 0){
return 1; //Errors with form
} else {
if($subfieldID == "1"){ // If the first field...
$is_main_photo = 1;
} else {
$is_main_photo = 0;
}
if(!$database->addNewPhoto($ownerID,$subphotoDesc,$fullURL,$userSession,$is_main_photo, $subsessionid)){
return 2; // Failed to add to database
}
}
return 0; // Success
}
It creates the folder no problem but doesnt do anything else.
Add a log message to see what's the value of $subphotoType. My guess is that when you upload the file from Internet Explorer it's neither image/png nor image/jpeg, in which case $filename will be empty because you don't have an else clause.
if($subphotoType == "image/png"){
$filename = $randNum.".png";
} else if ($subphotoType == "image/jpeg"){
$filename = $randNum.".jpg";
} else {
// No else! $filename will be empty.
}
If you tune your error reporting settings properly you should see a notice saying you are trying to use an undefined variable.

Categories