我有两个域,例如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']; // 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中和handler.phploc
如下:<?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";
}
}
?>
这个脚本可以很好地将数据存储到数据库中,但不能用于上传图像文件。有没有人能帮我修改上面的脚本,以便上传一个图像文件?
谢谢。
答案中没有代码,只是一个工作流示例,将绕过curl
:
- 用户将上传的文件发送到"站点1",与正常情况一样。
- "site 1"处理表单和上传的文件。该文件被放置在一个临时目录中,该目录可以通过web访问。
- 在"站点1",上传的文件被检查后,呼叫
file_get_contents('http://site2.loc/pullfile.php?f=filename&sec=checkcode')
。pullfile.php
的内容将做到这一点,将文件从"站点1"拉到"站点2"。 -
file_get_contents()
的返回可以检查从"站点2"pullfile.php
返回的错误,如果错误,处理它。没有错误,删除临时文件。 -
&sec=checkcode
可用于确认文件已成功上传至"site 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;
http://php.net/manual/en/function.curl-setopt.phpCURLOPT_POSTFIELDS在HTTP " post "中发送的全部数据操作。要发布文件,请在文件名前加上@,并使用完整的路径。这可以作为一个urlencoded字符串传递,比如"虽然= va1& para2 = val2&…'或作为一个数组,字段名作为键和字段数据作为值。如果value是数组,则为Content-Type报头将被设置为multipart/form-data。
代码片段:
$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']
然后远程脚本还必须从$_FILES变量中获取文件,并将其复制到move_uploaded_file
(PHP.net)
还有一个提示:在这样做之前检查$_FILES['c_pic']['error']
,以防止将垃圾上传到远程服务器。
Curl上传文件
// 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;
}