I have an HTML code that allows me to upload the file successfully in server.
<form action="http://aa.bb.ccc.dd/xxx/upload.php" method="post" enctype="multipart/form-data">
<label for="text">Campaign:</label>
<input type="text" name="campaign" value="abcde" readonly="readonly"/><br/>
<label for="file">Upload type:</label>
<input type="text" name="filename" value="0.csv" readonly="readonly"/><br/>
<label for="file">Filename:</label>
<input type="file" name="file" id="file"/><br/>
<input type="submit" name="submit" value="Submit" />
</form>
I am writing an equivalent code in php to upload a file via curl. But the file does not get uploaded. Can anyone please help me on this. My php server code is as follows:
<code>$target_url = 'http://aa.bb.ccc.dd/xxx/upload.php';
$file_name_with_full_path = realpath('./upload/abc.txt');
$post = array('campaign' => 'abcde','file'=>'#'.$file_name_with_full_path,'filename'=>'5.csv');
$header = array('Content-Type: multipart/form-data');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$target_url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$result=curl_exec ($ch);
curl_close ($ch);
echo "Result: ".$result."\n";</code>
The result also gives 1, but the file is not uploaded when I check in the server. What is that I am missing?
Any help would be greatly appreciated!
I am interested in using PHP 'cURL'. This looks like a fairly standard requirement.
I looked at some of the 'cURL PHP examples on the web'.
Actually, using the code you have posted, there isn't anything really amiss that i can see.
Whatever, i have used your code and created similar scripts. Alas, you didn't post your 'upload.php' script. I have created one that does validation as mentioned in the PHP manual: http://www.php.net/manual/en/features.file-upload.php.
Although this example is for a 'localhost'. I have run it using a ' real' external host and it works fine.
Tested on PHP 5.3.18 on windows and Linux with PHP 5.3.28.
The Html form, was some confusion with labels as regards 'for':
<form action="process_uploaded_file.php" method="post" enctype="multipart/form-data">
<label for="text">Campaign:</label>
<input type="text" name="campaign" value="abcde" readonly="readonly"/><br/>
<label for="filetype">Upload type:</label>
<input type="text" name="filetype" value="0.csv" readonly="readonly"/><br/>
<label for="file">Filename:</label>
<input type="file" name="file" id="file"/><br/>
<input type="submit" name="submit" value="Submit" />
</form>
cURL Script:
<?php
$target_url = 'http://localhost/testmysql/process_uploaded_file.php';
$full_path_to_source_file = __DIR__ .'/sourcefiles/testupload1.csv' ;
$post = array('campaign' => 'abcde', 'file'=>'#'. $full_path_to_source_file, 'filename' => 'curl1.csv');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$target_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$result=curl_exec ($ch);
curl_close ($ch);
var_dump($result);
Notice, no special 'enctype' header was required. Used the 'RETURNTRANSFER' option explicitly although the information was returned anyway.
Process Uploaded File script:
Implements a lot of recommended checks.
<?php session_start();
define('BIGGEST_FILE', 256 * 1024); // max upload file size
define('UPLOAD_DIRECTORY', 'P:/developer/xampp/htdocs/uploadedfiles'); // my data upload directory
if (empty($_FILES)) { // process the uploaded file...
die('no input file provided... '. __FILE__.__LINE__);
}
/* */
// validate the data -- see http://www.php.net/manual/en/features.file-upload.php
try {
// Undefined | Multiple Files | $_FILES Corruption Attack
// If this request falls under any of them, treat it invalid.
if ( !isset($_FILES['file']['error'])
|| is_array($_FILES['file']['error'])) {
throw new RuntimeException('Invalid parameters.');
}
// Check $_FILES['file']['error'] value.
switch ($_FILES['file']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
throw new RuntimeException('No file sent.');
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
throw new RuntimeException('Exceeded filesize limit.');
default:
throw new RuntimeException('Unknown errors.');
}
// You should also check filesize here.
if ($_FILES['file']['size'] > BIGGEST_FILE) {
throw new RuntimeException('Exceeded filesize limit.');
}
// DO NOT TRUST $_FILES['file']['mime'] VALUE !!
// Check MIME Type by yourself.
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $_FILES['file']['tmp_name']);
/* */
if (false === $fileExt = array_search($mimeType,
array(
'jpg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
'csv' => 'text/plain',
),
true
)) {
throw new RuntimeException('Invalid file format.');
}
// check 'campaign' for safe in filename...
if (preg_match('/\w/', $_POST['campaign']) !== false) {
$campaign = $_POST['campaign'];
}
else {
$campaign = md5($_POST['campaign']); // sort of useful
}
// Now move the file to my data directory
// You should name it uniquely.
// DO NOT USE $_FILES['file']['name'] WITHOUT ANY VALIDATION !!
// On this example, obtain safe unique name from its 'campaign' and 'tmp_name'.
$destFilename = sprintf('campaign_%s_%s.%s',
$campaign,
sha1_file($_FILES['file']['tmp_name']),
$fileExt);
if (!move_uploaded_file($_FILES['file']['tmp_name'],
UPLOAD_DIRECTORY .'/'. $destFilename)) {
throw new RuntimeException('Failed to move uploaded file.');
}
echo $_FILES['file']['tmp_name'], ' uploaded to: ', UPLOAD_DIRECTORY .'/'. $destFilename;
} catch (RuntimeException $e) {
echo $e->getMessage();
}
Related
I'm attempting to write a file to a server from my local machine using LibCURL, C++, and php, and I am running into an error, instead of the form completing, I am getting the error message "411 length required".
I am working from this example
http://curl.haxx.se/libcurl/c/postit2.html
This is my php form which I have verified as working
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Enter file: <input type="file" name="sendfile" size="40">
<input type="submit" value="send" name="submit">
</form>
<?php
echo “request method: " . $_SERVER[REQUEST_METHOD];
if( "$_SERVER[REQUEST_METHOD]" == "POST" || "$_SERVER[REQUEST_METHOD]" == "PUT")
{
echo "Success <br>";
if( $_FILES['sendfile']['name'] != "" )
{
$target_dir = "test/";
$target_file = $target_dir . basename($_FILES["sendfile"]["name"]);
if (move_uploaded_file($_FILES["sendfile"]["tmp_name"], $target_file))
{
echo "The file ". basename( $_FILES["sendfile"]["name"]). " has been uploaded.";
}
else
{
echo "Sorry, there was an error uploading your file.";
}
}
else
{
die("No file specified!");
}
}
?>
</body>
</html>
And this is the libcurl code which is pretty faithful to the example apart from the 3 lines in the set upload file section. This is something which I tried based on a different example.
//setup
curl_global_init(CURL_GLOBAL_ALL);
handle = curl_easy_init();
post = NULL;
last = NULL;
header_list = NULL;
uploadFile = NULL;
curl_easy_setopt(handle, CURLOPT_NOPROGRESS, ofGetLogLevel() <= OF_LOG_VERBOSE ? 0 : 1);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, true);
curl_easy_setopt(handle, CURLOPT_VERBOSE, ofGetLogLevel() <= OF_LOG_VERBOSE);
curl_easy_setopt(handle, CURLOPT_CAINFO, ofToDataPath("cacert.pem").c_str());
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, content_writer);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &content);
curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, header_writer);
curl_easy_setopt(handle, CURLOPT_WRITEHEADER, &header);
//seturl
curl_easy_setopt(handle, CURLOPT_URL, “link to hosted php file on server”);
//add form field
curl_formadd(&post, &last, CURLFORM_COPYNAME, "sendfile", CURLFORM_FILE, “filepath on my local system”, CURLFORM_END);
//set upload file
FILE* uploadFile = fopen(“filepath on my local system”, "rb");
curl_easy_setopt(handle, CURLOPT_UPLOAD, 1);
curl_easy_setopt(handle, CURLOPT_READDATA, uploadFile);
//perform
CURLcode ret = curl_easy_setopt(handle, CURLOPT_VERBOSE, ofGetLogLevel() <= OF_LOG_VERBOSE);
ret = curl_easy_setopt(handle, CURLOPT_NOPROGRESS, ofGetLogLevel() <= OF_LOG_VERBOSE ? 0 : 1);
ret = curl_easy_setopt(handle, CURLOPT_HTTPPOST, post);
ret = curl_easy_perform(handle);
curl_formfree(post);
post = NULL;
fclose(uploadFile);
uploadFile = NULL;
I have tried adding a header with the string "Content-Length: 0" and "Content-Length: 44000" (the size of the test jpg) but neither change the error.
there are similar questions on here but only one is using c++ which is this one
error 411 Length Required c++, libcurl PUT request
but it doesn't quite fit my situation and doesn't provide any answers either.
Set CURLOPT_INFILESIZE like so:
curl_easy_setopt(handle, CURLOPT_INFILESIZE, 44000);
I've got the following code and it works perfectly fine for uploading one image to Imgur using their API:
$client_id = $myClientId;
$file = file_get_contents($_FILES["file"]["tmp_name"]);
$url = 'https://api.imgur.com/3/image.json';
$headers = array("Authorization: Client-ID $client_id");
$pvars = array('image' => base64_encode($file));
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL=> $url,
CURLOPT_TIMEOUT => 30,
CURLOPT_POST => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $pvars
));
$json_returned = curl_exec($curl); // blank response
$json = json_decode($json_returned, true);
curl_close ($curl);
However I need to upload multiple images at once. On the client side, the user will have multiple <input type="file" /> fields. I'm completely stuck now with figuring out where and how I will need to modify this code in order to handle multiple image upload when they come through to the server in the form of an array. Does anyone have any ideas?
Change the markup as follows:
<form action="file-upload.php" method="post" enctype="multipart/form-data">
Send these files:<br />
<input name="file[]" type="file" multiple="multiple" /><br />
<input type="submit" value="Send files" />
</form>
Now, you can loop through the $_FILES array using a foreach, like so:
foreach ($_FILES['file']['tmp_name'] as $index => $tmpName) {
if( !empty( $tmpName ) && is_uploaded_file( $tmpName ) )
{
// $tmpName is the file
// code for sending the image to imgur
}
}
I am developing a web application that uses JQuery AJAX and PHP to upload some data into my database.
One of the fields of the form to be submitted is an URL of a image (any address of the WEB). This image should be downloaded to my FTP server and then its new addrress would be inserted into the database.
How can I download an image from any URL and upload it to my FTP server?
Form:
<form id="form-id" method="post" action="insert.php" charset=utf-8">
<input type="text" name="title" id="title">
<input type="text" name="image-url" id="image-url">
<input type="submit" name="submit" id="submit">
</form>
JavaScript
$("#submit").live("click", function(event){
event.preventDefault();
$.ajax({
type : "POST",
url : "insert.php",
data : {
'title': valueTitle,
'image': valueImage
},
cache : false,
success : function(html) {
if (html == "success") {
//...
} else if (html == "ftp-error") {
//...
} else if (html == "sql-error") {
//...
}
}
});
});
insert.php
$title = $_REQUEST['title'];
$image = $_REQUEST['image'];
$imageInMyServer = downloadImageFromURLAndUploadFTP($image);
function downloadImageFromURLAndUploadFTP($image) {
//that is what I want to know how to do.
}
//sql query with $title and $imageInMyServer
Notes:
The file I want to download is not on my server. It is somewhere else in the Internet and I need to download it to my FTP server
No. I cannot use the first external URL in my SQL Query
Here is a great example on how to do FTP transfers in PHP. As far as downloading the file, you could use wget if you're on linux (using the exec() function).
exec('wget -q ' . $url . ' -0 /path/to/newfile');
Stealing a code snippet from that link I gave you, here is what your function might look like:
function downloadImageFromURLAndUploadFTP($image) {
// in your case it would be some img extension like .jpg, .gif, or .png
// you can check the extension of $image and use that if you want.
$newFile = '/path/to/newfile.ext';
exec('wget -q ' . $image . ' -0 ' . $newFile);
if (file_exists($newFile)) {
// set up connection and login
$connect = ftp_connect($ftpServer);
$login = ftp_login($connect, $ftpUser, $ftpPass);
// check connection
if (!$connect || !$login) {
die('FTP connection has failed!');
} else {
echo "Connected to {$ftpServer}, for user {$ftpUser}";
}
// upload the file
$fileNameOnFTPServer = 'whateverYouWantToNameIt.ext'; // arbitrary extension
$upload = ftp_put($connect, $fileNameOnFTPServer, $newFile, FTP_BINARY);
// check upload status
if (!$upload) {
echo "FTP upload has failed!";
} else {
echo "Uploaded {$image} to {$ftpServer} as {$fileNameOnFTPServer}";
}
ftp_close($connect);
}
}
Note: Sometimes file_exists() doesn't behave the way we intended when the path begins with /. For example /path/to/file might exist but file_exists() will think it doesn't unless you remove the beginning "/". One way to get around that is to check it like this:
file_exists(substr($newFile, 1))
Good luck!
An alternative solution if you do not have exec privileges is to use curl to grab the image, or you could use file_get_contents(), there are many ways, its just personal preference.
Ive put together what your script may look like, im sure you can improve it.
insert.php
<?php
if(isset($_POST['image']) && isset($_POST['title'])){
if(substr($_POST['image'],0,4)=='http'){
$image = curlgetimage($_POST['image']);
$info = pathinfo($_POST['image']);
if(isset($info['extension']) && ($info['extension']=='gif' || $info['extension']=='png' || $info['extension']=='jpg')){
$path='./temp/'.md5($_POST['image']).'.'.$info['extension'];
file_put_contents($path,$image);
if(ftp_put_image($path)===true){
//Do your database stuff, remember to escape..
unlink($path);
echo 'Success';
}else{
echo 'ftp-fail';
}
}else{
echo'File type not allowed';
}
}else{
echo'Must start with http://';
}
}else{
header('Location: http://www.example.com/');
}
function ftp_put_image($file){
if(!file_exists($file)){return false;}
$fp = fopen($file, 'r');
$conn_id = ftp_connect('ftp.yourhost.com'); //change
$login_result = ftp_login($conn_id,'username','password'); //change
$return=(ftp_fput($conn_id, $file, $fp, FTP_BINARY))?true:false;
ftp_close($conn_id);
fclose($fp);
return $return;
}
function curlgetimage($url) {
$header[] = 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg';
$header[] = 'Connection: Keep-Alive';
$header[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8';
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_USERAGENT, 'YourSpiderBot/0.01 (Bla Bla Robot; http://www.example.com; spider#example.com)'); //change
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_REFERER, $url);
curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
$return = curl_exec($curl);
curl_close($curl);
return $return;
}
?>
I'm using cURL to transfer image files from one server to another using PHP. This is my cURL code:
// Transfer the original image and thumbnail to our storage server
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, 'http://' . $server_data['hostname'] . '.localhost/transfer.php');
curl_setopt($ch, CURLOPT_POST, true);
$post = array(
'upload[]' => '#' . $tmp_uploads . $filename,
'upload[]' => '#' . $tmp_uploads . $thumbname,
'salt' => 'q8;EmT(Vx*Aa`fkHX:up^WD^^b#<Lm:Q'
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$resp = curl_exec($ch);
This is the code in transfer.php on the server I'm uploading to:
if($_FILES && $_POST['salt'] == 'q8;EmT(Vx*Aa`fkHX:up^WD^^b#<Lm:Q')
{
// Save the files
foreach($_FILES['upload']['error'] as $key => $error)
{
if ($error == UPLOAD_ERR_OK)
{
move_uploaded_file($_FILES['upload']['tmp_name'][$key], $_FILES['upload']['name'][$key]);
}
}
}
All seems to work, apart from one small logic error. Only one file is getting saved on the server I'm transferring to. This is probably because I'm calling both images upload[] in my post fields array, but I don't know how else to do it. I'm trying to mimic doing this:
<input type="file" name="upload[]" />
<input type="file" name="upload[]" />
Anyone know how I can get this to work? Thanks!
here is your error in the curl call...
var_dump($post)
you are clobbering the array entries of your $post array since the key strings are identical...
make this change
$post = array(
'upload[0]' => '#' . $tmp_uploads . $filename,
'upload[1]' => '#' . $tmp_uploads . $thumbname,
'salt' => 'q8;EmT(Vx*Aa`fkHX:up^WD^^b#<Lm:Q'
);
The code itself looks ok, but I don't know about your move() target directory. You're using the raw filename as provided by the client (which is your curl script). You're using the original uploaded filename (as specified in your curl script) as the target of the move, with no overwrite checking and no path data. If the two uploaded files have the same filename, you'll overwrite the first processed image with whichever one got processed second by PHP.
Try putting some debugging around the move() command:
if (!move_uploaded_file($_FILES['upload']['tmp_name'][$key], $_FILES['upload']['name'][$key])) {
echo "Unable to move $key/";
echo $_FILES['upload']['tmp_name'][$key];
echo ' to ';
echo $_FILES['upload']['name'][$key];
}
(I split the echo onto multiple lines for legibility).
wondering if anyone can help me. I've been searching for a few days for help on how to publish photos to Facebook using the API. I came across the following script that seems to work for everyone however I am unsure how to connect this to a form where users can select the photo from their hard drive and upload it. Can anyone point me in the right direction?
PHP Code:
$token = $session['access_token'];
$file= 'photo.jpg';
$args = array(
'message' => 'Photo from application',
);
$args[basename($file)] = '#' . realpath($file);
$ch = curl_init();
$url = 'https://graph.facebook.com/me/photos?access_token='.$token;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $args);
$data = curl_exec($ch);
Code for the form:
<form action="<?=$PHP_SELF;?>" enctype="multipart/form-data" method="POST">
<input name="MAX_FILE_SIZE" type="hidden" value="10000000" />
<input id="file" name="file" type="file" />
<input name="submit" type="submit" value="Upload" />
</form>
Clark,
The php script receives the file and its details in the $_FILES variable.
For Eg. If you are uploading a file names Image1.jpg then the $_FILES array would have the following values
array(1) {
["file"]=> array(5) {
["name"]=> string(21) "Image1.jpg"
["type"]=> string(10) "image/jpeg"
["tmp_name"]=> string(23) "C:\wamp\tmp\phpD1DF.tmp
["error"]=> int(0)
["size"]=> int(355315)
}
}
Here, name = actual file name
type = file type
tmp_name = path of the temp location where the file is uploaded on the server
size = file size
For uploading the file to facebook the values that you should be interested in the "name" and the "tmp_name".
So the arguments that you should send to facebook for the photo upload should look something like this
$args = array(
'message' => 'Photo from application',
);
$args[$_FILES['file']['name']] = '#' . $_FILES['file']['tmp_name'];
I think this should work for you.
Btw, i checked out the facebook doc for photo upload # http://developers.facebook.com/docs/reference/api/photo they say the file name should be passed in the param "source", so if the above arguments dont work for you, you can try
$args = array(
'message' => 'Photo from application',
'source' => '#' . $_FILES['file']['tmp_name']
);
Give it a try :)
Hope this helps.