tags:

views:

35

answers:

2

So here is my code:

<?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';
}

Its purpose is simple. It opens a test.docx file, searches for all occurences of a string "$FIRST_AND_LAST_NAME" and replaces them with "John Doe".

It works perfectly on my Windows development server (the "John Doe" string is in the docuemnt when I open it).

It does not work on my Lunux production server ("$FIRST_AND_LAST_NAME" string is still there, there is no "John Doe").

There is no error or notice, the "ok" is printed without any errors. I made sure the test.docx file has priviledges set to 777.

+1  A: 

If close() returns false, there was an error writing out the archive.

Use getStatusString to get the exact error message.

Pekka
I get 'Fatal error: Call to undefined method ZipArchive::getStatusString()'. It seems the server is older version of PECL zip.
Richard Knop
@Richard aww. Can't see any pre-5.2.7 way of getting the error message... Error reporting is turned on fully?
Pekka
Yes. I have error_reporting(E_ALL); at the top of the file.
Richard Knop
@Richard I can't see any documentation on the previous, PECL-based versions of ZipArchive ... No idea how they handled write errors back then. They must have somehow, but I can't see how.
Pekka
It's actuall probably both PHP < 5.2.7 and also older PECL zip. It should still work though. It's not that old. The compiled PHP on server is 5.2.6. That is relatively recent.
Richard Knop
Check if the zip file's writeable by the web server.
Marc B
@Marc B I have set the file's priviledges to 777 in Filezilla. Is there anything else that I need to do?
Richard Knop
@Richard no, that should be okay (plus PHP would probably raise an fopen() warning if it wouldn't work.)
Pekka
@Richard have you tried doing a `print_r` on the Zip object? Maybe it has an error message set somewhere. Also, there is a function to get a class's methods (can't remember its name right now) maybe there is another method to show the error.
Pekka
@Pekka I will try tomorrow. I've already left the work and am too exhausted to fiddle with this from home.
Richard Knop
@Richard can't blame ya ;)
Pekka
A: 

Ok, I have used a class I found at phpclasses:

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

Here is the working code:

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();

    }
}
Richard Knop
Alright, I know it's an old class for PHP 4 but hey, it works. And I just needed to get it work now. I can refactor later.
Richard Knop