Архив за Октябрь 2008

Класс для работы с zip-архивами

В PHP 5.2.0 был добавлен встроенный класс для работы с zip архивами на запись и чтение. Сегодня мы рассмотрим несколько примеров его использования. Прежде всего, убедитесь, что включена поддержка библиотеки php_zip.dll. Для этого в файле php.ini нужно убрать символ комментария (;) в начале строки

extension=php_zip.dll

и перезапустить Apache.

Теперь переходим к созданию архива. Все операции с архивом выполняются с помощью объекта ZipArchive. После создания экземпляра класса создаем файл архива с помощью метода open(), который в качестве параметров принимает имя архива и константу, указывающую способ открытия.

Чтобы добавить в архив файл, используем метод addFile(), который принимает два параметра: имя исходного файла и имя, под которым файл будет добавлен в архив. Завершает работу с архивом метод close().

<?php
// Создаем архив
$zip = new ZipArchive;
$res = $zip -> open("archive.zip", ZIPARCHIVE::CREATE);
if ( $res === true ) {
    $zip -> addFromString("string.txt", "Это строка, которая будет записана в файл string.txt, а сам файл помещен в архив");
    // Файл file.txt будет помещен в архив под именем file_zip.txt
    $zip -> addFile("file.txt", "file_zip.txt");
    $zip -> close();
    echo "<p>Файлы добавлены в архив</p>";
} else {
    echo "<p>Ошибка</p>";
}
?>

Напишем небольшой скрипт, который будет создавать архив со всеми файлами из какой-нибудь папки.

<?php
// Создаем архив и добавляем в него все файлы из директории
$zip = new ZipArchive;
$res = $zip -> open("images.zip", ZIPARCHIVE::CREATE);
if ($res === true) {
    $dir = opendir( "./images" );
    chdir( "./images" );
   
    while( $d = readdir( $dir ) ) {
        if( is_file( $d ) ) {
            echo "Добавляем в архив файл ".$d." размером ".filesize( $d )."<br />";
            $zip -> addFile( $d, $d);       
        }
    }
    closedir( $dir );
    $zip -> close();
    echo "<p>Файлы добавлены в архив</p>";
} else {
    echo "<p>Ошибка</p>";
}
?>

Извлечение файла из архива выполняется в три этапа:

  • открываем архив с помощью метода open()
  • извлекаем файлы (метод extractTo())
  • закрываем архив методом close().
<?php
// Извлекаем файлы из архива
$zip = new ZipArchive;
if ( $zip -> open("archive.zip") === true ) {
   $zip -> extractTo("testunzip");
   $zip -> close();
   echo "<p>Архив распакован</p>";
} else {
   echo "<p>Ошибка при извлечении файлов из архива</p>";
}
?>

Обратите внимание, что здесь используется тот же метод open(), что и при создании архива, но константа ZIPARCHIVE::CREATE не указывается. Мы собираемся что-то извлечь из архива, значит, он должен существовать.

Метод extractTo() принимает два параметра: имя папки, в которую будет извлечено содержимое архива и имена объектов, которые необходимо извлечь. В нашем примере второй параметр не задан. Это означает, что будет распаковано все содержимое архива.

С помощью методов объекта ZipArchive можно не только добавлять и извлекать файлы, но и получить информацию об архиве:

// читаем сведения об архиве
echo "Number of files: ".$zip->numFiles."<br/>";
echo "status: ".$zip->status."<br/>";
echo "statusSys: ".$zip->statusSys."<br/>";
echo "filename: ".$zip->filename."<br/>";
echo "comment: ".$zip->comment."<br/>";

Общее представление о DOM. Часть 2

Перемещение по иерархическому дереву DOM

Оказавшись внутри древовидной структуры DOM, вы можете перемещаться по ней вверх и вниз, влево и вправо. Ниже приведен перечень наиболее важных свойств каждого узла DOM:

  • firstChild — первый порожденный узел.
  • lastChild — последний порожденный узел.
  • childNodes — все порожденные узлы (в виде массива).
  • parentNode — родительский узел.
  • nextSibling — следующий узел того же уровня (расположенный справа).
  • previousSibling — предыдущий узел того же уровня (расположенный слева).

Кроме того, свойство nodeName возвращает имя дескриптора узла (или #text для текстовых узлов), тогда как свойство nodeValue возвращает значение узла (что особенно полезно для текстовых узлов).

Получение информации об узле

Как упоминалось выше, информацию об узле можно собирать, что очень удобно для работы с произвольными данными DOM.

Если свойство nodeName предоставляет сведения об имени узла (имя дескриптора или #text для текстовых узлов), то свойство nodeValue полезно только для текстовых узлов, поскольку возвращает конкретный текст в искомом узле. Третью категорию информации об узле предоставляет свойство nodeType. По существу, эта информация касается вида узла. Ниже представлены возможные значения свойства nodeType.

  • 1 — дескриптор
  • 2 — атрибут
  • 3 — текст (включая пробелы)
  • 8 — HTML-комментарий
  • 9 — документ
  • 10 — DTD (определение типа документа)
  • 11 — фрагмент

В приведенном ниже фрагменте кода анализируется простая структура DOM и выводится информация, касающаяся всех порожденных узлов.

<script type="text/javascript">
window.onload = function() {
  var s = "";
  with (document.getElementById("para")) {
    for (var i=0; i<childNodes.length; i++) {
      with (childNodes[i]) {
        s += nodeName + ": " + nodeValue + " (" + nodeType + ")\n";
      }
    }
  }
  window.alert(s);
}
</script>
<p id="para"><em>JavaScript</em> Phrasebook</p>

Удаление элементов

Для удаления узла из иерархического дерева DOM служит метод removeChild(), доступный для каждого узла. Однако следует иметь в виду, что этот метод необходимо вызывать из родительского элемента удаляемого узла, указывая последний в качестве параметра. В приведенном ниже примере отображается список узлов и удаляется последний узел после каждого щелчка на соответствующей кнопке.

<script type="text/javascript">
function removeItem() {
  var list = document.getElementById("list");
  if (list.childNodes.length > 0) {
    list.removeChild(list.lastChild);
  }
}
</script>
<ol id="list"><li>Item</li><li>Item</li><li>Item</li><li>Item</li></ol>
<input type="button" onclick="removeItem();" value="Удалить" />

При наличии непосредственного доступа к удаляемому узлу (с помощью свойства curNode) можно применит следующий подход:

curNode.parentNode.removeChild(curNode);

Если этот код вызывается в функции обработки событий для самого узла, то curNode можно заменить на this.