|
Автор |
Сообщение |
alexander4321
Новенький
Зарегистрирован: 27.09.2012 Сообщения: 28
|
|
|
|
Добрый день! Дочитался в книге PHP5/6 и MySQL6 до стр.120 13.7 Функция explode(): выделение подстрок. Здесь рассмотрен пример чтения строки из файла CSV. А совсем недавно мне подсказали, что файл xls можно преобразовать в формат CSV и затем уже загрузить в базу MySQL ( я спрашивал, как можно загрузить в MySQL файл excel ). В книге очень понятно разобран такой пример, но в примере только одна строка, а в файле для загрузки 5 полей и несколько тысяч строк. Поэтому возникли следующие вопросы:
1) как переменной $str в примере из книги присвоить файл .xls?
Причем, будут ли как то разделяться не только поля, но и строки в выводе Array (повторяю, что строк довольно много)?
2) насколько я понял, вывод Array уже не будет сложно записать в базу MySQL. Так ли это?
Спасибо! |
|
Вернуться к началу |
|
|
den
Старожил
Зарегистрирован: 31.01.2006 Сообщения: 13870 Откуда: Кировоград, Украина
|
|
|
|
Вы дочитали до 120-ой страницы, но вижу многое не поняли
Читаем с помощью file весь CVS файл
В цикле foreach перебираем все строки
Разбираем строки и добавляем их в MySQL
Вообще в книге должен быть пример. CSV - в базу данных. Там где создание прайс-листа
Вот рабочий пример (из реального проекта), только функции для работы с файлами используются немного другие. Но принцип тот же. Читаем файл, забрасываем полученную инфу в БД
// открыть файл
$f = fopen('basa2.csv','r');
// подключиться к БД
include "config.php";
mysql_connect($dbhost, $dbuser, $dbpasswd);
mysql_select_db($dbname);
// удалить все из таблицы куда будем загружать инфу
// вам не надо, но это файл из реального проекта - там было надо
$q = "delete from ua_sbit";
mysql_query($q) or die(mysql_error());
// в цикле читаем файл сразу функцией fgetcsv
while($array=fgetcsv($f, 1024, ';')) {
// получили данные $n - первое поле
// $email - второе поле
$n = $array[0];
$email = $array[1];
// для защиты
$n = mysql_real_escape_string($n);
// сам запрос, выводим для отладки
$q = "insert into ua_sbit values(0, '$n', '$email')";
echo $q . "<br>";
// выполняем запрос
mysql_query($q) or die(mysql_error());
}
fclose($f);
Для уменьшения нагрузки на сервер можно упаковывать запросы - выполнять сразу 2-3 запроса за 1 раз. Тем более у вас вон тысячи строк будут. У меня такой задачи не стояло, то я и не делал |
|
Вернуться к началу |
dhsilabs@jabber.ru |
|
|
alexander4321
Новенький
Зарегистрирован: 27.09.2012 Сообщения: 28
|
|
|
|
Добрый день! Перечитал сначала до 120 страницы. Многие вещи из того, что до этого мог только глазами побежать стали понятны. Видимо, всю книгу нужно будет 2-3 раза прочитать, пока станут понятны хотя бы основные вещи, все таки не художественная литература.
Спасибо за приведенный пример! В примере только 2 переменных ($n и $email), т. к. 2 в файле CSV, видимо, было 2 поля, соответственно, в моем случае будет 5 переменных, т. к. количество полей в файле 5. А при команде insert почему записано values(0, $n, $email)? 0 - это индекс? У меня в качестве индекса должно быть одно из полей ( каталожный номер ). Видимо, при записи в MySQl нужно будет указать какое поле считать за индекс? Спасибо! |
|
Вернуться к началу |
|
|
den
Старожил
Зарегистрирован: 31.01.2006 Сообщения: 13870 Откуда: Кировоград, Украина
|
|
|
|
записано не
Код: |
values(0, $n, $email)
|
А:
Код: |
values(0, '$n', '$email')
|
Это важно. Учитесь сразу обращать внимания на всякие мелочи вроде кавычек. Потом будет проще.
Если полей 5, можно создать пять переменных. Если не красиво, можно создать класс с 5 полями или массив, но зачем так усложнять. Переменных всего 5...
0 - это индекс, который увеличивается автоматически, поэтому значение можно не указывать. В вашем случае можно считать индексом каталожный номер (артикул). Его используйте как первичный индекс, насколько я понимаю, эти номера должны быть уникальными. |
|
Вернуться к началу |
dhsilabs@jabber.ru |
|
|
alexander4321
Новенький
Зарегистрирован: 27.09.2012 Сообщения: 28
|
|
|
|
Извиняюсь, но до сих пор не было возможности разбираться с кодом. Сегодня попробовал и, на удивление, все получилось. Сам не ожидал.
Привожу код, который у меня получилось исполнить на локальном хостинге.
1) config.php
<?php
$dbhost = "localhost"; // Имя сервера
$dbuser = "root"; // Имя пользователя
$dbpasswd = "1234"; // Пароль
$dbname = "price"; //название базы данных
$dbcnx = @mysql_connect($dbhost,$dbuser,$dbpasswd);
if (!$dbcnx) // Если дескриптор равен 0 соединение не установлено
{
echo("<P>В настоящий момент сервер базы данных не доступен, поэтому
корректное отображение страницы невозможно.</P>");
exit();
}
?>
2) price.php
<?php
// открыть файл
$f = fopen('price.csv','r');
// подключиться к БД
include "config.php";
mysql_connect($dbhost, $dbuser, $dbpasswd);
mysql_select_db($dbname);
// удалить все из таблицы куда будем загружать инфу
// вам не надо, но это файл из реального проекта - там было надо
//$q = "delete from ua_sbit";
//mysql_query($q) or die(mysql_error());
// в цикле читаем файл сразу функцией fgetcsv
while($array=fgetcsv($f, 1024, ';')) {
// получили данные $cat_num - первое поле
// $descr - второе поле и т. д.
$cat_num = $array[0];
$descr = $array[1];
$amount = $array[2];
$price = $array[3];
$company = $array[4];
// для защиты
//$n = mysql_real_escape_string($n);
// сам запрос, выводим для отладки
$q = "insert into avtom values('$cat_num', '$descr', '$amount', '$price', '$company')";
echo $q . "<br>";
// выполняем запрос
mysql_query($q) or die(mysql_error());
}
fclose($f);
?>
Единственная проблема, которая возникла еще при при сохранении файла .xls в формат .csv - это то, что русские буквы были заменены на краказябры. Соответственно, и в базу они записались как краказябры. Не подскажите, как можно решить эту проблему? Спасибо за помощь! |
|
Вернуться к началу |
|
|
den
Старожил
Зарегистрирован: 31.01.2006 Сообщения: 13870 Откуда: Кировоград, Украина
|
|
|
|
Надо выполнить запрос SET NAMES <кодировка>
Например
mysql_query('SET NAMES utf8');
Подберите кодировку и все будет в порядке с БД. Запрос нужно выполнять после выбора БД:
mysql_connect($dbhost, $dbuser, $dbpasswd);
mysql_select_db($dbname);
mysql_query('SET NAMES utf8'); |
|
Вернуться к началу |
dhsilabs@jabber.ru |
|
|
alexander4321
Новенький
Зарегистрирован: 27.09.2012 Сообщения: 28
|
|
|
|
Также попробовал загрузить в базу прайс длинной две с небольшим тысячи строк. Прайс грузится очень быстро, но возникают следующие ошибки:
1) в двух строчках в столбце descr прямо в тексте нашел '(апостроф). Соответственно, при выводе в браузер отобразилась ошибка в этих строках, запись в базу данных на этих строках закончилась. Как можно автоматически экранировать подобные знаки, если они вдруг встретятся в тексте?
2) код "insert into avtom values... пришлось заменить на код "replace into avtom values..., т .к. при нахождении подобного же первичного ключа, загруженного ранее, выдавало ошибку Duplicate entry.
Заранее спасибо за помощь!
Спасибо за подсказку по кодировке! Попробую это применить
Последний раз редактировалось: alexander4321 (Чт Окт 18, 2012 12:23 pm), всего редактировалось 1 раз |
|
Вернуться к началу |
|
|
den
Старожил
Зарегистрирован: 31.01.2006 Сообщения: 13870 Откуда: Кировоград, Украина
|
|
|
|
1) mysql_real_escape_string()
2) ну так и должно быть, поскольку значения уже есть и инсертом вставить нельзя
я вместо репласе когда делаю замену прайса просто удаляю все из базы и потом уже работаю инсертом, но так не всегда можно поступить |
|
Вернуться к началу |
dhsilabs@jabber.ru |
|
|
alexander4321
Новенький
Зарегистрирован: 27.09.2012 Сообщения: 28
|
|
|
|
Спасибо! |
|
Вернуться к началу |
|
|
den
Старожил
Зарегистрирован: 31.01.2006 Сообщения: 13870 Откуда: Кировоград, Украина
|
|
|
|
Не за что! |
|
Вернуться к началу |
dhsilabs@jabber.ru |
|
|
alexander4321
Новенький
Зарегистрирован: 27.09.2012 Сообщения: 28
|
|
|
|
den писал(а): |
mysql_query('SET NAMES utf8');
|
Не получилось таким образом сделать. Дело в том, что данные уже в формате CSV содержат краказябры. Соответственно, и в базу данных они так же записываются. Пробовал это делать и на локальном и на удаленном хостинге - результат одинаковый. Вот образец вывода в браузер:
insert into price values('19087', '?ал?? Ї?а?¤??? ??ў?? \\ FIAT DUCATO (06-)', '+', '1 700,00', 'avtom')
Да и помимо краказябр из каталожного номера, если первой цифрой был 0 (ноль), то он удаляется (в XLS было 08670, в CSV стало 8670). |
|
Вернуться к началу |
|
|
den
Старожил
Зарегистрирован: 31.01.2006 Сообщения: 13870 Откуда: Кировоград, Украина
|
|
|
|
Значит нужно перекодировать CSV функцией convert_cyr_string() в нужную кодировку, а затем вносить результат уже в БД |
|
Вернуться к началу |
dhsilabs@jabber.ru |
|
|
alexander4321
Новенький
Зарегистрирован: 27.09.2012 Сообщения: 28
|
|
|
|
Запарился я с этим прайсом. Почитал про функцию convert_cyr_string(), она перекодирует из кириллицы в кириллицу. А при сохранении файла xls в csv файл закодирован в ANSI. Получается, что функция convert_cyr_string() не подходит. Нашел другую функцию iconv(). Тут можно из кириллицы перекодировать в UTF-8. Но проблема в том, что в формате ANSI вместо символов уже содержатся вопросительные знаки. Предполагаю, что проблема начинается именно при сохранении файла в формат CSV. Видимо, при сохранении в CSV теряется много данных. Нельзя ли использовать другие способы для записи XLS в MySQL? Спасибо! |
|
Вернуться к началу |
|
|
den
Старожил
Зарегистрирован: 31.01.2006 Сообщения: 13870 Откуда: Кировоград, Украина
|
|
|
|
Давай начнем с самого начала!
1) Сохрани прайс в CSV и открой в блокноте, русские символы нормально отображаются?
Дальше продолжим после ответа на этот вопрос |
|
Вернуться к началу |
dhsilabs@jabber.ru |
|
|
alexander4321
Новенький
Зарегистрирован: 27.09.2012 Сообщения: 28
|
|
|
|
Сейчас добился того, что хотя бы не пропадают символы - вопросительные знаки вместо текста больше не появляются.
К ответу на вопрос:
1) вот текст строки с русским текстом в файле xls
Боковое зеркало (145) правое эл., грунт. с подогрев. \ ALFA ROMEO 145/146 (94-)
2) этот же текст после сохранения с расширением csv
Ѓ®Є®ў®Ґ §ҐаЄ «® (145) Їа ў®Ґ н«., Јагв. б Ї®¤®ЈаҐў. \ ALFA ROMEO 145/146 (94-) |
|
Вернуться к началу |
|
|
|
|
 Главная страница сайта
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
|
|