W3docs

Понимание функции 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.

Практика

Практика
Что делает функция ftp_alloc() в PHP?
Что делает функция ftp_alloc() в PHP?
Was this page helpful?