Как использовать CURLOPT_WRITEFUNCTION при загрузке файла с помощью CURL - PullRequest
2 голосов
/ 19 марта 2011

Мой класс для загрузки файла напрямую по ссылке:

MyClass{

          function download($link){
                ......
                $ch = curl_init($link);
                curl_setopt($ch, CURLOPT_FILE, $File->handle);
                curl_setopt($ch,CURLOPT_WRITEFUNCTION , array($this,'__writeFunction'));
                curl_exec($ch);
                curl_close($ch);
                $File->close();
                ......

            }

          function __writeFunction($curl, $data) {
                return strlen($data);            
          } 
}

Я хочу знать, как использовать CRULOPT_WRITEFUNCTION при загрузке файла.Выше кода, если я удалю строку:

curl_setopt($ch,CURLOPT_WRITEFUNCTION , array($this,'__writeFunction'));

Тогда все будет хорошо, я могу скачать этот файл. Но если я использую опцию CURL_WRITEFUNCTION, я не могу загрузить файл.

Ответы [ 4 ]

4 голосов
/ 19 марта 2011
<?php 
$ch = curl_init();
curl_setopt($ch, CURLOPT_BUFFERSIZE, 8096);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_URL, 'http://blog.ronnyristau.de/wp-content/uploads/2008/12/php.jpg');

$content = curl_exec($ch);

curl_close($ch);

$out = fopen('/tmp/out.png','w');
if($out){
    fwrite($out, $content);
    fclose($out);
}
4 голосов
/ 12 апреля 2013

Я знаю, что это старый вопрос, но, возможно, мой ответ поможет вам или кому-то еще. Попробуйте это:

function get_write_function(){
    return function($curl, $data){
        return strlen($data);
    }
}

Я не знаю точно, что вы хотите сделать, но с PHP 5.3 вы можете многое сделать с помощью обратного вызова. Что действительно хорошо в генерации функции таким образом, так это то, что значения, переданные через ключевое слово «use», остаются с функцией впоследствии, вроде констант.

function get_write_function($var){
    $obj = $this;//access variables or functions within your class with the object variable
    return function($curl, $data) use ($var, $obj) {
        $len = strlen($data);
        //just an example - you can come up with something better than this:
        if ($len > $var){
            return -1;//abort the download
        } else {
            $obj->do_something();//call a class function
            return $len;
        }
    }
}

Вы можете извлечь функцию как переменную следующим образом:

function download($link){
    ......
    $var = 5000;
    $write_function = $this->get_write_function($var);
    $ch = curl_init($link);
    curl_setopt($ch, CURLOPT_FILE, $File->handle);
    curl_setopt($ch, CURLOPT_WRITEFUNCTION , $write_function);
    curl_exec($ch);
    curl_close($ch);
    $File->close();
    ......

}

Это был просто пример. Вы можете увидеть, как я использовал это здесь: Параллельный запрос cURL с обратным вызовом WRITEFUNCTION . На самом деле я не тестировал весь этот код, поэтому возможны незначительные ошибки. Дайте мне знать, если у вас возникнут проблемы, и я это исправлю.

0 голосов
/ 01 мая 2014

Кажется, что cURL использует вашу функцию вместо записи в запрос, если указано CURLOPT_WRITEFUNCTION.

Таким образом, правильное решение будет:

MyClass{

      function download($link){
            ......
            $ch = curl_init($link);
            curl_setopt($ch, CURLOPT_FILE, $File->handle);
            curl_setopt($ch,CURLOPT_WRITEFUNCTION , array($this,'__writeFunction'));
            curl_exec($ch);
            curl_close($ch);
            $File->close();
            ......

        }

      function __writeFunction($curl, $data) {
            echo $data;
            return strlen($data);            
      } 
}

Это также может обрабатывать двоичные файлы.

0 голосов
/ 19 марта 2011

Почему вы используете curl для загрузки файла? Есть ли особая причина? Вы можете просто использовать fopen и fread

Я написал для него небольшой класс.

<?php
class Utils_FileDownload  {
    private $source;
    private $dest;
    private $buffer;
    private $overwrite;
    public function __construct($source,$dest,$buffer=4096,$overwrite=false){
        $this->source = $source;
        $this->dest   = $dest;
        $this->buffer = $buffer; 
        $this->overwrite = $overwrite;
    }
    public function download(){
        if($this->overwrite||!file_exists($this->dest)){
            if(!is_dir(dirname($this->dest))){mkdir(dirname($this->dest),0755,true);}
            if($this->source==""){
                $resource = false;
                Utils_Logging_Logger::getLogger()->log("source must not be empty.",Utils_Logging_Logger::TYPE_ERROR);
            }
            else{ $resource = fopen($this->source,"rb"); }
            if($this->source==""){
                $dest = false;
                Utils_Logging_Logger::getLogger()->log("destination must not be empty.",Utils_Logging_Logger::TYPE_ERROR);
            }
            else{ $dest     = fopen($this->dest,"wb"); }
            if($resource!==false&&$dest!==false){
                while(!feof($resource)){
                    $read = fread($resource,$this->buffer);
                    fwrite($dest,$read,$this->buffer);
                }
                chmod($this->dest,0644);
                fclose($dest); fclose($resource);
                return true;
            }else{
                 return false;   
            }
        }else{
            return false;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...