CURL POST отправка файла

Discussion in 'PHP' started by slva2000, 26 Nov 2009.

  1. slva2000

    slva2000 New Member

    Joined:
    20 Nov 2009
    Messages:
    42
    Likes Received:
    2
    Reputations:
    0
    Есть форма на сайта:

    PHP:
    бла бла

    <form method="post" action="/profileedit/" enctype="multipart/form-data">
    <
    input name="avatar" type="file" size="22" />  

    бла бла
    Пытаюсь методом CURL отправить данные, в т.ч. файл. Данные улетают, сохраняются, как положено, а файл нет.

    Вот результат снифера если отправлять форму браузером:

    Code:
    icq=748852941
    бла, бла
    skype=...
    avatar=filename="photo.jpg" Content-Type: image/jpeg
    Вот код php отправки:

    PHP:

    function post($url,$data$refer='') { 

    $process curl_init($url); 
    if (!
    $refer==''curl_setopt($processCURLOPT_REFERER$refer);
    curl_setopt($processCURLOPT_HTTPHEADER$this->headers); 
    curl_setopt($processCURLOPT_HEADER1); 
    curl_setopt($processCURLOPT_USERAGENT$this->user_agent); 
    if (
    $this->cookies == TRUEcurl_setopt($processCURLOPT_COOKIEFILE$this->cookie_file); 
    if (
    $this->cookies == TRUEcurl_setopt($processCURLOPT_COOKIEJAR$this->cookie_file); 
    curl_setopt($processCURLOPT_ENCODING $this->compression); 
    curl_setopt($processCURLOPT_TIMEOUT30); 
    if (
    $this->proxycurl_setopt($processCURLOPT_PROXY$this->proxy); 
    curl_setopt($processCURLOPT_POSTFIELDS$data); 
    curl_setopt($processCURLOPT_RETURNTRANSFER1); 
    curl_setopt($processCURLOPT_FOLLOWLOCATION1); 
    curl_setopt($processCURLOPT_POST1); 
    $return curl_exec($process); 
    curl_close($process); 
    return 
    $return



    $avatar 'filename="c://photo.jpg" Content-Type: image/jpeg';
    $post_data "icq=".mt_rand(587964257797964257)."&skype=&avatar=".$avatar;

    echo 
    post ("http://site.com/profile/"$post_data"http://site.com/profileediter/");

    Данные в форме сохраняются (редактирование профиля), а аватор нет!

    Помогите разобратся в том, где ошибка
     
  2. slva2000

    slva2000 New Member

    Joined:
    20 Nov 2009
    Messages:
    42
    Likes Received:
    2
    Reputations:
    0
    Уф, ну и не разбериха с этим курлом... Нашёл две детали (только с отладочными скриптами):

    1. CURLOPT_POST должна идти обязательно перед CURLOPT_POSTFIELDS (иначе не принимает файл)
    2. Заголовки я формировал для своей функции классические:

    PHP:
    $this->headers[] = 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg'
    $this->headers[] = 'Connection: Keep-Alive'
    $this->headers[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8'
    $this->user_agent 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)'
    С ними отправить файл не удавалось. Что ж, решил скопировать заголовки со снифера (реальный пост на сайте):

    PHP:
    $head[] = "Content-Type: image/gif";

    $head[] = "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10";
    $head[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
    $head[] = "Accept-Language: ru,en-us;q=0.7,en;q=0.3";
    $head[] = "Accept-Encoding: gzip,deflate";
    $head[] = "Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7";
    $head[] = "Keep-Alive: 300";
    $head[] = "Connection: keep-alive";
    $head[] = "Referer: http:/xxx.ru/";
    $head[] = "Content-Type: multipart/form-data";
    Тоже не принимал такие. Удалил CURLOPT_HTTPHEADER с функции, всё заработало. Файл был принят сервером.
    В голове не осталось ничего полезного :wacko
     
  3. slva2000

    slva2000 New Member

    Joined:
    20 Nov 2009
    Messages:
    42
    Likes Received:
    2
    Reputations:
    0
    Забыл добавить:

    CURLOPT_POSTFIELDS должен быть массивом:

    array("name_input" => "value");
     
  4. svesve

    svesve Elder - Старейшина

    Joined:
    15 Jun 2007
    Messages:
    574
    Likes Received:
    86
    Reputations:
    11
    поидеи поститься файл так

    PHP:
    <?php
        $ch 
    curl_init();
        
    curl_setopt($chCURLOPT_HEADER0);
        
    curl_setopt($chCURLOPT_VERBOSE0);
        
    curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
        
    curl_setopt($chCURLOPT_USERAGENT"Mozilla/4.0 (compatible;)");
        
    curl_setopt($chCURLOPT_URL$url);
        
    curl_setopt($chCURLOPT_POSTtrue);
        
    // same as <input type="file" name="file_box">
        
    $post = array(
            
    "file_box"=>"@/path/to/myfile.jpg",
        );
        
    curl_setopt($chCURLOPT_POSTFIELDS$post); 
        
    $response curl_exec($ch);
    ?>
     
    1 person likes this.
  5. b3

    b3 Banned

    Joined:
    5 Dec 2004
    Messages:
    2,170
    Likes Received:
    1,155
    Reputations:
    202
    Объясни одну вещь, нафига слать все эти заголовки если ты используеш cURL ? Разве не для этого был создан cURL, что б те кто поленился изучать протоколы мог юзать Константы?

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

    PHP:
    <?php  
    /***********************************************************************************************************************  
    *    Скрипт предназначен для автоматической смены аватарки на сайте vkontakte.ru. Замена аватарки происходит 1 раз в 24 часа.  
    *    Имена аватарок:  
    *    ponedelnik,  
    *    vtornik,  
    *    sreda,  
    *    chetverg,  
    *    pjatniza,  
    *    subbota,  
    *    woskresenje  
    *    Формат файлов .png  
    *    Запускать скрипт можно с сайта CronJob.ru рекомендую ставить промежуток 12 часов. Запуск производится по ссылке:  
    *    http://www.example.com/SCRIPT_FILENAME.php?start  
    ************************************************************************************************************************/  
    if(!@function_exists(curl_init))    
    {    
        echo 
    '<center><b>cURL not Supported</b></center><br>';    
        exit;    
    }  
    ###  
    if(file_exists('ponedelnik.png') && file_exists('vtornik.png') && file_exists('sreda.png') && file_exists('chetverg.png') && file_exists('pjatniza.png') && file_exists('subbota.png') && file_exists('woskresenje.png'))  
    {  
        echo 
    '<a href="?start">START</a>';  
    }  
    else  
    {  
    echo 
    '<b>Нехватает файлов изображений</b>';  
    ###  
    }  
    if(!isset(
    $_GET['start']))  
    {  
        exit;  
    }  
    ###########################################  
    ###########################################  
    ##############[CONFIG]#####################  
    $id '123';                          ###    <=== Your ID  
    $login '[email protected]';      ###    <=== Your email for login  
    $pass '123';                     ###    <=== Your password  
    ###########################################  
    ###########################################  
    $pass md5($pass);  
    $login str_replace('@','%40',$login);  
    $cookie "remixmid=$id; remixemail=$login; remixpass=$pass";  
    ###############################################################################################  
    $date =  date('w');  
    $arr = array(  
    '1' => 'ponedelnik',  
    '2' => 'vtornik',  
    '3' => 'sreda',  
    '4' => 'chetverg',  
    '5' => 'pjatniza',  
    '6' => 'subbota',  
    '0' => 'woskresenje'  
    );  
    $foto $arr[$date].'.png';  
    ###############################################################################################  
    $ch curl_init('http://vkontakte.ru/profileEdit.php?page=photo');    
          
    curl_setopt($chCURLOPT_RETURNTRANSFER1);    
          
    curl_setopt($chCURLOPT_TIMEOUT60);    
          
    curl_setopt($chCURLOPT_USERAGENT'Opera/9.62 (Windows NT 6.0; U; ru) Presto/2.1.1');    
          
    curl_setopt($chCURLOPT_COOKIE$cookie);   
          
    curl_setopt($chCURLOPT_FOLLOWLOCATION1);   
          
    $res curl_exec($ch);    
          
    curl_close($ch);    
    ###############################################################################################  
    if(preg_match_all('#action="(.*?)"#',$res$url2))  
        {  
            
    $action_url $url2[1][1];   
            
    $data = array(   
            
    'photo' => "@".$_SERVER['DOCUMENT_ROOT'].$foto,   
            
    'subm' => '1'   
            
    );   
    ###############################################################################################  
    $ch curl_init($action_url);    
        
    curl_setopt($chCURLOPT_RETURNTRANSFER1);    
        
    curl_setopt($chCURLOPT_TIMEOUT60);    
        
    curl_setopt($chCURLOPT_POSTtrue);    
        
    curl_setopt($chCURLOPT_POSTFIELDS$data);  
        
    curl_setopt($chCURLOPT_USERAGENT'Opera/9.62 (Windows NT 6.0; U; ru) Presto/2.1.1');    
        
    curl_setopt($chCURLOPT_COOKIE$cookie);   
        
    curl_setopt($chCURLOPT_FOLLOWLOCATION1);   
    $res curl_exec($ch);    
        
    curl_close($ch);  
    ###############################################################################################    
        
    }  
    ?>
     
  6. slva2000

    slva2000 New Member

    Joined:
    20 Nov 2009
    Messages:
    42
    Likes Received:
    2
    Reputations:
    0
    Да, я часто вижу таких, которым лиш бы брякнуть. Открывай нотепад и вперёд:


    upload.php:

    PHP:
    <?
    print_r($_POST);
    echo 
    "<br><br>";
    print_r($_FILES);
    ?>

    (не забудь положить 0.gif в ./home/localhost/)

    Варинат 1. (единственный рабочий из предложеных)

    index.php:

    PHP:
    <?php
    $ch 
    curl_init();
    $data = array('name' => 'Foo''file' => '@'.$_SERVER['DOCUMENT_ROOT'].'/0.gif');

    curl_setopt($chCURLOPT_URL'http://localhost/upload.php');
    curl_setopt($chCURLOPT_POST1);
    curl_setopt($chCURLOPT_POSTFIELDS$data);
    curl_exec($ch);
    ?>

    Варинат 2. (Стройка вместо массива. НЕ рабочий)

    index.php:

    PHP:
    <?php
    $ch 
    curl_init();
    $data "name=Foo&file=@".$_SERVER['DOCUMENT_ROOT']."/0.gif";

    curl_setopt($chCURLOPT_URL'http://localhost/upload.php');
    curl_setopt($chCURLOPT_POSTFIELDS$data);
    curl_setopt($chCURLOPT_POST1);
    curl_exec($ch);
    ?>

    Варинат 3. (CURLOPT_POST после CURLOPT_POSTFIELDS. НЕ рабочий)

    index.php:

    PHP:
    <?php
    $ch 
    curl_init();
    $data = array('name' => 'Foo''file' => '@'.$_SERVER['DOCUMENT_ROOT'].'/0.gif');

    curl_setopt($chCURLOPT_URL'http://localhost/upload.php');
    curl_setopt($chCURLOPT_POSTFIELDS$data);
    curl_setopt($chCURLOPT_POST1);
    curl_exec($ch);
    ?>

    попрошу прокоментировать знатоков.
     
  7. slva2000

    slva2000 New Member

    Joined:
    20 Nov 2009
    Messages:
    42
    Likes Received:
    2
    Reputations:
    0
    cURL Information: libcurl/7.16.0 OpenSSL/0.9.8d zlib/1.2.3

    b3 заголовки я отправлял с целью, что сервер принимает еменно "то, что нужно", т.е. рефер, например ему нужен правильный, и т.д. Оказалос, безусловно, что своими заголовками, я только напортачил. :) КУРЛ без этого сам правильно их сформировал.

    Кста, а что ты скажешь про юзер-Агента? То, где я постю, это НЕОБХОДИМАЯ деталь. Причём, рандомные.

    Но основная то беда не в нём. См мой ответ.
     
    #7 slva2000, 26 Nov 2009
    Last edited: 26 Nov 2009
  8. b3

    b3 Banned

    Joined:
    5 Dec 2004
    Messages:
    2,170
    Likes Received:
    1,155
    Reputations:
    202
    PHP:
    curl_setopt($chCURLOPT_USERAGENT'Opera/9.62 (Windows NT 6.0; U; ru) Presto/2.1.1');
    Загнал в файл список агентов и вытягивай рандомно.
     
  9. slva2000

    slva2000 New Member

    Joined:
    20 Nov 2009
    Messages:
    42
    Likes Received:
    2
    Reputations:
    0
    b3 это был риторический вопрос. Я к тому, что хеадреы часто приходится модифицировать. А при моей задаче (постинг ПОСТом с файлом), хеадеры воообще никикие не катят, если их указывать явно. Убрал полностью - пожалуйста. Добавил хотя бы Юзер-Агента - уже никак.
     
  10. b3

    b3 Banned

    Joined:
    5 Dec 2004
    Messages:
    2,170
    Likes Received:
    1,155
    Reputations:
    202
    Помоему ето бред сивой кабылы. Приводи примеры, посмотрим.
     
  11. slva2000

    slva2000 New Member

    Joined:
    20 Nov 2009
    Messages:
    42
    Likes Received:
    2
    Reputations:
    0
    Пример простой. Идёт пост на один какой либо ресурс. Было бы логично для каждого поста брять один из (положим) 5-ти разных заголовков Юзер_Агента. Это обеспечит анонимность, если использовать прокси.
     
  12. b3

    b3 Banned

    Joined:
    5 Dec 2004
    Messages:
    2,170
    Likes Received:
    1,155
    Reputations:
    202
    Ты по сколько раз будеш один и тот же вопрос задавать? Я на него ответил пару постов назад. Вопрос заключается в другом, зачем слать Заголовки как в сокетах, если можно по человечески отослать:
    PHP:
    curl_setopt($chCURLOPT_USERAGENT'Opera/9.62 (Windows NT 6.0; U; ru) Presto/2.1.1');
    Если нужен рандомный, что тебе мешает загнать в массив и выводить рандомно?
    ТЫ вообщем действительно несеш чтото)) Если любиш слать Хедеры как в сокетах, так уже и писал бы на них, помоему для етого и есть курла предназначение, работать с протоколом не зная его, юзая константы, а у тебя каша выходит, пишеш на курле, не юзая константы, полукурл-полусокет))) и кстати полусокет явно кривой, заголовки с ошибками, но то пох, ога!!11админ
     
  13. Luck3r

    Luck3r New Member

    Joined:
    1 Nov 2009
    Messages:
    14
    Likes Received:
    1
    Reputations:
    0
    slva2000
    Почитай: http://ru.wikipedia.org/wiki/HTTP
     
  14. slva2000

    slva2000 New Member

    Joined:
    20 Nov 2009
    Messages:
    42
    Likes Received:
    2
    Reputations:
    0
    b3,

    Вообще то, это всё были не вопросы а ответы на один твой:


    Я и обяснил, нафига их слать и какими. Какого тут демогогию то разводить...? Вопросы были в моём посту Вчера 14:58.

    На него кто нить внятно может ответить..? Посылать РТФМы я бы не рекомендовал, ибо, противоречат они действительности.
     
    #14 slva2000, 27 Nov 2009
    Last edited: 27 Nov 2009
  15. zEr0r

    zEr0r Elder - Старейшина

    Joined:
    17 Feb 2008
    Messages:
    67
    Likes Received:
    28
    Reputations:
    14
    Делай как я: составляй хедеры в ручную и отправляй через сокеты и не будет никаких проблем

    структура хедера проста:
    $header = "данное1\r\n";
    $header .= "данное2\r\n";
    $header .= "данное3\r\n";
    $header .= "последнееданное\r\n\r\n"


    данное это например Location: http://ya.ru
    или Cookie...
     
    #15 zEr0r, 28 Nov 2009
    Last edited: 28 Nov 2009