Войти Регистрация

PHP работа с FTP: создание FTP класса


Как работать с PHP и FTP?

В данной статье нашей целью есть создать FTP класс на PHP, который будет отлично написан и практичен в использовании.

Наши цели

Это очень важно сначала спланировать свою работу и определить наши потребности, которые мы будем воплощать. В этом случае это:

  1. Соединение с сервером
  2. Создание папки на сервере
  3. Загрузка файла на сервер
  4. Изменение папки
  5. Листинг папок
  6. Скачивание файла

Когда и как я могу использовать FTP класс?

Данный класс можно использовать в следующих случаях:

Для автоматической загрузки изображений, например при написании галереи для сайта.

Для бекапа базы данных, а точнее для передачи копий файлов БД на другой сервер. (Хотя этого делать не рекомендуется, потому что FTP протокол не очень защищен).

Для других целей связанных с FTP доступом к вашему приложению.

Этот класс тестировался на многих серверах. Тестирование дало положительные результаты.

Что такое FTP?

FTP, или File Transfer Protocol, за определением Википедии: «Стандарт интернет протокола, используемый для копирования с одного хоста на другой через TCP/IP».

Также, это значит что вы можете копировать файлы из одного компьютера на другой.

Шаг 1 – Подготовка

Начало элементарное. В папке нового проекта, создайте два файла index.php и ftp_class.php.

PHP работа с FTP

index.php это наш главный файл. в котором будем создавать объекты, и вызывать необходимые методы. ftp_class.php это и будет наш FTP класс.

В следующем шаге, мы будем создавать структуру (скелет) нашего класса. Будьте внимательны и прочтите каждый шаг.

Шаг 2 – Настройка FTP класса

Суть объектно-ориентированного программирования (ООП) в том, чтобы сложный код был прост в использовании. Создавая класс (представим, что класс это шаблон) – мы инкапсулируем или структурируем данные. После чего мы можем один и тот же класс использовать снова и снова, без переписывания кода. Вам всего лишь нужно вызвать нужный метод («метод» аналогичен функции класса: function…).

Давайте приступим к созданию нашего FTP класса. Откройте файл ftp_class.php и впишите туда код поданный ниже в примере. Это базовая структура каждого класса. В данном случае я назвал класс «FTPClient».

Функция construct, известная как конструктор, это особый метод, который вызывается автоматически при создании нового объекта.

Class FTPClient  

{  

    // *** Переменныекласса

    public function __construct() { }  

}

Следует отметить, что вначале используется два символа __ для метода construct.

Шаг 3 – Переменные FTP класса

Далее, мы устанавливаем нужные нам переменные класса.

private $connectionId;  

private $loginOk = false;  

private $messageArray = array();

Префикс «private» определяет сферу доступности переменной. В данном случае, это означает, что переменная не может быть доступна за пределами класса.

Переменная $connectionId хранит текущую FTP связь, остальные переменные определяют статусы соединения и информационные сообщения.

Шаг 4 – Информационный лог

Почти в каждом методе, мы будем обращаться к методу «logMessage». Это простая функция, которая обеспечит визуальную связь нашего класса с пользователем.

Обратите внимание, что мы не будем возвращать конкретные сообщения с описанием ошибки, а всего лишь true или false. Это имеет свои преимущества, но все-таки не детализирует проблему.

Итак, добавим следующие два метода. logMessage принимает переменную $message и сохраняет ее в массив класса благодаря этой строке: $this->messageArray[] = $message;

private function logMessage($message)  

{  

    $this->messageArray[] = $message;  

}

Так как, $messageArray это переменная класса, то мы обращаемся к ней через $this->.

В классе, $this касается самого объекта, т.е. класса.

Для получения сообщений мы вызываем метод getMessages.

public function getMessages()  

{  

    return $this->messageArray;  

}

Этот метод является открытым (public) методом. Как упоминалось раньше private/public свойства, касаются видимости переменной или метода. Свойство private означает то, что метод не может быть видимым за областью класса, поэтому мы присвоили свойство public.

Может быть, вы думаете, что можно сделать переменную $messageArray открытой, но это не практично, правильнее сделать это через метод.

Есть множество примеров обработки логовых сообщений, но мы работаем над простым примером, с целью научиться.

Шаг 5 – Соединение с сервером

На этом этапе, мы создадим метод «connect». Он будет соединять нас с FTP сервером.

public function connect ($server, $ftpUser, $ftpPassword, $isPassive = false)  

{

    // *** Set up basic connection  

    $this->connectionId = ftp_connect($server);  

  

    // *** Login with username and password  

    $loginResult = ftp_login($this->connectionId, $ftpUser, $ftpPassword);  

  

    // *** Sets passive mode on/off (default off)  

    ftp_pasv($this->connectionId, $isPassive);  

  

    // *** Check connection  

    if ((!$this->connectionId) || (!$loginResult)) {  

        $this->logMessage('FTP connection has failed!');  

        $this->logMessage('Attempted to connect to ' . $server . ' for user ' . $ftpUser, true);  

        return false;  

    } else {  

        $this->logMessage('Connected to ' . $server . ', for user ' . $ftpUser);  

        $this->loginOk = true;  

        return true;  

    }  

}

Мы передаем в нашем соединении следующую информацию: сервер($server), имя пользователя ($ftpUser), пароль ($ftpPassword) - которая позволит установить связь.

Первая строка метода открывает FTP соединение, с помощью ftp_connect, на указанном нами сервере. Далее мы сохраняем нашу связь в переменной, $connectionId.

Далее передаем логин, пароль и включаем или отключаем пассивный режим. Я советую вам оставить его включенным, однако, если у вас возникнут проблемы с соединением, попробуйте его отключить. Пассивный режим может приводить к небольшим проблемам FTP соединения.

Далее, определяем, если соединение было успешным, мы добавляем запись в лог. Помните: мы используем $this-> для доступа к logMessage(), так как это метод нашего FTP класса.

Шаг 6 – Вызов объекта

Наш FTP класс уже работает, мы можем это проверить! Откройте файл index.php, и добавьте в него следующий код.

Заметьте, что я добавил настройки доступа к FTP серверу в файле index.php. Лучше их вынести в ваш файл конфигурации, но так как это пример, мы это делать не будем. Отредактируйте настройки для своего FTP сервера.

После внесения настроек, мы подключаем FTP класс, с помощью строки include('ftp_class.php'); Следующая строка PHP кода, создает объект FTP класса, и записывает его в переменную $ftpObj. $ftpObj будет использоваться для доступа к различным открытым методам нашего класса. Это достигается с помощью ->, так как показано в примере кода: $ftpObj -> connect, вызвали метод connect и передали ему настройки подключения к FTP серверу.

// *** Впишите сюда ваш хост, имя пользователя и пароль 

define('FTP_HOST', '192.168.1.88');   

define('FTP_USER', 'Blimpf');   

define('FTP_PASS', 'catfish');   

// *** Include the class   

include('ftp_class.php'); 

// *** Create the FTP object   

$ftpObj = new FTPClient(); 

// *** Connect   

$ftpObj -> connect(FTP_HOST, FTP_USER, FTP_PASS);

Как вы видите, подключится к FTP серверу просто!

Определение статуса подключения

В предыдущем примере мы подключились к серверу. Но правильнее будет дополнить код, чтобы пользователь мог видеть сообщения типа: «Подключен», или «Не удалось подключиться». Для этого можно пользоваться поданным ниже примером.

// *** Connect   

if ($ftpObj -> connect(FTP_HOST, FTP_USER, FTP_PASS)) {   

    // *** Then add FTP code here   

    echo 'Подключен';   

} else {   

    echo 'Не удалось подключиться ';   

}
  

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

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

print_r($ftpObj -> getMessages());

Эта строка будет выводить сообщения.

Шаг 7 – Создаем папку

Далее мы создадим метод makeDir. Этот метод будет создавать папки на сервере. Единственным параметром данного метода будет путь с именем папки - $directory. Создается папка с помощью функции ftp_mkdir. Данная функция использует, сохраненный нами, connectionId и переменную $directory для создания папки. Добавьте следующий кодуфайл ftp_class.php:

public function makeDir($directory)   

{   

    // *** If creating a directory is successful...   

    if (ftp_mkdir($this->connectionId, $directory)) {   

        $this->logMessage('Directory "' . $directory . '" created successfully');   

        return true; 

    } else {   

        // *** ...Else, FAIL.   

        $this->logMessage('Failed creating directory "' . $directory . '"');   

        return false;   

    }   

}

Для вызова данного метода, добавьте в ваш index.php файл, следующий код:

$dir = 'photos';

// *** Make directory   

$ftpObj->makeDir($dir);

Переменная $dir это имя папки, в нашем случае это «photos». Следующие строки вызывают метод, который создает папку на сервере.

Если вы получаете сообщение «Доступ запрещен» или ошибку, убедитесь, что вы выбрали уникальное имя папки, прописали правильный путь. Может вам необходимо создавать папку в другой папке, типа /httpdocs, как того требует хостинг.

Шаг 8 – Загрузка файла

Давайте попробуем загрузить в нашу папку фотографию с именем zoe.jpg. При загрузке файла, нам необходимо определить тип загружаемого файла – binary (бинарный) или ascii (текстовый).

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

$asciiArray = array('txt', 'csv');

Далее мы определим расширение нашего файла, сейчас мы протестируем это на asciiтипу файлов. Самый быстрый и простой способ определить расширение с помощью функции explode(). В примере ниже данная функция разбивает имя файла на два кусочка, и хранит их в массиве, причем границей разбиения имени файла является “.”. Далее мы с помощью функции end, выбираем последний элемент массива, который и есть наше расширение. Пример строки смотрите ниже:

$extension = end(explode('.', $fileFrom));

Далее мы проверяем, есть ли расширение в массиве допустимых расширений, с помощью функции in_array. Если находим совпадение в массиве, мы даем значение FTP_ASCII для переменной $mode, в другом случае мы будем думать, что это бинарный файл и значение $modeбудет FTP_BINARY.

in_array($extension, $asciiArray);

ftp_put загружает файл на сервер. Мы передаем в эту функцию: connectionId, путь к папке на сервере ($fileTo), путь к файлу на компьютере ($fileFrom), режим ($mode).

Теперь добавьте данный метод к вашему FTP классу в файле ftp_class.php:

public function uploadFile ($fileFrom, $fileTo)   

{   

    // *** Set the transfer mode   

    $asciiArray = array('txt', 'csv');   

    $extension = end(explode('.', $fileFrom));   

    if (in_array($extension, $asciiArray)) {   

        $mode = FTP_ASCII;   

    } else {   

        $mode = FTP_BINARY;   

    }   

    // *** Upload the file   

    $upload = ftp_put($this->connectionId, $fileTo, $fileFrom, $mode);   

    // *** Check upload status   

    if (!$upload) {   

            $this->logMessage('FTP upload has failed!');   

            return false;   

        } else {   

            $this->logMessage('Uploaded "' . $fileFrom . '" as "' . $fileTo);   

            return true;   

        }   

}

Добавьте следующие строки кода к вашему index.php файлу.

$fileFrom = 'zoe.jpg';   

$fileTo = $dir . '/' . $fileFrom;   

// *** Upload local file to new directory on server   

$ftpObj -> uploadFile($fileFrom, $fileTo);

Видите, как прост FTP класс при взаимодействии PHP с FTP. Все это благодаря объектно-ориентированному программированию. С помощью ООП, наша PHP работа с FTP, становиться проще некуда.

Шаг 9 – Просмотр файлов

Давайте убедимся, что наш файл в папке photo. Мы осуществим это с помощью перемещения в папку photoи вывода ее контента на экран.

 

Создадим метод changeDir, который будет использовать функцию ftp_chdir, для изменения текущей директории на FTP сервере. Пример метода подан ниже, не забудьте поместить его в файл ftp_class.php:

public function changeDir($directory)   

{   

    if (ftp_chdir($this->connectionId, $directory)) {   

        $this->logMessage('Current directory is now: ' . ftp_pwd($this->connectionId));   

        return true;   

    } else {   

        $this->logMessage('Couldn\'t change directory');   

        return false;   

    }   

}

С помощью метода getDirListing мы выведем содержимое текущей папки на монитор. Для этого мы будем использовать функцию ftp_nlist. Текущая директория уже установлена по умолчанию, поэтому мы не будем передавать параметры в функцию.

Если хотите, вы можете изменить директорию, передав переменной $directoryпуть к папке в которой вы хотите просмотреть контент. Переменная $parameters по умолчанию назначена “-la”. Это команда для Linux, что бы вывести более данных о директории на монитор. Вы можете удалить этот параметр или передать пустую строку.

Добавим метод в ftp_class.php:

public function getDirListing($directory = '.', $parameters = '-la')   

{   

    // get contents of the current directory   

    $contentsArray = ftp_nlist($this->connectionId, $parameters . '  ' . $directory);    

    return $contentsArray;   

}

Метод getDirListing возвращает массив, который содержит листинг нашей директории.

Для проверки работы метода добавьте следующий код в файл index.php:

        // *** Change to folder   

        $ftpObj->changeDir($dir);   

        // *** Get folder contents   

        $contentsArray = $ftpObj->getDirListing();   

        // *** Output our array of folder contents   

        echo '  

<pre>';   

        print_r($contentsArray);   

        echo '</pre><p>'; 
 

Ваш результат будет выглядеть таким образом:

 Работа FTP класса

Шаг 10 – Скачивание файла

Теперь приступим к скачиванию файла. Наш метод будет начинаться так, как и uploadFile, в смысле с определения ascii или binary.

Для нашего метода, необходимо будет передавать имя файла на сервере (ну и естественно путь к нему), и новое имя загружаемого файла (имя загруженного файла на вашем компьютере).

Для загрузки файла с FTP сервера, вам необходимо вызвать функцию ftp_get.

ftp_get($this->connectionId, $fileTo, $fileFrom, $mode, 0);

Эта функция принимает следующие параметры: conectionId, путь и имя файла на компьютере (будет перезаписано при совпадении) - $fileTo, путь и имя файла на сервере - $fileFrom, и режим - $mode.

Теперь допишем наш метод для загрузки файла в FTP класс (ftp_class.php):

public function downloadFile ($fileFrom, $fileTo)   

{   

    // *** Set the transfer mode   

    $asciiArray = array('txt', 'csv');   

    $extension = end(explode('.', $fileFrom));   

    if (in_array($extension, $asciiArray)) {   

        $mode = FTP_ASCII;   

    } else {   

        $mode = FTP_BINARY;   

    }   

    // try to download $remote_file and save it to $handle   

    if (ftp_get($this->connectionId, $fileTo, $fileFrom, $mode, 0)) {   

        return true;   

        $this->logMessage(' file "' . $fileTo . '" successfully downloaded');   

    } else {   

        return false;   

        $this->logMessage('There was an error downloading file "' . $fileFrom . '" to "' . $fileTo . '"');   

    }  

}

Так как мы сейчас находимся в папке photo на сервере, нам нет необходимости передавать путь в переменной $fileFrom, мы передадим всего лишь имя файла.

Вставьте этот код в index.php:

$fileFrom = 'zoe.jpg';      // The location on the server   

$fileTo = 'zoe-new.jpg';            // Local dir to save to

// *** Download file   

$ftpObj->downloadFile($fileFrom, $fileTo);

Шаг 11 – Завершение работы

В завершение создания FTP класса, добавим метод __deconstruct. Этот метод закрывает соединение с FTP сервером, когда прекращается работа с классом.

public function __deconstruct()   

{   

    if ($this->connectionId) {   

        ftp_close($this->connectionId);   

    }   

}

Заключение

Отлично мы создали FTP класс для работы с сервером. Я надеюсь, что вы теперь лучше понимаете, как работать с FTP используя PHP. Теперь вы имеете нужную базу знаний и можете расширить класс, дописав в него методы для переименования и удаления файлов и папок, или другие нужные вам методы.

Если есть у вас какие-то замечания по поводу PHP работы с FTP, то будем рады выслушать ваше мнение в комментариях.



Дальше: PHP regexp: примеры регулярных выражений


Дискуссия по теме     3 Комментария 
Добавить комментарий
xander 23.06.2012 в 02:49
"Насколько я понимаю создание класса всегда начинается с функции __construct()," Не всегда. Конструктор вызывается автоматически при объявлении класса. В нем делаются некие действия при создании объекта, присваиваются передаваемые самому классу параметры, и проч. А если он пустой и в нем ничего не делается - то и нафиг оно надо?
xander 22.06.2012 в 04:06
"В завершение создания FTP класса, добавим метод __deconstruct. Этот метод закрывает соединение с FTP сервером, когда прекращается работа с классом." Хм, а помоему деструкторы класса всегда писались как "__destruct()", конструкторы то понятно - "__construct(), но непонятно зачем он тут пустой?
Тарас 22.06.2012 в 22:01
Насколько я понимаю создание класса всегда начинается с функции __construct(), которая его конструирует... а в конце, наверное вы правы, должно быть __destruct()
Просмотров: 9286