За последние 24 часа нас посетили 34504 программиста и 1752 робота. Сейчас ищут 966 программистов ...

Добавилось меньше строк, чем ожидалось

Тема в разделе "PHP и базы данных", создана пользователем DemoN1810, 25 дек 2015.

  1. DemoN1810

    DemoN1810 Новичок

    С нами с:
    16 дек 2015
    Сообщения:
    97
    Симпатии:
    0
    Если кратко: достаю содержимое текстового файла в массив, считаю сколько строк, разбиваю по разделителю \ и заношу в базу, $count=23000, а цикл добавил в базу только 22971 строк; вопрос: я что-то не так сделал или сервер перестал ожидать выполнение цикла?
    Код (PHP):
    1. include_once "база";
    2. header('Content-type: text/html; charset=utf-8');
    3. $answer=file('путь до файла');
    4. $count=count($answer);
    5. while($i<=$count) {
    6. $i=$i+1;
    7. $answ=$answer[$i];
    8. $pieces=explode("\\", $answ);
    9. mysql_query("INSERT INTO таблица(колонка1,колонка2) VALUES ('".$pieces[0]."','".$pieces[1]."')");
    10. } 
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    mysql_query - старое расширение, используй PDO или MySQLi.
    $pieces[0] - нужно экранировать запрос, так как данные из переменной могут поломать синтаксис (http://php.ru/manual/pdo.prepare.html

    функция mysql_query возвращает результат, подсчитывай кол-во успешного и нет

    Добавлено спустя 1 минуту 50 секунд:
    облегчи задачу серверу, делай за один раз 1000 вставок,
    Код (PHP):
    1. ... VALUES ('',''), ('',''), ...  
     
  3. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    возможно кончилось время php. читай про set_time_limit().
    возможно нарушение уникальности значений в таблице.

    После инсерта можешь сравнивать mysqli_affected_rows() с ожидаемым числом строк.
     
  4. DemoN1810

    DemoN1810 Новичок

    С нами с:
    16 дек 2015
    Сообщения:
    97
    Симпатии:
    0
    именно тут не нужно, я сам для себя спарсил базу из файла, не буду же я сам себя взламывать
    транзакции делать чтоли? нисколько не облегчает
    ещё лучше, mysql и mysqli в одном файле
     
  5. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    DemoN1810, видно ты сам все знаешь.
    ну так быстро переходи на mysqli иначе ты в команде отстающих.

    По поводу не добавляющихся значений, в цикле ты сразу делаешь инкремент, поэтому не все данные добавляются.

    И я прислушался бы к совету denis01 насчет все сразу добавлять в базу.
    И плюс лучше тут использовать цикл for

    примерно так:
    Код (PHP):
    1. $answer = file('path');
    2. $count = count($answer);
    3. $val = '';
    4. for ($i = 0; $i < $count; $i++) {
    5.     $pieces = explode("\\", $answer[$i]);
    6.     if ($i == 0) {
    7.         $val .= "('$pieces[0]', '$pieces[1]')";
    8.     } else {
    9.         $val .= ",('$pieces[0]', '$pieces[1]')";
    10.     }
    11. }
    12. echo $query = "INSERT INTO tablename(`column0`,`column1`) VALUES $val;";
    13.  
     
  6. DemoN1810

    DemoN1810 Новичок

    С нами с:
    16 дек 2015
    Сообщения:
    97
    Симпатии:
    0
    $i=null=0, $i+1=null+1=0+1=1 в начале цикла, или я что то недопонял? например только что моим способом занёс ещё около 9 тыс записей и всё быстро и без потерь занеслось
     
  7. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    Вся эта суета из-за того что вроде у тебя что-то не добавлялось, но тут все добавилось! Ну и отлично!

    а по поводу цикла.
    давай разберем порядок как все там происходит.

    первая твоя ошибка, ты не инициализировал переменную $i и начал к ней обращаться, это должно было вызвать у тебя ошибку
    Код (PHP):
    1. Notice: Undefined variable: i in тут будет ссылка на файл где была ошибка и будет указана строчка кода
    ты ее не увидел потому что кажись у тебя отключен вывод ошибок.

    И так. первая итерация Должно быть минимум два notice. Объясняю почему. Два обращения к не инициализированной переменной в логическом выражении цикла и в теле цикла. В то время как в переменной у нас null.

    смотрим твой код. Ты делаешь так
    Код (PHP):
    1. $i = $i+1; 
    что тут произошло?
    Вот что:
    Код (PHP):
    1.  $i = NULL+1; 
    В итоге значение в $i будет 1
    следующая строчка кода
    Код (PHP):
    1. $answ=$answer[$i]; 
    в итоге, мы с ужасом понимаем потеряли часть данных. т.е. $answer[0] осталась за бортом!

    Это мы рассмотрели первую итерацию цикла.

    И теперь, важный момент,
    смотрим логическое выражение цикла и последнюю итерацию цикла:
    Код (PHP):
    1. while($i<=$count) {
    ты пишешь меньше или равно.

    В то время как у тебя $i == $count
    вот эта строчка кода
    Код (PHP):
    1. $answ=$answer[$i];
    вызовет у тебя ошибку
    Код (PHP):
    1. Notice: Undefined offset: 1 in тут файл где была ошибка и будет указана строчка
    А вот почему это произошло, разбирайся сам, и поделись с нами!

    На будущее, включать вывод ошибок на время отладки приложения.
    http://php.net/manual/ru/function.error-reporting
     
  8. DemoN1810

    DemoN1810 Новичок

    С нами с:
    16 дек 2015
    Сообщения:
    97
    Симпатии:
    0
    разве он не сам по умолчанию ставится? например вывело же предупреждение о mysql, значит есть вывод ошибок
     
  9. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    это зависит от того как было настроено тобой или до тебя
     
  10. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    DemoN1810, ты пришел за помошью вроде бы. ни одного плохого совета тебе не дали, но ты как будто отбиваешся от атак :)

    не веди себя так, как будто ты всё знаешь. очевидно это не так.
    включи полный вывод ошибок и добейся чтобы при этом ни одного нотиса и варнинга не возникало.
    добавляй пачками и сравнивай affected rows с желаемым числом. результат протоколируй.
    увеличивай time limit.
    проверь не влияет ли на результат уникальность ключей.
     
  11. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    взлом это следствие нарушения синтаксиса, ты можешь сгенерировать не работающий запрос

    https://dev.mysql.com/doc/refman/5.5/en/insert.html
    Код (PHP):
    1. INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);