На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Serafim, fatalist
  
    > strpos и mb_strpos не видят квадратные скобки в путях напрямую , хотя видят, если это же имя файла берется из текста
      Очередной вопрос. Есть две переменные. Одна получает значение как путь к файлу, другая как путь к папке. Значения сравниваются и фильтруются по результату. Все хорошо работает, но если в пути встречаются квадратные скобки, то их не видит и результат отбрасывается. Пробовал вместо strpos использовать mb_strpos, ставил кодировку UTF-8, но тоже не помогает. Пробовал preg_match, но видимо с ним хуже разобрался, не могу настроить. Причем, если тот же путь скопировать и поставить как значение переменной, в том числе накидать вручную массив, то все работает. Код совсем простенький:
      ExpandedWrap disabled
        if(strpos($file,$folder) !== false)

      где
      ExpandedWrap disabled
        $file='.\ещё пустая папка\в ней ещё одна[hhh]kkk\file.jpg';
        $folder='.\ещё пустая папка\в ней ещё одна[hhh]kkk';

      по крайней мере в таком виде хотел (настраивал получение) и получаю при выводе. Так вот, если эта строки копировать, то при сравнении вхождения будут, а если сравнивает при получении, тоесть берет из "диска" то вхождений нет.
      При использовании preg_match по идее просто нужно было поменять местами искомое и место для поиска, но но видимо что-то не так, ругается на какие-то точки в конце.
      ExpandedWrap disabled
        Warning: preg_match(): No ending delimiter '.' found in

      Очень бы хотелось получить подсказку как получить правильное сравнение.
      Сообщение отредактировано: D-G -
        Все нормально ищется:

        ExpandedWrap disabled
          $file='.\ещё пустая папка\в ней ещё одна[hhh]kkk\file.jpg';
          $folder='.\ещё пустая папка\в ней ещё одна[hhh]kkk';
           
          $pos = strpos($file,$folder);
           
          if ($pos === FALSE) {
            echo "позиция не найдена";
          } else {
            echo "позиция: $pos";
          }


        Добавлено
        Цитата D-G @
        preg_match

        Напрямую это использовать не получится, ибо символы .\[] есть управляющие для регулярных выражений. Их квотить надо.
          Цитата JoeUser @
          Все нормально ищется:

          Так все правильно, если брать значения как я их привел, явно назначенные переменным, то все нормально ищется. Но когда эти значения берутся из предыдущих выражений, тоесть из тех, что перед этим искали папки и файлы в этой же функции, то оно их дальше не сортирует, не раскидывает как мне нужно.
          Про управляющие символы я понимаю, но я ведь подставляю опять же переменную, со значениями, которые получены перед этим. Если просто вручную написать:
          ExpandedWrap disabled
            $file='\.\\ещё пустая папка\\в ней ещё одна\[hhh\]kkk\\file\.jpg';

          То конечно же ищется.
          Будь у меня какое-то регулярное выражение, а не 7тыщ значений переменной, было бы проще. Но нужно построить поиск именно как сто процентное совпадение, а не как похожее. Ведь регулярка типа:
          ExpandedWrap disabled
            preg_match("/^.*\.(.*)/",$file)

          Покажет одинаковость как такой строки:
          ExpandedWrap disabled
            $file='.\ещё пустая папка\в ней ещё одна[hhh]kkk\file.jpg'
            так и такой
            [code]
            $file='.\this is anothe dir[hhh]kkk\file.jpg'

          Я подобное выражение использую для поиска типов файлов, потому что важно совпадение концовки. Ну или для поиска конкретного файла типа
          ExpandedWrap disabled
            preg_match_all("/^.*index\.(php|html)$/i",$annown,$match)

          Тогда находит все индекс файлы пхп или штмл. А как добиться проверки на сто процентное совпадение неизвестных файлов и папок? По идее glob тоже не подходит. Пока кроме strpos ничего не нашел и не придумал.
          Если надо, могу показать весь предыдущий и последующий код, хотя в конце почти ничего нет, уже вывод сортировки, и он не сортирует именно эти квадратные скобки и именно если берет значения прямо из имени и пути файла-папки. А вот если вручную ему подсунуть, как я прописал в примере, то все в порядке. Может я конечно как-то не правильно объясняю, но как могу. Стараюсь.
          Сообщение отредактировано: D-G -
            Цитата D-G @
            Так все правильно, если брать значения как я их привел, явно назначенные переменным, то все нормально ищется. Но когда эти значения берутся из предыдущих выражений

            И "когда эти значения берутся из предыдущих выражений" что не так?
            Какая разница откуда берется выражение?
            Может не тут ошибка, а там ... где "оно берется"?

            ЗЫ: Я показал правильный участок кода. Он работает. Смотри инициализацию "до того как".
              Цитата JoeUser @
              ЗЫ: Я показал правильный участок кода. Он работает. Смотри инициализацию "до того как".

              Как я уже говорил, в таком виде он и у меня работает. По поводу инициализации "до того как" даже не знаю. Делаю проверки с помощью echo, print_r, var_damp на каждом шагу от начала функции. Да там и нет особых проблем. Просто разделяются файлы от папок. А в этой строке сравниваются пути.
              Это у меня такой замученый код получился для поиска пустых папок. Конечно хочется упростить, но пока не получается. Пробовал перед этим и с помощью filesize (но у всех папок показывает ноль) и другими способами. И вот появилась идея сравнивать пути. Если в пути файла есть путь папки, то папка с файлом, если же ни к одному файлу путь не подходит, то папка пустая. Таким образом в конце функции создается два массива: один с полными папками, второй с пустыми. Вот код:
              ExpandedWrap disabled
                function find_empty($dir)
                {
                  global $files;global $folders; global $pic_on; global $parth_on; global $annown;
                  function find_file_folder($dir) // эта часть функции в функции ищет  папки и файлы
                  {
                      global $pic_on; global $parth_on; global $files;global $folders;
                      foreach (glob($dir.DIRECTORY_SEPARATOR."*") as $annown)
                      {
                        if (is_dir($annown))
                       {
                          if (find_file_folder($annown)) continue; // пропускаем
                           $folders[]=$annown;
                          // echo $annown; echo '<br>';  // ищет  папки
                         }
                          else
                          {
                           $files[] =$annown;
                           // echo $annown; echo '<br>';  //  ищет   файла
                         }
                        }
                  }
                   find_file_folder($dir);  // тут вызывается поиск папок и файлов и передается ниже для сравнения строк
                 // если тут создать массивы вручную и написать в них несколько значений, в том числе и с квадратными скобками, то все //в порядке
                    foreach($files as $file)
                   {
                        foreach($folders as $folder)
                      {
                            if(strpos($file,$folder) !== false)  // сравниваем пути
                            {
                                $folders_notempty[$folder] = $folder;
                                print_r($folder); echo '<br>';  // уже в этом месте строк с квадратными скобками нет, но если убрать // скобки то появляется. Если убрать действие от обратного и сортировать в другую сторону (восклицательный знак) то появляется
                            }
                        }
                    }
                    foreach($folders as $folder)
                    {
                        if(!in_array($folder, $folders_notempty))
                                  {
                            $folders_empty[] = $folder;
                                      // print_r(folders_empty); echo '<br>';
                                      //echo $folder; echo '<br>';
                                      $parth_on[]=$folder;
                                 //     $pic_on[]=$folder;
                                      $pic_on[] ='<img src="./icon/icons8-folder-48.png" width="100%" height="100%" >';   // делаем превью с иконкой и выводим в список. там отдельная функция принимает значения
                          //            echo $folder; echo '<br>';
                                   }
                      }
                }

              Тут закоментированы все проверки, чтоб лишний раз их не писать и всегда были под рукой. Надо бы ещё на switch перевести, ато замирает секунды на 4-5 на 7 тыщ файлов. Да и секундомер надо бы поставить для замера скорости. Но честно говоря пока не разобрался как это сделать корректно.
              Сообщение отредактировано: D-G -
                Цитата D-G @
                Это у меня такой замученый код получился для поиска пустых папок.

                ExpandedWrap disabled
                  if (2 < count(scandir(...)))
                  {
                     // папка не пустая
                  }
                  Цитата K313 @
                  if (2 < count(scandir(...)))
                  {
                  // папка не пустая
                  }

                  А если в нем несколько пустых папок? Допустим 10 пустых в одной. Это ж будет считаться как не пустая. Хотя по факту в ней файлов не будет. Я пробовал подобное, но пока не получилось. Хотя count не подумал применять. Опять же, почему больше 2? Почему не меньше 1? Попробую все варианты. Отпишусь, ато получится как с моим кодом, вроде рабочий, а баги вылазят. Вопрос в любом случае пока остается открытым: почему читая имя файла непосредственно strpos не видит квадратные скобки, хотя видит их в тексте. Мало ли, может ещё где-то пригодится. Тем более, что столкнулся с подобной проблемой в регулярках. preg_match хорошо ищет слово в тексте, если оно начинается с точки. А вот если имя файла начинается с точки, то он его не видит. Любую точку в названии файла видит, а начальную пропускает. Это не относится к виду ".\". Это в случае ".\.имя файла.расширение". В регулярку подставляю переменную, так же как перед этим в strpos.
                  Сообщение отредактировано: D-G -
                    Цитата D-G @
                    ЗЫ: Я показал правильный участок кода. Он работает. Смотри инициализацию "до того как".

                    Возможно вы правы. Я упростил ситуацию на мой взгляд до максимума. Создал файл с проверочным кодом в двух видах: в первом варианте переменные получают данные из функций, во втором из текста. Назвал файл eror.php. Положил его на один уровень с единственной папкой в которой есть файл. Имя папки периодически меняю, вставляя туда квадратные скобки. При этом strpos постоянно видит вхождения, но в результатах (выводе массива) имя папки с квадратными скобками не отображается. Как только убираю хоть одну квадратную скобку,папка появляется и в ней виден файл. Функцию получения имени папки упростил с расчетом, что она одна.
                    Ну и для примера работа того же варианта строки strpos при работе с текстовыми данными. Правда для наглядности работы добавил в имени файла несколько точек в пути. Тогда вхождение смещается для наглядности.
                    Вот код:
                    ExpandedWrap disabled
                      <head>
                      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
                       
                      </head>
                      <?php
                      $dir='.';
                       
                      $folders=glob($dir.DIRECTORY_SEPARATOR."*", GLOB_ONLYDIR);
                      foreach ($folders as $folder)
                      {
                      if (is_dir($folder))  echo $folder; echo '<br>----<br>'; // тут для проверки результата
                       }
                      echo '<br>----<br>';
                      function find_all_files($path)
                      {
                        global $file;
                        foreach (glob($path.DIRECTORY_SEPARATOR."*") as $file)
                        {
                           if (is_dir($file))
                           {
                              if (!find_all_files($file)) continue;
                           }
                           else
                           {
                              $parth_on[] =$file; print_r($parth_on); // тут проверяю массив и при добавлении квадратных скобок папка пропадает
                           }
                        }
                      }
                      find_all_files('.');
                          $pos = strpos($file,$folder);
                          
                          if ($pos !== FALSE) {
                            echo "позиция: $pos";
                          } else {
                            echo "Позиция не найдена";}
                       
                      ?>
                       
                      <?php
                          $file='.....\в ней ещё одна[hhh]kkk\file.jpg';
                          $folder='.\в ней ещё одна[hhh]kkk';
                      $pos = strpos($file,$folder);
                          
                          if ($pos !== FALSE) {
                           echo "позиция: $pos";
                          } else {
                            echo "Позиция не найдена";}
                      ?>

                    Вот что получается, если нет квадратных скобок
                    ExpandedWrap disabled
                      .\в ней ещё одна[hhhkkk
                      ----
                      Array ( [0] => .\eror.php ) Array ( [0] => .\в ней ещё одна[hhhkkk\file.jpg ) позиция: 0 позиция: 4

                    А вот что с квадратными скобками
                    ExpandedWrap disabled
                      .\в ней ещё одна[hhh]kkk
                      ----
                      Array ( [0] => .\eror.php ) позиция: 0 позиция: 4

                    Если проблема не в работе strpos, то как решить проблему? И какое же вхождение он видит?
                    Цитата K313 @
                    if (2 < count(scandir(...)))
                    {
                    // папка не пустая
                    }

                    Что-то у меня пока не получается пока ваш вариант. Не натолкнете ещё дальше на мысли?
                    Сообщение отредактировано: D-G -
                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                    0 пользователей:


                    Рейтинг@Mail.ru
                    [ Script execution time: 0,0464 ]   [ 16 queries used ]   [ Generated: 28.03.24, 15:35 GMT ]