﻿
<h1 class=p1>Работа с каталогами</h1>
<br>
<br>

<p class=text>Для установки текущего каталога применяется функция <b>chdir</b>:</p>
<blockquote><pre>
  <em class=gr>int</em> <b>chdir</b> <em class=gr>( string</em> <b>directory</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Работать с этой функцией можно следующим образом:</p>
<ul>
  <li><b>chdir</b><em class=gr>(</em>"/tmp/data"<em class=gr>);</em><em class=comnt> // переход по абсолютному пути</em></li>
  <li><b>chdir</b><em class=gr>(</em>"./js"<em class=gr>);</em><em class=comnt> // переход в подкаталог текущего каталога</em></li>
  <li><b>chdir</b><em class=gr>(</em>".."<em class=gr>);</em><em class=comnt> // переход в родительский каталог</em></li>
  <li><b>chdir</b><em class=gr>(</em>"~/data"<em class=gr>);</em><em class=comnt> // переходим в /home/пользователь/data (для Unix)</em></li>
</ul>
<p class=text>Чтобы узнать текущий каталог можно воспользоваться функцией <b>getcwd</b>:</p>
<blockquote><pre>
  <em class=gr>string</em> <b>getcwd</b> <em class=gr>( string</em> <b>path</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Для того чтобы открыть каталог используется функция <b>opendir</b>, открывающая каталог, заданный параметром path:</p>
<blockquote><pre>
  <em class=gr>int</em> <b>opendir</b> <em class=gr>( string</em> <b>path</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>После того, как каталог открыт, прочитать его можно функцией <b>readdir</b>:</p>
<blockquote><pre>
  <em class=gr>string</em> <b>readdir</b> <em class=gr>( int</em> <b>dir</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Эта функция возвращает имена элементов, содержащихся в каталоге. Кроме файлов и папок в каталогах находятся также элементы "." и "..". Первый элемент указывает на текущий каталог, а второй - на родительский. Текущий каталог, кстати, можно открыть, указав его имя как ".":</p>
<blockquote><pre>
   <b>$dir</b><em class=gr> =</em> <b>opendir</b> <em class=gr>(</em>"."<em class=gr>);</em>
</pre></blockquote>
<p class=text>После того, как работа с каталогом закончена, его нужно закрыть. Закрытие каталога выполняется при помощи функции <b>closedir</b>:</p>
<blockquote><pre>
  <em class=gr>void</em> <b>closedir</b> <em class=gr>(</em><b>$dir</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Ниже приведен пример, осуществляющий чтение и вывод файлов, находящихся в текущем каталоге.</p>
<blockquote><pre>
<em class=red>&lt;?</em>
  <b>$dir</b><em class=gr> =</em> <b>opendir</b> <em class=gr>(</em>"."<em class=gr>);
  echo</em> "Files:\n"<em class=gr>;
  while (</em><b>$file</b><em class=gr> =</em> <b>readdir</b> <em class=gr>(</em><b>$dir</b><em class=gr>)) 
  {
    echo</em> "<b>$file</b>&lt;br&gt;"<em class=gr>;
  }</em>
  <b>closedir</b> <em class=gr>(</em><b>$dir</b><em class=gr>);</em>
<em class=red>?&gt;</em>
</pre></blockquote>

<p class=text>Заметим, что эта функция возвращает также "." и "..". Если этого делать не нужно, то исключить эти значения можно следующим образом:</p>
<blockquote><pre>
<em class=red>&lt;?</em>
  <b>$dir</b><em class=gr> =</em> <b>opendir</b> <em class=gr>(</em>"."<em class=gr>);
  while ( </em><b>$file</b><em class=gr> =</em> <b>readdir</b> <em class=gr>(</em><b>$dir</b><em class=gr>))
  {
    if (( </em><b>$file</b><em class=gr> !=</em> "."<em class=gr>) && (</em><b>$file</b><em class=gr> !=</em> ".."<em class=gr>))
    {
      echo</em> "<b>$file</b>&lt;br&gt;"<em class=gr>;
    }
  }</em>
  <b>closedir</b> <em class=gr>(</em><b>$dir</b><em class=gr>);</em>
<em class=red>?&gt;</em>
</pre></blockquote>

<p class=text>В качестве примера на рассмотренные функции, давайте создадим скрипт, удаляющий все файлы из каталога c:/temp, к которым не было доступа в течение суток. Функция удаления файлов в этом случае вызывается рекурсивно.</p>
<blockquote><pre>
<em class=red>&lt;?</em>
  <em class=gr>function</em> <b>delTemporaryFiles</b> <em class=gr>(</em><b>$directory</b><em class=gr>)
  {</em>
  <b>$dir</b><em class=gr> =</em> <b>opendir</b> <em class=gr>(</em><b>$directory</b><em class=gr>);
  while (( </em><b>$file</b><em class=gr> =</em> <b>readdir</b> <em class=gr>(</em><b>$dir</b><em class=gr>)))
  {
    if( </em><b>is_file</b> <em class=gr>(</em><b>$directory</b>."/".<b>$file</b><em class=gr>))
    {</em>
      <b>$acc_time</b><em class=gr> =</em> <b>fileatime</b> <em class=gr>(</em><b>$directory</b>."/".<b>$file</b><em class=gr>);</em>
      <b>$time</b><em class=gr> = </em> <b>time</b>();
      if ((</em><b>$time</b><em class=gr> - </em><b>$acc_time</b><em class=gr>) > </em>24*60*60<em class=gr>)
      {
        if ( </em> <b>unlink</b> <em class=gr>(</em><b>$directory.</b>"/".<b>$file</b><em class=gr>))
        {
          echo (</em>"Файлы успешно удалены"<em class=gr>);
        }
      }
    }
    else if ( </em><b>is_dir</b> <em class=gr>(</em><b>$directory</b>."/".<b>$file</b><em class=gr>) && (</em><b>$file</b><em class=gr> !=</em> "."<em class=gr>) && (</em><b>$file</b><em class=gr> != </em>".."<em class=gr>))
    {</em>
      <b>delTemporaryFiles</b> <em class=gr>(</em><b>$directory</b>."/".<b>$file</b><em class=gr>);
    }
  }</em>
  <b>closedir</b> <em class=gr>(</em><b>$dir</b><em class=gr>);
  }</em>
  <b>delTemporaryFiles</b> <em class=gr>(</em>"c:/temp"<em class=gr>);</em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=text>Создание каталогов производится с помощью функции <b>mkdir</b>:</p>
<blockquote><pre>
  <em class=gr>bool</em> <b>mkdir</b> <em class=gr>( string</em> <b>dirname</b>, <em class=gr>int</em> <b>mode</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Эта функция создает каталог с именем dirname и правами доступа mode. В случае неудачи возвращает false. Права доступа задаются только для каталогов UNIX, поскольку в Windows этот аргумент игнорируется. Ниже приведен пример создания каталога test в директории c:/temp.</p>
<blockquote><pre>
<em class=red>&lt;?</em>
  <b>$flag</b><em class=gr> =</em> <b>mkdir</b> <em class=gr>(</em>"c:/temp/test", 0700<em class=gr>);
  if(</em><b>$flag</b><em class=gr>)
  {
    echo(</em>"Каталог успешно создан"<em class=gr>);
  }
  else
  {
    echo(</em>"Ошибка создания каталога"<em class=gr>);
  }</em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=text>Удалить каталог можно с помощью функции <b>rmdir</b>:</p>
<blockquote><pre>
  <em class=gr>bool</em> <b>rmdir</b> <em class=gr>( string</em> <b>dirname</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Теперь удалим только что созданный каталог /test:</p>
<blockquote><pre>
<em class=red>&lt;?</em>
  <b>$flag</b><em class=gr> =</em> <b>rmdir</b> <em class=gr>(</em>"c:/temp/test"<em class=gr>);
  if(</em><b>$flag</b><em class=gr>)
  {
    echo(</em>"Каталог успешно удален"<em class=gr>);
  }
  else
  {
    echo(</em>"Ошибка удаления каталога"<em class=gr>);
  }</em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=text>Функция <b>rmdir</b> удаляет только пустые каталоги. Для того чтобы удалять непустые каталоги, давайте напишем функцию и удалим каталог c:/temp со всеми вложенными папками и файлами:</p>
<blockquote><pre>
<em class=red>&lt;?</em>
  <em class=gr>function</em> <b>full_del_dir</b> <em class=gr>(</em><b>$directory</b><em class=gr>)
  {</em>
  <b>$dir</b><em class=gr> = opendir(</em><b>$directory</b><em class=gr>);
  while((</em><b>$file</b><em class=gr> = readdir(</em><b>$dir</b><em class=gr>)))
  {
    if (</em> <b>is_file</b> <em class=gr>(</em><b>$directory</b>."/".<b>$file</b><em class=gr>))
    {</em>
      <b>unlink</b> <em class=gr>(</em><b>$directory</b>."/".<b>$file</b><em class=gr>);
    }
    else if (</em> <b>is_dir</b> <em class=gr>(</em><b>$directory</b>."/".<b>$file</b><em class=gr>) &&
             (</em><b>$file</b><em class=gr> != </em>"."<em class=gr>) && (</em><b>$file</b><em class=gr> != </em>".."<em class=gr>))
    {</em>
      <b>full_del_dir</b> <em class=gr>(</em><b>$directory</b>."/".<b>$file</b><em class=gr>);  
    }
  }</em>
  <b>closedir</b> <em class=gr>(</em><b>$dir</b><em class=gr>);</em>
  <b>rmdir</b> <em class=gr>(</em><b>$directory</b><em class=gr>);
  echo(</em>"Каталог успешно удален"<em class=gr>);
  }</em>
  <b>full_del_dir</b> <em class=gr>(</em>"c:/temp"<em class=gr>)</em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=text>При рекурсивном вызове функции не передавайте в качестве аргументов записи "." и "..", указывающие на текущий и родительский каталоги, так как в этом случае вы можете потерять ваши данные. Пропускайте эти записи явным образом при помощи условного оператора.</p>
