OpenCart, Export/Import Tool ошибка Could not close zip file

Версия CMS, в которой наблюдалась ошибка, — OpenCart 2.0.3.1.

Модуль/расширение, с которым наблюдалась ошибка, — Export/Import Tool.

Суть ошибки, — невозможно выполнить экспорт информации. При попытке экспорта информации вы получаете следующую ошибку:

Could not close zip file php://output.

Причина ошибки

В ошибке говорится, что модуль не может получить доступ к папке где он должен сохранить и отдать файл. Причина ошибки может различаться  и универсального решения быть не может. В моем случае, проблема была в более новой версии PHP при которой функция realpath(), используемая в модуле, не возвращала путь к папке \tmp\.

Если просмотреть логи ([ВАШ САЙТ]/system/logs/error.log), то можно увидеть что модуль жалуется на open_basedir и пишет следующее:

PHP Warning: realpath() [<a href='function.realpath'>function.realpath</a>]: open_basedir restriction in effect. File(/tmp) is not within the allowed path(s): ([ЗНАЧЕНИЕ OPEN_BASEDIR]) in [КОРНЕВОЙ ПУТЬ СЕРВЕРА]/[ВАШ САЙТ]/system/PHPExcel/Classes/PHPExcel/Shared/File.php on line 175

Первое что приходит на ум при просмотре логов, это то что open_basedir ограничивает работу скрипта. Вполне возможно, что в вашем случае так оно и есть, и проблему нужно решать отключением или сменой значения этого параметра. Но, в этой ситуации, если посмотреть на логи более внимательно, видно что модуль не определяет корневой путь к моему аккаунту на сервере:

...restriction in effect. File(/tmp) is not within the...

Не путайте, разговор именно о пути к папке-корню аккаунта хостинга, не к папке с сайтом.

Возвращается только имя папки где модуль должен сохранить и отдать файл (tmp), но пути к этой папке нет, функция модуля realpath() вернула пустую строку и модуль пытается обратится выше к корню сервера. Сайт, на котором я наблюдал эту ошибку, находится на виртуальном хостинге. Само собой, что доступ к корню, откуда можно получить доступ к аккаунтам других клиентов, ограничен хостинговой компанией параметром open_basedir, а без указания полного пути к вашему аккаунту модуль пытается обратится «слишком высоко», что open_basedir и не дает ему сделать.

Решение ошибки

Чтобы решить проблему нужно поправить код модуля:

  1. Откройте файл: [ВАШ САЙТ]/system/PHPExcel/Classes/PHPExcel/Shared/File.php
  2. Найдите строку в конце файла: return realpath(sys_get_temp_dir());
  3. Замените ее следующей строкой: return "[ЗНАЧЕНИЕ OPEN_BASEDIR]".sys_get_temp_dir();

[ЗНАЧЕНИЕ OPEN_BASEDIR] лучше всего скопировать из описания ошибки в файле логов ([ВАШ САЙТ]/system/logs/error.log). Не ошибитесь, нужен именно путь к корню вашего аккаунта, а не к корню сайта. А еще точнее путь к папке где модуль должен обработать и отдать файл.

Другой путь узнать нужный адрес это посмотреть phpinfo. Создайте файл в корне вашего сайта, например info.php со следующим содержанием:

<?php

phpinfo();

?>

Откройте его в браузере по адресу: http://site.com/info.php . Найдите в нем значение open_basedir (в браузере, нажмите «ctrl+f «для поиска и введите open_basedir). Скопируйте и подставьте его в строку. Например в моем случае значение выглядело следующим образом

 /var/www/teoway.com/data:.

Значит подставить нужно так 

return "/var/www/teoway.com/data/".sys_get_temp_dir();