Отправка файла через HTTP PUT в PHP

Я боролся в течение нескольких часов, пытаясь понять, как получить эту работу. Я пытаюсь отправить файл через HTTP-PUT в eXist db. Для сервера существует аутентификация пользователя, поэтому я пытался сделать что-то вроде этого:

У меня есть URL-адрес, на который нужно положить документ, У меня есть имя пользователя и пароль для eXist DB. У меня есть контент, который нужно отправить через PUT

Я пытался заставить работать cURL, но он молча завершался неудачей. Я пытался использовать потоки PHP, но продолжал получать сообщение об ошибке "201/ создан", но файл фактически не был создан.

Любая помощь с этим будет С благодарностью.

Вот пример кода, который я пробовал использовать потоки PHP

        $data = file_get_contents($tmpFile);                                                                                                    
         $header = array(
             "Авторизация: базовая" . base64_encode($this->ci->config->item('ws_login') . ':' . $this->ci->config->item('ws_passwd')),
             "Тип контента: текст /xml");  
         $params = array(
             'http' => массив ('method' => 'PUT',
                 'header' => $ header,
                 'content' => $ data));
         $ ctx = stream_context_create ($ params);

         $ response = file_get_contents ($ url, false, $ ctx);

5 ответов

Решение

Ага! После небольшой "резиновой утки" с сварливой карликовой куклой на моем столе я нашел решение:

        $ data = file_get_contents ($ tmpFile);
         $ params = array ('http' => массив (
                 'method' => 'PUT',
                 'header' => "Авторизация: базовая" . base64_encode($this->ci->config->item('ws_login') . ':' . $this->ci->config->item('ws_passwd')) . "\r\n Контент-тип: text / xml \ r \ n",
                 'content' => file_get_contents ($ tmpFile)));
         $ ctx = stream_context_create ($ params);
         $ response = @file_get_contents ($ url, false, $ ctx);

         return ($ response == '');

CURL работает для меня. Вот фрагмент из моего кода,

                $handle = curl_init ($server_url);

                if ($handle)
                {
                    // specify custom header
                    $customHeader = array(
                        "Content-type: $file_type"
                    );
                    $curlOptArr = array(
                        CURLOPT_PUT => TRUE,
                        CURLOPT_HEADER => TRUE,
                        CURLOPT_HTTPHEADER => $customHeader,
                        CURLOPT_INFILESIZE => $file_size,
                        CURLOPT_INFILE => $file,
                        CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
                        CURLOPT_USERPWD => $user . ':' . $password,
                        CURLOPT_RETURNTRANSFER => TRUE
                    );
                    curl_setopt_array($handle, $curlOptArr);
                    $ret = curl_exec($handle);
                    $errRet = curl_error($handle);
                    curl_close($handle);

РЕДАКТИРОВАТЬ: Просто обновил мой код. Я сам не использую аутентификацию, так что это не проверено.

Это работает для меня...

function put($_server,$_file,$_data)
{
  $fp = @fsockopen ($_server, 80, $errno, $errstr, 30);
  if ($fp)
  {
    $p = "PUT $_file HTTP/1.0\r\n";
    $p.= "User-Agent: Mozilla/3.0 (Windows NT 5.0; U) Opera 7.21  [da]\r\n";
    $p.= "Host: $_server\r\n";
    $p.= "Accept: text/html, application/xml;q=0.9, application/xhtml+xml;q=0.9, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1\r\n";
    $p.= "Accept-Language: da;q=1.0,en;q=0.9\r\n";
    $p.= "Accept-Charset: windows-1252, utf-8, utf-16, iso-8859-1;q=0.6, *;q=0.1\r\n";
    $p.= "Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0\r\n";
    $p.= "Referer: http://www.nasa.gov/secret/flightplans.asp\r\n";
    $p.= "Content-type: application/x-www-form-urlencoded\r\n";
    $p.= "Content-length: ".strlen($_data)."\r\n";
    $p.= "\r\n";
    $p.= $_data;

    //echo($p);
    fputs ($fp, $p);
  }
  else die("dagnabbit : $errstr");

  while ($l=fgets($fp))
    echo($l);
  fclose($fp);
}

Многие из заголовочных строк, вероятно, не нужны... но это работает, когда я разговариваю с моим couchdb, поэтому я не удосужился их отсеять.

Если в вашем eXist-db включен интерфейс SOAP, есть библиотека с открытым исходным кодом под названием PheXist, которая облегчит взаимодействие с базой данных.

function _publish($service, $doc) {
    $params = array(
        'http' => array(
            'method' => 'PUT'));
    $context = stream_context_create($params);
    $fp = fopen($service, 'rb', false, $context);
    $response = fwrite($fp,file_get_contents($doc));
    if ($response === false) {
        return false;
    }
    // Pull out the status code from the header
    $metaData = stream_get_meta_data($fp);
    preg_match_all("/HTTP\/1\.[1|0]\s(\d{3})/", $metaData['wrapper_data'][0], $matches);
    $code = end($matches[1]);
    if ($code == 200) {
        return true;
    } else {
        return false;
    }
}

с http://www.littlehart.net/atthekeyboard/2008/01/11/how-to-http-put-a-file-somewhere-using-php/

Другие вопросы по тегам