I want to upload images to a server using ajax and php.
On client-side i hava the following code:
var reader = new FileReader();
reader.readAsDataURL(file, 'UTF-8');
reader.onload = function (event) {
var result = event.target.result;
$.ajax({
type: "POST",
url: "url",
data: {
data: result,
name: file.name,
mimeType: file.type
}
});
};
On server-side my code looks like the following:
$path = 'somehow/'
$fp = fopen( $path . $_POST['name'], 'w');
$data = explode( ',', $_POST['data'] );
fwrite($fp, base64_decode( $data[ 1 ] ));
fclose($fp);
chmod($path . $_POST['name'], 7777);
list($width, $height) = getimagesize($path . $_POST['name']);
Now the method "getimagesize" always runs into an error "getimagesize(): Read error!"
Does anybody know, why this happens? When i look into the filesystem on the server the file 'FILENAME.JPG' exists ...
You can use $result = #getimagesize($file) to suppress the error.
So, when the $result is empty, means there is an error occurred.
There are two possible reasons for this error : either the url path is incommplete/incorrect or the picture file is corrupt and cannot be opened. A file may be corrupted, for example, if the image is not fully/correctly loaded onto the server.
Related
I'm almost finishing building a functionality for parsing CSV files to JSON and just need help in piecing it together. The way it works is that files will be uploaded using AJAX/Jquery. Once the files has been uploaded and sent the PHP to parse the CSV file to JSON will then execute.
After parsing, the converted file will be push or sent to the API as a JSON object. Here is the code that I have been working. For the uploading i'm using this plugin AJAX/JQuery File Uploader
This functionality is also built on using RactiveJS
AJAX/Jquery File Uploader
This is the section where I'm currently uploading or placing the file. URL is pointed at the upload.php.
<div id="fileuploader">Upload</div>
<script>
$(document).ready(function() {
$("#fileuploader").uploadFile({
url: 'upload.php',
});
})
</script>
Uploads.php
Is there a way to GET the temporary copy of the uploaded file and parse using the PHP code I have built below to convert the CSV to JSON
<?php
if ( 0 < $_FILES['file']['error'] ) {
echo 'Error' . $_FILES['file']['error'] . '<br/>';
}
else {
move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']);
}
?>
PHP (CSV to JSON)
Right now be the file is being declared manually.
<?php
$json_data = csvToJson('lms.csv');
?>
<?php
function csvToJson($fname) {
if (!($fp = fopen($fname, 'r') )) {
die("Can't open file");
}
else {
('Upload File');
}
$key = fgetcsv($fp, "1024", ",");
$json = array();
while ($row = fgetcsv($fp, "1024", ",")) {
$json[] = array_combine($key, $row);
}
fclose($fp);
foreach ( $json as $k=>$v ) {
$json[$k]['accountName'] = $json[$k]['ACCOUNT NAME'];
$json[$k]['dateRequested'] = $json[$k]['DATE'];
unset($json[$k]['ACCOUNT NAME']);
unset($json[$k]['DATE']);
}
return json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);
}
?>
<?php // $target_file = fopen($_FILES["fileToUpload"]["tmp_name"], 'r'); ?>
Send Converted to API (Ractive/AJAX/JS)
As you can see the sending part is triggered by an on-click event (app.on)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ractive/0.9.0-build-48/ractive.js"></script>
<script type="text/javascript">
var app = new Ractive({
el : '#container',
template : '#template',
});
var proxy = 'http://192.168.1.126/lms-dev-noel/proxy.php';
var endpoint = 'account/leads/';
var rt = 'POST';
var url = proxy+'?endpoint='+endpoint+'&rt='+rt;
var lms_json = <?php echo json_encode($json_data); ?>;
var jobjects = JSON.parse(lms_json);
for ( i = 0; i < jobjects.length; i++ ) {
var data = jobjects[i];
console.log(data);
$.ajax({
type : 'POST',
url : url,
data : data,
dataType : 'json',
success : function() {
},
error : function(error) {
console.log('Error')
}
});
}
</script>
Warning and Notices
Well, it depends a bit on where that csvToJson function is located in your code. If it's within uploads.php, or in a separate file that you can include in uploads.php, then you can just do:
move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']);
$json_data = csvToJson('uploads/' . $_FILES['file']['name']);
echo $json_data;
Then in the script, change
var lms_json = <?php echo json_encode($json_data); ?>;
to
var lms_json;
and move it to the top of your javascript.
It seems like you are trying to assign the variable before the API call has been made. Instead you need to capture the data from the the response of the uploadFile call (as per these docs: http://hayageek.com/docs/jquery-upload-file.php):
$("#fileuploader").uploadFile({
url: 'upload.php',
onSuccess:function(files,data,xhr,pd)
{
//data: response from server
lms_json = data;
}
});
My problem here is even though it gets saved "successfully" the file is not actually saved. (I'm running this on the Cloud9IDE)
My folder exports is set to be readable and writable via chmod 777 -R ./.
Can someone explain to me why the hello.txt file is not being created, and what I can do to solve this problem?
JQuery:
$("[data-action=save-file]").on("click", function(e) {
var filename = "hello.txt"
var content = "Hello world!"
$.ajax({
type: "GET",
url: "submit.php",
data: {
"filename": filename,
"content": content,
},
cache: false,
success: function(msg) {
console.log(msg)
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log("Some error occurred")
}
})
})
PHP:
<?php
$filename = $_GET["filename"];
$fp = fopen("anon/".$filename, "wb");
if (!$fp) {
echo getcwd();
exit;
} else {
$outputstring = $_GET["outputstring"];
fwrite($fp, $outputstring);
}
$fclose($fp);
?>
I've also tried...
<?php
$filename = $_GET["filename"];
$outputstring = $_GET["outputstring"];
file_put_contents($filename, $outputstring, FILE_APPEND | LOCK_EX);
?>
If this is the actual code that is posted, then the arguments being sent by ajax are "content" and "filename", while php is expecting "outputstring" and "filename", so, on the php end, there is no "outputstring" and the program doesn't check for "content" in $_GET.
$filename = $_GET["filename"];
$outputstring = $_GET["content"];
file_put_contents($filename, $outputstring, FILE_APPEND | LOCK_EX);
Also there is a max length to too url parameters for GET (Max size of URL parameters in _GET), so if file content is ever an actual file this may be truncated. Try using type: "POST" instead.
maybe you should start debugging server side:
first of all, when using file_put_contents, check if it returns false (use operator ===). In this case folder anon/ doesn't exists.
second: check for writability of that folder with is_writable.
if (!isset($_GET[...], $_GET[...])) die("missing vars...");
if (!is_writable($filenamewithpath)) die("dir not writable");
if (file_put_contents(...) === false) die("dir doesn't exists");
if directory not writable, try using chmod($path, 0777). could be that your main directory is 0777 but not the sub-directories.
by the way, as others pointed out, your ajax call is sending "content", not "outputstring" as parameter. you should rename the data object key.
try also to use absolute path (using for example __DIR__ . "/anon/". $filename);
The code in php $fp.close() is error. It should be fclose($fp).
wb is not any mode in php. use w+ instead of wb
and you need to check folder is exist or not
$path = "anon";
if (!file_exists($path) && is_dir($path))
{
if (!mkdir($path, 0777, TRUE))
{
return false;
}
}
I am adding a file upload function to my php page. The code seems correct to me and it even adds the file to the server with the correct name, but with no contents. i.e. there is an empty .jpg file when loading an image.
Can any of you more experienced php developers see what I am doing wrong to produce empty files.
calling script:
<script>
$(document).ready(function(){
$("#mediaFileInput").on("change", function(e){
console
if (e.target.value) {
var formData = new FormData(e.target.form);
$.ajax({
url: 'media.php', //Server script to process data
type: 'POST',
success: function(data){
location.reload();
},
// Form data
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
}
});
});
</script>
media.php
<?php
require('config/config.php');
$file_uploaded;
$mime_type;
// Handle multipart file uploads
if (isset ( $_FILES ['file'] )) {
$file_uploaded = fopen($_FILES['file']['name'], "r");
$mime_type = $_FILES['file']['type'];
} else if ($_SERVER["REQUEST_METHOD"] == "POST") {
/* PUT data comes in on the stdin stream */
$file_uploaded = fopen("php://input", "r");
/* Open a file for writing */
$mime_type = $_SERVER["CONTENT_TYPE"];
}
$file_name = $_FILES['file']['name'];
$new_path = "media/" . $file_name;
$media_url = "/" . $new_path;
$fp = fopen($new_path, "w");
/* Read the data 1 KB at a time
and write to the file */
while ($data = fread($file_uploaded, 1024)) {
fwrite($fp, $data);
}
/* Close the streams */
fclose($fp);
fclose($file_uploaded);
chmod($new_path, 0755);
// insert into database.
$stmt = $db_conn->prepare("INSERT INTO MEDIA (type, url) VALUES(?, ?)");
$stmt->bind_param('ss',
$mime_type,
$media_url);
$stmt->execute();
$media_id = $db_conn->insert_id;
$stmt->close();
echo json_encode(array("id" => $media_id, "type" => $mime_type, "url" => $media_url));
?>
You should not be using fopen("php://input", "r"); because according to the docs for it:
php://input is not available with enctype="multipart/form-data".
When you're uploading a file, of course, you have to use enctype="multipart/form-data". So instead, use move_uploaded_file.
Also, fopen($_FILES['file']['name'], "r"); in your other branch doesn't make sense, since that's just trying to open a filename with no particular path. Use move_uploaded_file.
My problem is as follows...
I have a screen in which the user can select a PNG image from its computer, using this:
<input id='icon' type='file' accept='image/png' style='width:400px; height:20px' onchange='llenarThumbnail(this)'>
<img id='thumb' src='#'>
When the user selects the image, a thumbnail is shown automatically, using onclick='llenar Thumbnail(this)', like this:
function llenarThumbnail(input){
if (input.files && input.files[0]){
var reader = new FileReader();
reader.onload = function (e){
$('#thumb').attr('src', e.target.result).width(48).height(48);
};
reader.readAsDataURL(input.files[0]);
}
}
Then, when the user clicks on the proper button to upload the image (not a submit button), I do the following to encode the image into Base64:
function getBase64Image(img){
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
console.log(dataURL);
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
Then, using AJAX I send this encoded image data to the server, and a PHP script does the following:
$binary=base64_decode($imagen_data);
header('Content-Type: bitmap; charset=utf-8');
$file = fopen($icono, 'wb');
fwrite($file, $binary);
fclose($file);
As I was printing diferent alerts along the process, I could see that the encoding was performing (i'm not so sure if correctly or not), and PHP receives the data and creates the PNG file, but when I open the image, the image is empty, there's no data... Thats why I'm asking if this to methods are compatible... I guess they are because they're both Base64... But if its not this, then what am i doing wrong???
Please, I'm tired of looking for this all over the internet! I need some answers! Thank you!
Without seeing your ajax POST, here's a Wild Guess:
Try leaving the prefix on until the URL gets to php.
Which php server are you using?
Some other usual gotchas:
Make sure you have properly set up your upload directory.
Make sure you have permissions set properly on the upload directory.
Client Side:
// create a dataUrl from the canvas
var dataURL= canvas.toDataURL();
// post the dataUrl to php
$.ajax({
type: "POST",
url: "upload.php",
data: {image: dataURL}
}).done(function( respond ) {
// you will get back the temp file name
// or "Unable to save this image."
console.log(respond);
});
Server File: upload.php
<?php
// make sure the image-data exists and is not empty
// php is particularly sensitive to empty image-data
if ( isset($_POST["image"]) && !empty($_POST["image"]) ) {
// get the dataURL
$dataURL = $_POST["image"];
// the dataURL has a prefix (mimetype+datatype)
// that we don't want, so strip that prefix off
$parts = explode(',', $dataURL);
$data = $parts[1];
// Decode base64 data, resulting in an image
$data = base64_decode($data);
// create a temporary unique file name
$file = UPLOAD_DIR . uniqid() . '.png';
// write the file to the upload directory
$success = file_put_contents($file, $data);
// return the temp file name (success)
// or return an error message just to frustrate the user (kidding!)
print $success ? $file : 'Unable to save this image.';
}
I could not get markE solution to work, had to change the data modification :
From :
$parts = explode(',', $dataURL);
$data = $parts[1];
$data=base64_decode($data)
To :
$img = str_replace('data:image/png;base64,', '', $dataURL);
$img = str_replace(' ', '+', $img);
$data=base64_decode($img);
Method from
I am working in extjs+PHP[yii framework]. i am working on file upload control. i have view code as-
Ext.define('Balaee.view.kp.dnycontent.Content',
{
extend:'Ext.form.Panel',
requires:[
'Balaee.view.kp.dnycontent.ContentView'
],
id:'ContentId',
alias:'widget.Content',
enctype : 'multipart/form-data',
title:'This day in a history',
items:[
{
xtype: 'fileuploadfield',
hideLabel: true,
emptyText: 'Select a file to upload...',
//inputType: 'file',
id: 'upfile',
name:'file',
width: 220
}],
buttons: [{
xtype : 'button',
fieldlabel:'upload',
action:'upload',
name:'upload',
text: 'Upload',
formBind:'true',
handler: function() {
var form = this.up('form').getForm();
if(form.isValid()){
form.submit({
url: 'index.php/QuestionBank/Qbpaper/getFile',
waitMsg: 'Uploading your photo...',
// uploadPath:'/app/model',
success: function(fp, o) {
Ext.Msg.alert('Success', 'Your photo "' + o.result.file + '" has been uploaded.');
}
});} } }]});
i had written above code to send file from extjs4. My server side is in PHP [Yii framework]. To server side i had written code to receive this file as-
public function actiongetFile()
{
$fileName = $_FILES['upfile']['name'];
$fileSize = $_FILES['upfile']['size'];
$fileType = $_FILES['upfile']['type'];
$fp = fopen($fileName, 'r');
$content = fread($fp, filesize($fileName));
$content = addslashes($content);
fclose($fp);
if(!get_magic_quotes_gpc()){
$fileName = addslashes($fileName);
}
But server side code is not working correctly. While sending file from extjs,its giving error as-"Ext.Error: You're trying to decode an invalid JSON String:
PHP notice
Undefined index: upfile "
So in php how to access file which is get send via extjs4. Please help me
name:'file'
THIS ^ is index of you file in array.
id is internal, but name is a label for submition.
Try it. Use:
$_FILES['file']['name']
instead of:
$_FILES['upfile']['name']