За последние 24 часа нас посетили 17543 программиста и 1727 роботов. Сейчас ищут 952 программиста ...

Обход директории и запись файлов в БД

Тема в разделе "PHP для новичков", создана пользователем СергейЧИТА, 17 ноя 2014.

  1. СергейЧИТА

    СергейЧИТА Новичок

    С нами с:
    4 ноя 2014
    Сообщения:
    123
    Симпатии:
    0
    Не получается написать скрипт, который cron'ом запускается, просматривает определённую директорию,записывает имена файлов в массив и далее элементы массива записывает в соответсвующую таблицу в БД под mysql

    Код (Text):
    1.  
    2. <?php
    3.             $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('/image/'), RecursiveIteratorIterator::CHILD_FIRST);
    4.             $db1=mysqli_connect("localhost","e18366_dbuser","password1","e18366_db");
    5.             $query1="INSERT INTO `e18366_db`.`mesto` (`contetnimg`, `opismesto`, `otziv`) VALUES ('/image/$iterator', 'картинка', 'отсутствует')";
    6.             $result=mysqli_query($db1,$query1);
    7.             if (!$result){
    8.             echo "No INSERT NAMEJPG for BD_mesto";
    9.             }
    10.             mysqli_close($db1);
    11. ?>
    отругивается вот на эту строчку
    Код (Text):
    1.  
    2. $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('/image/'), RecursiveIteratorIterator::CHILD_FIRST);
    пишет
     
  2. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    с английским беда? всё что он хочет - он пишет доступным языком. проверяй то на что он ссылается.
     
  3. СергейЧИТА

    СергейЧИТА Новичок

    С нами с:
    4 ноя 2014
    Сообщения:
    123
    Симпатии:
    0
    как я понял он почему-то смотрит в /home/e18366/public_html/site.ru/index.php, хотя мне нужен список имён и расширений файлов в директории /home/e18366/public_html/site.ru/image/ и занести этот список в БД по строкам в соответствующее поле
    почитав функцию используемую RecursiveIteratorIterator, не могу понять почему смотрит в директорию /home/e18366/public_html/site.ru/ вместо /home/e18366/public_html/site.ru/image/ и как результат естественно не находит файлов -пишет No such file or directory'
     
  4. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    нет, он там не смотрит
    он смотрит
    ты просто не знаешь про абсолютные и относительные пути
    то есть он вообще не смотрит в ту директорию в которую ты думаешь. понимаешь? вообще. он работает как ты указал. абсолютно. в корне сервера каталог имейдж.
     
  5. СергейЧИТА

    СергейЧИТА Новичок

    С нами с:
    4 ноя 2014
    Сообщения:
    123
    Симпатии:
    0
    подправил сл образом
    Код (Text):
    1.  
    2. $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('/home/e18366/public_html/site.ru/image/'), RecursiveIteratorIterator::CHILD_FIRST);
    выдал вот это теперь:
    т.е. объект класс RecursiveIteratorIterator не может преобразован быть в строку
    смотрю мануал на RecursiveIteratorIterator
    http://php.ru/manual/class.recursiveiteratoriterator.html
    не могу понять почему не преобразовывает-должен же вроде...запутался
     
  6. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    а ты вообще понимаешь что ты делаешь когда применяешь подобные штуки? это называется классы но для тебя это всё темный лес поэтому я для твоего удобства буду называть это штуками.
     
  7. sergeyKh

    sergeyKh Новичок

    С нами с:
    12 ноя 2013
    Сообщения:
    2
    Симпатии:
    0
    Здравствуйте, СергейЧИТА, вообще то Ganzal прав, для начала Вам было бы не лишним почитать об объектно-ориентированном подходе и о средствах PHP для применения ООП. В $iterator Вы получаете объект, в котором содержатся файлы, пути к этим файлам, директории, для которых Ваша директория image является родительской, сама эта директория image, и этот объект нельзя использовать так как у Вас:
    Код (Text):
    1. $query1="INSERT INTO `e18366_db`.`mesto` (`contetnimg`, `opismesto`, `otziv`) VALUES ('/image/$iterator', 'картинка', 'отсутствует')";
    Для понимания Вы можете пробежаться в цикле по объекту и вывести все его содержимое на экран.
    Для создания SQL запроса для записи в базу данных также можно организовать цикл, правда сначала из объекта необходимо удалить ненужные Вам элементы.
    Кроме того, непонятно как будет обновляться Ваша директория, если Вы к существующим там файлам будете добавлять новые, то каждый раз при запуске Ваш скрипт выберет все элементы и новые, и старые, которые уже, возможно, записаны в базу данных, получите целую 'кучу' повторяющихся записей.
     
  8. СергейЧИТА

    СергейЧИТА Новичок

    С нами с:
    4 ноя 2014
    Сообщения:
    123
    Симпатии:
    0
    Посидев немного подумав, почитал мануалы...вообщем вот такой скрипт слоял:
    Код (Text):
    1.  
    2. <?php
    3. //Подключение к БД
    4.     mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    5.     $db=mysqli_connect("localhost","e18366_dbuser","passwd1","e18366_db");
    6. //Определение директории для обхода  
    7.     $dirimg="/image/";
    8. //Определение массива для имён файлов в директории
    9.     $a=array();
    10. //Условие, что выбрана именно директория, а не файл
    11.     if (is_dir($dirimg)){
    12. //если ссылка(указатель) на директoрию (проверка доступности)при её открытии-условие истина, то далее
    13.         if ($ukdirimg = opendir($dirimg)){
    14. //Выполняем дальнейшие действия до тех пор пока можем видеть элемент(файл) в указанной директории
    15.             while (($file=readdir($ukdirimg))!==false){
    16. //              array_push($a, $dirimg.$file);
    17. //Заполняем массив для имён файлом непосредственно именами хранящихся файлов
    18.                 array_push($a, $file);
    19.                 var_dump($file);
    20.             }
    21. //Закрываем директорию после чтения имён файлов в ней
    22.         closedir($ukdirimg);
    23.         }
    24.    
    25.     }
    26. //Перебираем все сохранённые имена файлов в массиве и вставляем их в поле в БД
    27.     foreach ($a as $i => $filename){
    28.     $query="INSERT INTO `e18366_db`.`mesto` (`idmesto`, `contetnimg`, `opismesto`, `otziv`) VALUES (NULL, '". mysql_real_escape_string($filename)."', 'отличное место', 'отзыв положительный')";
    29.         echo mysql_error();
    30.         $result=mysqli_query($db,$query);
    31.     }
    32.  
    33.    
    34. /*
    35. while ($date = mysql_fetch_assoc($result)){
    36.         //После предыдущей строчки пишет Warning: mysql_fetch_assoc() expects parameter 1 to be resource, null given in /home/e18366/public_html/site.ru/index.php on line 35
    37.     $query2="INSERT INTO `e1836_db`.`mesto` (`idmesto`, `contetnimg`, `opismesto`, `otziv`) VALUES (NULL, '".$date['contetnimg']."', 'fs', 'sdf')";
    38.     $result2=mysqli_query($db,$query3);
    39.     //Пытаюсь вывести для отладки на экран, но не выводит
    40.     echo 'Файл в БД добавлен- '.$date['contetnimg'];
    41.     var_dump($date['contetnimg']);
    42.     var_dump(mysql_error());
    43.     }
    44.  
    45. */
    46.  
    47.  
    48. //Проверяем корректность вставки имён файлов из директории в БД
    49.     $query3="SELECT * FROM `mesto`";
    50.     echo mysql_error();
    51.     $result3=mysqli_query($db,$query3);
    52. //Выводит информацию о переменной
    53.     var_dump($result3);
    54. //Закрываем сеанс работы с БД   
    55.     mysqli_close($db);
    56. ?>
    На экран в браузере выдаёт вот это:
    В директории /home/e18366/public_html/site.ru/image/ имеются файлы-изображения JPG. В менеджере (phpmyAdmin) я таблицу mesto вычистил до запуска скрипта. После запуска таблица не заполнилась((
    как по коду видно, пытался несколько вариантов, но безуспешно...не могу понять где подправить и как(т.к. вариантов нет)
    я думал об этом, но пока это сл задача, сейчас же я просто хочу хотя бы один раз заполнить...далее думаю будет некое условие нужно вписывать о проверке кандидата вставляемой строчки и наличие аналогичной строчки уже в БД, если её нет-то insert, если имеется-то insert не нужно делать-значит уже сведения об этой картике имеются в БД.
     
  9. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    эх, жалко ты бросил конкретную реализацию на итератерах ковырять. впрочем, "правильнее" - через самописный итератор сделать.
    почему "правильнее"? давай сначала про свои итераторы.

    чтоб рекурсивно обойти файловую систему нужно 1. взять некоторый каталог, 2. прочитать его, 3. для каждого элемента-файла - записать в память, 4. для каждого элемента-каталога - рекурсивно вызвать эту же последовательность начиная с пункта 1. ну и на каждой итарации 2 нужно будет отсеивать . и .. (сам знаешь зачем). то есть получается достаточно "длинная" функция. и по большей части интерфейс этой функции будет таким как удобно ее создателю. то есть никакой стандартизации.
    допустим список файлов есть, ок. но нам к примеру надо фильтровать по какому-то условию. значит либо переписывать саму функцию либо делать пост-фильтрацию её выходного значения. в любом случае это будет код уровня пользователя... типа медленный.

    и тогда они придумали итератор файловой системы. вот честно не знаю чего они с ним сделали но то что вроде как встроено в ядро пыха работает почему-то медленнее чем самописная функция. не отрицаю что руки могут быть мутированы у меня и тот бенчмарк который я когда-то проводил упирался именно в реализацию мною понятой работы с итератором. но результаты были плачевные. а потом я пошел по интернету и нашел что много у кого ровно такой же неожиданный результат. глубже копать не стал. болт забил и дальше живу...
    суть итератора в том что он позволяет тебе не писать лишней рекурсивной функции а взять готовый инструмент языка. на странице мана (только не той которую ты привел а на настоящем сайте) есть два примера работы с итератором:

    Код (Text):
    1. $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
    2. foreach($objects as $name => $object){
    3.     echo "$name\n";
    4. }
    понимаешь как надо было делать? тогда бы и не словил ошибку Catchable fatal error: Object of class RecursiveIteratorIterator could not be converted to string

    второй вариант:
    Код (Text):
    1. $Directory = new RecursiveDirectoryIterator('path/to/project/');
    2. $Iterator = new RecursiveIteratorIterator($Directory);
    3. $Regex = new RegexIterator($Iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH);
    ищет все дот-пи-эйч-пи внутри указанного пути. далее потом итерируешь итератор как в примере 1 - там уже только файлы пхп гарантированны.

    очень просто парой строк получить список файлов. ок. есть фильтрация по имени. ок. если надо дополнительную фильтрацию - по датам, размеру, владельцам, этцетера - в цикле итерации итератора соответствующие проверки делать. просто, красиво. но почему-то дико медленно... поэтому своя рекурсивная функция - "правильнее". по крайней мере быстрее.
     
  10. СергейЧИТА

    СергейЧИТА Новичок

    С нами с:
    4 ноя 2014
    Сообщения:
    123
    Симпатии:
    0
    Это я где-то читал на каком-то сайте...обсуждения...поэтому я вот и решил реализовать самостоятельно, так как там было написано, что если даже брать уже изобретённый велосипед с функцией из-под коробки пыха и будет всё работать, но в действительности по непонятным причинам рабоать будет медленно...вот..
    поэтому я вроде всё старался логично реализовать, но скрипт после запуска вроде отрабатывает без ошибок, однако если посмотреть через менеджер PhpMyAdmin а строки не добавились(кол-во строк = кол-ву файлов jpg в директории /image/)...пробовал различные варианты, но так и не могу исправить
    вот здесь что-то не до конца дописал или не могу понять почему здесь не отрабатывает-по логике (как я думаю) в этом месте должны быть вставка в БД-в том числе должна создаться соотв. кол-во строк с данными о картинке(id_img (счётчик на уровне БД), имя файла(напримр 1.jpg-который именно в папке /image/1.jpg лежит), описание текстовое(пока для всех одинаковое), отзыв(тоже пока одинаковый для всех)....но после выполнения скрипта-результата не вижу в БД((
    Код (Text):
    1.  
    2. //Перебираем все сохранённые имена файлов в массиве и вставляем их в поле в БД
    3.    foreach ($a as $i => $filename){
    4.      $query="INSERT INTO `e18366_db`.`mesto` (`idmesto`, `contetnimg`, `opismesto`, `otziv`) VALUES (NULL, '". mysql_real_escape_string($filename)."', 'отличное место', 'отзыв положительный')";
    5.        echo mysql_error();
    6.       $result=mysqli_query($db,$query);
    7.    }
    а по коду видно ранее, что $a-это массив с именами_файлов.расширение
    Код (Text):
    1.  
    2. ...
    3. array_push($a, $file);
    4. ...
    вот в трёх соснах заблудился(((
     
  11. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.250
    Адрес:
    там-сям
    просто отлаживай свой код! ты должен понимать каждую строку своего накопи-пасченого текста :) используй сообщения об ошибках как подсказки доброго учителя. читай доки по используемым функциям и классам. проверяй промежуточные результаты.

    те, кто подсказывают, уже умеют такие задачки решать как 2*2, а ты как научишся если не будешь сам пытаться?!
     
  12. СергейЧИТА

    СергейЧИТА Новичок

    С нами с:
    4 ноя 2014
    Сообщения:
    123
    Симпатии:
    0
    Вообщем добился полшага вперёд))подумал, почитал, исправил
    вот код который у меня получился (написал с комментами в него)
    Код (Text):
    1.  
    2. <?php
    3.  
    4. //Подключение к БД
    5.     mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    6.     $db=mysqli_connect("localhost","e18366_dbuser","passwd1","e18366_db");
    7. //Определение директории для обхода  
    8.     $dirimg="/home/e18366/public_html/site.ru/image/";
    9.     echo 'Вывод директории для обхода '.$dirimg."<br />";
    10. //Определение обычного (не ассоциативного) массива для имён файлов в директории
    11.     $a=array();
    12. //Условие определён ли массив(существует ли) реально или нет
    13.  
    14.  if(isset($a)) echo "Массив определён <br />";
    15.   else echo "Массив не определён <br />";
    16.  
    17. //Условие, что выбрана именно директория, а не файл
    18.     if (is_dir($dirimg)){
    19.     echo "Условие прошло что объект работы является директория <br />";
    20. //если ссылка(указатель) на директрию при её открытии-условие истина, то далее
    21.         if ($ukdirimg = opendir($dirimg)){
    22. //Выполняем дальнейшие действия пока можем видеть элемент(файл) в указанной директории
    23.             while (($file=readdir($ukdirimg))!==false){
    24. //              array_push($a, $dirimg.$file);
    25. //Заполняем массив для имён файлом непосредственно именами хранящихся файлов
    26. //Условие, что выбран именно файл, а не директория
    27. //              if (is_file($file)){
    28.                     array_push($a, $file);
    29.                     var_dump($file);
    30. //              }
    31.             }
    32. //Закрываем директорию после чтения имён файлов в ней
    33.         closedir($ukdirimg);
    34.         }
    35.     }
    36.     else echo "Условие не прошло что объект работы является директория <br />";
    37. //Количество элементов в массиве
    38. $kol=count($a);
    39. echo 'Кол-во элементов в массиве '.$kol."<br />";
    40.  
    41. //Попытка вывести все элементы массива
    42. for ($i = 1; $i <= count($a) ; $i++)
    43.   {
    44.     echo 'Элемент № '.$i.' значение- '.$a[$i]."<br />";
    45.   }
    46.  
    47.  
    48. //Перебираем все сохранённые имена файлов в массиве и вставляем их в поле в БД
    49.     foreach ($a as $i => $filename){
    50.         echo '<br /> 1 вариант Вывод имя_файла.расширение в виде переменной $filename: '.$filename."";
    51.         echo '<br /> 2 вариант Вывод имя_файла.расширение в виде переменной $a[$i]: '.$a[$i]."<br />";
    52.         $query="INSERT INTO `e18346_db`.`mesto` (`idmesto`, `contetnimg`, `opismesto`, `otziv`) VALUES (NULL, '".$filename."', 'отличное место', 'отзыв положительный')";
    53.         echo mysql_error();
    54.         $result=mysqli_query($db,$query);
    55.     }
    56.  
    57.  
    58. //Проверяем корректность втсавки имён файлов из директории в БД
    59.     $query3="SELECT * FROM `e18366_db`.`mesto`";
    60.     echo mysql_error();
    61.     $result3=mysqli_query($db,$query3);
    62. //Выводит информацию о переменной
    63. $f=1;
    64. while ($date3=mysqli_fetch_assoc($result3)){
    65.     echo '<br / Из базы получен элемент №> '.$f.'значение= '.$date3['contetnimg'];
    66.     $f++;
    67.     }
    68. //Закрываем сеасн работы с БД   
    69.     mysqli_close($db);
    70. ?>
    вот что выдаёт в браузер
    Т.е. у меня в директории /image ещё есть две директории...но мне нужно только список файлов в директории /image...т.е. мне нужно ещё дополнительное условие-проверить кандидат в элемент массива-является ли файлом или нет...если является-то в массив..если нет-переход к слежующему кандидату...
    пробовал различные функции и условия...что-то не получается(( просьба подсказать какую функцию можно использовать, если кандидат-является указатель(как видно по коду пробовал функцию is_file(), но как и понятно не получилось


    и пока думаю как избежать повторных строк(ранее говорилось в комментах)....думал через update...но думаю ещё нужно условие по этому моменту вписать в код...пока паузу возьму по этому моменту...поэтапно
     
  13. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
  14. СергейЧИТА

    СергейЧИТА Новичок

    С нами с:
    4 ноя 2014
    Сообщения:
    123
    Симпатии:
    0
    всё работает вот так реализовал(с учётом закомментированных строк, которыми я отлаживал скрипт):

    корявенько конечно написано, но работает:)в принципе готов закрыть тс)
    Код (PHP):
    1. <?php
    2.  
    3. //Подключение к БД
    4.     mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    5.     $db=mysqli_connect("localhost","e18366_dbuser","passwd1","e18366_db");
    6. //Определение директории для обхода    
    7.     $dirimg="/home/e18366/public_html/site.ru/image/";
    8.     //echo 'Вывод директории для обхода '.$dirimg."<br />"; 
    9. //Определение обычного (не ассоциативного) массива для имён файлов в директории
    10.     $a=array();
    11. //Условие определён ли массив(существует ли) реально или нет
    12. /*
    13.  if(isset($a)) echo "Массив определён <br />"; 
    14.  else echo "Массив не определён <br />"; 
    15. */
    16. //Условие, что выбрана именно директория, а не файл
    17.     if (is_dir($dirimg)){
    18. //    echo "Условие прошло что объект работы является директория <br />"; 
    19. //если ссылка(указатель) на директрию при её открытии-условие истина, то далее
    20.         if ($ukdirimg = opendir($dirimg)){
    21. //Выполняем дальнейшие действия пока можем видеть элемент(файл) в указанной директории
    22.             while (($file=readdir($ukdirimg))!==false){
    23. //                array_push($a, $dirimg.$file);
    24. //Заполняем массив для имён файлом непосредственно именами хранящихся файлов
    25. //Условие, что выбран именно файл, а не директория
    26.                 $kandidat='/home/e18366/public_html/site.ru/image/'.$file;
    27.                 if (is_file($kandidat)){
    28.                     array_push($a, $file);
    29. //                    var_dump($file);
    30.                 }
    31.             }
    32. //Закрываем директорию после чтения имён файлов в ней
    33.         closedir($ukdirimg);
    34.         }
    35.     }
    36. //    else echo "Условие не прошло что объект работы является директория <br />"; 
    37. //echo 'Вывод массива $a: '.$a;//Выводит следующее:"Вывод массива $a: Array"
    38. //Количество элементов в массиве
    39. $kol=count($a);
    40. //echo 'Кол-во элементов в массиве '.$kol."<br />"; 
    41.  
    42. /*
    43. //Попытка вывести все элементы массива
    44. for ($i = 1; $i <= count($a) ; $i++) 
    45.   { 
    46.     echo 'Элемент № '.$i.' значение- '.$a[$i]."<br />"; 
    47.   } 
    48.   
    49. */ 
    50. //Перебираем все сохранённые имена файлов в массиве и вставляем их в поле в БД
    51.     foreach ($a as $i => $filename){
    52. //        echo '<br /> 1 вариант Вывод имя_файла.расширение в виде переменной $filename: '.$filename.""; 
    53. //        echo '<br /> 2 вариант Вывод имя_файла.расширение в виде переменной $a[$i]: '.$a[$i]."<br />"; 
    54.         
    55.         $query4="SELECT count(*) as CCC FROM `e18366_db`.`mesto` where (`contetnimg`='".$filename."')";
    56.         $result4=mysqli_query($db,$query4);
    57.         $date5=mysqli_fetch_assoc($result4);
    58.     //    var_dump($date5);
    59.         if ($date5["CCC"] == 0){
    60.             $query="INSERT INTO `e18366_db`.`mesto` (`idmesto`, `contetnimg`) VALUES (NULL, '".$filename."')";
    61.             echo mysql_error();
    62.             $result=mysqli_query($db,$query);
    63. //            echo 'Есть вставка <br />';
    64.         }
    65. //         else echo "Вставки нет <br />"; 
    66.     }
    67.  
    68.  
    69. //Проверяем корректность вставки имён файлов из директории в БД
    70.     $query3="SELECT * FROM `e18366_db`.`mesto`";
    71.     echo mysql_error();
    72.     $result3=mysqli_query($db,$query3);
    73. //Выводит информацию о переменной
    74. $f=1;
    75. /*
    76. while ($date3=mysqli_fetch_assoc($result3)){
    77.     echo '<br / Из базы получен элемент №> '.$f.'значение= '.$date3['contetnimg'];
    78.     $f++;
    79.     }
    80. */
    81. //Закрываем сеасн работы с БД    
    82.     mysqli_close($db);
    83. ?>