В первой части мы рассмотрели основы Phake и продемонстрировали способы выполнения задач с его помощью, включая группы, зависимости и аргументы. В этой части мы рассмотрим некоторые примеры реальных приложений Phake. Обратите внимание, что следующие примеры в значительной степени основаны на вещах, которые я обычно делаю вручную, которые требуют какой-то автоматизации.
Загрузка файлов на сервер с помощью задачи Phake
Давайте начнем с написания задачи, которая будет загружать файлы на FTP-сервер.
task('up', function($args){ $host = $args['host']; $user = $args['user']; $pass = $args['pass']; $port = 21; //default ftp port $timeout = 60; //timeout for uploading individual files //connect to server $ftp = ftp_connect($host, $port, $timeout); ftp_login($ftp, $user, $pass); //login to server $root_local_dir = $args['local_path']; $root_ftp_dir = $args['remote_path']; $dir_to_upload = $args['local_path']; $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir_to_upload), RecursiveIteratorIterator::SELF_FIRST); //iterate through all the files and folders in the specified directory foreach($iterator as $path){ //if the current path refers to a file if($path->isFile()){ $current_file = $path->__toString(); $dest_file = str_replace($root_local_dir, $root_ftp_dir, $current_file); $result = ftp_nb_put($ftp, $dest_file, $current_file, FTP_BINARY); //while the end of the file is not yet reached keep uploading while($result == FTP_MOREDATA){ $result = ftp_nb_continue($ftp); } //once the whole file has finished uploading if($result == FTP_FINISHED){ echo "uploaded: " . $current_file . "\n"; } }else{ //if the current path refers to a directory $current_dir = $path->__toString(); //if the name of the directory doesn't begin with dot if(substr($current_dir, -1) != '.'){ //remove the path to the directory from the current path $current_dir = str_replace($root_local_dir, '', $current_dir); //remove the beginning slash from current path $current_dir = substr($current_dir, 1); //create the directory in the server ftp_mksubdirs($ftp, $root_ftp_dir, $current_dir); echo "created dir: " . $current_dir . "\n"; } } } });
Как видно из приведенного выше кода, задача принимает пять аргументов:
- host — имя домена или IP-адрес сервера, на который вы хотите загрузить файлы
- пользователь
- проходят
- local_path — путь, который вы хотите загрузить
- remote_path — путь на сервере
Затем мы передаем эти аргументы методу ftp_connect
. Метод ftp_connect
возвращает поток ftp, который мы затем предоставляем в качестве первого аргумента для метода ftp_login
вместе с именем пользователя и паролем.
После этого мы можем перебрать все файлы в локальном пути, используя рекурсивный итератор итератор и рекурсивный итератор каталога . Итератор рекурсивного итератора принимает рекурсивный объект итератора каталога в качестве первого аргумента, а второй аргумент является константой из класса RecursiveIteratorIterator
. В нашей задаче мы RecursiveIteratorIterator::SELF_FIRST
в качестве второго аргумента. Это указывает итератору включать полный путь в каждую итерацию. Затем мы перебираем все файлы и каталоги по этому пути, используя цикл foreach
.
Мы можем проверить, является ли текущий путь файлом, используя метод isFile
. Если это файл, мы просто преобразуем его в строку, используя магический метод __toString
, и после преобразования мы присваиваем его переменной $current_file
. Далее мы объявляем другую переменную ( $dest_file
), которая будет содержать путь к текущему файлу без пути к корневому каталогу. Это будет использоваться в качестве имени пути для файла, который будет создан на сервере. Когда этим переменным присвоены значения, мы можем предоставить их в качестве аргументов для метода ftp_nb_put
. Это берет поток ftp, который был возвращен методом ftp_connect
ранее как первый аргумент. Второй аргумент — это путь к файлу на сервере, а третий — путь к файлу на вашем компьютере. Четвертый аргумент — это способ передачи; в этом случае мы использовали FTP_BINARY
. Затем мы можем загрузить файл, используя метод ftp_nb_continue
который принимает поток ftp в качестве аргумента. Пока этот метод возвращает константу FTP_MOREDATA
это означает, что конец файла все еще не достигнут, поэтому мы используем цикл while для его проверки. Как только это сделано, он возвращает FTP_FINISHED
.
Если текущий путь ссылается на каталог, мы также конвертируем его в строку, а затем проверяем, начинается ли он с .
потому что, как вы уже знаете, нам нужно исключить каталоги, которые начинаются с .
, Популярным примером является каталог .git
который git использует для хранения истории. Нам необходимо исключить эти каталоги, так как они часто не нужны для запуска приложения или веб-сайта и содержат метаданные или информацию о версиях.
Если текущий каталог не является скрытым, мы удаляем из него корневой путь, поскольку нам не нужно создавать этот путь на сервере. Вот почему мы используем str_replace
для замены str_replace
части пустой строкой.
Как только это будет сделано, мы можем просто вызвать метод ftp_mksubdirs
чтобы создать путь на сервере.
Метод ftp_mksubdirs
принимает поток ftp, корневой каталог на сервере и путь к текущему каталогу. Обратите внимание, что это не метод, встроенный в PHP; сначала мы должны объявить это, прежде чем сможем его использовать. Вот функция:
function ftp_mksubdirs($ftpcon, $ftpbasedir, $ftpath){ @ftp_chdir($ftpcon, $ftpbasedir); $parts = explode('/',$ftpath); foreach($parts as $part){ if(!@ftp_chdir($ftpcon, $part)){ ftp_mkdir($ftpcon, $part); ftp_chdir($ftpcon, $part); } } }
Эта функция создает каталоги, если они еще не существуют. Так что, если вы перейдете по следующему пути:
app / views / users
… И каталог app
, views
и users
еще не существует на сервере, он создает их все.
Вы можете запустить задачу выше, выполнив такую команду в терминале:
phake up host=someserver.com user=me pass=secret local_path=/home/wern/www/someproject remote_path=/public_html
Обратите внимание, что эта задача в основном относится к моему личному случаю использования — вы можете выполнять развертывание другим способом или вам вообще не нужна часть str_replace
. Важно то, что это живое задание, которое я на самом деле использую и которое облегчает мою жизнь.