Доброго времени года!
Вводные данные. Итак, в определённую папку на хостинге (обычный shared, не VDS) каждый день из 1С: Альфа-Авто (спец. редакция 1С: Предприятие 8.3 для СТО и прочих авто-организаций) выгружается файл в формате CSV следующего содержания:
"Параметр 1","Параметр 2","Параметр 3","Параметр 4","Параметр 5"
"Параметр N","Параметр N","Параметр N","Параметр N","Параметр N"
...
Это база запчастей/деталей в наличии (кол-во > 0). Для парсинга файла и преобразования его значений в массив (для последующего использования), я использую вот такой код:
$file = file_get_contents('/home/user/site.ru/public_html/upload/catalog.csv');
$lines = explode(PHP_EOL, $file);
$array = array();
foreach ($lines as $line) {
$array[] = str_getcsv($line);
}
Вот тут появляется
первый затык. По старой доброй традиции, 1С всё фигачит в кодировке CP1251 (или KOI8-R), и, вместо кириллицы, одни крякозябры в массиве
$array
. Так же, при последующих попытках сделать
INSERT
этих значений в БД, их не понимает mysqli и выдаёт ошибки.
Можно ли как-то пересохранять этот CSV файл или преобразовывать его «на лету» в формат UTF-8 (без BOM, например) перед парсингом? Да, есть Notepad++, но делать это каждый день вручную — просто физически нет человекоресурсов, да и не по фей-шую это, всё же.
Хорошо. Двигаемся дальше!
Для внесения значений в БД, пишу вот так:
// Init MySQLi.
$mysqli = mysqli_init();
// Connect to DB.
if (!$mysqli->real_connect('localhost', $login, $password, $table)) die('Ошибка подключения (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
// Loop INSERT.
foreach ($array as $row) {
if (!$mysqli->query("INSERT INTO catalog(id, name, brand, stock, price) VALUES ('$row[0]', '$row[1]', '$row[2]', '$row[3]', '$row[4]')")) echo "Ошибка (" . $mysqli->errno . ") " . $mysqli->error;
}
// Close MySQLi connection.
$mysqli->close();
(Ячейка таблицы ID имеет значения UNIQUE и PRIMARY)
В удачные дни этот файл весит около 500 Кб (~4000 наименований номенклатуры). Это второй затык, ибо грузить каждый раз заново такое кол-во, пусть даже и глубокой ночью по Cron, в MySQL — не есть хорошо (ИМХО). Следовательно, вопрос: как лучше сравнивать каждую строчку (элемент массива) из CSV файла с существующими строками в БД и вносить только те значения, которые были изменены (главный, логично, файл CSV)?
При этом, нужно как-то указать опции:
1. Если такой ID есть в БД, но его нет в файле CSV, то делать DELETE элемента;
2. Если такого ID нет в БД, но есть в файле CSV, то делать INSERT, иначе — пропустить элемент;
3. Если такой ID есть и в БД и в файле CSV, то делать UPDATE, иначе — пропустить элемент.
Надеюсь на вашу помощь. Заранее, спасибо!