ZIP a file and protect with a password in PHP
Use PHP 7.2 to create password protected zip file:
$zip = new ZipArchive;$res = $zip->open('filename.zip', ZipArchive::CREATE); //Add your file nameif ($res === TRUE) { $zip->addFromString('FILENAME_WITH_EXTENSION', 'file content goes here'); //Add your file name $zip->setEncryptionName('FILENAME_WITH_EXTENSION', ZipArchive::EM_AES_256, 'PASSWORD'); //Add file name and password dynamically $zip->close(); echo 'ok';} else { echo 'failed';}
Yes, creation of password protected archives is not supported (they will be created simply as non-protected archives).
But, still it can be used to extract password protected archives.
Returning to the problem.
You always can just
<?php echo system('zip -P pass file.zip file.txt'); ?>
(this will work both on Windows and our beloved Linux)
But, if it not fits into your requirements, let's continue.
I would suggest you to use DotNetZip (Windows only), you will exactly dynamically generate AES-encrypted zip archives from PHP.
<?php// origin: https://stackoverflow.com/a/670804/3684575try{ $fname = "zip-generated-from-php-" . date('Y-m-d-His') . ".zip"; $zipOutput = "c:\\temp\\" . $fname; $zipfact = new COM("Ionic.Zip.ZipFile"); $zip->Name = $zipOutput; $dirToZip= "c:\\temp\\psh"; # Encryption: 3 => 256-bit AES. # 2 => 128-bit AES. # 1 => PKZIP (Weak). # 0 => None $zip->Encryption = 3; $zip->Password = "AES-Encryption-Is-Secure"; $zip->AddDirectory($dirToZip); $zip->Save(); $zip->Dispose(); if (file_exists($zipOutput)) { header('Cache-Control: no-cache, must-revalidate'); header('Content-Type: application/x-zip'); header('Content-Disposition: attachment; filename=' . $fname); header('Content-Length: ' . filesize($zipOutput)); readfile($zipOutput); unlink($zipOutput); } else { echo '<html>'; echo ' <head>'; echo ' <title>Calling DotNetZip from PHP through COM</title>'; echo ' <link rel="stylesheet" href="basic.css"/>'; echo ' </head>'; echo '<body>'; echo '<h2>Whoops!</h2>' . "<br/>\n"; echo '<p>The file was not successfully generated.</p>'; echo '</body>'; echo '</html>'; } }catch (Exception $e) { echo '<html>'; echo ' <head>'; echo ' <title>Calling DotNetZip from PHP through COM</title>'; echo ' <link rel="stylesheet" href="basic.css"/>'; echo ' </head>'; echo '<body>'; echo '<h2>Whoops!</h2>' . "<br/>\n"; echo '<p>The file was not successfully generated.</p>'; echo '<p>Caught exception: ', $e->getMessage(), '</p>', "\n"; echo '<pre>'; echo $e->getTraceAsString(), "\n"; echo '</pre>'; echo '</body>'; echo '</html>';}?>
But still, this is very dirty solution and more of that, not works on Linux.
So, although PHP is a mature language, there is no adequate method (excluding custom extension or something like that) to achieve such a simple task with pure PHP.
What you also can do, is to wait until PHP 7.2 will be available for production (cuz ZipArchive::setEncryptionName is implemented (thanks to Pierre and Remi)).
But, until then you also can try to port php_zip >= 1.14.0 to PHP < 7.2, but there is currently no compiled binaries available, so you have to compile it yourself and try if it is possible at all (I believe it is).
p.s. I would try it, but have no VS2015+ on my PC right now.
ZipArchive::setPasswordThis function only sets the password to be used to decompress the archive; it does not turn a non-password-protected ZipArchive into a password-protected ZipArchive.
working code:
$file = 'file_name_to_be_compressed.extension'
system('zip -P ZIP_PASSWORD '.$file.'.zip '.$file);