Can PHP decompress a taz file? (.tar.Z) - php

I have tried to use Zlib to decompress the file, but it just said "Data error" and gave me an empty file.
This is the code I tried:
// Open a new temp file to write new file to
$tempFile = fopen("tempFile", "w");
// Make sure tempFile is empty
ftruncate($tempFile, 0);
// Write new decompressed file
fwrite($tempFile, zlib_decode(file_get_contents($path))); // $path = absolute path to data.tar.Z
// close temp file
fclose($tempFile);
I have also tried to decompress it in parts, going from .tar.Z to .tar to just a file. I tried using lzw functions to take off the .Z, but I was unable to make it work. Is there a way to do this?
EDIT:
Here is some more code I have tried. Just to make sure the file_get_contents was working. I still get a "data error".
$tempFile = fopen("tempFile.tar", "w");
// Make sure tempFile is empty
ftruncate($tempFile, 0);
// Write new decompressed file
$contents = file_get_contents($path);
if ($contents) {
fwrite($tempFile, gzuncompress($contents));
}
// close temp file
fclose($tempFile);
EDIT2: I think the reason why LZW was not working is because the contents of the .tar.Z file looks like this:
��3dЀ��0p���a�
H�H��ŋ3j��#�6l�
The LZW functions I have tried both use ASCII characters in their dictionaries. What kind of characters are these?

So you want to decompress a taz file natively with PHP? Give my new extension a try!
lzw_decompress_file('3240_05_1948-1998.tar.Z', '3240_05_1948-1998.tar');
$archive = new PharData('/tmp/3240_05_1948-1998.tar');
mkdir('unpacked');
$archive->extractTo('unpacked');
Also note, the reason the zlib functions aren't working is because you need LZW compression, not gzip compression.

according to this url https://kb.iu.edu/d/acsy you can try
<?php
$file = '/tmp/archive.z';
shell_exec("uncompress $file");
if you don't have Unix like OS check https://kb.iu.edu/d/abck for appropriate program.

The file is compressed with LZW compression, and I tried a few but there seems to be no reliable method for decompressing these in PHP. Cosmin's answer contains the correct first step but after using your system's uncompress utility to decompress the file, you still have to extract the TAR file. This can be done with PHP's built-in tools for handling its custom PHAR files.
// the file we're getting
$url = "ftp://ftp.ncdc.noaa.gov/pub/data/hourly_precip-3240/05/3240_05_2011-2011.tar.Z";
// where to save it
$output_dir = ".";
// get a temporary file name
$tempfile = sys_get_temp_dir() . basename($url);
// get the file
$compressed_data = file_get_contents($url);
if (empty($compressed_data)) {
echo "error getting $url";
exit;
}
// save it to a local file
$result = file_put_contents($tempfile, $compressed_data);
if (!$result) {
echo "error saving data to $tempfile";
exit;
}
// run the system uncompress utility
exec("/usr/bin/env uncompress $tempfile", $foo, $return);
if ($return == 0) {
// uncompress strips the .Z off the filename
$tempfile = preg_replace("/.Z$/", "", $tempfile);
// remove .tar from the filename for use as a directory
$tempdir = preg_replace("/.tar$/", "", basename($tempfile));
try {
// extract the tar file
$tarchive = new PharData($tempfile);
$tarchive->extractTo("$output_dir/$tempdir");
// loop through the files
$dir = new DirectoryIterator($tempdir);
foreach ($dir as $file) {
if (!$file->isDot()) {
echo $file->getFileName() . "\n";
}
}
} catch (Exception $e) {
echo "Caught exception untarring: " . $e->getMessage();
exit;
}
} else {
echo "uncompress returned error code $return";
exit;
}

Please try this.
<?php
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
}
?>
Source : http://php.net/manual/en/phardata.extractto.php
I haven't tested it but i hope it will work for you.

Related

Get name of all files from a directory and do a "for" with them

I have a php code that reads an encrypted file and decrypts it. What is a whole mass? That is, there is a folder that will only have 4/5 encrypted files and I want to decrypt all, preferably for a win rar.
<?php
$file= "text.txt";
$decrypted = decrypt_file($file,'pass');
header('Content-type:application/txt');
fpassthru($decrypted);
function decrypt_file($file,$passphrase){
$iv = substr(md5("\x18\x3C\x58".$passphrase,true),0,8);
$key = substr(md5("\x2D\xFC\xD8".$passphrase,true).md5("\x2D\xFC\xD8".$passphrase,true),0,24);
$opts = array('iv'=>$iv, 'key'=>$key);
$fp = fopen($file,'rb');
stream_filter_append($fp, 'mdecrypt.tripledes', STREAM_FILTER_READ, $opts);
return $fp;
}
?>
The glob() function does just that. And to make a zip file you can use ZipArchive too. Here's an exmaple:
<?php
// create a zip file
$zip = new ZipArchive();
$res = $zip->open('test.zip', ZipArchive::CREATE);
$directory = 'path/to/folder';
foreach (glob("$directory/*.txt") as $filename) {
// get the decrypted content
$decrypted = decrypt_file($filename,'pass');
// add it to the zip
$zip->addFromString($filename, $decrypted);
}
$zip->close();
header("Location: test.zip");
So we loop over each file, decrypt it and add that text to the zip as its own file with the same filename. When we're finished, we're left with test.zip in this example, so we redirect the user towards that file to download it. You could instead output the correct content-type and associated headers for the zip instead. Also note that you may need to sort out permissions for saving test.zip, and look at the ZipArchive's open method to provide the correct flags for overwriting. Good luck!

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
}

How to extract bz2 file in php

I have exported an SQL file from a database by using phpmyadmin. The file is named final.sql.bz2 and then I uploaded it onto my Live Server.
The question is, how could I extract that file by using PHP code? I tried to search for that on google, but not getting any result. How could I unzip it?
You should use the bzip function from PHP not the zip functions they are different.
http://php.net/manual/en/book.bzip2.php
Or if its possible you can use exec to execute the bunzip2 command to extract your file from your archive:
bunzip2 [DATEI].bz2
I needed to extract bz2 in shared hosting where tar couldnt help me to extract (got error with bzip2 and lbzip2, and I could not install anything or do sudo...)
I solved it by creating a php file and run it from command line (of course you can modify the script to use it online too).
bunzip2.php
<?php
function decompress($data)
{
// Decompress the file
if (#file_exists($data)) {
$bz = bzopen($data, 'r');
$uncompressed = '';
// Read the uncompressed data.
while (!feof($bz)) {
$uncompressed .= bzread($bz, 4096);
}
// Close the Bzip2 compressed file and write
// the data to the uncompressed file.
bzclose($bz);
if (stripos($data, '.tbz2') !== false) {
$newFile = str_replace('.tbz2', '.tar', $data);
} else {
if (stripos($data, '.tbz') !== false) {
$newFile = str_replace('.tbz', '.tar', $data);
} else {
$newFile = str_replace('.bz2', '', $data);
}
}
file_put_contents($newFile, $uncompressed);
return $newFile;
// Else, decompress the string
} else {
return bzdecompress($data);
}
}
decompress($argv[1]);
?>
php bunzip2.php my.tar.bz2
(I just searched for bz2+php on github, I did not check the code in detail but it does the work ;)

Unable to copy image from URL in PHP with upload class

I'm trying to make a upload class with PHP. so this is my first PHP class:
//Create Class
class Upload{
//Remote Image Upload
function Remote($Image){
$Content = file_get_contents($Image);
if(copy($Content, '/test/sdfsdfd.jpg')){
return "UPLOADED";
}else{
return "ERROR";
}
}
}
and usage:
$Upload = new Upload();
echo $Upload->Remote('https://www.gstatic.com/webp/gallery/4.sm.jpg');
problem is, this class is not working. where is the problem? I'm new with PHP classes and trying to learn it.
thank you.
copy expects filesystem paths, e.g.
copy('/path/to/source', '/path/to/destination');
You're passing in the literal image you fetched, so it's going to be
copy('massive pile of binary garbage that will be treated as a filename', '/path/to/destination');
You want
file_put_contents('/test/sdfsdfg.jpg', $Content);
instead.
PHP's copy() function is used for copying files that you have permission to copy.
Since you're getting the contents of the file first, you could use fwrite().
<?php
//Remote Image Upload
function Remote($Image){
$Content = file_get_contents($Image);
// Create the file
if (!$fp = fopen('img.png', 'w')) {
echo "Failed to create image file.";
}
// Add the contents
if (fwrite($fp, $Content) === false) {
echo "Failed to write image file contents.";
}
fclose($fp);
}
Since you want to download a image, you could also use the imagejpeg-method of php to ensure you do not end up with any corrupted file format afterwards (http://de2.php.net/manual/en/function.imagejpeg.php):
download the target as "String"
create a image resource out of it.
save it as jpeg, using the proper method:
inside your method:
$content = file_get_contents($Image);
$img = imagecreatefromstring($content);
return imagejpeg($img, "Path/to/targetFile");
In order to have file_get_contents working correctly you need to ensure that allow_url_fopen is set to 1 in your php ini: http://php.net/manual/en/filesystem.configuration.php
Most managed hosters disable this by default. Either contact the support therefore or if they will not enable allow_url_fopen, you need to use another attempt, for example using cURL for file download. http://php.net/manual/en/book.curl.php
U can use the following snippet to check whether its enabled or not:
if ( ini_get('allow_url_fopen') ) {
echo "Enabled";
} else{
echo "Disabled";
}
What you describe is more download (to the server) then upload. stream_copy_to_stream.
class Remote
{
public static function download($in, $out)
{
$src = fopen($in, "r");
if (!$src) {
return 0;
}
$dest = fopen($out, "w");
if (!$dest) {
return 0;
}
$bytes = stream_copy_to_stream($src, $dest);
fclose($src); fclose($dest);
return $bytes;
}
}
$remote = 'https://www.gstatic.com/webp/gallery/4.sm.jpg';
$local = __DIR__ . '/test/sdfsdfd.jpg';
echo (Remote::download($remote, $local) > 0 ? "OK" : "ERROR");

Unzipping to a variable

I need to process the contents of a zipped file, but I can't change the permissions on the server where my program will be hosted.
This means that I can't download the zip file to the server, so I need to read the contents of the file into a variable without writing it to the file system.
Can I grab the string contents of such variable and get the unzipped contents into a new variable?
So far, I've looked into using the zip php extension, and the pclzip library, but both need to use actual files.
This is what I want to do in pseudo code:
$contentsOfMyZipFile = ZipFileToString();
$myUnzippedContents = libUnzip($contentsOfMyZipFile);
Any ideas?
Look at this example.
<?php
$open = zip_open($file);
if (is_numeric($open)) {
echo "Zip Open Error #: $open";
} else {
while($zip = zip_read($open)) {
zip_entry_open($zip);
$text = zip_entry_read($zip , zip_entry_filesize($zip));
zip_entry_close($zip);
}
print_r($text);
?>
I use this in my project:
function unzip_file( $data ) {
//save in tmp zip data
$zipname = "/tmp/file_xxx.zip";
$handle = fopen($zipname, "w");
fwrite($handle, $data);
fclose($handle);
//then open and read it.
$open = zip_open($zipname);
if (is_numeric($open)) {
echo "Zip Open Error #: $open";
} else {
while ($zip = zip_read($open)) {
zip_entry_open($zip);
$text = zip_entry_read($zip, zip_entry_filesize($zip));
zip_entry_close($zip);
}
}
/*delete tmp file and return variable with data(in this case plaintext)*/
unlink($zipname);
return $text;
}
I hope it helps you.

Categories