Как запретить PHP-переменным быть массивами или объектами?

#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, поэтому я пропустил это.