#php #mysql #simplexml
#php #mysql #simplexml
Вопрос:
Я думаю, что (название) — это проблема, с которой я столкнулся. Я настраиваю соединение с MySQL, читаю XML-файл, а затем вставляю эти значения в таблицу, перебирая элементы. Проблема в том, что вместо вставки только 1 записи, иногда я вставляю 2, или 3, или 4. Похоже, это зависит от предыдущих значений, которые я прочитал. Я думаю, что я повторно инициализирую переменные, но, полагаю, мне чего-то не хватает — надеюсь, чего-то простого.
Вот мой код. Изначально у меня было около 20 столбцов, но я сократил включенную версию, чтобы ее было легче читать.
$ctr = 0;
$sql = "insert into csd (id,type,nickname,hostname,username,password) ".
"values (?,?,?,?,?,?)";
$cur = $db->prepare($sql);
for ($ctr = 0; $ctr < $expected_count; $ctr ) {
unset($bind_vars,$dat);
$lbl = "csd_{$ctr}";
$dat['type'] = (string) $ref->itm->csds->$lbl->type;
$dat['nickname'] = (string) $ref->itm->csds->$lbl->nickname;
$dat['hostname'] = (string) $ref->itm->csds->$lbl->hostname;
$dat['username'] = (string) $ref->itm->csds->$lbl->username;
$dat['password'] = (string) $ref->itm->csds->$lbl->password;
$bind_vars = array( $id,$dat['$type'], $dat['$nickname'], $dat['$hostname'],
$dat['$username'], $dat['$password']);
print_r ($bind_vars);
$res = $db->execute($cur, $bind_vars);
}
P.S. Я также пометил этот SimpleXML, потому что именно так я читаю файл, хотя этот код не включен выше. Это выглядит следующим образом:
$ref = simplexml_load_file($file);
ОБНОВЛЕНИЕ: я изменил код в соответствии с предложениями, и теперь это не всегда один и тот же шаблон, но он одинаково нарушен. Когда я отображаю массив bind перед вставкой, он выглядит следующим образом. Обратите внимание, что я также считаю строки до и после, поэтому есть 0 строк, затем я вставляю 1, затем есть 2:
0 CSDs on that ITEM now.
Array
(
[0] => 2
[1] => 0
[2] =>
[3] => X
[4] => XYZ
[5] =>
[6] =>
[7] =>
[8] => audio
[9] =>
[10] => 192.168.0.50
[11] => 192.168.0.3
[12] => 255.255.255.0
[13] => 255.255.255.0
[14] =>
[15] =>
[16] =>
[17] => 21
[18] => 5
[19] => Y
[20] => /dir
)
2 CSDs on that ITEM now.
Комментарии:
1. каким должен быть вывод и где ошибка?
2. Выполните
print_r($bind_vars)
и проверьте правильность массива.3. Моя первоначальная мысль заключалась в том, что если бы я мог объявлять эти переменные как ЦЕЛЫЕ ЧИСЛА и СТРОКИ, у меня не возникло бы проблемы с тем, что они автоматически становятся массивами только потому, что я добавил к ним другое значение. Но опять же, я мог что-то упустить.
4. @apis17: Реального вывода нет, но XML-файл с 2 записями должен вызывать вставку из 2 записей. Это вызывает 4. И файл с 5 записями вставляет 10. Но иногда 2 XML-записи приводят к 3 записям базы данных. И сообщения об ошибке нет; просто неожиданное поведение.
5. И вот отладочный результат, который он генерирует: 1 CSDS для этого элемента сейчас. Теперь для этого элемента 3 CSD. Теперь по этому пункту 5 CSD. Сейчас по этому пункту 6 CSD. Теперь для этого элемента 8 CSD. Теперь по этому элементу 10 CSD.
Ответ №1:
не уверен в точном ответе, но это может помочь
$ctr = 0;
$sql = "insert into csd (id,type,nickname,hostname,username,password) ".
"values (?,?,?,?,?,?)";
$cur = $db->prepare($sql);
for ($ctr = 0; $ctr < $expected_count; $ctr ) {
//list ( $lbl, $type, $nickname, $hostname, $username, $password) = "";
//$bind_vars = array();
// use unset
unset($bind_vars,$dat);
$lbl = "csd_{$ctr}";
$dat['type'] = $ref->itm->csds->$lbl->type;
$dat['nickname'] = $ref->itm->csds->$lbl->nickname;
$dat['hostname'] = $ref->itm->csds->$lbl->hostname;
$dat['username'] = $ref->itm->csds->$lbl->username;
$dat['password'] = $ref->itm->csds->$lbl->password;
$bind_vars = array($id,$dat['$type'],$dat['$nickname'],$dat['$hostname'],$dat['$username'],$dat['$password']);
$res = $db->execute($cur, $bind_vars);
# this is a separate function which works, but which only
# does SELECTS and cannot be the problem. I include it because I
# want to count the total rows.
printf ("%d CSDs on that ITEM now.n", CountCSDs($id_to_sync));
}
или, может быть, вам следует сначала проверить значение / echo $expected_count
, чтобы определить правильное количество
Комментарии:
1. Я проверил ожидаемое количество, и оно было правильным. Итак, я повторяю цикл нужное количество раз — просто каждый раз я вставляю слишком много записей. Подразумевает ли ваш ответ, что unset работает лучше, чем просто установка значений в «» ? Я попробую.
2. Точно такое же поведение. У меня есть XML-файл с expected_count равным 5, и количество после каждой вставки идет 2, 4, 5, 8, 9. Это должно идти 1, 2, 3, 4, 5.
3. просто идея. я не уверен, но если это не удастся, возможно, есть другой способ, если вы могли бы дать мне еще одну подсказку о том, что произойдет и каким должен быть результат.
4. возможно, 2, 4, 5, 8, 9 — это номер компакт-диска. 🙂
5. Я изменил код, как вы рекомендовали, а затем привел их все в виде строк, например $dat[‘fldname’] = (string) $ref->itm-> csds->$lbl-> type; и теперь шаблон немного отличается. На первом проходе он вставляет 2, на втором он вставляет 2, на третьем проходе вставляет 1, на четвертом проходе вставляет 1, а на пятом проходе вставляет 1, в общей сложности 7 вместо ожидаемых 5. Таким образом, мой номер CD теперь 2, 4, 5, 6, 7 ?
Ответ №2:
Оказывается, скрипт выполнялся заданием cron, но КТО-ТО ДРУГОЙ запускал мой скрипт с другим заданием cron, и поэтому иногда создавалось в два раза больше записей, а иногда и нет. И чем больше я смотрел на это, и чем больше я создавал кода для устранения неполадок, тем медленнее это делалось, а значит, тем хуже становилось.
Другими словами, когда я не смотрел на это, это работало лучше, чем когда я смотрел на это.
Черт бы побрал всех этих людей, пытающихся мне помочь!
Комментарии:
1. Это был правильный ответ, но я принял приведенный выше, потому что такой способ позволил мне лучше видеть, что происходит, что позволило мне узнать, что он выполнялся дважды. Поскольку другой пользователь записывал данные в другой файл журнала, я не сразу заметил.
2. наконец-то!! это задание cron и выполняется одновременно. возможно, нам следует позаботиться о cron job в следующий раз 🙂
3. Да, я посмотрел, где хранятся скрипты, но это было в другой области, чем другие задания cron, поэтому я пропустил это.