Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP-使用CURL将图像文件上载到其他域_Php_File Upload_Curl - Fatal编程技术网

PHP-使用CURL将图像文件上载到其他域

PHP-使用CURL将图像文件上载到其他域,php,file-upload,curl,Php,File Upload,Curl,我有两个域,例如site1.loc和site2.loc。在site1.loc中,我有一个php表单文件,如下所示: <?php $c_name = ""; $c_phone = ""; if($_SERVER['REQUEST_METHOD']=="POST"){ $c_name = $_POST['c_name']; $c_phone = $_POST['c_phone']; $c_pic = $_FILES['c_pic']['name']; // Imag

我有两个域,例如site1.locsite2.loc。在site1.loc中,我有一个php表单文件,如下所示:

<?php
$c_name = "";
$c_phone = "";

if($_SERVER['REQUEST_METHOD']=="POST"){

    $c_name = $_POST['c_name'];
    $c_phone = $_POST['c_phone'];
    $c_pic = $_FILES['c_pic']['name']; // Image file

        // submit target URL
        $url = 'http://site2.loc/handler.php';

        $fields = array(
           'field1'=>$c_name,
           'field2'=>$c_phone,
           'field3'=>$c_pic
        );

        $postvars='';
        $sep='';
        foreach($fields as $key=>$value) 
        { 
           $postvars.= $sep.urlencode($key).'='.urlencode($value); 
           $sep='&'; 
        }


        //open connection
        $ch = curl_init();

        //set the url, number of POST vars, POST data
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_POST,count($fields));
        curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);

        //execute post
        $result = curl_exec($ch);

        if(curl_errno($ch)) {
            echo 'Error: ' . curl_error($ch);
        }
        else {
            echo $result;
        }

        //close connection
        curl_close($ch);

}


echo '
<form action="" method="post" enctype="multipart/form-data">
    Name : <input type="text" name="c_name" value="'.$c_name.'" /> <br />
    Phone : <input type="text" name="c_phone" value="'.$c_phone.'" /> <br />
    Image : <input type="file" name="c_pic" /> <br />
    <input type="submit" />
</form>
    ';
?>
<?php
ob_start();
if (!isset($_SESSION)) { session_start(); }

    // CONNECT TO DB
    $db_con = mysql_connect("localhost", "root", "root");// or die("Could not connect to db.");
    if(!mysql_select_db("site2",$db_con)) die("No database selected.");

    // POST
    if(isset($_POST)){
        $c_name = $_POST['field1'];
        $c_phone = $_POST['field2'];    
        $c_pic = $_POST['field3'];  

        // UPLOAD FILE
        /* UPLOAD IMAGE CODE HERE */

        // INSERT TO DB
        if(mysql_query("INSERT INTO kontak (nama, telpon) VALUES ('$c_name','$c_phone')")){
            echo "INSERT SUCCESS";
        } else {
            echo "INSERT FAILED";
        }
    }

?>

site2.loc中的handler.php,如下所示:

<?php
$c_name = "";
$c_phone = "";

if($_SERVER['REQUEST_METHOD']=="POST"){

    $c_name = $_POST['c_name'];
    $c_phone = $_POST['c_phone'];
    $c_pic = $_FILES['c_pic']['name']; // Image file

        // submit target URL
        $url = 'http://site2.loc/handler.php';

        $fields = array(
           'field1'=>$c_name,
           'field2'=>$c_phone,
           'field3'=>$c_pic
        );

        $postvars='';
        $sep='';
        foreach($fields as $key=>$value) 
        { 
           $postvars.= $sep.urlencode($key).'='.urlencode($value); 
           $sep='&'; 
        }


        //open connection
        $ch = curl_init();

        //set the url, number of POST vars, POST data
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_POST,count($fields));
        curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);

        //execute post
        $result = curl_exec($ch);

        if(curl_errno($ch)) {
            echo 'Error: ' . curl_error($ch);
        }
        else {
            echo $result;
        }

        //close connection
        curl_close($ch);

}


echo '
<form action="" method="post" enctype="multipart/form-data">
    Name : <input type="text" name="c_name" value="'.$c_name.'" /> <br />
    Phone : <input type="text" name="c_phone" value="'.$c_phone.'" /> <br />
    Image : <input type="file" name="c_pic" /> <br />
    <input type="submit" />
</form>
    ';
?>
<?php
ob_start();
if (!isset($_SESSION)) { session_start(); }

    // CONNECT TO DB
    $db_con = mysql_connect("localhost", "root", "root");// or die("Could not connect to db.");
    if(!mysql_select_db("site2",$db_con)) die("No database selected.");

    // POST
    if(isset($_POST)){
        $c_name = $_POST['field1'];
        $c_phone = $_POST['field2'];    
        $c_pic = $_POST['field3'];  

        // UPLOAD FILE
        /* UPLOAD IMAGE CODE HERE */

        // INSERT TO DB
        if(mysql_query("INSERT INTO kontak (nama, telpon) VALUES ('$c_name','$c_phone')")){
            echo "INSERT SUCCESS";
        } else {
            echo "INSERT FAILED";
        }
    }

?>

CURLOPT_post字段要在HTTP“post”中发布的完整数据
活动若要发布文件,请在文件名前加上@,并使用完整的
路径这可以作为URL编码的字符串传递,如
“para1=va1¶2=val2&…”或作为字段名为key和
字段数据作为值。如果值是数组,则内容类型标头
将设置为多部分/表单数据

代码段:

$postvars['file'] = '@full/path/to/file.jpg';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);
curl_exec($ch);

您现在这样做的方式将不起作用,因为您的服务器不会将文件发送到远程服务器,而是发送本地文件名(来自用户)。此外,要通过CURL传输文件,需要在名称前添加“@”

$c_pic = '@'. $_FILES['c_pic']['tmp_name']
然后,远程脚本还必须从$\u FILES变量获取文件,并使用
move\u uploaded\u file
()


还有一个提示:在执行此操作之前,请检查
$\u文件['c_pic']['error']
,以防止将垃圾上载到远程服务器。

此答案中没有代码,只是一个将绕过
curl
的工作流示例:

  • 用户将上传文件的表单按照正常方式发布到“站点1”
  • “站点1”处理表单和上载的文件。该文件放置在可通过web访问的临时目录中
  • 在“站点1”上,检查上传的文件后,制作一个
    file\u get\u contents('http://site2.loc/pullfile.php?f=filename&sec=checkcode)
    call。php
    pullfile.php
    的内容就是这样做的,将文件从“site1”拉到“site2”
  • 可以检查从“site 2”
    pullfile.php
    返回的
    file\u get\u contents()
    返回的错误,并在出现错误时进行处理。没有错误,请删除临时文件
  • &sec=checkcode
    可用于确认文件已成功上载到“站点2”。它可能是该文件的MD5或您提出的其他内容
  • 只是个主意

    编辑:一些示例代码有助于使事情更清楚,可能:]

    // ---- Site 1, formprocess.php ----
    
    // Your form processing goes here, including
    // saving the uploaded file to a temp dir.
    
    // Once the uploaded file is checked for errors, 
    // you need move it to a known temp folder called 
    // 'tmp'.
    
    // this is the uploaded file name (which you would
    // have got from the processed form data in $_FILES
    // For this sample code, it is simple hard-coded.
    $site1File = 'test.jpg';
    
    $site1FileMd5 = md5_file('./tmp/'.$site1File);
    
    // now make a remote request to "site 2"
    $site2Result = file_get_contents('http://'.SITE_2_URL.'/pullfile.php?f='.$site1File.'&md5='.$site1FileMd5);
    
    if ($site2Result == 'done') {
        unlink('./tmp/'.$site1File);
    } else {
        echo '<p>
             Uploaded file failed to transfer to '.SITE_2_URL.'
              - but will be dealt with later.
             </p>';
    }
    
    卷曲上传文件

    // data fields for POST request
    $fields = array("f1"=>"value1", "another_field2"=>"anothervalue");
    
    // files to upload
    $filenames = array("/tmp/1.jpg", "/tmp/2.png");;
    
    $files = array();
    foreach ($filenames as $f){
       $files[$f] = file_get_contents($f);
    }
    
    // URL to upload to
    $url = "http://example.com/upload";
    
    
    // curl
    
    $curl = curl_init();
    
    $url_data = http_build_query($data);
    
    $boundary = uniqid();
    $delimiter = '-------------' . $boundary;
    
    $post_data = build_data_files($boundary, $fields, $files);
    
    
    curl_setopt_array($curl, array(
      CURLOPT_URL => $url,
      CURLOPT_RETURNTRANSFER => 1,
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 30,
      //CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => "POST",
      CURLOPT_POST => 1,
      CURLOPT_POSTFIELDS => $post_data,
      CURLOPT_HTTPHEADER => array(
        //"Authorization: Bearer $TOKEN",
        "Content-Type: multipart/form-data; boundary=" . $delimiter,
        "Content-Length: " . strlen($post_data)
    
      ),
    
    
    ));
    
    
    //
    $response = curl_exec($curl);
    
    $info = curl_getinfo($curl);
    //echo "code: ${info['http_code']}";
    
    //print_r($info['request_header']);
    
    var_dump($response);
    $err = curl_error($curl);
    
    echo "error";
    var_dump($err);
    curl_close($curl);
    
    
    
    
    function build_data_files($boundary, $fields, $files){
        $data = '';
        $eol = "\r\n";
    
        $delimiter = '-------------' . $boundary;
    
        foreach ($fields as $name => $content) {
            $data .= "--" . $delimiter . $eol
                . 'Content-Disposition: form-data; name="' . $name . "\"".$eol.$eol
                . $content . $eol;
        }
    
    
        foreach ($files as $name => $content) {
            $data .= "--" . $delimiter . $eol
                . 'Content-Disposition: form-data; name="' . $name . '"; filename="' . $name . '"' . $eol
                //. 'Content-Type: image/png'.$eol
                . 'Content-Transfer-Encoding: binary'.$eol
                ;
    
            $data .= $eol;
            $data .= $content . $eol;
        }
        $data .= "--" . $delimiter . "--".$eol;
    
    
        return $data;
    }
    

    为什么要绕过curl?因为它不是必需的,而且有些服务器不包含curl扩展名。问题明确说明了curl的用法,所以我猜Fredy的服务器上有curl。对我和我个人来说,
    file\u get\u contents($url)
    调用远没有处理
    curl
    以及对其进行
    post
    调用所需的一切复杂。问题是,您必须自己处理超时失败,因为最终请求将失败,图像将无法从site1中删除,而在curl选项中,不存储图像在脚本执行完成后,inbetween PHP将从临时目录中清除文件本身。我已经尝试过,但没有成功。如果你别无选择,我会期待的。