среда, 4 февраля 2009 г.

Работа с файловой системой

В symfony существует много полезных инструментов предзначенных для решения различных задач. И ковыряя "The API Documentation", либо исходники можно найти очень полезные инструменты. В частности в symfony существуют удобные инструменты для работы с файловой системой, о которых я кратенько и напишу.

sfFinder - ищейка

Первый инструмент - это sfFinder. Предзначен для нахождения файлов и директорий. Пожалуй первый метод с которого начинается работа - это type($type), который в общем задает тип искомых элементов и может принимать в качестве параметра:

  • file включает в разультат только файлы
  • dir включает в разультат только директории
  • any и файлы и директории

И последний метод - это пожалуй in($path[, $path2, ..]). Метод который запускает поиск и возвращает результат. Метод in() в параметрах принимает путь, где собственно искать и принимает он переменное кол-во параметров, т.е. можно задать ->in('.'), а можно ->in('apps', 'lib'). Метод этот последний не в том смысле, что больше нет методов, а в том что он как правило завершает цепочку вызовов методов.

Между вызовом ->type() и ->in() вызываются методы задающие параметры поиска. Полный список методов можно найти здесь.
Я же хочу рассмотреть лишь некоторые из них, наиболее часто используемые.

  • ignore_version_control() - игнорировать директории и файлы систем контроля версий, такие как .svn
  • maxdepth($level) - уровень вложенности элементов, глубже которого не искать
  • follow_link() - следовать по сим. линкам
  • relative() - возвращать относительный путь, если не указать, то для всех найденных элементов возвращается полный путь от корня
  • name($patter[, $pattern[, ..]]) - шаблон имени для поиска. Метод принимает переменное кол-во аргументов, т.е. можно задать несколько шаблонов
  • not_name($patter[, $pattern2[, patternN]]) - противоположен предыдущему. Исключает из результатов все элементы у которых имена совпадают с заданными шаблонами
  • mindepth($level) - задает минимальный уровень вложенности
  • size($size[, $size2[, ... $sizen]]) задает шаблон размера файла. Так же может принимать несколько шаблонов. Шаблоны можно задавать вида "< 10K" "> 10M"
  • discard($name[, $name2[, $nameN]]) - удаляет из результатов директорию совпадающую с указанными шаблонами. Принимает переменное кол-во аргументов
  • prune($name[, $name2[, $nameN]]) - удаляет из результатов вложенные элементы директорий совпадающих с задаными шаблонами
  • exec($callable[, $callable2[, $callableN]]) - вызвать функцию для каждого элемента. Например ->exec(array($object, 'methodName'))
Так же все методы принимающие переменное кол-во аргументов, можно вызывать несколько раз, задавая разные параметры, например: $finder->name('*.js', '*.css') то же самое, что и $finder->name('*.js')->name('*.css')

Ну и несколько примеров.


    // найти все классы таблиц моделей
    sfFinder::type('file')
        ->name('*Table.class.php')
        ->ignore_version_control()
        ->in('lib/model/doctrine');

    // найти все классы моделей
    sfFinder::type('file')
        ->name('*.class.php')
        ->not_name('*Table.class.php')
        ->prune('base')
        ->ignore_version_control()
        ->in('lib/model/doctrine');

    // найти все конфигурационные файлы модулей
    sfFinder::type('file')
        ->name('module.yml')
        ->ignore_version_control()
        ->in('apps');

    // найти все загруженные файлы размером больше 10Мб
    sfFinder::type('file')
        ->size('> 10M')
        ->ignore_version_control()
        ->follow_link()
        ->in('web/uploads');

    // найти все js и css файлы
    sfFinder::type('file')
        ->ignore_version_control()
        ->follow_link()
        ->name('*.js', '*.css')
        ->in('web');
    

sfFilesystem

Второй инструмент sfFilesystem представляет базовые методы для манипуляций с файловой системой. Подробнее с методами можно ознакомиться в The API Documentation.

Здесь я лишь коротко рассмотрю некоторые методы.

  • sh($cmd) - выполнить команду оболочки, возвращает результат выполненной команды. Например:
    
            $fs = new sfFilesystem;
            // вывести листинг содержимого текущей дирктории
            echo $fs->sh('ls');
            // выполнить svn update 
            $fs->sh(sprintf('svn update %s', sfConfig::get('sf_root_dir')));
            
  • copy($origin, $target, $options = array()) - копировать $origin в $target. В качестве $options принимает массив с опциями. Допустимая опция - override определяет перезаписывать ли файл, если он существует. Даже если override = false и в $target уже существует копируемый файл, но его дата последней модификации меньше, чем у оригинального, то файл будет перезаписан.
  • mirror($origin, $target, sfFinder $finder, $options = array()) - зеркалировать $origin в $target. При зеркалировании используется в том числе и метод copy($origin, $target, $options) и ему передается массив опций $options. Параметр $finder это экземпляр класса sfFinder, который осуществит поиск элементов в $origin.
  • touch($file) - создать пустой файл.
  • remove($file) - удалить файл или файлы. Принимает строку либо массив
  • rename($origin, $target) - переименовать
  • chmod($files, $mode, $umask = 0000) - изменить права. $files - либо строка путь к файлу/директории, либо массив.
  • symlink($origin, $target, $copyOnWindows = false) - создать символическую ссылку.
  • relativeSymlink($origin, $target, $copyOnWindows = false) - создать символическую ссылку с относительным путем.
  • replaceTokens($files, $beginToken, $endToken, $tokens) - производит замену в файлах. $files - файлы, в которых надо производить замену. $beginToken - открывающий обрамитель, $endToken - закрывающий обрамитель, $tokens - хеш массив замен. Пример:
    
            // во всех файлах .js и .css в директории web
            // заменить вставки "{revision}" на "137"
            $files = sfFinder::type('file')
                        ->ignore_revision_control()
                        ->follow_link()
                        ->name('*.css', '*.js')
                        ->in(sfConfig::get('sf_web_dir'));
            $fs = new sfFilesystem;
            $fs->replaceTokens($files, '{', '}', array('revision' => 137));
            

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

[ читать дальше ]