Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.10.2018, 17:48   #1
sollerij
 
Регистрация: 04.10.2018
Сообщений: 7
По умолчанию Вывод файлов из БД в файловую систему

Уважаемые господа, добрый день!

Возникла проблема с выводом файлов из БД PostgreSQL в файловую систему на боевом сервере. Есть код, который отрабатывает локально на моем компе, на котором установлен MAMP. Смысл этого кода - выбрать данные из БД поместить данные в директорию файловой системы, затем отправить эти файлы на удаленный сервер (отправляю библиотекой php cURL). На боевом серваке с другой ОС данные манипуляции не работают, работа кода останавливается на выборке файлов из БД и размещении их в файловой системе.

ОС локальной системы: MacOS 10.14.1 Версия MAMP: 4.5 Веб-сервер: Apache/2.2.34 (Unix) Версия PHP: 7.2.1

ОС боевой системы: Debian GNU/Linux 9.4 (stretch) Веб-сервер: Apache/2.4.25 (Debian) Версия PHP: 7.0.30-0+deb9u1

При выводе файлов на боевом серваке из БД возникают следующие ошибки:

Некорректно отправляется содержимое файла - файл в файловую систему приходит битый, размер файла либо нулевой, либо 1КБ.
Название файла передается неполностью, на каком-то символе режется. (ПР: «prezentatsiya_1128329_435», «prezentatsiya_1128329_л). От типа символа - число или буква не зависит. Название файлов приходит из БД уже переведенное в транслит. (Делал перевод из русской литерации в латиницу средствами PHP, но это не помогало, поэтому сделали транслитерацию в БД)

Я предположил, что какая-то проблема с локалью на Debian 9 и осуществил следующие шаги:
Код:
1. export LANGUAGE=ru_RU.UTF-8
2. export LANG=ru_RU.UTF-8
3. export LC_ALL=ru_RU.UTF-8
4. locale-gen ru_RU.UTF-8
5. apt-get install --reinstall locales
6. dpkg-reconfigure locales
Они работают на время терминальной сессии, на MacOS стоял английский язык ОС , на время терминальной сессии язык переключался на русский, но при переподключении к серверу через терминал настройки локали сбрасывались; команда dpkg-reconfigure locales не влияла на отображение интерфейса командной строки. Смена языка на MacOS на русский помогла в отображении русского языка в терминале, но не более того.

После применения данных настроек команда locale показывает следующие результаты:

Код:
LANG=ru_RU.UTF-8
LANGUAGE=
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=

Я предполагаю, что, всё-таки дело в настройках локали, поэтому не прилагаю рабочий код, если будет необходимо, добавлю.

Искал информацию по настройке локали на Debian взял инструкцию в данном источнике, пункт Standard(https://wiki.debian.org/Locale#Standard), выполнял следующие шаги:

1. Редактировал файл /etc/default/locale, добавив строку LANG=ru_RU.UTF-8
2. Перезагружал сервер.
3. Не помогло
4. Смотрел файл /etc/locale.gen
5. После применения команды dpkg-reconfigure locales раскомментированы следующие строки "en_US.UTF-8 UTF-8", "ru_RU.UTF-8 UTF-8"
6. Не помогло

Правил файл php.ini - увеличил размер отправляемых файлов:

Код:
upload_max_filesize = 30M
Отправка файлов разрешена, значение директивы:

Код:
file_uploads = On
Значение настройки post_max_size:

Код:
post_max_size = 8M
Подскажите, с чем может быть связана данная проблема? Где собака зарыта? Не хватает опыта, чтобы самостоятельно определить в каком направлении двигаться для решения данной задачи.
sollerij вне форума Ответить с цитированием
Старый 04.10.2018, 18:54   #2
Streletz
Старожил
 
Регистрация: 03.01.2014
Сообщений: 2,870
По умолчанию

Информации много, но...
Цитата:
Сообщение от sollerij Посмотреть сообщение
не прилагаю рабочий код
Без кода сложно будет найти в нём ошибку (если причина в нём).
Цитата:
Сообщение от sollerij Посмотреть сообщение
какая-то проблема с локалью
Если везде UTF-8 вряд-ли.
Цитата:
Сообщение от sollerij Посмотреть сообщение
работа кода останавливается
И не выводит никаких сообщений об ошибках и даже не пишет в лог (притом, что по поведению явно exception)?
Дайте stack trace.
Цитата:
Сообщение от sollerij Посмотреть сообщение
Код:
upload_max_filesize = 30M
post_max_size = 8M
Файл на сервер обычно передаётся POST запросом. Что толку увеличивать максимальный размер файла, если максимальный объём данных запроса остаётся прежним?..
Streletz вне форума Ответить с цитированием
Старый 05.10.2018, 11:30   #3
sollerij
 
Регистрация: 04.10.2018
Сообщений: 7
По умолчанию Как корректно вывести файлы из БД в файловую систему?

Цитата:
Сообщение от Streletz Посмотреть сообщение
Информации много, но...

Без кода сложно будет найти в нём ошибку (если причина в нём).
Там где-то 200 строк кода, я приложу отдельным сообщением в файле.

Цитата:
Сообщение от Streletz Посмотреть сообщение
И не выводит никаких сообщений об ошибках и даже не пишет в лог (притом, что по поведению явно exception)?
Дайте stack trace.
Здесь у меня возникли некоторые сложности из-за понимания работы ООП. Для того, чтобы выводить лог ошибок, я написал отдельный метод, в который записывается результат отработки кода в той или иной части файла. Также, я смотрел, что можно установить error_handler, который бы выводил и пользовательские ошибки, и системные, но на данный момент я пока не понял, как он работает.

Вот такую тестовую штуку написал, но она не работает:
Код:
public function __construct()	{
		// Установка перехватчика ошибок<br/>
		set_error_handler("myErrorHandler");
	}

public function myErrorHandler($errno, $errstr, $errfile, $errline){
		echo "<b>Custom error:</b> [$errno] $errstr<br>";
		$error_number =  "<b>Custom error:</b> [$errno] $errstr<br>";
		$error_file_line = " Error on line $errline in $errfile<br>";
		// echo " Error on line $errline in $errfile<br>";
		// echo " Error on line $errline in $errfile<br>";
		$error_data = $error_number . "\n". $error_file_line;
		API::errorOutput($error_data);
	}
Цитата:
Сообщение от Streletz Посмотреть сообщение
Файл на сервер обычно передаётся POST запросом. Что толку увеличивать максимальный размер файла, если максимальный объём данных запроса остаётся прежним?..
Спасибо, увеличил post_max_size до 35М.
sollerij вне форума Ответить с цитированием
Старый 05.10.2018, 12:19   #4
sollerij
 
Регистрация: 04.10.2018
Сообщений: 7
По умолчанию Как корректно вывести файлы из БД в файловую систему?

Собственно, сам код.
Вложения
Тип файла: zip code_1.zip (5.3 Кб, 11 просмотров)
sollerij вне форума Ответить с цитированием
Старый 05.10.2018, 18:52   #5
Streletz
Старожил
 
Регистрация: 03.01.2014
Сообщений: 2,870
По умолчанию

Цитата:
Сообщение от sollerij Посмотреть сообщение
Вот такую тестовую штуку написал, но она не работает
Гуглите про try catch в PHP. Ставите на проблемный участок и будет Вам перехват ошибок. Дёшево, но сердито.
По результатам вывода ошибок можно будет уменьшить объём кода для форума за счёт локализации проблемы (это так, на будущее).
Цитата:
Сообщение от sollerij Посмотреть сообщение
Там где-то 200 строк кода
Там их 360 и походу этот файл не имеет отношения к делу. Если я правильно понял, там только отправка, а где приём?
Streletz вне форума Ответить с цитированием
Старый 10.10.2018, 12:05   #6
sollerij
 
Регистрация: 04.10.2018
Сообщений: 7
По умолчанию Как корректно вывести файлы из БД в файловую систему?

Спасибо за совет.
Сейчас настраиваю работу с исключениями в коде.
Еще такие вопросы:
1. Подскажите, пожалуйста, что Вы подразумеваете под stack trace? Достаточно ли мне изучить работу данного метода Exception::getTrace — Получает трассировку стека?
2. Правильно ли я понимаю, что Exception в PHP позволяют настроить пользовательский отлавливатель ошибок, а как в таком случае мне отловить ошибки системы? Допустим, в процедурном программировании мне в этом помогала строка ini_set(display_errors,1);

Во вложении файл с кодом приема файлов на сервер. Метод getFile().
Вложения
Тип файла: zip file_download.zip (1.5 Кб, 10 просмотров)
sollerij вне форума Ответить с цитированием
Старый 10.10.2018, 15:52   #7
Streletz
Старожил
 
Регистрация: 03.01.2014
Сообщений: 2,870
По умолчанию

Цитата:
Сообщение от sollerij Посмотреть сообщение
что Вы подразумеваете под stack trace?
Stack trace (трассировка стека) – это список методов, которые были вызваны до момента, когда в приложении произошло исключение (отсюда).
Цитата:
Сообщение от sollerij Посмотреть сообщение
Exception::getTrace — Получает трассировку стека
Этот метод возвращает трассировку стека исключения. Для отладки через try-catch сгодится.
Цитата:
Сообщение от sollerij Посмотреть сообщение
Метод getFile().
У меня он работает корректно. При при том, что я загружаю файлы даже с изначально "русскими" названиями, не могу воспроизвести ошибку.
Посмотрите, что приходит к Вам на сервер через var_dump. Дайте stack trace с рабочего сервера.
Streletz вне форума Ответить с цитированием
Старый 10.10.2018, 16:11   #8
sollerij
 
Регистрация: 04.10.2018
Сообщений: 7
По умолчанию

Цитата:
Stack trace (трассировка стека) – это список методов, которые были вызваны до момента, когда в приложении произошло исключение
Получается, имеется в виду, что мы знаем, в какой момент произошла ошибка, делая трассировку видим набор методов, которые выполнились до момента ошибки и ищем, что не так уже в конкретных методах, таким образом сужая круг поиска?

Еще дурацкий вопрос:
Не могли бы Вы подсказать возможно ли такое употребление блока try-catch:
Код:
$api_key = $row['api_key'];
$type_send_file[] = $row['type_send_file'];
$provider_name = $row['provider_name'];
try {
    //check if
    $var_out = false;
    if ($api_key) {
        $var_out = 'Значение API-ключа= ' . $api_key;
    }
    if ($type_send_file) {
        foreach ($type_send_file as $value) {
	    $var_out = 'Значение $type_send_file= ' . $value;
	}
    }
    if ($provider_name) {
        $var_out = 'Значение $provider_name= ' . $provider_name;
    }
    if ($var_out) {
	throw new customException($var_out);
    }
}
catch (customException $e) {
    echo $e->errorMessage();
    echo $e->getTrace();
}
Я бы хотел, чтобы у меня в итоговую переменную $var_out записывались поочередно значения переменных, затем эти значения передавались в лог. В случае, как у меня, я передаю в лог только последнее значение переменной, т.е. в порядке выполнения строк кода. Я думал, что можно $var_out определить как массив, но при этом массив я передать не могу через Exception. Как мне корректно передать несколько значений и возможно ли это?
sollerij вне форума Ответить с цитированием
Старый 10.10.2018, 19:24   #9
Streletz
Старожил
 
Регистрация: 03.01.2014
Сообщений: 2,870
По умолчанию

Цитата:
Сообщение от sollerij Посмотреть сообщение
Получается, имеется в виду, что мы знаем, в какой момент произошла ошибка, делая трассировку видим набор методов, которые выполнились до момента ошибки и ищем, что не так уже в конкретных методах, таким образом сужая круг поиска?
По сути, да.
Цитата:
Сообщение от sollerij Посмотреть сообщение
$e->getTrace();
getTrace возвращает ассоциативный массив. Для быстрой отладки, его можно вывести и через var_dump (не забыв теги pre). А, вообще подумайте как отобразить stack trace в читабельном виде.
Цитата:
Сообщение от sollerij Посмотреть сообщение
Я бы хотел, чтобы у меня в итоговую переменную $var_out записывались поочередно значения переменных, затем эти значения передавались в лог.
Для этого есть штатная функция error_log (по запросу "php логирование в файл" у меня это была 4я ссылка в Яндексе).

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

Последний раз редактировалось Streletz; 10.10.2018 в 19:30.
Streletz вне форума Ответить с цитированием
Старый 11.10.2018, 09:14   #10
sollerij
 
Регистрация: 04.10.2018
Сообщений: 7
По умолчанию Как корректно вывести файлы из БД в файловую систему?

Цитата:
Для этого есть штатная функция error_log (по запросу "php логирование в файл" у меня это была 4я ссылка в Яндексе).
Все верно, я пользуюсь этой функцией в кастомном классе Exception, в котором обрабатываю входящие параметры исключений.
Возможно, я некорректно задал вопрос. Я подразумевал, что хотел бы получать в кастомном классе Exception все значения, которые приходят в блок try{}. То есть, есть у меня 16 параметров, которые я хотел бы проверить в одном блоке try{}, и я хотел бы вывести значения всех параметров в один этот кастомный класс.
Сам класс имеет следующий вид:
Код:
class customException extends Exception{
    public function errorMessage() {
        date_default_timezone_set("Europe/Kaliningrad");
        $time = date("Y-m-d H:i:s");
        $errorMsg = $time . ' Error on line ' . $this->getLine() . ' in ' . $this->getFile() . ": " . $this->getMessage() . "\n";
        error_log($errorMsg, 3, __DIR__ . "/logs/api_error.log");
        return $errorMsg;
    }
}
Цитата:
Вообще советую почитать книгу Котерова по PHP 7
Спасибо. Прочту.
sollerij вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поиск файлов по маске и нахождения общего размера найденных файлов и вывод в терминал Колямбий Помощь студентам 0 21.04.2013 21:31
Как форматировать флешку в файловую систему, из ntfa в fat32 igor 91 Общие вопросы C/C++ 1 04.02.2013 12:05
Создать файловую систему через делфи Renok Общие вопросы Delphi 13 02.03.2012 23:52
вывод файлов mojohead Помощь студентам 3 11.05.2011 12:10
Создать файловую систему Joliet на языке С++ Лисничая Дарья Помощь студентам 1 22.09.2009 09:47