【问题标题】:File-size differences before and after upload PHP-CURL to Windows WCF将 PHP-CURL 上传到 Windows WCF 前后的文件大小差异
【发布时间】:2014-12-26 10:20:05
【问题描述】:

我正在尝试使用 PHP 上传文件。不是凝灰岩对吧?好吧,我需要通过 Webservices WCF 来完成。现在我坚持最后一部分。当我上传文件时,它是:892599(这是 Windows 和 Linux 在文件系统上告诉我的。也是 PHP 告诉我的。但是,当它到达现场(Windows Server,WCF)时,它只有 891400。

这一定与编码或操作系统差异有关,但我不知道现在该往哪里看。下面是我的 PHP 代码。

正如您在代码中看到的,我尝试了不同的方法,但结果都相同。文件大小差异。源文件(我尝试上传的文件是文本/纯 us_ascii 编码文件)

try{
    header("Content-type: text/plain; charset=utf-8", true);

    $filename = "ahstray.obj";
    $file_content = file_get_contents($filename);
    $file_hash = hash_file('sha512', $filename, false);
    $bits = pack("H*", $file_hash);
    $file_hash = base64_encode($bits);        
    $filesize = strlen($file_content); //filesize($filename); //strlen(file_get_contents($filename));

    $boundary = "uuid:".uniqid();        
    $headers = array(
        'MIME-Version: 1.0',
        'Content-Type: multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="'.$boundary.'";start-info="text/xml"',
        'SOAPAction: "'.$action.'"',
        'Host: www.url.com',
        'Content-length: '.$filesize,
        'Accept-Encoding: gzip, deflate',
        'User-Agent: PHP-Post-FileUpload'
    );
    $post_data = "\r\n\r\n\r\n--{$boundary}\r\n";
    $post_data .= "Content-ID: <http://tempuri.org/0>\r\n";
    $post_data .= "Content-Transfer-Encoding: 8bit\r\n";
    $post_data .= 'Content-Type: application/xop+xml;charset=utf-8;type="text/xml"';
    $post_data .= "\r\n\r\n";

    $post_data .= '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">';
        $post_data .= '<s:Header>';
            $post_data .= '<h:FileHash xmlns:h="http://www.materialise.be/eRP">'.$file_hash.'</h:FileHash>';
            $post_data .= '<h:FileName xmlns:h="http://www.materialise.be/eRP">'.$filename.'</h:FileName>';
            $post_data .= '<h:FileSize xmlns:h="http://www.materialise.be/eRP">'.$filesize.'</h:FileSize>';
            $post_data .= '<h:UserDomain xmlns:h="http://www.materialise.be/eRP">'.$domain.'</h:UserDomain>';
            $post_data .= '<h:UserName xmlns:h="http://www.materialise.be/eRP">'.$gebruiker.'</h:UserName>';
            $post_data .= '<h:UserPassword xmlns:h="http://www.materialise.be/eRP">'.$encrypted_password.'</h:UserPassword>';
        $post_data .= '</s:Header>';
        $post_data .= '<s:Body>';
            $post_data .= '<UploadFileDTO xmlns="http://www.url.com/eRP">';
                    $post_data .= '<FileStream>';
                        $post_data .= '<xop:Include href="cid:http://tempuri.org/1/635551016730489495" xmlns:xop="http://www.w3.org/2004/08/xop/include" />';
                    $post_data .= '</FileStream>';
            $post_data .= '</UploadFileDTO>';
        $post_data .= '</s:Body>';
    $post_data .= '</s:Envelope>';

    $post_data .= "\r\n--{$boundary}\r\n";
    $post_data .= "Content-ID: <http://tempuri.org/1/635551016730489495>\r\n";
    $post_data .= "Content-Transfer-Encoding: binary\r\n";
    $post_data .= "Content-Type: application/octet-stream\r\n\r\n";

    $post_data .= $file_content.$file_content;        
    $post_data .= "--{$boundary}\r\n";


    $sock = fsockopen("ssl://www.url.com", 443, $errorno, $error, 30) or die($error);
    $data = "POST https://www.url.com/FilesTransfer.svc HTTP/1.1\r\n";
    $data .= implode("\r\n", $headers);
    $data .= $post_data;

    if($sock){                        
        fwrite($sock, $data);
        echo fread($sock, strlen($data));
        fflush($sock);
        fclose($sock);
    }        

    /*
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    $error = curl_error($ch);

        print_r_pre($response);
        print_r_pre($error);
        curl_close($ch);
        */

} catch (Exception $e){
    print('<pre>');
    print_r($e);
    print('</pre>');
}

【问题讨论】:

    标签: php web-services wcf file-upload filesize


    【解决方案1】:

    所以这个问题的解决方案很简单。这是一个部分请求,这意味着当您设置“内容长度”时,您应该计算请求的完整大小。因此,您尝试上传的文件的 XML 部分和大小。

    请求现在看起来像这样:

    try{
    
            $file_content = utf8_encode(file_get_contents($filename));
            $hash = hash('sha512', $file_content, false);
            $bits = pack("H*", $hash);
            $file_hash = base64_encode($bits);       
            $filesize = filesize($filename); //filesize($filename); //strlen(file_get_contents($filename));
    
            $boundary = "uuid:".uniqid();     
    
             $xml_request = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">';
                $xml_request .= '<s:Header>';
                    $xml_request .= '<h:FileHash xmlns:h="http://www.materialise.be/eRP">'.$file_hash.'</h:FileHash>';
                    $xml_request .= '<h:FileName xmlns:h="http://www.materialise.be/eRP">'.$filename.'</h:FileName>';
                    $xml_request .= '<h:FileSize xmlns:h="http://www.materialise.be/eRP">'.$filesize.'</h:FileSize>';
                    $xml_request .= '<h:UserDomain xmlns:h="http://www.materialise.be/eRP">'.$this->domain.'</h:UserDomain>';
                    $xml_request .= '<h:UserName xmlns:h="http://www.materialise.be/eRP">'.$this->gebruiker.'</h:UserName>';
                    $xml_request .= '<h:UserPassword xmlns:h="http://www.materialise.be/eRP">'.$this->encrypted_password.'</h:UserPassword>';
                $xml_request .= '</s:Header>';
                $xml_request .= '<s:Body>';
                    $xml_request .= '<UploadFileDTO xmlns="http://www.url.com/eRP">';
                            $xml_request .= '<FileStream>';
                                $xml_request .= '<xop:Include href="cid:http://tempuri.org/1/635551016730489495" xmlns:xop="http://www.w3.org/2004/08/xop/include" />';
                            $xml_request .= '</FileStream>';
                    $xml_request .= '</UploadFileDTO>';
                $xml_request .= '</s:Body>';
            $xml_request .= '</s:Envelope>';
    
            $headers = array(
                'MIME-Version: 1.0',
                'Content-Type: multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="'.$boundary.'";start-info="text/xml"',
                'SOAPAction: "http://www.url.com/UploadFile"',
                'Host: www.url.com',
                'Accept-Encoding: gzip, deflate',
                'Connection: Keep-Alive'
            );
    
            $post_data = "--{$boundary}\r\n";
            $post_data .= "Content-ID: <http://tempuri.org/0>\r\n";
            $post_data .= "Content-Transfer-Encoding: 8bit\r\n";
            $post_data .= 'Content-Type: application/xop+xml;charset=utf-8;type="text/xml"';
            $post_data .= "\r\n\r\n";
    
            $post_data .= $xml_request;
    
            $post_data .= "\r\n--{$boundary}\r\n";
            $post_data .= "Content-ID: <http://tempuri.org/1/635551016730489495>\r\n";
            $post_data .= "Content-Transfer-Encoding: binary\r\n";
            $post_data .= "Content-Type: application/octet-stream\r\n\r\n";
    
            $headers[] = "Content-length: ".($filesize+strlen($post_data));
    
            $post_data .= $file_content;       
            $post_data .= "--{$boundary}\r\n";
    
            $ch = curl_init($this->wsdl_url);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_VERBOSE, 0);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            $response = curl_exec($ch);
            $error = curl_error($ch);
    

    【讨论】:

      猜你喜欢
      • 2018-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-05
      • 1970-01-01
      • 1970-01-01
      • 2017-01-23
      相关资源
      最近更新 更多