I am using the following code to upload files without refreshing my page but I need to send the userid of the currently logged in user together with the files, which is stored in $_SESSION['UserID'].
var fileSelect = document.getElementById('file');
var files = fileSelect.files;
var formData = new FormData();
var div = document.getElementById('UploadInfo');
// Loop through each of the selected files.
for (var i = 0; i < files.length; i++) {
var file = files[i];
// Check the file type.
if (!file.type.match('image.*')) {
alert("File: " + file.name + " is not an image and will not be uploaded.");
continue;
}
// Add the file to the request.
formData.append('images[]', file, file.name);
}
var xhr = new XMLHttpRequest();
xhr.open('POST', 'Php/upload_file.php', true);
xhr.send(formData);
I have tried using the following line without success, which means i am not recieveing the userid value in my phpscript, $_POST is empty and $_FILES contains only the fileinfo.
formData.append('UserID', '<%=$_SESSION["UserID"] %>');
Is there any other way I can accomplish this?
My PHP code:
if(isset($_FILES)) {
$numberOfFiles = count($_FILES['images']['name']);
for($id = 0; $id < $numberOfFiles; $id++)
{
if (file_exists($_FILES["images"]["tmp_name"][$id])) {
$destination = "../UploadedImages/" . $_FILES['UserID'] . $_FILES["images"]["name"][$id];
move_uploaded_file($_FILES["images"]["tmp_name"][$id], $destination);
}
}
}
exit();
It looks like you need to use $_POST in your php script, you had $_FILES['UserID'] instead of $_POST['UserID'] .I also added a check to see if the UserID was passed, and added a variable $userId, then if $_POST['UserID'] did not get passed to the php script, i use die and send back an error.
NOTE: You should be checking $_POST['UserID'] to make sure it doesn't contain SQL injection scripts, or harmful code that can cause issues.
if(isset($_FILES) || isset($_POST)) {
$numberOfFiles = count($_FILES['images']['name']);
$userId = ''; //Create userId variable
//Check if the UserID exists in the autoglobal $_POST
if(array_key_exists('UserID', $_POST) === true) {
//Now we can add UserId to our variable
$userId = $_POST['UserID'];
} else {
die('UserID was not passed');
}
for($id = 0; $id < $numberOfFiles; $id++)
{
if (file_exists($_FILES["images"]["tmp_name"][$id])) {
$destination = $userId . $_FILES["images"]["name"][$id];
move_uploaded_file($_FILES["images"]["tmp_name"][$id], $destination);
}
}
} else {
echo "$_POST and $_FILES dont exist";
}
Edits: Fixed up some syntax errors, please re look at the code and make sure you have the latest version.
Related
JavaScript:
const XHR = new XMLHttpRequest();
function sendData(data) {
XHR.open('POST', 'savedata.php');
XHR.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
XHR.send('data=' + JSON.stringify(data);
}
PHP:
if (isset($_POST['data'])) {
if (file_exists('data.json')) {
$file = file_get_contents('data.json');
$accumulatedData = json_decode($file);
$data = json_decode($_POST['data']);
array_push($accumulatedData, $data);
$encodedAccumulatedData = json_encode($accumulatedData);
file_put_contents('data.json', $encodedAccumulatedData);
}
}
If the intervals between the data transfers are very short, data get lost. How to prevent this?
This sounds like a race condition, likely because multiple requests write to the same data.json file at the same time.
You should be able to prevent this by locking the file so only one PHP process has access to it at a time.
if (isset($_POST['data'])) {
if (file_exists('data.json')) {
$fp = fopen("data.json", "r+");
// acquire an exclusive lock, block until we can aquire it.
if (flock($fp, LOCK_EX)) {
// we can still use file_get_contents, which is better than using fread.
$file = file_get_contents('data.json');
$accumulatedData = json_decode($file);
$data = json_decode($_POST['data']);
array_push($accumulatedData, $data);
$encodedAccumulatedData = json_encode($accumulatedData);
// Remove existing file contents
ftruncate($fp, 0);
// Write new JSON array to file
fwrite($fp, $encodedAccumulatedData);
// release the lock
flock($fp, LOCK_UN);
} else {
// This should rarely happen since flock will block until it can get a lock.
// just in case, we should instruct the client to try again later.
echo "Couldn't get the lock!";
}
}
}
I'm do output with json_encode to sending to javascript, with this code.
<?php
include "Connection.php";
$syntax_query = "select * from product";
$thisExecuter = mysqli_query($conn, $syntax_query);
$result = array();
while($row = mysqli_fetch_assoc($thisExecuter)){
array_push(
$result,
array(
"id" => $row["product_id"],
"name" => $row["product_name"]
)
);
}
echo json_encode($result);
?>
so output show like this,
[{"id":"121353568","name":"Baju Casual - Black"},{"id":"556903232","name":"Tas LV - Red"},{"id":"795953280","name":"Sword - Wood"},{"id":"834032960","name":"Scooter - Iron Plate"}]
and code javascript like this
function showHint() {
const xmlhttp = new XMLHttpRequest();
xmlhttp.onload = function() {
var obj = this.responseText;
document.getElementById("txtHint").innerHTML = obj.id;
}
xmlhttp.open("GET", "Download.php");
xmlhttp.send();
}
so obj.id its not working, output show undifined.
I use ajax calls when I want to call a Php file and get a response from the same as below to try once that as I have shown. Before moving with Ajax you must need jquery to be imported into the calling file.
If Jquery is imported then ignore the steps
Here are steps,
Go to the link https://code.jquery.com/jquery-3.6.0.min.js copy whole content (use ctl+A to select whole content and ctl+C to copy)
Open a new file in the current project folder and paste the copied content (use ctl+V to paste) save it as 'jquery-3.6.0.min.js'
Import the js file in the HTML file in script tag as shown '
Now, this is the ajax example to call the PHP file and to get a response
function showHint() {
//since you have used GET method I have used here GET but You can use POST also here
$.ajax({
url: 'Download.php',
type: 'get',
//if any value you want to pass then uncomment below line
// data: {'name_to_pass':'value'},
//the variable can be accessed in the php file by 'name to pass' under $_GET['name_to_pass'] or $_POST['name_to_pass'] based on type
success: function(res)
{
// open DevTool console to see results
console.log(JSON.parse(res));
}
});
}
Hope this will help you out, thank you
Maybe you need a JSON.parse in the response, something like JSON.parse(this.responseText).
And also I can see the result is an Array so you will need to iterate obj
obj.forEach(item => {
document.getElement("txtHint").innerHTML = item.id;
});
you should define the response type as json
header('Content-Type: application/json; charset=utf-8');
echo json_encode($result);
function showHint() {
const xmlhttp = new XMLHttpRequest();
xmlhttp.onload = function() {
**var obj = this.responseText;**
document.getElementById("txtHint").innerHTML = obj.id;
}
xmlhttp.open("GET", "Download.php");
xmlhttp.send();
}
When you get the responseText it's text, not an object.
var obj = this.responseText; should be let obj = JSON.parse(this.responseText);
Then you can access obj.id as a property.
The background is, frontend passed an id back to backend and backend uses the id to extract information from database. The extracted data need further processing at backend and then gets sent back to frontend.
Here is the front end code:
html:
<!DOCTYPE html>
<html>
<head>
<title>Test!</title>
<meta charset="utf-8">
<script src="loadPage.js">
</script>
</head>
<body onload = "loadPage()">
<div id="stack"><p>test part</p>
</div>
</body>
</html>
js:
function __getParameters() {
var parm = {};
var url = window.location.href;
var pairs = url.slice(url.indexOf('?') + 1).split('&');
for (var i = 0; i < pairs.length; i++) {
pair = pairs[i].split('=');
parm[pair[0]] = pair[1];
}
return parm;
}
function __loadData(star) {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// var data = JSON.parse(xmlhttp.responseText);
console.log(xmlhttp.responseText);
if (xmlhttp.responseText == "") {
document.getElementById("stack").innerHTML = "f*ck";
} else {
document.getElementById("stack").innerHTML = xmlhttp.responseText;
}
}
}
var url = "getXML.pl";
url = url + "?STAR=" + star;
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function loadPage() {
var parm = __getParameters();
// document.getElementById("stack").innerHTML = parm["STAR"];
if (parm == undefined) {
// wrong url error page
} else if (parm['STAR'] == undefined) {
// missing star error page
} else if (parm['user' == undefined]) {
// missing user id error page
} else {
var star = parm["STAR"];
var user = parm["user"];
__loadData(star);
}
}
The backend uses perl to extract data from database, and it will print the output to stdout. The output is a XML in string form. Then I must use an existed python script to process the extracted data.
However, the server seems not support python (But the server can run python if I directly run python scripts on it. The reason for my statement is that I wrote a python cgi and I got a 500 error, while the perl cgi is ok. I'm sure the python script is correct since it can run directly on the server. I have no access to error log and I cannot modify the config file of the server).
So I piped the output of the perl script to python, and run it using 'system()'. The python script will output a processed string to stdout.
Here is the backend scripts:
perl script:
#!/depot/perl-5.14.2/bin/perl
# extract posted data
local ($buffer, #pairs, $pair, $name, $value, %FORM);
$ENV{"REQUEST__METHOD"} =~ tr/a-z/A-Z/;
if ($ENV{"REQUEST_METHOD"} eq "POST") {
read(STDIN, $buffer, $ENV{"CONTENT_LENGTH"});
} else {
$buffer = $ENV{"QUERY_STRING"};
}
#pairs = split(/&/, $buffer);
foreach $pair (#pairs) {
($name, $value) = split(/=/, $buffer);
$value =~ tr/+/ /;
$value =~ s/%(..)/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
$star = $FORM{STAR};
print "Content-type:text/html\n\n";
my $cmd = "***/sq_star.pl --xml --star_id " . $star;
$cmd = $cmd . " | ***/python parseXML.py";
system($cmd);
the sq_star.pl (I just remove the path here and replace it with ***) near the end of perl script is just an existed script that will extract data from database. And parseXML.py is an existed script which does a lot to the input string.
The strange thing is, the responseText is always an empty string. I tried to run the perl script directly on the server, it can print expected results. And if I remove $cmd = $cmd . " | ***/python parseXML.py";, the responseText will be the data extracted from the database.
What I have tried for now:
1. I wrote a simple test python with just one line of print. Still empty response
2. I tried to store the output as $output =`$cmd`; and print $output; in the perl script, still empty.
3. I tried to store the original data in a txt and let the python read from the txt. Still empty
It seems that that data processed by python just cannot be sent back .....
-------------------update----------------
It seems to be the problem of the server. I guess the server is not set to support python so if I directly send requests to a python script on backend, there will be 500 error. But somehow my way, i.e., calling python in perl, gets around the error, but still the python just doesn't work... Just my guess
I found the problem. It is because the interpreter I specified cannot be found by the server. system(...) line actually doesn't run at all. The reason that I didn' t see any error is because system() hides the error for me. Actually the return value of system() is -1, which means something wrong. I should have checked the return value
var PId = 12;
var catId = 3;
var Param = 'productid='+PId+'&CatId='+catId;
var encriptedCode = '<?php echo $this->encrypt->encode( .... need to pass the Param .... );?>';
I am trying to pass the javascript value into php method, whatever i am trying it's not working. Any one help me to detect where i am wrong. using this code in time of ajax call
You would need to make an Ajax request and pass that information through using the GET request.
Something like this:
var PId = 12;
var catId = 3;
var Param = 'productid='+PId+'&CatId='+catId;
$.get( Param ); // makes the call to the PHP script
Then in your PHP file you can retrieve the data passed.
I guess that you need result of $this->encrypt->encode method to use in your JS file. So you need to retrieve it using XMLHttpRequest.
var PId = 12;
var catId = 3;
var Param = 'productid='+PId+'&CatId='+catId;
var req = new XMLHttpRequest();
var encriptedCode;
req.open('GET', 'path/to/your/file.php?' + Param, true);
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4) {
if(req.status == 200) {
encriptedCode = req.responseText;
// Do some something with your encrypted code
} else {
// Handle error here
}
}
};
req.send(null);
and the PHP file should looks like here
<?php
// Load here libs for encryption
$productId = (int)$_GET['productid'];
$catId = (int)$_GET['CatId'];
echo $encryptObj->encrypt->encode($productId, $catId);
It should be as simple as:
encriptedCode = '<?php echo $this->encrypt->encode(?>Param<?php);?>';
I am trying to upload an image and some strings/numbers using AJAX. The code is working fine (as in, everything is getting into the database) except for one very important problem. I very much want the "character" variable to be unique, and every attempt I use to bring up an error message for trying a character name that has already been taken does not work. Here is my code:
AJAX:
function CSubmit() {
clearInterval(MoveDrawTimer);
var a=document.forms['form-id']["thefiles"].value; if (a == "") { document.getElementById("info").innerHTML="You must upload an image."; return };
if (showFileSize() > 5000000) { document.getElementById("info").innerHTML="File is too big. Maximum size is 5,000,000 bytes."; return };
var accepted = [".gif",".png",".jpg",".jpeg"];
if (Ext in oc(accepted) == true) {
var dataURLToBlob = function(dataURL) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = parts[1];
return new Blob([raw], {type: contentType});
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {type: contentType}); };
newImage = dataURLToBlob(dataURL); } else { document.getElementById("info").innerHTML="Cannot send file. Check your extensions."; return };
var canvas = document.getElementById("Cinfo");
var context = canvas.getContext("2d");
context.clearRect(0, 0, 400, 400);
var TotalSpent = StrPts + IntPts + WisPts + SpdPts + MovPts;
var theform = document.getElementById("CharName");
if (theform.value == "") { document.getElementById("info").innerHTML="Your character must have a name."; return }
if ( /[^a-zA-Z0-9]/.test(theform.value) ) {
document.getElementById("info").innerHTML="Name must contain only letters and / or numbers."; return }
if (theform.value.length > 14) { document.getElementById("info").innerHTML="Character names must be 14 characters max."; return }
if (TotalSpent !== 2) { document.getElementById("info").innerHTML="You must spend exactly 2 points."; return }
var fd = new FormData();
fd.append('data', newImage);
fd.append('character', theform.value);
fd.append('str', StrPts);
fd.append('int', IntPts);
fd.append('wis', WisPts);
fd.append('spd', SpdPts);
fd.append('mov', MovPts);
//beginning of server transmission. above is javascript front end authentication.
//sending the following information:
//theform.value // character name
//StrPts, IntPts, WisPts, SpdPts, MovPts // the character stats
var xmlhttp;
if (window.XMLHttpRequest)
{ // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{ // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); }
xmlhttp.onreadystatechange=function(){ xmlhttp.addEventListener("progress", document.getElementById("info").innerHTML="Please wait . . ." , false);
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
if (xmlhttp.responseText.length <= 14) {
document.getElementById("info").innerHTML="Congratulations, " + xmlhttp.responseText + " has been approved.";
SelectScreen();} } }
xmlhttp.open("POST","CHunique.php",true);
xmlhttp.send(fd);
};
As you can see, I am appending everything to a form and then sending it to CHunique.php, which is the following (currently an incomplete test page for demonstration of problem):
<?php
#$con=mysqli_connect("$db_host","$db_username","$db_pass", "$db_name") or die ("Could not connect to the database. Please try again later.");
mysqli_set_charset($con,"UTF8");
$Err = "fine";
session_start();
$login = $_SESSION['account'];
$CHresult = mysqli_query($con,"SELECT * FROM CHstats");
while($row = mysqli_fetch_array($CHresult)) {
$thecharacters = $row['character'];
if (strtolower($character) === strtolower($thecharacters)) { $Err = " Character name already in use."; break; }; }
The problem here is that I do not get any response back from the server at all. It stays infinitely on its "progress" function, which is to say "Please wait . . . " This is true for ALL while loops that I attempt on the php page...the server just gets stuck in loading. This is a huge problem because I need to use a while loop to loop through all the characters in order to see if the user's name is unique or not.
Again, everything is working fine, including the image upload, EXCEPT for this check. This check is very important, and I'm wondering why every single while loop I try in the php page just results in an infinite load time?? Please help.
Also keep in mind I do not use JQuery.
Why not just change your query to do the work for you, doesn't really make sense to do the comparison in PHP
$query = sprintf("SELECT * FROM CHstats WHERE LOWER(character) = LOWER('%s')", $thecharacters);
$result = mysqli_query($con, $query);
if(mysqli_num_rows($result) > 0){
// duplicate character name
}
Also, are you sure that the while loop is what's causing your page to hang? It is very likely that the connection to mysql isn't being made or is taking a long time. If you haven't already, move a die statement around your code to see where it is getting hung up.
YES! I actually solved it all on my own after several hours of frustration. The answer lies in my stupid AJAX conditional: if (xmlhttp.responseText.length <= 14). The responses were more than 14 characters and thus caused the server to load indefinitely.