关于PHP使用ZipArchive创建带密码保护的压缩包的示例,好多只提到setPassword进行设置,包括ai助手也是
可是如果真的那样操作,发现用压缩软件打开后并不需要密码验证,可以直接解压读取文件内容的.
后来参考了官方的说明: PHP: ZipArchive::setEncryptionName - Manual
对需要加密的文件还是需要使用setEncryptionName进行设置后才有效果的.
比如以下代码:
$zip = new \ZipArchive;
$res = $zip->open('test.zip', \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
if ($res === TRUE) {$zip->setPassword('huang');$zip->addFromString('test1.txt', 'huang 666');$zip->setEncryptionName('test1.txt', \ZipArchive::EM_AES_256);$zip->addFromString('test2.txt', 'huang 222');// $zip->setEncryptionName('test2.txt', \ZipArchive::EM_AES_256);$res = $zip->close();$this->assertTrue($res);// unlink('test.zip');
} else {$this->assertNotTrue($res);
}
对test2.txt未设置setEncryptionName,生成的压缩包中test2.txt将不受密码保护,可以直接读取其中内容
最终展示一下我的代码:
/**
* 文件打包操作
*
* @param string $filePath 文件或文件夹路径
* @param string $zipFile 生成的压缩包路径
* @param string $pwd 密码,为空则不设置密码
* @return string 压缩包路径
*/
function zip(string $filePath, string $zipFile, string $pwd = '')
{if (!is_dir($filePath) && !is_file($filePath)) {throw new \Exception('filePath must be file or dir:' . $filePath);}$zip = new \ZipArchive();$res = $zip->open($zipFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);if ($res !== true) {throw new \Exception("create zip failed:" . $res);}if (!empty($pwd)) {$zip->setPassword($pwd);}$filePath = str_replace("\\", '/', $filePath);if (is_file($filePath)) {$filename = basename($filePath);$zip->addFile($filePath, $filename);if (!empty($pwd)) {$zip->setEncryptionName($filename, \ZipArchive::EM_AES_256);}} else {$trimLen = mb_strlen($filePath);if ($filePath[-1] == '/') {$trimLen -= 1;}$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($filePath),\RecursiveIteratorIterator::LEAVES_ONLY);foreach ($files as $file) {if (!$file->isDir()) {$path = $file->getRealPath();$relativePath = mb_substr($path, $trimLen);$path = str_replace("\\", '/', $path);$relativePath = str_replace("\\", '/', $relativePath);$zip->addFile($path, $relativePath);if (!empty($pwd)) {$zip->setEncryptionName($relativePath, \ZipArchive::EM_AES_256);}}}}$zip->close();return $zipFile;
}