5

我有两个域,例如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>
    ';
?>

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

<?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";
        }
    }

?>

该脚本运行良好,可以将数据存储到数据库,但不能上传图像文件。任何人都可以帮我修改上面的脚本以上传图像文件吗?

之前谢谢。

4

4 回答 4

5

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

  1. 用户按照正常情况将带有上传文件的表单发布到“站点 1”。
  2. “站点 1”处理表单和上传的文件。该文件放置在一个可通过网络访问的临时目录中。
  3. 在“站点 1”上,检查上传的文件后,file_get_contents('http://site2.loc/pullfile.php?f=filename&sec=checkcode')拨打电话。的内容就是pullfile.php这样做的,将文件从“站点 1”拉到“站点 2”。
  4. file_get_contents()可以检查来自“站点 2”的错误返回,如果出现pullfile.php错误,则处理它。没有错误,删除临时文件。
  5. &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>';
}

这将是站点 2 上的“pullfile.php”

// ----- Site 2, pullfile.php -----

// This script will pull a file from site 1 and
// place it in '/uploaded'

// used to cross-check the uploaded file
$fileMd5 = $_GET['md5'];
$fileName = basename($_GET['f']);

// we need to pull the file from the './tmp/' dir on site 1
$pulledFile = file_get_contents('http://'.SITE_1_URL.'/tmp/'.$fileName);

// save that file to disk
$result = file_put_contents('./uploaded/'.$fileName,$pulledFile);
if (! $result) {
    echo 'Error: problem writing file to disk';
    exit;
}

$pulledMd5 = md5_file('./uploaded/'.$fileName);
if ($pulledMd5 != $fileMd5) {
    echo 'Error: md5 mis-match';
    exit;
}

// At this point, everything should be right.
// We pass back 'done' to site 1, so we know 
// everything went smooth. This way, a 'blank'
// return can be treated as an error too.
echo 'done';
exit;
于 2013-05-16T10:14:18.347 回答
3

CURLOPT_POSTFIELDS 要在 HTTP“POST”操作中发布的完整数据。要发布文件,请在文件名前加上 @ 并使用完整路径。这可以作为 urlencoded 字符串传递,如 'para1=va1¶2=val2&...' 或作为字段名称作为键和字段数据作为值的数组。如果 value 是一个数组,则 Content-Type 标头将设置为 multipart/form-data。

http://php.net/manual/en/function.curl-setopt.php

代码片段:

$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);
于 2013-05-16T10:04:11.423 回答
2

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

$c_pic = '@'. $_FILES['c_pic']['tmp_name']

然后远程脚本还必须从 $_FILES 变量中获取文件并使用move_uploaded_filePHP.net)将其复制到某处

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

于 2013-05-16T10:04:35.183 回答
0

卷曲上传文件

// 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;
}
于 2018-09-23T15:14:58.320 回答