2009-11-07 38 views
8

Tôi đã phải vật lộn trong vài giờ cố gắng tìm ra cách để có được công việc này. Tôi đang cố gắng gửi một tập tin thông qua HTTP-PUT đến một db eXist. Có xác thực người dùng cho máy chủ, vì vậy tôi đã cố gắng thực hiện một việc như sau:Gửi tệp qua HTTP PUT trong PHP

Tôi có URL nơi tài liệu được PUTted đến Tôi có tên người dùng và mật khẩu cho eXist DB Tôi có nội dung cần được gửi qua PUT

Tôi đã cố gắng làm việc với cURL nhưng nó sẽ không hoạt động một cách im lặng Tôi đã cố gắng sử dụng luồng PHP nhưng vẫn nhận được "lỗi 201/tạo" nhưng không có tệp nào thực sự được tạo.

Bất kỳ trợ giúp nào về điều này sẽ được đánh giá cao.

Dưới đây là một số mẫu mã tôi đã cố gắng sử dụng PHP suối

 
     $data = file_get_contents($tmpFile);                          
     $header = array(
      "Authorization: Basic " . base64_encode($this->ci->config->item('ws_login') . ':' . $this->ci->config->item('ws_passwd')), 
      "Content-Type: text/xml" 
     ); 
     $params = array(
      'http' => array(
       'method' => 'PUT', 
       'header' => $header, 
       'content' => $data)); 
     $ctx = stream_context_create($params); 

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

Bạn có thể cung cấp một số mã nguồn không? –

Trả lời

9

Aha! Sau một chút "ducking cao su" với lùn nhồi búp bê gắt gỏng trên bàn của tôi ở đây, tôi đã tìm ra giải pháp:

 
     $data = file_get_contents($tmpFile); 
     $params = array(
      'http' => array(
       'method' => 'PUT', 
       'header' => "Authorization: Basic " . base64_encode($this->ci->config->item('ws_login') . ':' . $this->ci->config->item('ws_passwd')) . "\r\nContent-type: text/xml\r\n", 
       'content' => file_get_contents($tmpFile) 
      ) 
     ); 
     $ctx = stream_context_create($params); 
     $response = @file_get_contents($url, false, $ctx); 

     return ($response == ''); 
+0

Bạn có thể giải thích? Có phải đó là sự bổ sung của khóa 'nội dung', hay câu lệnh trả về? –

+0

Đó là một điều: thay đổi cách tôi đã xây dựng tiêu đề. Tôi vẫn phải ngăn chặn ra khỏi file_get_contents vì nó trả về một cảnh báo, nhưng tôi có thể sống với điều đó cho đến bây giờ cho đến khi tôi tìm thấy một cách tốt hơn để bẫy nó. – GrumpyCanuck

0

Nếu tồn tại-db của bạn đã giao diện SOAP cho phép, có một mã nguồn mở thư viện gọi PheXist điều đó sẽ làm cho tương tác với cơ sở dữ liệu dễ dàng hơn.

0
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; 
    } 
} 

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

+0

Đó là từ blog của riêng tôi và tôi thấy rằng nó không hoạt động chính xác. ;) – GrumpyCanuck

+1

Tôi không chắc liệu điều đó có vui nhộn hay buồn hay cả hai: O –

4

CURL làm việc cho tôi. Đây là đoạn trích từ mã của tôi,

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

CHỈNH SỬA: Chỉ cập nhật mã của tôi. Tôi không sử dụng xác thực bản thân vì vậy điều này không được thử nghiệm.

+0

Tôi không thể nhận được các công cụ xác thực HTTP để làm việc với cURL. Bạn có thể cập nhật ví dụ cURL đó để sử dụng không? – GrumpyCanuck

3

này làm việc cho tôi ...

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

Nhiều người trong số các dòng tiêu đề có lẽ không cần thiết ... nhưng nó hoạt động khi tôi nói chuyện với couchdb của tôi vì vậy tôi đã không nhận xung quanh để làm cỏ chúng ra .