За последние 24 часа нас посетили 18010 программистов и 1646 роботов. Сейчас ищут 1895 программистов ...

Глюки с strpos

Тема в разделе "Прочие вопросы по PHP", создана пользователем Kronas, 27 дек 2010.

  1. Kronas

    Kronas Активный пользователь

    С нами с:
    24 мар 2009
    Сообщения:
    6
    Симпатии:
    0
    Доброго времени суток.
    Второй день ломаю голову и не могу понять где собака порылась.

    Есть скрипт парсинга *.xls файлов (кусок кода в котором косяк):
    Код (Text):
    1.  
    2. for ($i = 1; $i <= $data->sheets[0]['numRows']; $i++) {
    3.     $row = " ".@implode(" | ", @$data->sheets[0]['cells'][$i]);
    4.     $sizes = $GLOBALS['db']->select_array_array("mod_conformity_sizes_variants", "uid", array("name", "pid"));
    5.     $brends = $GLOBALS['db']->select_array_array("mod_conformity_brends_variants", "uid", array("name", "pid"));
    6.     $size = "";
    7.     $brend = "";
    8.     $b_pos = "";
    9.     if (is_array($data->sheets[0]['cells'][$i])) {
    10.         foreach (@$data->sheets[0]['cells'][$i] as $item) {
    11.             $brend = $GLOBALS['db']->sql_fetch_assoc($GLOBALS['db']->sql_query("SELECT `pid`, `name` FROM `mod_conformity_brends_variants` WHERE `name`='".$item."' LIMIT 1"));
    12.             if ($brend['pid']) {
    13.                 break;
    14.             }
    15.         }
    16.         if(!$size['pid']) {
    17.             foreach ($brends as $b) {
    18.                 if (strpos($row, $b['name'])) {
    19.                     $brend['pid']=$b['pid'];
    20.                     break;
    21.                 }
    22.             }
    23.         }
    24.         foreach (@$data->sheets[0]['cells'][$i] as $item) {
    25.             $size = $GLOBALS['db']->sql_fetch_assoc($GLOBALS['db']->sql_query("SELECT `pid`, `name` FROM `mod_conformity_sizes_variants` WHERE `name`='".$item."' LIMIT 1"));
    26.             if ($size['pid']) {
    27.                 break;
    28.             }
    29.         }
    30.         if(!$size['pid']) {
    31.             foreach ($sizes as $s) {
    32.                 if (strpos($row, $s['name'])) {
    33.                     $size['pid']=$s['pid'];
    34.                     break;
    35.                 }
    36.             }
    37.         }
    38.     }
    39.     echo $i." - ".$brend['pid']." - ".$size['pid']." - ".$row."<br>";
    40.     if (isset($size['pid']) AND isset($brend['pid'])) {
    41.         $sql = "INSERT INTO `mod_catalog_price` (`pid`, `crdate`, `cruser`, `size`, `brend`, `price`, `currency`, `line`)
    42.             VALUES ('".$_POST['pid']."', '".date("Y-m-d H:i:s")."', '', '".$size['pid']."', '".$brend['pid']."', '".$data->sheets[0]['cells'][$i][$_POST['price']]."', '".$_POST['currency']."', '".$row."')";
    43.         $GLOBALS['db']->sql_query($sql);
    44.     }
    45.     else {
    46.         $no_parsed[$i] = $data->sheets[0]['cells'][$i];
    47.     }
    48. }
    $brends и $sizes - массивы с возможными вариантами представления бренда или размера вида array('id' => array('pid','name')).

    $row имеет вид "1 165/70 R14C KC11 89/87Q Kumho 09 Korea зима м.автоб - 4 72 576".
    $s['name'] имеен вид "165/70 R14".

    В этом куске кода strpos($row, $s['name']) не находит вхождение подстроки, а если вынести это в отдельный файл и $row и $s['name'] задать приведенные выше значения, то все работает как надо.
    Верная подстрока всегда присутствует в массиве (проверено и перепроверено 300 раз).

    Подскажите, пожалуйста, в какую сторону копать.
     
  2. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
     
  3. Jampire

    Jampire Активный пользователь

    С нами с:
    22 авг 2009
    Сообщения:
    181
    Симпатии:
    0
    Адрес:
    Гомель
    Перед исполнением условия с strpos, пробовали выводить переменные?
    Код (Text):
    1. if(!$size['pid'])    {
    2.     foreach ($sizes as $s)    {
    3.     echo $row." ||| ".$s['name']."<br />";
    4.         if (strpos($row, $s['name']))    {
    5.             $size['pid']=$s['pid'];
    6.             break;
    7.         }
    8.     }
    9. }
     
  4. Kronas

    Kronas Активный пользователь

    С нами с:
    24 мар 2009
    Сообщения:
    6
    Симпатии:
    0
    Пробовал, все четко. Подстрока присутствует в строке.
     
  5. Jampire

    Jampire Активный пользователь

    С нами с:
    22 авг 2009
    Сообщения:
    181
    Симпатии:
    0
    Адрес:
    Гомель
    Kronas
    Предоставьте больше информации. На каком момент скрипт прекращает работать? Может у вас даже до strpos скрипт не доходит.
     
  6. Kronas

    Kronas Активный пользователь

    С нами с:
    24 мар 2009
    Сообщения:
    6
    Симпатии:
    0
    Скрипт работать прекращает тогда, когда должен. Все остальное выполняется нормально, strpos тоже вроде-бы выполняется, но подстроку с размером в строке не находит, при этом бренды находятся в 99% случаев. Кодировка строки и подстрок - UTF-8
     
  7. Jampire

    Jampire Активный пользователь

    С нами с:
    22 авг 2009
    Сообщения:
    181
    Симпатии:
    0
    Адрес:
    Гомель
    Если strpos не отрабатывает, значит либо переданные ему данные не верны, либо скрипт не вошел в тело условия if().
     
  8. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Возможно, разные кодировки (в строке, которую нужно найти и в строке, в которой ищем).

    strpos может вернуть 0 в качестве результата поиска (совпадение найдено в нулевой позиции), в этом случае если не сравнивать на тип, можно получить, что подстрока какбы не найдена. Т.е.

    $searched = strpos($str, $search);
    // $searched может быть равен 0
    if($searched) echo('Найдено'); // это "Найдено" не отобразиться
    if($searched !== false) echo('Найдено'); // это "Найдено" отобразиться
     
  9. Kronas

    Kronas Активный пользователь

    С нами с:
    24 мар 2009
    Сообщения:
    6
    Симпатии:
    0
    С кодировками все в порядке.
    Я нашел в чем была причина.
    Как оказалось - в строке было по 2 пробела, а в подстроке - по одному, поэтому подстрока и не находилась. А при выводе отладки в окно браузера он сворачивал несколько пробелов в один и это было незаметно.

    Всю голову сломал, блин, а причина как всегда банальна и проста :).

    Спасибо всем кто откликнулся. Тему можно закрывать.