web-dev-qa-db-fra.com

Quelqu'un peut-il me donner un exemple pour la classe CURLFile de PHP?

J'avais un code très simple PHP pour télécharger un fichier sur un serveur distant; la façon dont je le faisais (comme cela a été suggéré ici dans d'autres solutions) est d'utiliser cUrl pour télécharger le fichier. 

Voici mon code:

$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);        

Le serveur exécute PHP 5.5.0 et il apparaît que @filename est obsolète dans PHP> = 5.5.0 comme indiqué ici sous la description CURLOPT_POSTFIELDS et, par conséquent, I reçois cette erreur:

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

Fait intéressant, il n'y a absolument rien à propos de cette classe sur php.net, si ce n'est un aperçu de base de la classe. Pas d'exemples, pas de description de méthodes ou de propriétés. C'est essentiellement vide ici . Je crois comprendre qu’il s’agit d’une toute nouvelle classe avec peu ou pas de documentation et très peu d’utilisation dans le monde réel. C’est pourquoi il n’ya pratiquement rien de pertinent dans les recherches sur Google ou ici sur Stackoverflow dans cette classe.

Je me demande s'il y a quelqu'un qui a utilisé cette classe CURLFile et peut éventuellement m'aider ou me donner un exemple d'utilisation à la place de @nomfichier dans mon code.

Modifier:

Je voulais aussi ajouter mon code "upload.php"; ce code fonctionnerait avec la méthode traditionnelle @filename mais ne fonctionne plus avec le code de classe 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:

Voulait ajouter du code Final/Working pour les autres à la recherche d'un exemple similaire de la classe CURLFile peu documentée ... 

curl.php (serveur local)

<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 (serveur distant)

$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";
} 
33
luci5r

Il y a un extrait de code sur le 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);

Vous pouvez également utiliser la fonction apparemment inutile curl_file_create( string $filename [, string $mimetype [, string $postname ]] ) si vous avez la phobie de créer des objets. 

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);
45
Danack

Merci pour votre aide, en utilisant votre code de travail, j'ai pu résoudre mon problème avec PHP 5.5 et le SDK Facebook. Je recevais cette erreur du code dans la classe SDK.

Je ne pense pas que cela compte comme une réponse, mais je suis sûr qu'il y a des gens à la recherche de cette erreur comme moi liée à Facebook SDK et php 5.5

Au cas où quelqu'un aurait le même problème, la solution pour moi était de changer un peu de code de base_facebook.php pour utiliser la classe CurlFile au lieu du nom de fichier @.

Depuis que j'appelle le sdk depuis plusieurs endroits, je viens de modifier quelques lignes du sdk:

Dans la méthode appelée "makeRequest", j'ai apporté cette modification:

Dans cette partie du code:

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

Modifiez la première partie (avec le téléchargement de fichier activé) en:

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, '&');
}

Peut-être que cela pourrait être amélioré en analysant chaque $ param et en recherchant '@' dans la valeur .. mais je ne l’ai fait que pour source et image car c’était ce dont j'avais besoin.

5
Claudio Romano

FOR curl_setopt (): l'utilisation de l'API @filename pour le téléchargement de fichiers est obsolète. Veuillez utiliser la classe CURLFile à la place

$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;
1
Rahul Sid

Demande Php POST envoyer plusieurs fichiers avec fonction curl:

<?php
    $file1 = realpath('ads/ads0.jpg');
    $file2 = realpath('ads/ads1.jpg');
    // Old method
    // Single file
    // $data = array('name' => 'Alexia', 'address' => 'Usa', 'age' => 21, 'file' => '@'.$file1);    
    // $data = array('name' => 'Alexia', 'address' => 'Usa', 'age' => 21, 'file[0]' => '@'.$file1, 'file[1]' => '@'.$file2);
    // CurlFile method   
    $f1 = new CurlFile($file1, mime_content_type($file1), basename($file1)); 
    $f2 = new CurlFile($file2, mime_content_type($file2), basename($file2)); 
    $data = array('name' => 'Alexia', 'address' => 'Usa', 'age' => 21, 'file[1]' => $f1, 'file[2]' => $f2);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://url.x/upload.php');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false); // !!!! required as of PHP 5.6.0 for files !!!
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);    
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)");
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 1, 2
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    // curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    $res2 = curl_exec($ch);
    echo $res2;
?>

<?php
    // upload.php
    $json = json_decode(file_get_contents('php://input'), true);
    if(!empty($json)){ print_r($json); }
    if(!empty($_GET)){ print_r($_GET); }
    if(!empty($_POST)){ print_r($_POST); }
    if(!empty($_FILES)){ print_r($_FILES); }
?>
0
Max

CURLFile a été expliqué ci-dessus, mais pour les transferts simples de fichiers où vous ne souhaitez pas envoyer de message en plusieurs parties (inutile pour un fichier et certaines API ne prennent pas en charge la multi-partie), la procédure suivante fonctionne.

$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
}

Notez que le code ci-dessus a un débogage supplémentaire - supprimez-le une fois qu'il fonctionne.

0
brianlmerritt