2013-06-10 11 views
29

Avevo un codice PHP molto semplice per caricare un file su un server remoto; il modo in cui lo stavo facendo (come è stato suggerito qui in alcune altre soluzioni) è quello di usare cUrl per caricare il file.Qualcuno può darmi un esempio per la classe CURLFile di PHP?

Ecco il mio codice:

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

Il server è in esecuzione PHP 5.5.0 e sembra che @nomefile è stato deprecato in PHP> = 5.5.0, come indicato here sotto la descrizione CURLOPT_POSTFIELDS, e, quindi, sto ottenendo questo errore:

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

è interessante notare che non c'è assolutamente nulla di questa classe su php.net a parte una panoramica di classe di base. Nessun esempio, nessuna descrizione di metodi o proprietà. È praticamente vuoto here. Capisco che è una nuova classe con poca o nessuna documentazione e un uso molto limitato del mondo reale, motivo per cui praticamente nulla di rilevante sta emergendo nelle ricerche su Google o qui su Stackoverflow in questa classe.

Mi chiedo se c'è qualcuno che ha usato questa classe CURLFile e può eventualmente aiutarmi o darmi un esempio di come usarlo al posto di @filename nel mio codice.

Edit:

ho voluto aggiungere il mio codice "upload.php" pure; questo codice dovrebbe funzionare con il metodo @nomefile tradizionale, ma non è più lavorare con il codice della 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"; 
} 

Modifica finale:

voluto aggiungere il codice finale/lavorare per gli altri in cerca di simile esempio di lavoro della classe CURLFile scarsamente documentata ...

curl.php (server locale)

<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 (server remoto)

$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"; 
} 
+0

Puoi var_dump ($ _ FILES)? – Danack

+1

in upload.php? Se lo faccio, come faccio a restituire il risultato sulla mia pagina curl.php? Stavo provando a farlo in precedenza, ma in realtà non restituisce nulla una volta eseguito il codice di invio. – luci5r

+0

OK - Doveva impostare RETURNTRANSFER su true; quindi ecco il risultato di var_dump ($ _ FILES) sotto upload.php: 'array (1) {[" file "] => array (5) {[" name "] => string (11)" phpC0F4.tmp "[ "type"] => string (24) "application/octet-stream" ["tmp_name"] => string (14) "/ tmp/phpj7C3Hv" ["error"] => int (0) ["size"] => int (483397)}} Il file phpj7C3Hv è stato caricato ' – luci5r

risposta

38

C'è un frammento sul RFC per il codice: 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); 

È anche possibile utilizzare la funzione apparentemente inutile curl_file_create(string $filename [, string $mimetype [, string $postname ]]) se hai una fobia di creare oggetti.

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); 
+0

Grazie amico - Lasciami dare un'occhiata laggiù. – luci5r

+0

Bene: il bit che ho incollato è quasi tutto il bit utile che non è presente nei documenti. – Danack

+0

La pagina offre sicuramente un aspetto più utile dell'uso effettivo della classe; e aggiungendo $ args ['file'] = nuovo CurlFile ($ _ FILES ['Filedata'] ['tmp_name']); curl_setopt ($ ch, CURLOPT_POSTFIELDS, $ args); sbarazzarsi dell'errore Deprecato; in effetti si è sbarazzato degli errori tutti insieme. Il problema che ho ora è che il mio "upload.php" all'altra estremità è diventato non valido. Non sono sicuro di quali modifiche devo apportare per poter recuperare il file, perché in realtà non sta più ricevendo il file. – luci5r

5

Grazie per il vostro aiuto, utilizzando il vostro codice di lavoro sono stato in grado di risolvere il mio problema con php 5.5 e Facebook SDK. Stavo ricevendo questo errore dal codice nella classe sdk.

io non pensa questo conteggio come una risposta, ma sono sicuro che ci sono persone alla ricerca di questo errore come me legati alla facebook SDK e php 5.5

Nel caso in cui qualcuno ha lo stesso problema, la soluzione per me era di cambiare un piccolo codice da base_facebook.php per usare la classe CurlFile invece del @filename.

Dal momento che sto chiamando l'SDK da diversi luoghi, ho appena modificato alcune righe di SDK:

Nel metodo chiamato "makeRequest" Ho fatto questo cambiamento:

In questa parte del codice:

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

modificare la prima parte (con upload di file abilitato) a:

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

Forse questo può essere migliorato analizzando ogni $ param e cercando '@' nel valore .. ma l'ho fatto solo per source e image perché era quello di cui avevo bisogno.

+0

Eccellente compagno - il tuo codice sarebbe utile anche per gli altri. – luci5r

+0

Utile; Grazie! FWIW, penso che potrebbe avere più senso abbandonare completamente il formato '@' e modificare il codice dell'applicazione per usare l'approccio 'CurlFile()'. Ma questo è in discussione. Ad ogni modo, grazie! – rinogo

1

FOR curl_setopt(): l'utilizzo dell'API @filename per il caricamento dei file è deprecato. Si prega di usethe classe CURLFile invece

$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; 
+0

Quando si utilizza la tecnica CurlFile, non si dovrebbe impostare CURLOPT_SAFE_UPLOAD (è impostato su true e dovrebbe essere lasciato in questo modo), in modo tale che la riga debba essere rimossa. CURLOPT_SAFE_UPLOAD non è lungo nemmeno incluso in PHP 7. – orrd

0

CURLFile è stato spiegato ben al di sopra, ma per semplice trasferimento di file in cui non si desidera inviare un messaggio multipart (non necessario per un file, e alcune API non supportano multipart), quindi i seguenti lavori.

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

Nota che il codice precedente ha un po 'di debug aggiuntivo - rimuoverli una volta che funziona.

Problemi correlati