Понимание функции PHP ftp_alloc()
Узнайте, что делает ftp_alloc() в PHP, её синтаксис, параметры и когда использовать её перед загрузкой файла на FTP-сервер.
FTP-расширение PHP позволяет перемещать файлы между вашим скриптом и удалённым сервером. Функция ftp_alloc() — это вежливое «предупреждение», которое вы отправляете перед загрузкой: она просит сервер зарезервировать дисковое пространство для файла, который вы собираетесь передать. На этой странице рассказывается, что ftp_alloc() реально делает, каков её синтаксис и параметры, почему большинству загрузок она не нужна и как читать диагностическое сообщение, которое она возвращает.
Что делает ftp_alloc()
ftp_alloc() отправляет FTP-команду ALLO (allocate) подключённому серверу с просьбой зарезервировать заданное количество байт для файла, который вы собираетесь загрузить. Функция не создаёт файл, не записывает данные и ничего не передаёт — она лишь спрашивает сервер, может ли он принять файл указанного размера.
Загвоздка: команда ALLO является необязательной в протоколе FTP, и подавляющее большинство современных FTP-серверов её игнорируют и просто возвращают успех вне зависимости от свободного места. Она имела значение только для устаревших систем (мейнфреймы, файловые системы с ориентацией на записи), которым требовалось заранее резервировать хранилище перед записью. Из-за этого результат true не гарантирует, что последующий вызов ftp_put() завершится успешно — воспринимайте ftp_alloc() как рекомендательную проверку, а не реальную гарантию наличия дискового пространства.
Синтаксис
ftp_alloc(FTP\Connection $ftp, int $size, string &$response = null): bool| Параметр | Описание |
|---|---|
$ftp | Ресурс FTP-соединения, возвращённый функцией ftp_connect() или ftp_ssl_connect(). |
$size | Количество байт для резервирования, целое число. |
$response | Необязательный. Передаётся по ссылке; получает текстовый ответ сервера (полезно для журналирования или отладки). |
Возвращаемое значение: true при успехе, false при ошибке. Начиная с PHP 8.1 аргумент $ftp является объектом FTP\Connection, а не ресурсом, однако использование не изменилось.
Как использовать ftp_alloc()
Перед вызовом ftp_alloc() необходимо установить соединение и выполнить аутентификацию. Типичный порядок действий: подключиться, войти в систему, переключиться в пассивный режим, затем выделить пространство.
<?php
$ftp = ftp_connect('ftp.example.com');
ftp_login($ftp, 'username', 'password');
ftp_pasv($ftp, true);
$size = 1024; // bytes you intend to upload
// $response captures the server's reply by reference
if (ftp_alloc($ftp, $size, $response)) {
echo "Allocated $size bytes. Server said: $response\n";
} else {
echo "Allocation failed: $response\n";
}
ftp_close($ftp);ftp_connect() открывает соединение, ftp_login() выполняет аутентификацию, а ftp_pasv() переводит сессию в пассивный режим (более безопасный за межсетевыми экранами и NAT). Третий аргумент ftp_alloc() — $response — заполняется по ссылке необработанным сообщением сервера, что позволяет записать в журнал точную причину отказа в выделении. Наконец, ftp_close() освобождает соединение.
Практический шаблон: проверка перед загрузкой
Наиболее полезна ftp_alloc() в роли защитной проверки перед реальной загрузкой — чтобы можно было завершить работу на раннем этапе на серверах, которые действительно поддерживают ALLO:
<?php
$ftp = ftp_connect('ftp.example.com');
ftp_login($ftp, 'username', 'password');
ftp_pasv($ftp, true);
$localFile = 'report.pdf';
$remoteFile = 'uploads/report.pdf';
$size = filesize($localFile); // bytes the upload will need
if (!ftp_alloc($ftp, $size, $response)) {
echo "Server refused to reserve {$size} bytes: $response\n";
} elseif (ftp_put($ftp, $remoteFile, $localFile, FTP_BINARY)) {
echo "Uploaded $localFile to $remoteFile\n";
} else {
echo "Upload failed even though allocation succeeded.\n";
}
ftp_close($ftp);Здесь filesize() даёт точное количество байт, ftp_alloc() выполняет рекомендательную проверку, а ftp_put() осуществляет фактическую передачу в бинарном режиме.
Распространённые ошибки
- Большинство серверов игнорируют
ALLO. Возвратtrueзачастую означает «команда принята», а не «пространство проверено». Всегда обрабатывайте возможный сбой загрузки после этого. - Функция не создаёт и не загружает файл. Используйте
ftp_put()илиftp_fput()для фактической передачи. - Передавайте
$sizeв байтах. Для реальной загрузки получайте значение с помощьюfilesize(), а не угадывайте. - Читайте
$response. Поскольку он заполняется по ссылке, это единственный способ узнать, почему сервер отказал — записывайте его в журнал. - Функция не сообщит размер удалённого файла. Для этого используйте
ftp_size().
Заключение
ftp_alloc() отправляет FTP-запрос ALLO для резервирования пространства под предстоящую загрузку и возвращает ответ сервера через параметр, передаваемый по ссылке. На практике это рекомендательный шаг, который большинство современных серверов игнорирует, поэтому дополняйте его надлежащей обработкой ошибок вокруг вашего реального вызова ftp_put(). Подробнее о функциях PHP в целом смотрите в главе Функции PHP.