Способы переноса файлов в PHP: полный обзор

Раздел: Управление файлами в PHP -> Операции с файлами

Копирование файлов в PHP: методы и примеры

Основным и наиболее простым способом копирования файла в PHP является встроенная функция copy(). Она принимает два обязательных параметра: путь к исходному файлу и путь назначения. При успешном выполнении возвращает true, иначе false.


<?php
$source = 'folder/original.txt';
$dest = 'backup/copy.txt';
if (copy($source, $dest)) {
    echo "Файл скопирован успешно.";
} else {
    echo "Ошибка копирования.";
}
?>
    

Php set file (установка файла в php)

Цель использования: быстрое перенесение файлов в пределах локальной файловой системы без дополнительной обработки. Случай: создание резервной копии, дублирование файла конфигурации.

Типичные ошибки:

  • Файл назначения недоступен для записи (нет прав). Решение: проверить права на целевую директорию с помощью is_writable().
  • Исходный файл не существует. Решение: перед копированием вызвать file_exists() или is_file().
  • Недостаточно места на диске. Решение: перед копированием проверить свободное пространство функцией disk_free_space().

Как скопировать большой файл, не загружая его полностью в память?

При работе с файлами размером в сотни мегабайт или гигабайт функция copy() может потреблять много памяти (зависит от реализации). Более контролируемый способ состоит в открытии обоих файлов в бинарном режиме и копировании данных частями с помощью fread() и fwrite().


<?php
$src = fopen('largefile.bin', 'rb');
$dst = fopen('largefile_copy.bin', 'wb');
if (!$src || !$dst) {
    die("Не удалось открыть файлы.");
}
$chunkSize = 1024 * 1024; // 1 МБ
while (!feof($src)) {
    $data = fread($src, $chunkSize);
    fwrite($dst, $data);
}
fclose($src);
fclose($dst);
echo "Большой файл скопирован.";
?>
    

Php move file (перемещение файла в php)

Цель: копирование файлов произвольного размера с фиксированным потреблением памяти. Случай: передача видеофайлов, дампов баз данных.

Проблемы:

  • При прерывании копирования файл назначения остаётся неполным. Решение: перед началом создавать временный файл и переименовывать его после успешного завершения.
  • Блокировки файлов. Если исходный файл открыт другим процессом на запись, чтение может дать неполные данные. Решение: временная блокировка flock().

Как скопировать файл с проверкой успешности и обработкой ошибок?

Для более надёжного копирования следует проверять каждый шаг и выбрасывать исключения при неудачах.


<?php
function safeCopy($source, $dest) {
    if (!file_exists($source)) {
        throw new Exception("Исходный файл не найден: $source");
    }
    if (!is_readable($source)) {
        throw new Exception("Нет прав на чтение исходного файла.");
    }
    $dir = dirname($dest);
    if (!is_dir($dir)) {
        mkdir($dir, 0755, true);
    }
    if (!is_writable($dir)) {
        throw new Exception("Целевая директория не доступна для записи.");
    }
    if (!copy($source, $dest)) {
        throw new Exception("Не удалось выполнить копирование.");
    }
    return true;
}

try {
    safeCopy('important.doc', 'backup/important.doc');
    echo "Копирование завершено.";
} catch (Exception $e) {
    echo "Ошибка: " . $e->getMessage();
}
?>
    

Check file php (проверка существования файла в php)

Цель: защита от частичного или некорректного копирования. Случай: критичные данные, где каждый сбой должен быть явно обработан.

Распространённые ошибки:

  • Забыли создать целевую директорию, структура может отсутствовать. Решение: использовать mkdir() с рекурсивным флагом.
  • Проверка на существование файла может не обнаружить проблемы с путём. Решение: использовать абсолютные пути или валидацию.

Как копировать файлы с использованием потокового API (stream_copy_to_stream)?

PHP предоставляет функцию stream_copy_to_stream(), которая эффективно переносит данные между двумя потоками. Она особенно удобна, когда один из потоков является HTTP-ресурсом.


<?php
$src = fopen('https://example.com/data.txt', 'rb');
$dst = fopen('local/data.txt', 'wb');
if ($src && $dst) {
    stream_copy_to_stream($src, $dst);
    fclose($src);
    fclose($dst);
    echo "Файл скопирован через поток.";
} else {
    echo "Не удалось открыть потоки.";
}
?>
    

Php copy file (копирование файла в php)

Цель: копирование данных между различными источниками (файлы, HTTP, FTP). Случай: загрузка файлов из интернета, работа с компрессированными потоками.

Проблемы:

  • Для URL необходимо разрешить allow_url_fopen в php.ini или использовать cURL. Решение: настройка php.ini или переход на библиотеку cURL.
  • Функция копирует все до конца потока, что может быть нежелательно при работе с непрерывными потоками. Решение: указать максимальную длину (третий параметр).

Как скачать файл из внешнего источника и сохранить локально?

Внешние файлы (например, изображение с сервера) можно скопировать той же функцией copy(), если включен allow_url_fopen. Для большей гибкости используют контекст потока.


<?php
$url = 'http://example.com/image.jpg';
$local = 'local/image.jpg';
$options = [
    'http' => [
        'method' => 'GET',
        'header' => 'User-Agent: PHP'
    ]
];
$context = stream_context_create($options);
if (copy($url, $local, $context)) {
    echo "Изображение скачано.";
} else {
    echo "Ошибка скачивания.";
}
?>
    

Цель: получение удалённых файлов через HTTP с дополнительными заголовками. Случай: загрузка контента с авторизацией или изменённым User-Agent.

Ошибки:

  • Сервер возвращает код ошибки (404, 403). Функция copy() не различает статус. Решение: предварительно проверить заголовки с помощью get_headers() или использовать cURL.
  • Неверный контекст может привести к блокировке. Решение: проверить наличие stream_context_set_default().

Расширенные примеры копирования файлов

Пример 1: Копирование с контролем целостности (проверка хеша)

После копирования полезно сравнить md5-хеши исходного и результирующего файла для гарантии идентичности.

Пример

<?php
$src = 'data.zip';
$dst = 'backup/data.zip';
if (copy($src, $dst)) {
    if (md5_file($src) === md5_file($dst)) {
        echo "Копирование выполнено без ошибок, хеши совпадают.";
    } else {
        echo "Файлы различаются, копирование повреждено.";
        unlink($dst); // удаляем повреждённую копию
    }
} else {
    echo "Не удалось скопировать файл.";
}
?>
    
Результат: "Копирование выполнено без ошибок, хеши совпадают." или сообщение об ошибке.

Пример 2: Копирование с сохранением времени модификации и прав доступа

Функция copy() не сохраняет метаданные. Для сохранения времени модификации используют touch() и chmod() после копирования.

Пример

<?php
$src = 'script.php';
$dst = 'archive/script.php';
if (copy($src, $dst)) {
    touch($dst, filemtime($src)); // сохраняем время модификации
    chmod($dst, fileperms($src)); // сохраняем права
    echo "Копия создана с оригинальными метаданными.";
}
?>
    
Результат: вывод сообщения, файл скопирован с атрибутами.

Пример 3: Пакетное копирование файлов из списка с журналированием ошибок

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

Пример

<?php
$files = ['a.txt', 'b.txt', 'missing.txt'];
$destDir = 'backup/';
$errors = [];
foreach ($files as $file) {
    if (!file_exists($file)) {
        $errors[] = "Файл $file не существует.";
        continue;
    }
    if (copy($file, $destDir . basename($file))) {
        echo "Скопирован: $file\n";
    } else {
        $errors[] = "Ошибка копирования $file.";
    }
}
if ($errors) {
    file_put_contents('copy_errors.log', implode("\n", $errors));
}
?>
    
Результат: вывод успешных или сообщения об ошибках, запись в файл copy_errors.log.

Пример 4: Копирование через FTP с помощью ftp_get

Для загрузки файла с FTP-сервера лучше использовать специализированные функции FTP.

Пример

<?php
$ftp_server = 'ftp.example.com';
$ftp_user = 'user';
$ftp_pass = 'pass';
$remoteFile = '/public_html/data.txt';
$localFile = 'local_data.txt';

$conn = ftp_connect($ftp_server);
if (!$conn) {
    die("Не удалось подключиться к FTP.");
}
if (!ftp_login($conn, $ftp_user, $ftp_pass)) {
    die("Ошибка авторизации.");
}
ftp_pasv($conn, true);
if (ftp_get($conn, $localFile, $remoteFile, FTP_BINARY)) {
    echo "Файл успешно скачан по FTP.";
} else {
    echo "Ошибка при FTP-копировании.";
}
ftp_close($conn);
?>
    
Результат: вывод о успехе или ошибке.

Пример 5: Копирование с эксклюзивной блокировкой (для конкурентного доступа)

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

Пример

<?php
$src = 'shared.dat';
$dst = 'shared_copy.dat';

$handle = fopen($src, 'rb');
if ($handle) {
    if (flock($handle, LOCK_SH)) { // разделяемая блокировка
        $destHandle = fopen($dst, 'wb');
        if ($destHandle) {
            stream_copy_to_stream($handle, $destHandle);
            fclose($destHandle);
        }
        flock($handle, LOCK_UN);
    }
    fclose($handle);
    echo "Копирование завершено с блокировкой.";
} else {
    echo "Не удалось открыть исходный файл.";
}
?>
    
Результат: сообщение о завершении.

Копирование файла в PHP - comments

En
Php copy file (php)