Странности с определением ID + цикл PHP

D
На сайте с 28.06.2008
Offline
975
1541

Есть парсер, где в таблицу пишутся ID и прочая ерунда, реализовано так


$i = 0;
foreach ($Level3 as $lev3){
$i++;

Ну и где-то там далеко внизу идет инсер в базу, где в качестве ID записывается переменная $i

Так как данных много за раз парсер не сможет все окучить да и бось чтобы не забанили, поэтому решил запускать его по категориям.

В этом случае прихожу к проблеме как определить с какого ID продолжать писать.

Так как опыта еще мало, решил это как смог - так:

$id = $db->query("SELECT MAX(`id`) FROM `table`");
$i = array();
foreach ($id as $item) {
$i[] = $item;
}
if(!isset($i[0]['MAX(`id`)'])){
$i=0;
} else {
$i= (int)$i[0]['MAX(`id`)'];
}

Проверил, в итоге перед циклом переменная $i принимает верное значение, но вот в самом цикле начинается магия.

В категории, на которой я тестирую - 4 товара.

Если один раз запустить парсер то

если прописано $i=0; запишется 4 товара как и положено, а если мой говнокод с определением максимального ID - то вообще ничего.

Проверяем дальше - запускаем еще раз.

При $i=0; запишется как и положено еще 4 товара, но !!!

если вставить мой быдлокод с определением ID - var_dump($i); мне покажет

int 4

что логично и внушает оптимизм :)) но в базу добавятся еще 8 записей вместо 4. (дубли будут)

Понять этого я не могу, надеюсь на вашу помощь.

totamon
На сайте с 12.05.2007
Offline
342
#1

смысл писать в ИД счетчик? база сама умеет это делать, на поле ИД установить флаг автоинкремент, в запрос вместо $i вставляй NULL

Хостинг от 90р (https://goo.gl/h1VRkY) и ВПС от 161р (https://goo.gl/vw9JH7) 14 дней бесплатный тест! Вечный хостинг для сайтов и ВПС (https://eternalhost.net/?from=1492) - заплатил один раз и пользуйся вечно! Монетизация любых сайтов PUSHами (https://clicktimes.me/auth/register?ref=8d34521c) - лучшая цена клика и показа ;)
D
На сайте с 28.06.2008
Offline
975
#2

Спасибо за подсказку!! В пхпмайадмин прописал у поля ID автоинкримент, далее так в запросе?

VALUES ('',

Попробовал прогнать - ничего не записалось

Так тоже попробовал

VALUES ('NULL'

Попробовал так

VALUES (LAST_INSERT_ID(),

В базу записалось 2 одинаковых товара - 2 раза записался первый товар, еще раз прогнал - опять они же записались :))

totamon
На сайте с 12.05.2007
Offline
342
#3
VALUES (NULL,

как-то так

D
На сайте с 28.06.2008
Offline
975
#4

С

VALUES (NULL,

мне на первом же прогоне записало 8 записей.

Два раза по 4. Почему так не понятно...

В конце цикла

foreach ($Level3 as $lev3){

У меня прописан запрос

$db->query("INSERT INTO

Если попробовать после запроса прописать - break;

То в базу запишутся 2 раза первый товар и все. ТОже мне не понятна эта песня.

Антон Лавеев
На сайте с 31.10.2005
Offline
408
#5

Сериал "Муки быдлокодера" :D

☠️☠️☠️
D
На сайте с 28.06.2008
Offline
975
#6

Частично Решил проблему добавлением уникального индекса на одно из полей :))

Дублей больше нет, но по ID видно что они просто перезаписываются что-ли.

ID не по порядку идут

---------- Добавлено 02.06.2019 в 08:44 ----------

Упростил цикл до минимума

foreach ($Level3 as $lev3){
$db->query("INSERT INTO `table` (`id`, `parent_id`, `name`, `4`, `5`, `6`, `7`, `8`, `9`)
VALUES (NULL, '{$linksLevel2[0]['id']}', '0', '0', '0', '0', '0', '0', '');");
}

var_dump($lev3); показывает что в цикл заходят 4 ссылки в виде строк.

Но запуская этот цикл я получаю в базу 8 записей. Почему?

totamon
На сайте с 12.05.2007
Offline
342
#7

Dram, тут видимо алгоритмические прорехи) само собой ведь ничего не происходит, пишет то что задано, нужно проработать логику и структуру программы, пройди по шагам, что выполняет скрипт, если не найдешь почему так а не так как хочется, попробуй выводить промежуточные результаты... http://phpfaq.ru/debug это изучи, получше любого курса будет, только сразу применяй)

IL
На сайте с 20.04.2007
Offline
412
#8
Dram:
В базу записалось 2 одинаковых товара - 2 раза записался первый товар, еще раз прогнал - опять они же записались )

Видимо, имеет смысл перед записью проверять наличие этого товара в базе.. по какому-то уникальному идентификатору (ID в прайсе, либо название).

if (!$good = Good::find(array('id_inner'=>$row['id_inner']))

$good = new Good;
// .. устанавливаем атрибуты
$good->save();

А ещё есть фишка - импортировать всю таблицу в таблицу в память (тип Memory) и

а) если товары точно есть

UPDATE product p INNER JOIN tmp_product tp SET p.price = tp.price, p.status = tp.status

б) старые обновляем, новые добавляем

INSERT INTO p (id_inner, name, price, status ...) SELECT id_inner, name, price, status FROM tmp_product tp

ON DUPLICATE KEY UPDATE name = tp.name, price = tp.price
D
На сайте с 28.06.2008
Offline
975
#9

Не, это все не то. Зачем городить кучу проверок, если банальный цикл из 4 итераций уходит на второй круг, а этого быть не должно априори.

Нужно понять почему так...

IL
На сайте с 20.04.2007
Offline
412
#10
Dram:
если банальный цикл из 4 итераций уходит на второй круг,

Так смотри код.. или кидай, вместе посмотрим )))

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий