Подтвердить что ты не робот

Может ли кто-нибудь дать мне пример для класса PHP CURLFile?

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

Здесь мой код:

$ch = curl_init("http://www.remotesite.com/upload.php"); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('fileupload' => '@'.$_FILES['Filedata']['tmp_name'])); 
echo curl_exec($ch);        

Сервер работает под управлением PHP 5.5.0, и похоже, что @filename устарело в PHP >= 5.5.0, как указано здесь под CURLOPT_POSTFIELDS, и поэтому я получаю эту ошибку:

Deprecated: curl_setopt(): The usage of the @filename API for file uploading is deprecated. Please use the CURLFile class instead in ... 

Интересно, что в этом классе на php.net нет абсолютно ничего, кроме основного обзора класса. Нет примеров, описания методов или свойств. Это в основном пустое здесь. Я понимаю, что это совершенно новый класс, практически без документации и очень мало реального использования, поэтому практически ничего не стоит в поиске в Google или здесь, в Stackoverflow этого класса.

Мне интересно, есть ли кто-нибудь, кто использовал этот класс CURLFile, и может помочь мне или дать мне пример использования его вместо @filename в моем коде.

Edit:

Я также хотел добавить свой код "upload.php"; этот код будет работать с традиционным методом @filename, но больше не работает с кодом класса CURLFile:

$folder = "try/";
$path = $folder . basename( $_FILES['file']['tmp_name']); 
if(move_uploaded_file($_FILES['file']['tmp_name'], $path)) {
echo "The file ".  basename( $_FILES['file']['tmp_name']). " has been uploaded";
}

Final Edit:

Требуется добавить Final/Working code для других, которые ищут похожий рабочий пример малодокументированного класса CURLFile...

curl.php(локальный сервер)

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label> <input type="file" name="Filedata" id="Filedata" /> 
<br />
<input type="submit" name="submit" value="Submit" />
</form>

<?php
if ($_POST['submit']) {
    $uploadDir = "/uploads/";
    $RealTitleID = $_FILES['Filedata']['name'];
    $ch = curl_init("http://www.remotesite.com/upload.php"); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $args['file'] = new CurlFile($_FILES['Filedata']['tmp_name'],'file/exgpd',$RealTitleID);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $args); 
    $result = curl_exec($ch);       
}
?>

upload.php(удаленный сервер)

$folder = "try/";
$path = $folder . $_FILES['file']['name']; 
if(move_uploaded_file($_FILES['file']['tmp_name'], $path)) {
echo "The file ".  basename( $_FILES['file']['name']). " has been uploaded";
} 
4b9b3361

Ответ 1

В RFC есть фрагмент кода: https://wiki.php.net/rfc/curl-file-upload

curl_setopt($curl_handle, CURLOPT_POST, 1);
$args['file'] = new CurlFile('filename.png', 'image/png', 'filename.png');
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args);

Вы также можете использовать, казалось бы, бессмысленную функцию curl_file_create( string $filename [, string $mimetype [, string $postname ]] ), если у вас есть фобия создания объектов.

curl_setopt($curl_handle, CURLOPT_POST, 1);
$args['file'] = curl_file_create('filename.png', 'image/png', 'filename.png');
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args);

Ответ 2

Спасибо за вашу помощь, используя ваш рабочий код, я смог решить мою проблему с php 5.5 и Facebook SDK. Я получил эту ошибку из кода в классе sdk.

Я не думаю, что это счет как ответ, но я уверен, что есть люди, которые ищут эту ошибку, как я, связанную с facebook SDK и php 5.5

В случае, если у кого-то такая же проблема, решение для меня заключалось в том, чтобы изменить небольшой код из base_facebook.php, чтобы использовать класс CurlFile вместо @filename.

Поскольку я вызываю sdk из нескольких мест, я только что изменил несколько строк sdk:

В методе, называемом makeRequest, я сделал это изменение:

В этой части кода:

if ($this->getFileUploadSupport()){
    $opts[CURLOPT_POSTFIELDS] = $params;
} else {
    $opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&');
}

Измените первую часть (с включенной загрузкой файла) на:

if ($this->getFileUploadSupport()){
  if(!empty($params['source'])){
     $nameArr = explode('/', $params['source']);
     $name    = $nameArr[count($nameArr)-1]; 
     $source  = str_replace('@', '', $params['source']);
     $size    = getimagesize($source); 
     $mime    = $size['mime'];
     $params['source'] = new CurlFile($source,$mime,$name);
  }

  if(!empty($params['image'])){
     $nameArr = explode('/', $params['image']);
     $name    = $nameArr[count($nameArr)-1]; 
     $image   = str_replace('@', '', $params['image']);
     $size    = getimagesize($image); 
     $mime    = $size['mime'];
     $params['image'] = new CurlFile($image,$mime,$name);
  }
  $opts[CURLOPT_POSTFIELDS] = $params;
} else {
    $opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&');
}

Возможно, это может быть улучшено при синтаксическом анализе каждого параметра $param и поиске значения "@" в значении.. но я сделал это только для источника и изображения, потому что это было то, что я необходимо.

Ответ 3

FOR curl_setopt(): использование API @filename для загрузки файлов устарело. Пожалуйста, вместо этого используйте класс CURLFile

$img='image.jpg';

$data_array = array(
        'board' => $board_id,
        'note' => $note,
        'image' => new CurlFile($img)
    );

$curinit = curl_init($url);
     curl_setopt($curinit, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($curinit, CURLOPT_POST, true);
     curl_setopt($curinit, CURLOPT_CUSTOMREQUEST, "POST");
     curl_setopt($curinit, CURLOPT_POSTFIELDS, $data_array);
     curl_setopt($curinit, CURLOPT_SAFE_UPLOAD, false);
     $json = curl_exec($curinit);
     $phpObj = json_decode($json, TRUE);  
     return $phpObj;

Ответ 4

CURLFile был объяснен намного выше, но для простого переноса одного файла, где вы не хотите отправлять многостраничное сообщение (не требуется для одного файла, а некоторые API не поддерживают multipart), выполняется следующее.

$ch = curl_init('https://example.com');

$verbose = fopen('/tmp/curloutput.log', 'w+'); // Not for production, but useful for debugging curl issues.

$filetocurl = fopen(realpath($filename), 'r');

// Input the filetocurl via fopen, because CURLOPT_POSTFIELDS created multipart which some apis do not accept.

// Change the options as needed.

$options = array(
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => array(
        'Content-type: application/whatever_you_need_here',
        'Authorization: Basic ' . $username . ":" . $password) // Use this if you need password login
    ),
    CURLOPT_NOPROGRESS => false,
    CURLOPT_UPLOAD => 1,
    CURLOPT_TIMEOUT => 3600,
    CURLOPT_INFILE => $filetocurl,
    CURLOPT_INFILESIZE => filesize($filename),
    CURLOPT_VERBOSE => true,
    CURLOPT_STDERR => $verbose  // Remove this for production
);

if (curl_setopt_array($ch, $options) !== false) {
    $result = curl_exec($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);
} else {
    // A Curl option could not be set. Set exception here
}

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