У меня есть два домена, например example1.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> '; ?>
и handler.php в site2.loc вот так:
<?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
:
file_get_contents('http://site2.loc/pullfile.php?f=filename&sec=checkcode')
. Содержимое pullfile.php
будет делать именно это, вытащить файл с сайта «1» на «сайт 2». file_get_contents()
может быть проверен для возврата ошибки из pullfile.php
« pullfile.php
» pullfile.php
и ошибки, справиться с ним. Нет ошибки, удалите временный файл. &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>'; }
И это будет «pullfile.php» на сайте 2
// ----- 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;
CURLOPT_POSTFIELDS Полные данные для публикации в HTTP-режиме «POST». Чтобы опубликовать файл, добавьте имя файла с помощью @ и используйте полный путь. Это может быть передано как строка с urlencoded, например 'para1 = va1 & para2 = val2 & …', или как массив с именем поля в качестве ключа и данными поля в качестве значения. Если значением является массив, заголовок 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);
То, как вы делаете это прямо сейчас, не будет работать, потому что ваш сервер не отправляет файл на удаленный сервер, а локальное имя файла (от пользователя). Также для передачи файла через CURL вам нужно добавить '@' перед именем.
$c_pic = '@'. $_FILES['c_pic']['tmp_name']
Затем удаленный скрипт также должен получить файл из переменной $ _FILES и скопировать его где-нибудь с помощью move_uploaded_file
( PHP.net )
Также совет: проверьте $_FILES['c_pic']['error']
прежде чем делать это, чтобы предотвратить загрузку мусора на удаленный сервер.