Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.129.249.105] |
|
Сообщ.
#1
,
|
|
|
Очередной вопрос. Есть две переменные. Одна получает значение как путь к файлу, другая как путь к папке. Значения сравниваются и фильтруются по результату. Все хорошо работает, но если в пути встречаются квадратные скобки, то их не видит и результат отбрасывается. Пробовал вместо strpos использовать mb_strpos, ставил кодировку UTF-8, но тоже не помогает. Пробовал preg_match, но видимо с ним хуже разобрался, не могу настроить. Причем, если тот же путь скопировать и поставить как значение переменной, в том числе накидать вручную массив, то все работает. Код совсем простенький:
if(strpos($file,$folder) !== false) где $file='.\ещё пустая папка\в ней ещё одна[hhh]kkk\file.jpg'; $folder='.\ещё пустая папка\в ней ещё одна[hhh]kkk'; по крайней мере в таком виде хотел (настраивал получение) и получаю при выводе. Так вот, если эта строки копировать, то при сравнении вхождения будут, а если сравнивает при получении, тоесть берет из "диска" то вхождений нет. При использовании preg_match по идее просто нужно было поменять местами искомое и место для поиска, но но видимо что-то не так, ругается на какие-то точки в конце. Warning: preg_match(): No ending delimiter '.' found in Очень бы хотелось получить подсказку как получить правильное сравнение. |
Сообщ.
#2
,
|
|
|
Все нормально ищется:
$file='.\ещё пустая папка\в ней ещё одна[hhh]kkk\file.jpg'; $folder='.\ещё пустая папка\в ней ещё одна[hhh]kkk'; $pos = strpos($file,$folder); if ($pos === FALSE) { echo "позиция не найдена"; } else { echo "позиция: $pos"; } Добавлено Цитата D-G @ preg_match Напрямую это использовать не получится, ибо символы .\[] есть управляющие для регулярных выражений. Их квотить надо. |
Сообщ.
#3
,
|
|
|
Цитата JoeUser @ Все нормально ищется: Так все правильно, если брать значения как я их привел, явно назначенные переменным, то все нормально ищется. Но когда эти значения берутся из предыдущих выражений, тоесть из тех, что перед этим искали папки и файлы в этой же функции, то оно их дальше не сортирует, не раскидывает как мне нужно. Про управляющие символы я понимаю, но я ведь подставляю опять же переменную, со значениями, которые получены перед этим. Если просто вручную написать: $file='\.\\ещё пустая папка\\в ней ещё одна\[hhh\]kkk\\file\.jpg'; То конечно же ищется. Будь у меня какое-то регулярное выражение, а не 7тыщ значений переменной, было бы проще. Но нужно построить поиск именно как сто процентное совпадение, а не как похожее. Ведь регулярка типа: preg_match("/^.*\.(.*)/",$file) Покажет одинаковость как такой строки: $file='.\ещё пустая папка\в ней ещё одна[hhh]kkk\file.jpg' так и такой [code] $file='.\this is anothe dir[hhh]kkk\file.jpg' Я подобное выражение использую для поиска типов файлов, потому что важно совпадение концовки. Ну или для поиска конкретного файла типа preg_match_all("/^.*index\.(php|html)$/i",$annown,$match) Тогда находит все индекс файлы пхп или штмл. А как добиться проверки на сто процентное совпадение неизвестных файлов и папок? По идее glob тоже не подходит. Пока кроме strpos ничего не нашел и не придумал. Если надо, могу показать весь предыдущий и последующий код, хотя в конце почти ничего нет, уже вывод сортировки, и он не сортирует именно эти квадратные скобки и именно если берет значения прямо из имени и пути файла-папки. А вот если вручную ему подсунуть, как я прописал в примере, то все в порядке. Может я конечно как-то не правильно объясняю, но как могу. Стараюсь. |
Сообщ.
#4
,
|
|
|
Цитата D-G @ Так все правильно, если брать значения как я их привел, явно назначенные переменным, то все нормально ищется. Но когда эти значения берутся из предыдущих выражений И "когда эти значения берутся из предыдущих выражений" что не так? Какая разница откуда берется выражение? Может не тут ошибка, а там ... где "оно берется"? ЗЫ: Я показал правильный участок кода. Он работает. Смотри инициализацию "до того как". |
Сообщ.
#5
,
|
|
|
Цитата JoeUser @ ЗЫ: Я показал правильный участок кода. Он работает. Смотри инициализацию "до того как". Как я уже говорил, в таком виде он и у меня работает. По поводу инициализации "до того как" даже не знаю. Делаю проверки с помощью echo, print_r, var_damp на каждом шагу от начала функции. Да там и нет особых проблем. Просто разделяются файлы от папок. А в этой строке сравниваются пути. Это у меня такой замученый код получился для поиска пустых папок. Конечно хочется упростить, но пока не получается. Пробовал перед этим и с помощью filesize (но у всех папок показывает ноль) и другими способами. И вот появилась идея сравнивать пути. Если в пути файла есть путь папки, то папка с файлом, если же ни к одному файлу путь не подходит, то папка пустая. Таким образом в конце функции создается два массива: один с полными папками, второй с пустыми. Вот код: 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 тыщ файлов. Да и секундомер надо бы поставить для замера скорости. Но честно говоря пока не разобрался как это сделать корректно. |
Сообщ.
#6
,
|
|
|
Цитата D-G @ Это у меня такой замученый код получился для поиска пустых папок. if (2 < count(scandir(...))) { // папка не пустая } |
Сообщ.
#7
,
|
|
|
Цитата K313 @ if (2 < count(scandir(...))) { // папка не пустая } А если в нем несколько пустых папок? Допустим 10 пустых в одной. Это ж будет считаться как не пустая. Хотя по факту в ней файлов не будет. Я пробовал подобное, но пока не получилось. Хотя count не подумал применять. Опять же, почему больше 2? Почему не меньше 1? Попробую все варианты. Отпишусь, ато получится как с моим кодом, вроде рабочий, а баги вылазят. Вопрос в любом случае пока остается открытым: почему читая имя файла непосредственно strpos не видит квадратные скобки, хотя видит их в тексте. Мало ли, может ещё где-то пригодится. Тем более, что столкнулся с подобной проблемой в регулярках. preg_match хорошо ищет слово в тексте, если оно начинается с точки. А вот если имя файла начинается с точки, то он его не видит. Любую точку в названии файла видит, а начальную пропускает. Это не относится к виду ".\". Это в случае ".\.имя файла.расширение". В регулярку подставляю переменную, так же как перед этим в strpos. |
Сообщ.
#8
,
|
|
|
Цитата D-G @ ЗЫ: Я показал правильный участок кода. Он работает. Смотри инициализацию "до того как". Возможно вы правы. Я упростил ситуацию на мой взгляд до максимума. Создал файл с проверочным кодом в двух видах: в первом варианте переменные получают данные из функций, во втором из текста. Назвал файл eror.php. Положил его на один уровень с единственной папкой в которой есть файл. Имя папки периодически меняю, вставляя туда квадратные скобки. При этом strpos постоянно видит вхождения, но в результатах (выводе массива) имя папки с квадратными скобками не отображается. Как только убираю хоть одну квадратную скобку,папка появляется и в ней виден файл. Функцию получения имени папки упростил с расчетом, что она одна. Ну и для примера работа того же варианта строки strpos при работе с текстовыми данными. Правда для наглядности работы добавил в имени файла несколько точек в пути. Тогда вхождение смещается для наглядности. Вот код: <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 "Позиция не найдена";} ?> Вот что получается, если нет квадратных скобок .\в ней ещё одна[hhhkkk ---- Array ( [0] => .\eror.php ) Array ( [0] => .\в ней ещё одна[hhhkkk\file.jpg ) позиция: 0 позиция: 4 А вот что с квадратными скобками .\в ней ещё одна[hhh]kkk ---- Array ( [0] => .\eror.php ) позиция: 0 позиция: 4 Если проблема не в работе strpos, то как решить проблему? И какое же вхождение он видит? Цитата K313 @ if (2 < count(scandir(...))) { // папка не пустая } Что-то у меня пока не получается пока ваш вариант. Не натолкнете ещё дальше на мысли? |