I am building archive with ZipArchive from directory which contains symbolic links which I want to preserve. Example structure:
-- file1
-- file2
-- directory/file3 --> ../file1
When I execute the code I have below, directory/file3
is present in the archive but instead of being symlink, it has the contents of file
. Although it works, there are large amount of links that I want to preserve to keep archive size smaller.
$zip = new ZipArchive();
$zip->open($zipFile, ZipArchive::CREATE | ZipArchive::OVERWRITE)
foreach($filesToZip as $name => $file) {
if (!$file->isDir()) {
$filePath = $file->getPathname();
$relativePath = substr($filePath, strlen($rootPath) + 1);
$zip->addFile($filePath, $relativePath);
}
}
$zip->close();
What would you recommend as solution?
I also tried using file->getRealPath()
which just makes the problem worse since it adds the file with its absolute path into the archive.
A symbolic link is essentially a text file, the content of which is the target path, and the file itself has a mode flag l
.
The principle is simple, but the functions involved are a bit complex:
if(is_link($filePath)) {
$targetPath = readlink($filePath);
$stat = lstat($filePath);
$zip->addFromString($relativePath, $targetPath);
$zip->setExternalAttributesName($relativePath,
ZipArchive::OPSYS_UNIX,
$stat['mode'] << 16);
}