【问题标题】:Problem saving edited zip archive (docx)保存已编辑的 zip 存档 (docx) 时出现问题
【发布时间】:2010-08-25 14:08:11
【问题描述】:

这是我的代码:

<?php

$zip = new ZipArchive;
if ($zip->open('test.docx') === TRUE) {

 $xmlString = $zip->getFromName('word/document.xml');
 $xmlString = str_replace('$FIRST_AND_LAST_NAME', 'John Doe', $xmlString);
    $zip->addFromString('word/document.xml', $xmlString);

 echo 'ok';

    $zip->close();
} else {
    echo 'failed';
}

它的目的很简单。它会打开一个 test.docx 文件,搜索所有出现的字符串“$FIRST_AND_LAST_NAME”并将它们替换为“John Doe”。

它在我的 Windows 开发服务器上完美运行(“John Doe”字符串在我打开它时在文档中)。

它在我的 Lunux 生产服务器上不起作用(“$FIRST_AND_LAST_NAME”字符串仍然存在,没有“John Doe”)。

没有错误或通知,“ok”打印没有任何错误。我确保 test.docx 文件的权限设置为 777。

【问题讨论】:

  • 没有警告?错误报告是否开启? close() 是否返回 true
  • 你有没有试过在 $xmlString 被解压后查看它的内容?可能是提取在 Linux 方面失败。 str_replace 不会生你的气,只是突然无缘无故地失败,所以它的输入($xmlString)很可能不是你所期望的。
  • @Pekka 我刚刚注意到 $zip->close() 返回 false。
  • @Marc 如果我回显 XML 字符串,则将“$FIRST_AND_LAST_NAME”替换为“John Doe”是正确的。

标签: php xml docx


【解决方案1】:

如果close() 返回 false,则写入存档时出错。

使用getStatusString 获取确切的错误消息。

【讨论】:

  • 我收到“致命错误:调用未定义的方法 ZipArchive::getStatusString()”。看来服务器是旧版本的 PECL zip。
  • @Richard 哇。看不到 5.2.7 之前的任何获取错误消息的方式...错误报告已完全打开?
  • @Richard 我在以前的基于 PECL 的 ZipArchive 版本上看不到任何文档……不知道他们当时是如何处理写入错误的。他们一定有某种方式,但我看不出是怎么回事。
  • 它实际上可能是 PHP
  • 检查 zip 文件是否可以被 Web 服务器写入。
【解决方案2】:

$zip-&gt;addFromString('word/document.xml', $xmlString);之前添加sleep(1)

它适用于我的 Ubuntu 12.04

不要忘记在创建 docx 文件的同时输入变量,我的意思是永远不要输入 FIRST_AND_LAST_NAME,然后在之后添加符号 $。它创建不同的 XML 代码。

【讨论】:

    【解决方案3】:

    好的,我使用了我在 phpclasses 找到的一个类:

    http://phpclasses.web4u.cz/package/6278-PHP-Edit-a-Zip-archive-in-pure-PHP-no-temporary-files.html

    这是工作代码:

    private function GenerateDocx($theTemplate, array $theReplacemenArray, $theOutputFile)
    {
        $aSearchArray = array();
        foreach(range('A','Z') as $aLetter) {
            $aSearchArray[] = str_repeat($aLetter, 5);
        }
        $aArrayCountDifference = count($aSearchArray) - count($theReplacemenArray);
        $aSearchArray = array_slice($aSearchArray, 0, -$aArrayCountDifference);     
    
        require_once('tbszip.php');
        $tbszip = new clsTbsZip();
        $tbszip->Open($theTemplate);
    
        $aXmlPath = 'word/document.xml';
    
        if (true === $tbszip->FileExists($aXmlPath)) {
    
            $aXmlString = $tbszip->FileRead($aXmlPath);
    
            $aXmlString = str_replace($aSearchArray, $theReplacemenArray, $aXmlString);
    
            if (1 != $tbszip->FileReplace($aXmlPath, $aXmlString)) {
                throw new Exception('FileReplace() failed.');
            }
    
            $tbszip->Flush(TBSZIP_FILE, $theOutputFile);
    
            $tbszip->Close();
    
        }
    }
    

    【讨论】:

    • 好吧,我知道它是 PHP 4 的一个旧类,但是嘿,它可以工作。我现在只需要让它工作。我可以稍后重构。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-22
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    相关资源
    最近更新 更多