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

#php #curl

#php #curl

Вопрос:

Я использую этот код для загрузки файла на мой сервер, используя HTTP POST:

 $ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
$post = array(
    "upload" => '@' . $filepath
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$curl_result = curl_exec($ch);
  

Этот код работает, когда $filepath не содержит пробелов. Однако возможно, что это возможно. Когда я тестирую путь с пробелами, я получаю ошибку curl «не удалось создать данные formpost».

Руководство по curl не говорит мне, что делать, все, что оно дает мне, это имена файлов unix без пробелов. Я попробовал следующее http://curl.haxx.se/mail/archive-2006-01/0079.html вроде так, но мне это тоже не помогло:

 "upload" => '"@' . $filepath . '"'
"upload" => '@"' . $filepath . '"'
  

У кого-нибудь есть идея?

Комментарии:

1. Переименуйте файл, чтобы в имени файла не было пробелов?! Это вариант :-)?

2. Извините, нет, путь также может содержать пробелы, и я не знаю, будет ли у меня папка / tmp на сервере, куда будет помещен этот скрипт .. (для создания локальной копии) 🙁

Ответ №1:

Текущие версии cURL (и PHP-cURL) без проблем обрабатывают пробелы в именах файлов. В старых версиях могли быть ошибки, я не уверен. Убедитесь, что вы используете достаточно свежие версии.

Я могу подтвердить, что пробелы в именах файлов вообще не являются проблемой в PHP 5.2.13 и libcurl / 7.19.4 в Linux.

Сообщение об ошибке, которое вы получаете, такое же, как когда PHP / cURL не может найти файл. Скорее всего, проблемы кроются где-то еще в вашем коде. Возможно, проблема в том, что пробелы в имени файла были экранированы недостаточно или чрезмерно, но, вероятно, это не проблема с самим cURL.

Я бы посоветовал поискать проблему в другом месте вашего кода или создать жестко запрограммированный пример возникновения проблемы (где $filename устанавливается в PHP напрямую, а не считывается откуда-либо еще).

Комментарии:

1. Я использую PHP версии 5.2.9-2 (Windows) с libcurl / 7.19.4 OpenSSL / 0.9.8k zlib / 1.2.3, поэтому я ожидаю, что это тоже сработает. Я попытался установить файл в жестком формате, но это не помогло..

2. Обновление: я вывожу это: echo «file: » . (file_exists(realpath($filepath))? ‘yes’: ‘no’); и получаем «no».. Тем не менее, я могу открыть файл просто отлично, когда я копирую вставляю путь в Explorer.. Загадочно!

3. Хорошо .. исправлено. Я пытался загрузить файл с «c:usersmy имя пользователя». PHP не имеет права входить в эту папку.. итак, да, с помощью «c:temppath с пробелами » это действительно работает!

Ответ №2:

Вам нужен реальный путь

 $filepath = 'D:7 habits copy.txt';
$url = 'http://www.speedyshare.com/upload.php?'.rand(10000000, 99999999);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
$post = array(
    "upload" => '@' . realpath($filepath)
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$curl_result = curl_exec($ch);
echo $curl_result;
  

Работал даже в Windows. Я почти уверен, что это будет работать в системах * NIX

Комментарии:

1. к сожалению, realpath не имеет значения : (

2. что такое ваш curl_errno ($ ch)? Поместите его после предложения curl_exec.

3. Ошибка 26: CURLE_READ_ERROR (26) Возникла проблема с чтением локального файла или ошибка, возвращенная обратным вызовом read. Вероятно, это связано с тем, что php также не может найти файл (см. Другой ответ)..

4. @Tominator Возможно, у вашего веб-пользователя просто недостаточно привилегий для чтения файла, который вы выбрали для загрузки с помощью curl?

5. @Tominator, не могли бы вы предоставить вывод var_export(реальный путь ($ filepath));

Ответ №3:

Я столкнулся с той же проблемой, и я не смог обновить CURL в системе.

Итак, я написал простую escape-функцию, которая выполняла итерации по строке, чтобы заменить пробел на знак, что является традиционным способом представления URL-адресов пробелами.

К моему удивлению, это сработало. 🙂

Код на C :

 #include <algorithm>
#include <string>

std::string s = "";
std::replace(s.begin(), s.end(), ' ', ' ');    
  

Ответ №4:

Вам нужно будет избежать пробелов. Не уверен в синтаксисе, который вы бы использовали, но, возможно, что-то вроде этого:

 'This is the file name with spaces.txt'
  

Для

 'This is the file name with spaces.txt'
  

опять же, я не уверен в синтаксисе, это просто пример

или вам может просто понадобиться добавить кавычки к имени файла, вот так:

 'This is the file name with spaces.txt'
  

Комментарии:

1. Нет, извините, все эти стратегии терпят неудачу : (

Ответ №5:

Поместите целевой файл в переменную, такую как ‘while read’, и передайте переменную в curl команде. Убедитесь, что переменная заключена в двойные кавычки, и curl обработает это.

Например:

 curl -T /PATH/TO/YOUR/FILE/DIRECTORY/"$f"
  

Комментарии:

1. Мой ответ правильный. Я не понимаю, почему он показывает -1. Отключите кинетику произвольным голосованием? любой может легко доказать, что мой ответ работает.