Изучаю чуть больше месяца, не могу передать массив целиком. Я хотел вывести путь до файлов и имена файлов. После возврата пропадает путь через 2 папки , остается корень. Структуру менял как ячейка-ячейка и ярлык-ячейка. Хоть в файл сбрасывается, да и ладно) И почему-то is_file else это не is_file is_dir
какая-то жесть, только через файл удается сконвертировать, даже строка не передается!!! почему foreach ($b as $as) {var_dump($as); echo '<br>';} return $b; } $b=listr('c:\OSPanel\domains\localhost'); foreach ($b as $as) {var_dump($as); echo '<br>';} Вот это исчезает: array(3) { [0]=> string(37) "c:\OSPanel\domains\localhost\script1\" [1]=> string(15) "4433863154.webp" } array(3) { [0]=> string(37) "c:\OSPanel\domains\localhost\script1\" [1]=> string(14) "image (1).webp" } array(3) { [0]=> string(37) "c:\OSPanel\domains\localhost\script1\" [1]=> string(10) "image.webp" } array(3) { [0]=> string(37) "c:\OSPanel\domains\localhost\script1\" [1]=> string(66) "x7d7aa4a48bda7112450f98c413c821f2.jpg.pagespeed.ic.ClgDe_4QLZ.webp" } array(3) { [0]=> string(34) "c:\OSPanel\domains\localhost\view\" [1]=> string(39) "Безымянный45 (3) (1) (28).jpg" } array(3) { [0]=> string(34) "c:\OSPanel\domains\localhost\view\" [1]=> string(39) "Безымянный45 (3) (1) (29).jpg" } array(3) { [0]=> string(34) "c:\OSPanel\domains\localhost\view\" [1]=> string(39) "Безымянный45 (3) (1) (30).jpg" } А это сразу снизу остается? array(3) { [0]=> string(29) "c:\OSPanel\domains\localhost\" [1]=> string(15) "4433863154.webp" } array(3) { [0]=> string(29) "c:\OSPanel\domains\localhost\" [1]=> string(12) "7257_001.gif" } array(3) { [0]=> string(29) "c:\OSPanel\domains\localhost\" [1]=> string(39) "DisastrousQuaintBangeltiger-max-1mb.gif" } array(3) { [0]=> string(29) "c:\OSPanel\domains\localhost\" [1]=> string(6) "b3.jpg" } array(3) { [0]=> string(29) "c:\OSPanel\domains\localhost\" [1]=> string(9) "eath2.gif" } array(3) { [0]=> string(29) "c:\OSPanel\domains\localhost\" [1]=> string(14) "image (1).webp" } array(3) { [0]=> string(29) "c:\OSPanel\domains\localhost\" [1]=> string(10) "image.webp" } array(3) { [0]=> string(29) "c:\OSPanel\domains\localhost\" [1]=> string(15) "Слой 18.gif" }
function listr($a){ $c=array_diff(scandir($a), ['..','.']); $b=[];$l=''; foreach ($c as $as) {$d=$a.'\\'.$as;if(is_dir($d)) $c[]=listr($d); if(preg_match('#\.jpg|\.gif|\.webp#', $as)){$l.=$a.'\\;'.$as."\n";} } $a=strlen($l); $d='';$h=''; $f=0; for ($i=0; $i <$a ; $i++) {$h=substr($l, $i ,1);if($h==';') {$b[$f][0]=$d; $d=''; } elseif($h=="\n" or $i==$a-1) {$b[$f][1]=$d;$b[$f][2]=''; $d=''; $f++;} else $d.=$h; } //foreach ($b as $as) {var_dump($as); echo '<br>';} return $b; } $b=listr('c:\OSPanel\domains\localhost'); //foreach ($b as $as) {var_dump($as); echo '<br>';} $a=count($b);$c=0; for ($i=0; $i < $a; $i++) { $b[$i][2]=new_name($b[$i][1],$b,0); } function new_name($e,$b,$c){ $a=count($b); for($j=0;$j<$a;$j++){ if($e==$b[$j][2]) {$c++;$e=$e.'_'.$c; new_name($e,$b,$c); } }return $e; } for ($i=0; $i < $a; $i++) { copy($b[$i][0].$b[$i][1], 'c:\OSPanel\domains\localhost\image\\'.$b[$i][2]); }
в общем, в этом фрагменте function listr($a){ $c=array_diff(scandir($a), ['..','.']); // пути дергаем $b=[];$l=''; foreach ($c as $as) {$d=$a.'\\'.$as;if(is_dir($d)) $c[]=listr($d); //папки снова отправляем if(preg_match('#\.jpg|\.gif|\.webp#', $as)){$l.=$a.'\\;'.$as."\n";} //файлы отбираем, закидываем исходный путь и найденный файл через разделитель } //задание скинуть в папку и уникализировать имена, в оригинальном массиве ячейки разного размера $a=strlen($l); $d='';$h=''; $f=0; for ($i=0; $i <$a ; $i++) {$h=substr($l, $i ,1);if($h==';') {$b[$f][0]=$d; $d=''; } elseif($h=="\n" or $i==$a-1) {$b[$f][1]=$d;$b[$f][2]=''; $d=''; $f++;} else $d.=$h; //формируем массив с 3-я ячейками, третья - это для итоговых имен файлов, т. к будет рекурсивный подбор приставок _1, _2 в случае совпадения имен } //foreach ($b as $as) {var_dump($as); echo '<br>';} return $b; } и тут все
function listr($a){ $c=array_diff(scandir($a), ['..','.']); // пути дергаем $b=[];$l=''; foreach ($c as $as) {$d=$a.'\\'.$as; //полный путь if(is_dir($d)) $c[]=listr($d); //папки снова отправляем на скан if(preg_match('#\.jpg|\.gif|\.webp#', $as)) //если картинки {$l.=$a.'\\;'.$as."\n";} //записываем в переменную построчно через разделитель точку с запятой на разных строках путь и имя файла } //задание скинуть в папку и уникализировать имена, в оригинальном массиве получились ячейки разного размера, по тому приведем в порядок $a=strlen($l); $d='';$h=''; $f=0; //готовим цикл по все длине переменной и раскидываем в 2 колонки путь и название картинки for ($i=0; $i <$a ; $i++) {$h=substr($l, $i ,1);if($h==';') //если разделитель {$b[$f][0]=$d; $d=''; } // заносив первую ячейку и очищаем накопленное. elseif($h=="\n" or $i==$a-1) // если новая строка или конец переменной {$b[$f][1]=$d;$b[$f][2]=''; $d=''; $f++;} // заносим во вторую ячейку имя файла, сразу формируем третью ячейку для итогового имени (точно не в этом дело) . ну и двигаем индекс массива else $d.=$h; //иначе рабочий процесс накопления символов до разделителя } //foreach ($b as $as) {var_dump($as); echo '<br>';} return $b; }
Очень много ошибок в логике скрипта PHP: function listr($path) { $result = []; $Iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); foreach ($Iterator as $value){ /**@var SplFileInfo $value*/ if(in_array($value->getExtension(), ['png', 'jpg', 'webp'])){ $result[] = [ $value->getPath(), $value->getFilename() ]; } } return $result; } .
а смысл использовать какие-то заготовки, если это обучение? где там ошибки в логике? Факт пишу, что кусок массива не возвращается из функции, даже в виде строки, а через файл забираю. Он выводится в конце функции. но не передается. --- Добавлено --- ну можно это все запустить в цикле без функции, и, если не будет изменений, то прекратить
1. Функция не должна делать много. Нужно разделить логику на чтение директории и парсинг строк. 2. Править то что работает неправильно в функции listr, если это необходимо 3. Рефакторинг. PHP: function recursiveReadFilesFordirs($a) { $c = array_diff(scandir($a), ['..', '.']); $l = ''; foreach ($c as $as) { $d = $a . '\\' . $as; if (is_dir($d)) { $l.= recursiveReadFilesFordirs($d); } if (preg_match('#\.php|\.gif|\.webp#', $as)) { $l .= $a . '\\;' . $as . "\n"; } } return $l; } function listr($a) { $b = []; $l = recursiveReadFilesFordirs($a); $a = strlen($l); $d = ''; $h = ''; $f = 0; for ($i = 0; $i < $a; $i++) { $h = substr($l, $i, 1); if ($h == ';') { $b[$f][0] = $d; $d = ''; } elseif ($h == "\n" || $i == $a - 1) { $b[$f][1] = $d; $b[$f][2] = ''; $d = ''; $f++; } else { $d .= $h; } } //foreach ($b as $as) {var_dump($as); echo '<br>';} return $b; }
я присваивал результаты другому массиву и пытался вернуть. не возвращает кусок, я обнулял массив, он неравномерный, вот в чем дело, может тогда без функции в цикле надо делать. Не понимаю, что внутри происходит, разделители менял, что мог, выносил за пределы функций. Вот смотрите: Код (Text): $a=strlen($l); $d='';$h=''; $f=0; $b=[]; //вот обнуляю, //готовим цикл по все длине переменной и раскидываем в 2 колонки путь и название картинки for ($i=0; $i <$a ; $i++) {$h=substr($l, $i ,1);if($h==';') //если разделитель {$b[$f][0]=$d; $d=''; } // заносив первую ячейку и очищаем накопленное. elseif($h=="\n" or $i==$a-1) // если новая строка или конец переменной {$b[$f][1]=$d;$b[$f][2]=''; $d=''; $f++;} // заносим во вторую ячейку имя файла, сразу формируем третью ячейку для итогового имени (точно не в этом дело) . ну и двигаем индекс массива else $d.=$h; //иначе рабочий процесс накопления символов до разделителя } //foreach ($b as $as) {var_dump($as); echo '<br>';} return $b; } --- Добавлено --- оно работает правильно! до return массив нормальный, после приходит только кусок. --- Добавлено --- Код (Text): //foreach ($b as $as) {var_dump($as); echo '<br>';} // вот тут все правильно, return $b; } $b=listr('c:\OSPanel\domains\localhost'); //foreach ($b as $as) {var_dump($as); echo '<br>';} //вот тут уж все, даже если не массив. а строка! названия массива менял тут, путь через точку обозначал. объявлять пробовал до цикла. Здесь что-то мне неведомое --- Добавлено --- у меня задача не делать как угодно, а запихивать, что можно, и изучать. Может какие-то кириллические сочетания ведут так себя.
\ я плюсы изучал до этого, мне в строчку удобнее, иначе я буду в 2 раза дольше все задания выполнять. Ваш код тоже не работает)) Также кусок не приходит, ну дело в символах, наверное. --- Добавлено --- вообще, спасибо всем, но не надо себя утруждать переделкой кода, я уже далеко вперед ушел, так сам бы мог. Написал на всякий случай, может кто-то сталкивался
Возможно. Зависит от файловой системы для указанного пути. Если NTFS, то следует применять мультибайтные функции https://www.php.net/manual/ru/ref.mbstring.php
да я посимвольно разберу, когда будет нужно. В винде на опенсервере это, даже с разрывами строк проблема, приходится конвертить самому. Линь тоже есть, если что
При структуре dir collection ->dir lite ->->file "lite-1.jpg" ->->file "lite-2.jpg" ->->file "lite-3.jpg" ->file additional.jpg ->file "eco.png" ->file "lite" ->file "lite.png" ->file "optim.png" ->file "rigid.png" ->file "strong.png" После вызова в цикле: $c[] = listr($d); $c содержит: PHP: array:8 [▼ 2 => "additional.jpg" 3 => "eco.png" 4 => "lite" 5 => "lite.png" 6 => "optim.png" 7 => "rigid.png" 8 => "strong.png" 9 => array:3 [▼ 0 => array:3 [▼ 0 => "images/collection\lite\" 1 => "lite-1.png" 2 => "" ] 1 => array:3 [▼ 0 => "images/collection\lite\" 1 => "lite-2.png" 2 => "" ] 2 => array:3 [▼ 0 => "images/collection\lite\" 1 => "lite-3.png" 2 => "" ] ] ]
PHP: function listr($a, &$b = []){ $c = array_diff(scandir($a), ['..', '.']); // пути дергаем $l = ''; foreach ($c as $as) { $d = $a . '\\' . $as; if (is_dir($d)) { $c[] = listr($d, $b); } //папки снова отправляем if (preg_match('#\.jpg|\.gif|\.webp|\.png#', $as)) { $l .= $a . '\\;' . $as . "\n"; } //файлы отбираем, закидываем исходный путь и найденный файл через разделитель } $a = strlen($l); $d = ''; $h = ''; $f = count($b); for ($i = 0; $i < $a; $i++) { $h = substr($l, $i, 1); if ($h == ';') { $b[$f][0] = $d; $d = ''; } elseif ($h == "\n" or $i == $a - 1) { $b[$f][1] = $d; $b[$f][2] = ''; $d = ''; $f++; } else { $d .= $h; } } return $b; }
Есть, минимум, пару вопросов к скрипту. Зачем $c[] = listr($d, $b);, если это не будет использоваться далее? Думаю, в контексте данного скрипта, логичнее Код (Text): if (is_dir($d)) { listr($d, $b); continue; } Зачем здесь PHP: if (preg_match('#\.jpg|\.gif|\.webp|\.png#', $as)) { $l .= $a . '\\;' . $as . "\n"; } собирать строку, а дальше ее парсить в массивы? Кода здесь можно собирать результирующий массив.
проблема на моей стороне, да, сейчас через глобальную переменную нашел вложенность массивов, а через массив такое же --- Добавлено --- там ячейки разной длины получаются из-за разной вложенности, я их скидывают в одну строку или файл и потом пересобираю
вот такой же косяк Код (Text): $a=[ [11, [ [11, 32, 13, 44, 55], [31, 42, 53, 66, 75], [12, 26, 33, 45, 52], [15, 22, 35, 64, 57], [21, 52, 32, 44, 38], ], 13, 44, 55], [31, 42, 53, 66, 75], [12, 26, 33, 45, 52], [15, 22, 35, 64, 57], [21, 52, 32, 44, 38], ]; $k=1; $e=[]; function f($a,$k,$e){ foreach ($a as $as){ if(is_array($as)){ $k++;//считаем глубину путей $e[]=$k;//скидываем вариант в массив f($as,$k,$e); //отправляем с новыми данными } } var_dump ($e); return ($e); } $e=f($a,$k,$e); var_dump ($e); //батоны $a=0; foreach ($e as $as) {if ($as>$a) $a=$as; //выбираем большую вложенность } echo $a;
получается, когда массив глобальный --- Добавлено --- похоже, var_dump собирает все в массив глобальный, потом выводит, а по факту все в локальном и последняя ветка приходит. В var_dump дофига лишних данных заметил, видимо, гребет все в подряд, ну, можно и свою функцию вывода через echo сделать, но решение найдено. Мораль - не верьте var_dump ))