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.
Related
Trying to save a jpg file to server with the name from an input box but gets saved as Array.jpg
Contents of html file:
<input type="text" name="datepicker" id="datepicker">
Contents of php file:
$image = $_POST['image'];
$location = "upload/";
$image_parts = explode(";base64,", $image);
$image_base64 = base64_decode($image_parts[1]);
$filename = ['datepicker'].'.jpg';
echo $_REQUEST['datepicker'];
$file = $location . $filename;
file_put_contents($file, $image_base64);
Script from the html:
<script type='text/javascript'>
function screenshot(){
html2canvas(document.body).then(function(canvas) {
// Get base64URL
var base64URL = canvas.toDataURL('image/jpeg').replace('image/jpeg', 'image/octet-stream');
// AJAX request
$.ajax({
url: 'ajaxfile.php',
type: 'post',
data: {image: base64URL},
success: function(data){
console.log('Upload successfully');
}
});
});
}
</script>
no error messages , just saves with wrong name.
Have now tried:
$filename = ['datepicker']; - saves as: Array (no extension).
$filename = $_POST['datepicker']; (nothing gets saved at all).
$filename = $_POST['datepicker'].'.jpg'; (saves as .jpg (just extension, no file name).
$filename = $_FILES['datepicker']['name']; (nothing gets saved at all).
$filename = $datepicker; (nothing gets saved at all).
$filename = "screenshot_".uniqid().'.jpg'; saved as screenshot_5d40158a1dad5.jpg
It seems to me that the form name field, datepicker, is not available to the php file at all.
Maybe this is because the call (or whatever you call it) to the php file is wrapped in javascript tags? I dont know. Just getting frustrated after 24 hours of trying to get this to work.
I think I have to pass form name field, datepicker, to the ajax code and then use it in the php file.
Anyone know how to amend my code to do this?
I have now resolved this. I had to amend the javascript in the html to include a var with the vale from the text input box and update the ajax to include it in the data line.
<script type='text/javascript'>
function screenshot(){
html2canvas(document.body).then(function(canvas) {
// Get base64URL
var base64URL = canvas.toDataURL('image/jpeg').replace('image/jpeg', 'image/octet-stream');
var val1 = $('#datepicker').val();
// AJAX request
$.ajax({
url: 'ajaxfile.php',
type: 'post',
//data: {image: base64URL, name: datepicker},
data: {image: base64URL, datepicker: val1},
success: function(data){
console.log('Upload successfully');
}
});
});
}
</script>
Then I had to update the php file with the file name to include the txt data from the form in the filename:
<?php
$image = $_POST['image'];
$location = "upload/";
$image_parts = explode(";base64,", $image);
$image_base64 = base64_decode($image_parts[1]);
$filename = $_POST['datepicker'].'.jpg';
$file = $location . $filename;
file_put_contents($file, $image_base64);
?>
$filename = $_POST['datepicker'].'.jpg';
What you are using is not a good way to store a file in a PHP.
you should prefix current date and some random number generated by PHP to image name before storing the image because if two images are to be stored in the same folder on server's first image will be overwritten and the second file will be stored in its place making the first image to be disappeared completely
try prefixing " date('Ymdhis').rand(100000,999999) " to your image file and use $_FILES['something']['name'] and $_FILES['something']['tmp_name'] to get name and temperary name of the image respectively to store image
I have now resolved this. I had to amend the javascript in the html to include a var with the value from the text input box and update the ajax to include it in the data line.
<script type='text/javascript'>
function screenshot(){
html2canvas(document.body).then(function(canvas) {
// Get base64URL
var base64URL = canvas.toDataURL('image/jpeg').replace('image/jpeg', 'image/octet-stream');
var val1 = $('#datepicker').val();
// AJAX request
$.ajax({
url: 'ajaxfile.php',
type: 'post',
//data: {image: base64URL, name: datepicker},
data: {image: base64URL, datepicker: val1},
success: function(data){
console.log('Upload successfully');
}
});
});
}
</script>
Then I had to update the php file with the file name to include the txt data from the form in the filename:
<?php
$image = $_POST['image'];
$location = "upload/";
$image_parts = explode(";base64,", $image);
$image_base64 = base64_decode($image_parts[1]);
$filename = $_POST['datepicker'].'.jpg';
$file = $location . $filename;
file_put_contents($file, $image_base64);
?>
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.
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've been trying to create a registration form that requires students to upload documents at the very end. However, after picking up the form values via jQuery, the PHP document can't seem to pick up my uploaded form. Any ideas?
Form:
<form id="joinUs" enctype="multipart/form-data" method="post">
<!--various form fields-->
<input type="file" name="transcript" id="transcript">
<div class="button" id="submit">Submit!</div>
</form>
jQuery:
$("#submit").click(function(){
//firstName, lastName, grade, studentID, email, phone are all form values
var data = "firstName="+firstName+"&lastName="+lastName+"&grade="+grade+"&studentID="+studentID+"&email="+email+"&phone="+phone;
$.ajax({
type: "POST",
url: "join_submit.php",
data: data,
success: function() {
location.href="http://mvcsf.com/new/success.php";
}
});
join_submit.php
$allowedExtensions = array("pdf");
$max_filesize = 20000;
$upload_path = "docs/transcripts";
$filename = $_FILES["transcript"]["name"];
$filesize = $_FILES["transcript"]["size"];
$extension = $_FILES["transcript"]["type"];
if ($_FILES["transcript"]["error"] > 0) {
echo "Error: " . $_FILES["transcript"]["error"] . "<br />";
}
else if((in_array($extension, $allowedExtensions)) && ($filesize < $max_filesize)) {
move_uploaded_file($_FILES["transcript"]["tmp_name"], $upload_path . $filename);
}
I ran this, and I got no errors. I also tried to print out the file name, except nothing printed out.
This should do it for you :
$("#submit").click(function () {
var transcript = $("#transcript").val();
var data = "firstName=" + firstName + "&lastName=" + lastName + "&grade=" + grade + "&studentID=" + studentID + "&email=" + email + "&phone=" + phone;
var formData = new FormData();
formData.append("file", transcript);
formData.append("data", data);
$.ajax({
type: "POST",
url: "join_submit.php",
enctype: 'multipart/form-data',//optional
cache: false,
contentType: false,
processData: false,
data: {
file: file
data: data
},
success: function () {
location.href = "http://mvcsf.com/new/success.php";
}
});
});
Cheers
First, In your code, you are posting data with $.ajax({...}) and the data sent is
"firstName="+firstName+"&lastName="+lastName+"&grade="+grade+"&studentID="+studentID+"&email="+email+"&phone="+phone;
There is no transcript at all.
Secondly, and most important, you cannot post file with $.ajax({...}) like that, it will not working like that. As #Roy M J says, you should take a look at FormData (for recent browser only), or take a look on the web for an upload jQuery plugin (don't re-invent the whell, some good plugin already exists :))
Take a look here
You cannot send a file like you do the values of HTML elements. There are two methods to file upload, the one I've used successfully is the AJAX method using a third-party feature called 'AjaxUploader'.You can download it here via GitHub. Once you've done it, add the ajaxuploader.js file in your 'js' folder (or wherever you've put all of your script files), include the file in the HTML page where you've to use the uploader. Now, uploading is as simple as follows.
HTML:
<input type="file" name="transcriptUploader" id="transcriptUploader" value="Upload" />
jQuery (you need to have the jQuery file included in your page):
new AjaxUpload('transcriptUploader', {
action: "page_to_handle_upload.php", // You need to have either a separate PHP page to handle upload or a separate function. Link to either one of them here
name: 'file',
onSubmit: function(file, extension) {
// This function will execute once a user has submitted the uploaded file. You can use it to display a loader or a message that the file is being uploaded.
},
onComplete: function(file, response) {
// This function will execute once your file has been uploaded successfully.
var data = $.parseJSON(response); // Parsing the returning response from JSON.
if(data.error == 0)
{
// If the file uploaded successfully.
}
else if(data.error == "size"){
// If the response object sent 'size' as the error. It means the file size exceeds the size specified in the code.
}
else if(data.error == "type"){
// If the response object sent 'type' as the error. It means the file type is not of that specified in the code (in your case, pdf).
}
else{
// In case the file didn't upload successfully or the code didn't return a usual error code. It is still an error so you need to deal with it appropriately.
}
}
});
Your back-end PHP code that will be doing all the heavy lifting (uploading the file, checking extensions, moving it etc):
if(isset($_FILES)) // Checking if a file is posted.
{
if ($_FILES['file']['error'] == 0) //Checking if file array contain 0 as an error. It means AJAX had no error posting the file.
{
$response = array(); // Initializing a new array.
$allowedExts = array("pdf"); // Allowable file format.
$filename = stripslashes($_FILES['file']['name']); // Storing file name.
//$extension = strtolower(self::_getExtension($filename)); // Fetching file extension.
// Code block to extract file extension and storing it in a variable called $extraction.
$i = strrpos($str, ".");
if (!$i)
{
$extension = "";
}
$l = strlen($str) - $i;
$extension = strlower(substr($str, $i + 1, $l));
$size = $_FILES['file']['size']; // Storing file size (in bytes).
$fileNameAfterUpload = md5((time() + microtime())) . '.' . $extension; // Concatinating file name and extension.
$baseSystemPath = "/var/www/<your_folder_name>/uploaded_transcripts/" // Path on which the file will be uploaded. Need to be relative web path.
$maxSize = 10*10*1024; // Storing file size. Be advised the file size is in bytes, so this calculation means max file size will be 10 MB.
$webPath = "uploaded_transcripts/". $filename; // Creating web path by concatinating base web path (the folder in which you'd be uploading the pdf files to) with file name.
if (in_array($extension, $allowedExts)) // Checking if file contains allowabale extensions.
{
if($size <= $maxSize) // Checking if the size of file is less than and equal to the maximum allowable upload size.
{
$moved = move_uploaded_file($_FILES['file']['tmp_name'], $webPath); // Moving the file to the path specified in $webPath variable.
if($moved == true)
{
$response['error'] = 0; // If moved successfully, storing 0 in the response array.
$response['path'] = $webPath; // Storing web path as path in the response array.
$response['filename'] = $filename; // Storing file name in the response array.
}
else
{
$response['error'] = 'internal'; // If move isn't successfull, return 'internal' to AJAX.
}
}
else
{
$response['error'] = 'size'; // If file size is too small or large, return 'size' to AJAX.
}
}
else
{
$response['error'] = 'type'; // If file type is not that of defined, return 'type' to AJAX.
}
echo json_encode($response); // Returning the response in JSON format to AJAX.
}
}
Do let me know if you need further assistance.
P.S: Don't forget to mark it as an answer if it worked.