I'm trying to retrieve some data from a MySQL database through php POST method to Unity.
But somehow, when I use the UnityWebrequest the post variable is always empty.
My C# script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class IDCheck : MonoBehaviour
{
int onlineID = -1;
readonly string urlCheckIdentifier = "http://www.mywebsite.php";
void Start(){
if (Application.internetReachability != NetworkReachability.NotReachable){
StartCoroutine("GetOnlineID");
}
}
void SetID(int _id){
onlineID = _id;
}
IEnumerator GetOnlineID(){
// TEST NUMBER 2
List<IMultipartFormSection> form = new List<IMultipartFormSection>();
form.Add(new MultipartFormDataSection("onlineid", "test"));
/* THIS WAS ATTEMPT NUMBER 1
WWWForm form = new WWWForm();
form.AddField("onlineid", "test");
*/
UnityWebRequest www = UnityWebRequest.Post(urlCheckIdentifier, form);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError){
Debug.Log("Error on upload");
} else {
Debug.Log(www.downloadHandler.text);
DownloadData data = JsonUtility.FromJson<DownloadData>(www.downloadHandler.text);
bool idFound = (data.succes == false)?false:true;
if (!idFound){
Debug.Log("Didnt work");
Debug.Log(data.succes);
} else {
SetID(data.id);
Debug.Log(onlineID);
}
}
}
}
My PHP script:
<?php
include_once 'dbconnect.php';
// UNIQUE DEVIDE ID IS GIVEN FROM THE APP VIA POST METHOD
$onlineid = $_POST["onlineid"];
// CHECK IF ID EXISTS IN CURRENT USERS TABLE
$query = "SELECT id, username FROM users WHERE uniqueID='$onlineid'";
$result = mysqli_query($dbconnection, $query);
$row = mysqli_fetch_row($result);
if($row){
// IF ID WAS FOUND, RETURN JSON TO THE APP
$dataArray = array('success' => true, 'error' => '', 'id' => $row[1], 'username' => $row[2], 'TESTuniqueIDPassed' => $onlineid);
} else {
// ID WAS NOT FOUND, CREATING NEW ONE.
$query2 = "INSERT INTO users(uniqueID) VALUES ('$id')";
$result2 = mysqli_query($dbconnection, $query2);
// GETTING THE NEWLY CREATED ID FROM THE DB.
$query3 = "SELECT id, username FROM users WHERE uniqueID='$id'";
$result3 = mysqli_query($dbconnection, $query3);
$row3 = mysqli_fetch_row($result3);
// RETURNING JSON WITH THE NEW ID
$dataArray = array('success' => true, 'error' => '', 'id' => $row3[1], 'username' => $row3[2], 'TESTuniqueIDPassed' => $onlineid);
}
header('Content-Type: application/json');
//echo json_encode($dataArray);
echo $onlineid;
?>
As you can see I even tried to just echo the $onlineid which should be populated with the POST method from unity, but that's always returning an empty string.
I've tried google of course but most posts about this subject are pretty old.
The solution to add
www.chunkedTransfer = false;
in front of the yield return call is now depreciated, and another suggested solution was to put
www.useHttpContinue = false;
in front of the yield return also did nothing to solve the problem.
Anybody any ideas where to go from here?
Regards,
Mark
I've tried a couple of things in the meantime while waiting for an anwser.
Stumbled upon an anwser myself so I will post it for the next person to have the same issue:
Your link should start with https instead of http, because Unity does not allow insecure links anymore.
Using MultipartFormDataSection still wont work, but WWWForm will!
Related
I have a database table with values, the primary key being ID. Now I am trying to receive the values of the table with the referenced ID from Unity. How do I send the referenced ID from Unity to this php file so that only the values from this ID should be received.
Currently I am receiving all the values of the table from all IDs.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class CheckForExistingID : MonoBehaviour {
public string[] Items;
public string ID = "001"; //Referenced ID
public string Name;
public string Age;
void Start () {
StartCoroutine (ReceiveValues());
}
IEnumerator ReceiveValues () {
WWW data = new WWW ("http://localhost/GetValue.php?id="+ID);
yield return data;
if (data.error != null) {
print (data.error);
} else {
print ("Received");
dataString = data.text;
Items = dataString.Split (';');
Name = Items[0];
Age = Items[1];
}
}
}
GetValue.php
<?php
...
...
...
$id = $_GET['id'];
$sql = "SELECT Name, Age FROM Students WHERE ID = $id";
$result = mysqli_query($conn, $sql);
if(mysqli_num_rows($result) > 0)
{
while($row = mysqli_fetch_assoc($result)){
echo "".$row['Name'] . ";";
echo "".$row['Age'] . ";";
}
}
?>
NOTE Do NOT use WWW as derHugo had pointed out, it is now obsolete. Similarly sanitize all data using prepared statements. Skip to the edit marker to find an updated answer.
I am not sure you are posting the data properly. You should use a WWWForm, add the fields you want and then handle them on the PHP side. I would also heavily consider adding some form of error handling in PHP with an echo to know if something failed.
On mobile so excuse the formatting for now I'll fix it later if it needs it.
string url = "http://localhost/GetValue.php";
WWWForm form = new WWWForm();
form.AddField("id", "TheIDHere");
WWW www = new WWW(url, form);
yield return www;
...
On the PHP side of things, it can look like
<?php
if (isset($_REQUEST["id"])) {
echo "Received ". $_REQUEST["id"]. " success!";
exit();
} else {
http_status_code(400);
echo "Request Failed";
}
Edit: As pointed out by derHugo, WWW is now obsolete, and is replaced by WebRequests. The above c# code should look like
WWWForm form = new WWWForm();
form.AddField("id", "yourID");
UnityWebRequest www = UnityWebRequest.Post("http://localhost/GetValue.php", form);
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.Success)
{
Debug.Log(www.error);
}
else
{
Debug.Log("Sucess");
}
As well, derHugo had pointed out that you are not sanitizing your data at all, so you would be subject to SQL Injections. Here is roughly what you would want to do to use prepared statements
// prepare a statement using the ID
$stmt = $mysqli->prepare("SELECT Name, Age FROM Students WHERE ID = ?");
// bind the ID from our POST
$stmt->bind_param("i", $_POST['id']);
// execute our prepare statement
$stmt->execute();
// store the result
$stmt->store_result();
// we have no found id
if($stmt->num_rows === 0) exit('No Data');
// bind the results we are looking for from our prepared statement
$stmt->bind_result($idName, $idAge);
// fetch the results from the table
$stmt->fetch();
// echo your results to Unity
echo $idName;
echo $idAge;
// deallocate the statement
$stmt->close();
Goal: Develop a registration form for a website
Problem: PHP returns unexpected results to Ajax using the json_encode function (for example, it returns DUPLICATE_USERNAME when it should return DUPLICATE_EMAIL).
Code explanation / algorithm:
User enters their details in the registration form (username, email, etc.)
When submit button is clicked, the input is acquired by a PHP script (registrationProcess.php) via POST
A database check is run so that the username and email are available (here we suppose that they aren't)
PHP returns the value back to the front-end via Ajax. It returns two strings, either DUPLICATE_USERNAME or DUPLICATE_EMAIL; the function that does this is handleRegisterError($error_type)
Depending on the returned string, the UI of the webpage is properly changed
This function is a part of a script that gets called after the submit button is clicked.
<?php
/**
* This function gets called in the PHP script if a registration error has been found. It is passed either DUPLICATE_USERNAME or DUPLICATE_EMAIL.
*/
function handleRegisterError($error_type) {
switch($error_type) {
case "DUPLICATE_USERNAME":
$data = array("error" => "DUPLICATE_USERNAME");
echo json_encode($data);
break;
case "DUPLICATE_EMAIL":
$data = array("error" => "DUPLICATE_EMAIL");
echo json_encode($data);
break;
default:
echo "Unexpected error in registrationProcess.php"
break;
}
}
/>
Now, the JavaScript code on the front-end HTML registration page that receives the code:
<script>
$.ajax({
dataType: 'json',
url: "../php/registrationProcess.php",
success: function(data) {
console.log("SUCCESS: " + data.error);
handleError(data.error);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log("ERROR CALLING AJAX! textStatus = " + textStatus + " | errorThrown = " + errorThrown);
}
});
function handleError(errorType) {
console.log("errorType = " + errorType);
switch(errorType) {
case "DUPLICATE_USERNAME":
// Display duplicate username error
$("#username-error").attr("hidden", false);
$("#username-input-field").css("margin-bottom", 8);
break;
case "DUPLICATE_EMAIL":
// Display duplicate email error
$("#email-error").attr("hidden", false);
$("#email-input-field").css("margin-bottom", 8);
break;
}
}
</script>
The receiving code consists of the basic Ajax form to receive results from PHP. It passes the received variable (data.error) to the handleError function, which in turn consists of a switch statement that changes the UI for a duplicate username/email error.
Debugging:
When PHP sends values from json_encode, it echoes the JSON code it is transmitting to the website, so I can easily see what the PHP transmits as JSON. For JavaScript debugging, I used the console.log function to print "SUCCESS", followed by the data.error (which should be similar to the value transmitted by PHP). The error that is used in JavaScript is then repeatedly printed to console from the handleError function just to be safe.
You can see an example of both sources of debugging I used to analyse the errors in these two images, where the JSON that is transmitted from PHP is seen on the top left and the console is seen on the right side of the image:
Problem analysis
I have placed the following user into the database:
username: Mike
email: mikey#gmail.com
To test the code, I've then run two separate tests: In the first test, I tried to create another username with the name Mike and a different email (which is expected to return a DUPLICATE_USERNAME error). In the second test, I tried to create another username with the name Jenna and the email mikey#gmail.com, which is expected to cause a DUPLICATE_EMAIL error.
My code successfully dealt with the first case, when the username was duplicated:
However, in the second case, PHP correctly recognised a DUPLICATE_EMAIL error, but the JavaScript / Ajax somehow interpreted that as DUPLICATE_USERNAME when it was being sent over.
What am I doing wrong in my code that is causing this bug? Is it maybe some state on the webpage that is being saved from previous data transmissions?
Thank you for the time taken to deal with this problem!
The script for registrationProcess.php:
<?php
include 'secureFunctions.php';
$username = "";
$birthday = "";
$gender = "";
$email = "";
$password = "";
$username = getVariable('username');
$birthday = getVariable('birthday');
$gender = getVariable('gender');
$email = getVariable('email');
$password = getVariable('password');
$db_host = "sql7.freesqldatabase.com";
$db_username = "sql7369409";
$db_password = "*******";
$db_name = "sql7369409";
$conn = new mysqli($db_host, $db_username, $db_password, $db_name);
if(mysqli_connect_error()) {
die("Database connection failed: " . mysqli_connect_error);
}
if($gender != "") {
// Edit gender for the database
switch ("gender") {
case "male":
$gender = "m";
break;
case "female":
$gender = "f";
break;
case "other":
$gender = "o";
break;
}
}
if($birthday != "") {
// Edit birthday for the database
$arr = explode('/', $birthday);
$birthday = $arr[2] . '-' . $arr[1] . '-' . $arr[0];
}
$sql = "INSERT INTO users (id, username, birthday, gender, email, password)
VALUES (NULL, '$username', '$birthday', '$gender', '$email', '$password')";
if (mysqli_query($conn, $sql)) {
echo "New record created successfully!";
header("Location: ../pages/index.html");
exit();
}
else {
handleRegisterError(registrationGetErrorType(mysqli_error($conn)), "TRUE");
}
function handleRegisterError($error_type, $devValue) {
//echo "errorType = $error_type ";
if($devValue == "TRUE") {
/*
switch ($error_type) {
case "DUPLICATE_USERNAME":
//echo "test2";
$data = array("error" => "DUPLICATE_USERNAME");
echo json_encode($data);
break;
case "DUPLICATE_EMAIL":
//echo "test1";
$data = array("error" => "DUPLICATE_EMAIL");
echo json_encode($data);
break;
case "UNKNOWN":
$data = array("error" => "UNKNOWN");
echo json_encode($data);
break;
}
*/
//$data;
if($error_type == "DUPLICATE_USERNAME") {
//echo " t1 ";
$data = array("error" => "DUPLICATE_USERNAME");
//echo json_encode($data);
} elseif($error_type == "DUPLICATE_EMAIL") {
//echo " t2 ";
$data = array("error" => "DUPLICATE_EMAIL");
//echo json_encode($data);
} else {
$data = array("error" => "UNKNOWN");
//echo json_encode($data);
}
echo json_encode($data);
}
}
?>
The above script also uses some methods from secureFunctions.php:
<?php
/**
* Retrieves a variable from HTML using the null coalesce operator (for security reasons)
* #param mixed $variableName
* #return void
*/
function getVariable($variableName) {
$result = $_POST[$variableName] ?? '';
return $result;
}
/**
* There are two types of registration errors: (1) username already in use (2) email already in use or (3) Unknown error
* First two errors look like this:
* (1): Duplicate entry 'skorjanc.survey#gmail.com' for key 'email'
* (2): Duplicate entry 'King_Fish' for key 'name'
*
* #param mixed $sqlDbText The error text from the server
* #return (1) DUPLICATE_USERNAME (2) DUPLICATE_EMAIL (3) UNKNOWN
*/
function registrationGetErrorType($sqlDbText) {
$filtered = str_replace("'", "", $sqlDbText); // Replace single quotes with air
$array = explode(" ", $filtered);
$key = $array[count($array)-1];
if($key == "email") {
return "DUPLICATE_EMAIL";
} elseif($key == "name") {
return "DUPLICATE_USERNAME";
}
return "UNKNOWN";
}
?>
As ArJay suggested, I am also attaching values of $array and $key in the registrationGetErrorType method for both cases (duplicate username and duplicate password):
(1) DUPLICATE_USERNAME
array = Array ( [0] => Duplicate [1] => entry [2] => King_Fish [3] => for [4] => key [5] => name )
key = name
(2) DUPLICATE EMAIL
array = Array ( [0] => Duplicate [1] => entry [2] => skor#gmail.com [3] => for [4] => key [5] => email )
key = email
I have found the cause of the problem.
When the submit button was clicked, all the values were actually sent to the correct PHP script from the form. The values were processed and the correct JSON object with the correct error was returned.
Then, however, the page refreshed because of the submit button functionality. Now, all of the form variables were set back to empty, such as username = "", email = "" etc. Those variables were again used by the same script and tested against existing database records, which in turn resulted in the wrong second error (DUPLICATE_USERNAME instead of DUPLICATE_EMAIL).
It seems that I have hit an algorithm error, as I have devised the code flow in such a way as to cause errors. I have, however, found a great tutorial on creating register/login pages, whose code I have tested (and it works!) - follow this link.
Thanks to everyone, specifically Peter Mortensen, for the patience on this error!
I am trying to update the value to database, but one way or an another i am not able to.
Code:
<?php
include 'init.php';
$dataid = $_POST['data_id'];
if(isset($dataid))
{
/*user connects to database and performs some operation here*/
/* values from database is returned and user passes the same to below function */
calculateamount($kk_data_id,$kk_egg,$kk_cash,$kk_in,$kk_out,$kk_expenditure,$kk_cashout,$kk_wholesale1,$kk_wholesale2,$kk_wholesale3,$kk_touch,$kk_galtha,$kk_kotla,$wholesale_1,$wholesale_2,$wholesale_3,$touch,$galtha,$kotla,$retail,$prevegg,$prevcash);
}
function calculateamount($kk_data_id,$kk_egg,$kk_cash,$kk_in,$kk_out,$kk_expenditure,$kk_cashout,$kk_wholesale1,$kk_wholesale2,$kk_wholesale3,$kk_touch,$kk_galtha,$kk_kotla,$rwholesale_1,$rwholesale_2,$rwholesale_3,$rtouch,$rgaltha,$rkotla,$rretail,,$prevegg,$prevcash)
{
/*performs Mathematical operations
with data retrieved and passes the final values to the below function to update to database*/
//ALL THE VALUES ARE CONVERTED TO STRING BEFORE PASSING ON TO THE BELOW FUNCTION
updatevaluestodatabase($finalwhl1amount,$finalwhl2amount,$finalwhl3amount,$finaltchamount,$finalgalamount,$finalkotamount,$finalretailval,$finalretamount,$finaltotamount,
$finaltottally);
}
function updatevaluestodatabase($finalwhl1amount,$finalwhl2amount,$finalwhl3amount,$finaltchamount,$finalgalamount,$finalkotamount,$finalretailval,$finalretamount,$finaltotamount,
$finaltottally)
{
$updatedata = "UPDATE kk_data SET wholesale1_amt=?,wholesale2_amt=?,wholesale3_amt=?,touch_amt=?,galtha_amt=?,kotla_amt=?,
kk_retail=?,retail_amt=?,kk_total_amount=?,kk_final_tally=? where kk_data_id = ?";
$updatestmt = mysqli_prepare($con, $updatedata);
mysqli_stmt_bind_param($updatestmt, sssssssssss,$finalwhl1amount,$finalwhl2amount,$finalwhl3amount,$finaltchamount,$finalgalamount,$finalkotamount,$finalretailval,$finalretamount,
$finaltotamount,$finaltottally,$dataid);
mysqli_stmt_execute($updatestmt);
mysqli_stmt_store_result($updatestmt);
$response = array();
$response["success"] = false;
if(mysqli_stmt_affected_rows($updatestmt) > 0 )
{
$response["success"] = true;
}
header('Content-Type: application/json');
echo json_encode($response);
}
?>
OUTPUT
Every time I run the below script in postman ('data_id' = value) or through application:
$response["success"] = false;
is returned always . Data is not updated to the database.
What I tried
Instead of using mysqli_stmt_affected_rows($updatestmt) I tried executing using mysqli_stmt_execute($updatestmt); in the if statement. But no luck there
I am unable to figure out where the issue is or if am incorrect in calling the function.
NOTE: I thought I would post a minimized code to avoid clumsiness.
I have this code is working fine my application gets the data with json and is all fine but when I insert special characters like ñ which I need to get I can't have been told that I should use the utf8_encode but I just don't know how to apply it here since.
<?php
require_once(dirname(__FILE__).'/ConnectionInfo.php');
//Set up our connection
$connectionInfo = new ConnectionInfo();
$connectionInfo->GetConnection();
if (!$connectionInfo->conn)
{
//Connection failed
echo 'No Connection';
}
else
{
if (isset($_POST['mod']) && isset($_POST['lec']) && isset($_POST['clase']))
{
$mod = $_POST['mod'];
$lec = $_POST['lec'];
$clase = $_POST['clase'];
//Create query to retrieve all contacts
$query = 'SELECT TituloEjercicio,PreguntaEjercicio,Opcion1Ejercicio,Opcion2Ejercicio,Opcion3Ejercicio,Opcion4Ejercicio,EstaCorrectaEjercicio FROM ejercicios WHERE QueModulo = ? and QueLeccion = ? and Queclase = ?';
$params = array($mod,$lec,$clase);
$stmt = sqlsrv_query($connectionInfo->conn, $query,$params);
if (!$stmt)
{
//Query failed
echo 'Query failed';
}
else
{
$contacts = array(); //Create an array to hold all of the contacts
//Query successful, begin putting each contact into an array of contacts
while ($row = sqlsrv_fetch_array($stmt,SQLSRV_FETCH_ASSOC)) //While there are still contacts
{
//Create an associative array to hold the current contact
//the names must match exactly the property names in the contact class in our C# code.
$contact = array("lbl_variable_cuestionario_titulo" => $row['TituloEjercicio'],
"lbl_variable_pregunta" => $row['PreguntaEjercicio'],
"opcion1" => $row['Opcion1Ejercicio'],
"opcion2" => $row['Opcion2Ejercicio'],
"opcion3" => $row['Opcion3Ejercicio'],
"opcion4" => $row['Opcion4Ejercicio'],
"EstaCorrecta" => $row['EstaCorrectaEjercicio']
);
//Add the contact to the contacts array
array_push($contacts, $contact);
}
//Echo out the contacts array in JSON format
echo json_encode($contacts);
sqlsrv_close($connectionInfo->conn);
}
}
sqlsrv_close($connectionInfo->conn);
}
sqlsrv_close($connectionInfo->conn);
?>
If your issue lies with pushing non-latin characters to MySQL then you might just have to configure your database to use UTF8. There are good tutorials online that show you how to do that.
Im trying to write a simple prgram that the server can get data from client.
I write a simple code in my script
var str = "testString";
$.post("http://anonymous.comze.com/test1.php", { string: str });
in the server,
$var = $_POST['string']; // this fetches your post action
$sql2 = "INSERT INTO afb_comments VALUES ('3',$var)";
$result2= mysql_query($sql2,$conn);
The question is var is always null. The sql2 can be executed if I change $var into "1111" for example,
but if I put $var, it doesn't work. Can anyone give some advice?
your are passing string to the query so it should be
$var = $_POST['string']; // this fetches your post action
$sql2 = "INSERT INTO afb_comments VALUES ('3','".$var."')";
$result2= mysql_query($sql2,$conn);
please also check datatype of the that column.
Use this example and learn from this code how to get data
Or
use can also use this link:
http://api.jquery.com/jQuery.get/
$user and $pass should be set to your MySql User's username and password.
I'd use something like this:
JS
success: function(data){
if(data.status === 1){
sr = data.rows;
}else{
// db query failed, use data.message to get error message
}
}
PHP:
<?php
$host = "localhost";
$user = "username";
$pass = "password";
$databaseName = "movedb";
$tableName = "part parameters";
$con = mysql_pconnect($host, $user, $pass);
$dbs = mysql_select_db($databaseName, $con);
//get the parameter from URL
$pid = $_GET["pid"];
if(empty($pid)){
echo json_encode(array('status' => 0, 'message' => 'PID invalid.'));
} else{
if (!$dbs){
echo json_encode(array('status' => 0, 'message' => 'Couldn\'t connect to the db'));
}
else{
//connection successful
$sql = "SELECT `Processing Rate (ppm)` FROM `part parameters` WHERE `Part Number` LIKE `" . mysqli_real_escape_string($pid) . "`"; //sql string command
$result = mysql_query($sql) or die(mysql_error());//execute SQL string command
if(mysql_num_rows($result) > 0){
$rows = mysql_fetch_row($result);
echo json_encode(array('status' => 1, 'rows' => $rows["Processing Rate (ppm)"]);
}else{
echo json_encode(array('status' => 0, 'message' => 'Couldn\'t find processing rate for the give PID.'));
}
}
}
?>
As another user said, you should try renaming your database fields without spaces so part parameters => part_parameters, Part Number => part_number.