Can't open pptx created by PHP (windows only)

I’m developing an API in PHP that unzips a pptx file, alters a few images and some xml, then re-zips the file.

When the program runs on a (Linux) server, I have no problem opening the altered file with LibreOffice Impress.
Locally I use Windows 10, and if I manually do the changes that my code does, I also have no problems.
But if the file is altered by my code locally (using Apache via MAMP), Impress will claim the file is broken and can’t be fixed. Office PowerPoint will open it without problems or mentions of any error.

The only reason I can think of is perhaps the way the file is stored on Windows when it is programmatically created.

=======================

Sample code (pptx to zip, extracting, re-archiving an then zip to pptx)

    $presentationFile = 'demo.pptx';
    $presArchive = 'demo.zip';

    //turn into .zip
    copy($presentationFile, $presArchive);
    unlink($presentationFile);

    //extract .zip
    $zipArchive = new \ZipArchive;
    $zipArchive->open($presArchive);
    $extractDir = 'demo';
    $zipArchive->extractTo($extractDir);
    $zipArchive->close();

    //delete zip
    unlink($presArchive);

    //archive again
    $rootPath = realpath($extractDir); //Get real path for our folder
    $zip = new \ZipArchive(); // Initialize archive object
    $zip->open($presArchive, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
    $files = new \RecursiveIteratorIterator( // Create recursive directory iterator
        new \RecursiveDirectoryIterator($rootPath),
        \RecursiveIteratorIterator::LEAVES_ONLY
    );
    foreach ($files as $name => $file){
        if (!$file->isDir()){ // Skip directories (they would be added automatically)
            // Get real and relative path for current file
            $filePath = $file->getRealPath();
            $relativePath = substr($filePath, strlen($rootPath) + 1);
            // Add current file to archive
            $zip->addFile($filePath, $relativePath);
        }
    }
    $zip->close();

    //turn back into .pptx
    copy($presArchive, $presentationFile);
    unlink($presArchive);

locally created file: https://www.dropbox.com/s/v9ehwcq1w3iea00/demo.pptx?dl=0

server created file: https://www.dropbox.com/s/tqpshib93p8emur/demo_server.pptx?dl=0

a sample file would help

@mike-kaganski I added some sample code and a sample file (on dropbox)

Thanks; and could you please attach the same pptx generated on linux?

file has been added

Aha, the problem found - this is the deficiency (?) of our zip code (need to consult documentation if that’s allowed; MS seems to handle it) - the filenames in the package use backslashes (\) instead of / which are used normally (MS Office also writes /!)

EDIT:

pkware appnote 6.2.0 (the normative document defining the package format used in both OOXML and ODF specifications) states this:

  file name: (Variable)

      The name of the file, with optional relative path.
      The path stored should not contain a drive or
      device letter, or a leading slash.  All slashes
      should be forward slashes '/' as opposed to
      backwards slashes '\' for compatibility with Amiga
      and Unix file systems etc.

So, the forward slashes are required in the ZIP file format (although possibly we should relax that a bit, because back-slashes don’t cause problems with e.g. 7-Zip, or InfoZip).

On the other hand, why should we try to handle invalid input, when the conformant implementations all write the proper names into packages?

This works. I’ve added a few lines of code to clean the backslashes to forward slashes.
Thank you so much, You wouldn’t believe how long I’ve been looking for an answer.