2016-11-13 2 views
3

Например, я хочу постоянно следить за каталогом за наличие файлов .xml.Как постоянно просматривать каталог для наличия файлов с определенным расширением?

Как только файл .xml находится в этом каталоге, программа должна начать обработку файла, например. чтение данных внутри файла, извлечение полезных данных и дальнейшие действия.

Решение Я пытался использовать:

Я попытался использовать бесконечна, а петля к непрерывно контролировать каталог, и используется glob() для проверки наличия файлов с .xml расширением. glob() возвращает массив с путями всех найденных файлов.

Итак, в цикле бесконечного while я проверяю, не верен ли массив, возвращаемый glob(), НЕ-ПУСТОЙ. Если да, то я читаю файл по каждому пути в массиве, возвращаемом glob(), и делаю соответствующую обработку в файле.

Проблема заключается в том, что, когда я запускаю его, я получаю

Fatal error: Maximum execution time of 30 seconds exceeded in C:\xampp\htdocs\Alpha\index.php on line 9 

Я считаю, что это происходит из-за бесконечный цикл While.

Вопросы:

  1. Это мой способ решения моей проблемы хороший способ?

  2. Что следует сделать для обхода вышеуказанной ошибки?

+1

Вы можете использовать javascript 'Server Sent Events' clientside и бесконечный цикл на стороне сервера скриптов PHP. Клиент js подключается к скрипту PHP и получает любые сообщения «Event-Stream», выводимые PHP. Это будет выполняться только при инициировании соединения с клиентом, тогда как задание cron будет работать независимо. – RamRaider

ответ

2

В качестве примера использования SSE для достижения Вашего заявленного намерения мониторинга каталога

РНР-скрипт, который делает в каталоге сканирование - в данном примере это простой glob, но может быть гораздо более сложным, с использованием recursiveIterator и т.д.

<?php 
    /* 
     sse.php 
    */ 
    set_time_limit(0); 
    ini_set('auto_detect_line_endings', 1); 
    ini_set('max_execution_time', '0'); 
    ob_end_clean(); 

    /* -- set headers -- */ 
    header('Content-Type: text/event-stream'); /* !important! */ 
    header('Cache-Control: no-cache'); 
    header('Access-Control-Allow-Credentials: true'); 
    header('Access-Control-Allow-Methods: GET'); 
    header('Access-Control-Expose-Headers: X-Events'); 

    /* -- utility function to send formatted sse message -- */ 
    if(!function_exists('sse_message')){ 
     function sse_message($evtname='dirmon', $data=null, $retry=1000){ 
      if(!is_null($data)){ 
       echo "event:".$evtname."\r\n"; 
       echo "retry:".$retry."\r\n"; 
       echo "data:" . json_encode($data, JSON_FORCE_OBJECT|JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS); 
       echo "\r\n\r\n"; 
      } 
     } 
    } 

    /* How often messages will be pushed to the client app */ 
    $sleep = 5; 

    /* The directory to monitor */ 
    $dir = 'c:/temp/'; 

    /* The name of the event to monitor in js client app */ 
    $evt = 'dirmon'; 


    while(true){ 
     if(connection_status() != CONNECTION_NORMAL or connection_aborted()) { 
      break; 
     } 

     /* Methods here to scan directory and produce data to send */ 
     $files=glob($dir . '*.xml'); 
     $count = count($files); 

     $payload=array(
      'dir' => $dir, 
      'files' => $count 
     ); 

     /* -- prepare and send sse message -- */ 
     sse_message($evt, $payload); 

     /* -- Send output -- */ 
     if(@ob_get_level() > 0) for($i=0; $i < @ob_get_level(); $i++) @ob_flush(); 
     @flush(); 

     /* wait */ 
     sleep($sleep); 
    } 

    if(@ob_get_level() > 0) { 
     for($i=0; $i < @ob_get_level(); $i++) @ob_flush(); 
     @ob_end_clean(); 
    } 
?> 

клиент страница

<!doctype html> 
<html> 
    <head> 
     <title>SSE</title> 
     <script type='text/javascript'> 
      var count=0; 
      function bindEvtSource(){ 

       var evt='dirmon'; 
       var url='/sse.php'; 

       if (!!window.EventSource) { 

        var evtSource = new EventSource(url); 

        evtSource.addEventListener('open', function(e){ 
         console.log(e.type); 
        },false); 

        evtSource.addEventListener('error', function(e){ 
         console.error('%o %s',e,e.type); 
        },false); 

        evtSource.addEventListener(evt, function(e){ 
         var json=JSON.parse(e.data); 
         var files=json.files; 
         if(files!=count) { 
          count=files; 
          alert('contents changed - process changes! Send Ajax Request? etc etc'); 
         } 
         document.getElementById('dirdata').innerHTML=e.data; 
        },false); 



       } else { 
        alert('Server Sent Events are not supported in this browser'); 
       } 
      } 
      document.addEventListener('DOMContentLoaded', bindEvtSource, false); 
     </script> 
    </head> 
    <body> 
     <div id='dirdata'></div> 
    </body> 
</html> 

Вы можете использовать ответ, чтобы затем выполнить дальнейшие действия, инициировав функцию в js - то есть: отправить Ajax-запрос на скрипт, который будет выполнять любую требуемую обработку (события, отправленные сервером, однонаправлены, и вы можете отправлять/получать только Получать!)

+0

Большое вам спасибо за ваш ответ. Сейчас я узнаю о работе CRON, потому что я начал с нее, прежде чем увидел ваш ответ. Поскольку я новичок, это занимает некоторое время. Как только я закончу, я попробую ваш ответ и прочитаю о скриптах сервера. Тогда я приму свой ответ. Упростить его прямо сейчас – Solace

Смежные вопросы