Strange error message with Phar - php

Using phar to create tar.gz archive returns a strange error, the following is the error message:
exception 'BadMethodCallException' with message 'Unable to add newly
converted phar
"c:/www/dimg/uploads/7e6d3a5e39e43d1351e7069517f11250.tar.gz" to the
list of phars, a phar with that name already exists' in
c:\www\dimg\upload.php:163 Stack trace:
0 c:\www\dimg\upload.php(163): PharData->compress(4096)
1 {main}
The snippet to produce Phar archives am using:
$dir_id = md5(microtime() . $_SERVER['REMOTE_ADDR']);
$upload_dir = 'uploads/' . $dir_id;
mkdir($upload_dir, 777);
try {
$a = new PharData($upload_dir . '.tar.gz');
$a->buildFromDirectory($upload_dir);
$a->compress(Phar::GZ);
} catch (Exception $e) {
$error = true;
$err_msg .= '<li>Exception : ' . $e . '</li>';
}
I tried to empty uploads directory but the same error is produced each time.

Instead of using
$a = new PharData($upload_dir . '.tar.gz');
Use:
$a = new PharData($upload_dir . '.tar');
Actually compress generates two .tar and then tar.gz. Since you have specified .tar.gz as the initial output, it cannot overwrite it with the same file type.

I believe the problem is that you are trying to build the directory that the tar.gz is being sent to. In other words, you are telling it to build to a particular directory, and then telling it to build that directory.
All you should need to do is build the tar.gz in another directory than the one you are trying to compress.

Related

how to copy/upload a locally created file to azure file storage using PHP

I'm trying to follow this link: https://learn.microsoft.com/en-us/rest/api/storageservices/copy-file
with examples from this repo: https://github.com/Azure/azure-storage-php/blob/master/samples/FileSamples.php#L235
The file is indeed copied to the azure server but the content aren't readable, to say the least, it takes a size but it's empty. This is only a text file as well, and what I plan to achieve after fixing this is to copy excel files generated via PHP to an azure file storage server.
Also, we are using file.core not blob.core
<?php
require_once "vendor/autoload.php";
use MicrosoftAzure\Storage\File\FileRestProxy;
use MicrosoftAzure\Storage\Common\Models\Range;
$accountName = "test";
$accountKey = "test";
$shareName = 'test';
$connectionString = "DefaultEndpointsProtocol=https;AccountName=$accountName;AccountKey=$accountKey";
$fileClient = FileRestProxy::createFileService($connectionString);
$dstfileName = 'demo-4.txt';
$srcfileName = 'demo-4.txt';
$sourcePath = sprintf(
'%s%s/%s',
(string)$fileClient->getPsrPrimaryUri(),
$shareName,
$srcfileName
);
try {
// Create destination file.
$fileClient->createFile($shareName, $dstfileName, 1024);
// Copy file.
return $fileClient->copyFile($shareName, $dstfileName, $sourcePath);
} catch (ServiceException $e) {
$code = $e->getCode();
$error_message = $e->getMessage();
echo $code . ": " . $error_message . PHP_EOL;
}
Update using file_get_contents
$srcfileName = 'demo-4.txt';
$content = file_get_contents('demo-4.txt');
$range = new Range(0, filesize('demo-4.txt') - 1);
$sourcePath = sprintf(
'%s%s/%s',
(string)$fileClient->getPsrPrimaryUri(),
$shareName,
$srcfileName
);
try {
// Create source file.
$fileClient->createFile($shareName, $srcfileName, 1024);
$fileClient->putFileRange($shareName, $srcfileName, $content, $range);
} catch (ServiceException $e) {
$code = $e->getCode();
$error_message = $e->getMessage();
echo $code . ": " . $error_message . PHP_EOL;
}
This is able to create the file with the content from the source file, but the problem is that the range is incorrect since I don't know how to correctly get that value.
The created file is presented by the image attached, it has multiple nulls in it because I'm guessing my range exceeds the actual length of the source file contents.
createFile method simply creates an empty file of size specified in the method call. It essentially maps to Create File REST API operation.
You should use createFileFromContent convenience method to create a file with content. It basically first creates an empty file and then writes the contents to that file.
Other option would be to call putFileRange method to write the contents to the file after you have created it using createFile method.

Could not open password protected zip archive

I was creating a zip archive with php 7.4 (lib-zip version 1.6.1) without any problems.
Now I try to protect these zip archive with a password. Not just for encrypting with php, but in general. I found this tutorial. It does what it should, but I could not read the files of the zip archive any more. If I doubleclick on the archive, the password prompt opens up, but it does not work with the password from the source code. I also copy and pasted it to prevent any keyboard struggle.
<?php
$zip = new ZipArchive();
$filePath = sprintf('%s/test/', __DIR__);
$fileName = 'test.zip';
$absoluteFilePath = $filePath . $fileName;
$excludeFolderNames = [
'.',
'..',
'.DS_Store',
$fileName,
];
$zipFlag = ZipArchive::CREATE;
if (file_exists($absoluteFilePath)) {
$zipFlag = ZipArchive::OVERWRITE;
}
$createFile = $zip->open($absoluteFilePath, $zipFlag);
if (true !== $createFile) {
throw new RuntimeException(sprintf('could not open file in "%s" caused by %s', $fileName, $createFile));
}
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($filePath));
$password = 'top-secret';
if (!$zip->setPassword($password)) {
throw new RuntimeException('Set password failed');
}
/** #var SplFileInfo $value */
foreach ($iterator as $key => $value) {
if (in_array($value->getFilename(), $excludeFolderNames)) {
continue;
}
$cleanFilePath = realpath($key);
if (!$cleanFilePath) {
throw new RuntimeException(sprintf('could not create real path from filepath: %s', $key));
}
$zipName = str_replace($filePath, '', $cleanFilePath);
if (!$zip->addFile($cleanFilePath, $zipName)) {
throw new RuntimeException(sprintf('Add file failed: %s', $cleanFilePath));
}
if (!$zip->setEncryptionName($zipName, ZipArchive::EM_AES_256)) {
throw new RuntimeException(sprintf('Set encryption failed: %s', $zipName));
}
}
$zip->close();
Does someone has the same problem or am I the problem?
UPDATE I:
I tought it solves my problem to save the zip-file outside the folder I want to zip. So I changed the following line:
$absoluteFilePath = sprintf('%s/%s', __DIR__, $fileName);
After a while the error occured again.
One possible reason I discovered, were .DS_Store files. In my example I exclude them. But the error occured again.
UPDATE II:
One further problem is, that there is no password prompt, if all files are empty.
UPDATE III:
Same code works with files without line break, but the error occurs, if the file has multiple lines.
I found help at the php-bugtracker. It turns out that I can extract all the files with an zip-extension like the comments tryed to tell me before. Now I wait for the new libzip version 1.7.0, where the default zip encryption is available. After this I hope I can extract my files without any extension.

Read an excel file stored in media folder

I'm developing a WordPress plugin that requires to upload an excel file and then read the data inside of it.
I'm using the function "media_handle_upload" to upload the excel file, then, when I try to use SpreadsheetReader to read the file there's an error saying that the file is not readable.
This is what I'm coding, (I know it's horrible coding, but I'm learning and this is just to get the plugin working)
if(isset($_FILES['test_upload_pdf'])){
$pdf = $_FILES['test_upload_pdf'];
// Use the wordpress function to upload
// test_upload_pdf corresponds to the position in the $_FILES array
// 0 means the content is not associated with any other posts
$uploaded=media_handle_upload('test_upload_pdf', 0);
// Error checking using WP functions
if(is_wp_error($uploaded)){
echo "Error uploading file: " . $uploaded->get_error_message();
}else{
echo $pdf."<br>";
$year = date('Y');
$month = date('m');
$targetPath = get_site_url()."/wp-content/uploads/".$year."/".$month."/".$_FILES['test_upload_pdf']['name'];
$targetPath2 = $_SERVER['DOCUMENT_ROOT']."/".$_SERVER["HTTP_HOST"]."/wp-content/uploads/".$year."/".$month."/".$_FILES['test_upload_pdf']['name'];
echo "<br>";
echo $targetPath2;
echo "<br>";
try
{
$Reader = new SpreadsheetReader($targetPath2);
}
catch (Exception $E)
{
echo $E -> getMessage();
}
I think the reader doesn't work because is trying to access "localhost" instead of the physical folder, for example, one of the $targetPath prints this:
http://127.0.0.1/wordpress/wp-content/uploads/2019/04/example.xlsx
So... My question is, there's a way to access the media files so I can open them with the reader?
Thanks.
Perhaps this helps:
https://developer.wordpress.org/reference/functions/wp_upload_dir/
Otherwise try to hardcode folder "/your/path/to/upload/folder/file.extension" and find out how to create this programmaticly

PHP Tar Extract w/ Variable

Understanding that the following question is not best practices by any means. The tool i am building is for personal use and will not be accessible to the internet in general. With that being said here is the idea or outline of what i am trying to accomplish.
PHP:
define("UPLOAD_DIR", "/var/www/html/uploads/");
if (!empty($_FILES["SANUpload"])) {
$myFile = $_FILES["SANUpload"];
if ($myFile["error"] !== UPLOAD_ERR_OK) {
echo "<p>An error occurred.</p>";
exit;
}
// ensure a safe filename
$name = preg_replace("/[^A-Z0-9._-]/i", "_", $myFile["name"]);
// don't overwrite an existing file
$i = 0;
$parts = pathinfo($name);
while (file_exists(UPLOAD_DIR . $name)) {
$i++;
$name = $parts["filename"] . "-" . $i . "." . $parts["extension"];
}
// preserve file from temporary directory
$success = move_uploaded_file($myFile["tmp_name"],
UPLOAD_DIR . $name);
if (!$success) {
echo "<p>Unable to save file.</p>";
exit;
}
// set proper permissions on the new file
chmod(UPLOAD_DIR . $name, 0644);
$val = shell_exec("tar -xvf $parts -C /var/www/html/uploads 2>&1");
echo '$val';
}
The goal is once it gets uploaded I need to sort the files and put them in the correct spots. The upload will ALWAYS be a TAR file because the scripts that i built for it the ONLY output is a tar file.
My goal is to extract the tar file in uploads directory and then run move commands to move the files where they need to be. Then do a clean up and delete any files in the UPLOADS dir.
I found this example on here :
$val = shell_exec("tar -xvf $parts -C /var/www/html/uploads 2>&1");
echo '$val';
This is another component i am looking at as well:
try {
$phar = new PharData('myphar.tar');
$phar->extractTo('/full/path'); // extract all files
$phar->extractTo('/another/path', 'file.txt'); // extract only file.txt
$phar->extractTo('/this/path',
array('file1.txt', 'file2.txt')); // extract 2 files only
$phar->extractTo('/third/path', null, true); // extract all files, and overwrite
} catch (Exception $e) {
// handle errors
}
The problem I am having with PharData is that it doesn't like the $path or $name variables. The same can be said for the example above PharData. Since the upload script could have different names I need to have the ability to unzip the file as a variable or to use a variable in the php script.
Technically - the script I have would keep the tar name the same however I could see a use case where someone might change that. So want to make sure that I have the option to address that.
So question is how do i extract a tar file - utilizing a variable name rather than have it spelled out and the actual name of the file all in PHP?
Figured out the issue - i needed to utilize the UPLOAD_DIR . $name in the pharData.
try {
$phar = new PharData(UPLOAD_DIR . $name);
$phar->extractTo(UPLOAD_DIR); // extract all files
} catch (Exception $e) {
// handle errors
}

php not opening file on mounted filesystem

I have the following bit of code that is giving me problems.
#$fullfilename="/data/extract/".$curpkg."/".$curfilename;
$fullfilename = "/tmp/test.txt";
$readline = 0;
$lictext="";
try {
$file = new SplFileObject($fullfilename);
$readline=$curline-1;
while ($readline <= ($curline -1 + $curlinecount)) {
$file->seek($readline);
$lictext = $lictext . $file->current()."\n<br>";
$readline = $readline + 1;
}
} catch (Exception $e) {
$lictext = "couldn't open it $fullfilename<br> Exception: $e<br>";
}
When I use the currently uncommented $fullfilename variable declaration, it works fine, but when I use the code that is commented out it does not. I get the following error:
couldn't open it /data/extract/test.txt
Exception: exception 'RuntimeException' with message \
'SplFileObject::__construct(/data/extract/test.txt):\
failed to open stream: No such file or directory' in \
/srv/www/htdocs/legal/index.php:70
Stack trace:
#0 /srv/www/htdocs/legal/index.php(70): \
SplFileObject->__construct('/data/extract/test.txt')
The only difference is that the data I want to use is a separate drive mounted at /data.
Permissions for the entire structure are 777: drwxrwxrwx 2 root root 53248 Jan 7 14:31 data.
I am at a loss here, I have the same problem with file_exists() and is_readable(). Can anyone give me some guidance here?

Categories