How to send data from Unity C# to PHP server?
I've been trying to practice unity these days, and I'd like to send the name of the object whenever I click to PHP server. I use VSCode to write PHP and XAMPP to set up Apache server. I just can't seem to send their name to my PHP. The results are always Undefined index: objectNameKey if I use $_POST["objectNameKey"] or an empty array if I use $_POST. I've been trying some of solutions but to no avail. I'm using unity 2017.4 and 2018.4, PHP 7.4.11.
PHP server
<?php
$objectName = $_POST["objectNameKey"];
print_r($objectName);
var_dump($objectName);
?>
The results were Undefined index: objectNameKey.
I tried
if(isset($_POST["objectNameKey"])){
$objectName = $_POST["objectNameKey"];
print_r($objectName);
var_dump($objectName);
}
The results were nothing since I didn't write else to respond to this. I guess the objectNameKey is still undefined index.
Then I tried
$objectName = $_POST;
print_r($objectName);
var_dump($objectName);
The results were empty arrays.
select.cs is to get the name of the object whenever I click and this one is working.
select.cs
using UnityEngine;
public class select : MonoBehavior
{
public static string objectName;
public static bool objEnabled;
void Start(){
}
void Update()
{
if (Input.GetMouseButtonUp(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider != null)
{
Debug.DrawLine(ray.origin, hit.point);
objectName = hit.collider.gameObject.name;
connectPHP.objectName = objectName;
connectPHP.objectEnabled = true;
}
}
}
}
}
I can get the name of the object whenever I click. Now this is where the problem starts to happen.
connectPHP.cs is to send the name of the object (objectName) to my PHP server.
I used WWWForm method and used $_POST["objectNameKey"] to catch it and the result was Undefined index: objectNameKey.
connectPHP.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class connectPHP : MonoBehaviour
{
public static string connectURL = "http://localhost:8080/practice/connect.php";
public static string objectName;
public static bool objectEnabled;
// Start is called before the first frame update
void Start()
{
}
//Unity data to PHP
IEnumerator Upload()
{
WWWForm form = new WWWForm();
form.AddField("objectNameKey", objectName);
UnityWebRequest www = UnityWebRequest.Post(connectURL, form);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log("Form upload complete!");
}
}
void Update()
{
if(objectEnabled == true)
{
StartCoroutine(Upload());
objectEnabled = false;
}
}
}
Then I chose to use MultipartFormSection method. I didn't know what to put in the field part.
formData.Add(new MultipartFormDataSection("field1=foo&field2=bar"));
So I chose to find some answers. I stumbled upon this youtube video. I tried to copy it. I used $_POST["objectNameKey"] to catch it and the result was still Undefined index: objectNameKey.
List<IMultipartFormSection> form = new List<IMultipartFormSection>();
form.Add(new MultipartFormDataSection("objectNameKey", objectName));
UnityWebRequest www = UnityWebRequest.Post(connectURL, form);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log("Form upload complete!");
}
Then I tried to use UnityWebRequest.Put method. I used $_POST to catch it and the result is empty array.
byte[] myData = System.Text.Encoding.UTF8.GetBytes(objectName);
UnityWebRequest www = UnityWebRequest.Put(connectURL, myData);
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log("Upload Complete!");
}
I just couldn't send objectName to PHP server.
Then, I saw this from unity documentation.
Note: Many server backend languages do not properly handle POST requests with Content-Type headers set to encoding others than application/x-www-form-urlencoded or multipart/form-data.
Then I thought maybe this was the source of my failure. So I tried to find how others solve this problem. I didn't really know how exactly they did it. I just tried to copy it and changed the values. I used $_POST to catch these two methods and still got nothing. I guessed I didn't change it right or it's right but the data didn't send to the PHP. Please correct me if I'm wrong.
public class Object{
public string ObjectName;
}
public class connectPHP : MonoBehavior {
public static string connectURL = "http://localhost:8080/practice/connect.php";
public static string objectName;
public static bool objectEnabled;
// Start is called before the first frame update
void Start()
{
}
//Unity data to PHP
IEnumerator Upload()
{
var user = new Object ();
user.ObjectName = objectName;
string json = JsonUtility.ToJson (user);
var req = new UnityWebRequest (connectURL, "POST");
byte[] jsonToSend = new System.Text.UTF8Encoding ().GetBytes (json);
req.uploadHandler = (UploadHandler)new UploadHandlerRaw (jsonToSend);
req.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer ();
req.SetRequestHeader("Content-Type", "Application/json");
yield return req.SendWebRequest ();
if (req.isNetworkError || req.isHttpError) {
Debug.Log (req.error);
} else {
Debug.Log("Success.");
}
}
void Update()
{
if(objectEnabled == true)
{
StartCoroutine(Upload());
objectEnabled = false;
}
}
}
I think I'm supposed to turn objectName into json format. $_POST didn't get anything.
And I tried
byte[] data = System.Text.Encoding.UTF8.GetBytes (JObject);
using (UnityWebRequest www = new UnityWebRequest (connectURL)) {
www.SetRequestHeader ("Content-Type", "application/json");
www.method = "POST";
www.uploadHandler = new UploadHandlerRaw (data);
www.downloadHandler = new DownloadHandlerBuffer ();
yield return www.SendWebRequest ();
if (www.isNetworkError || www.isHttpError) {
Debug.Log (www.error);
} else {
Debug.Log("Success.");
}
}
and they all failed. $_POST didn't get anything.
I've tried to pass the data from mssql through PHP to Unity and it has worked. So I'm not sure if it's a connection issue.
connectPHP.cs
IEnumerator Download()
{
using (UnityWebRequest webRequest = UnityWebRequest.Get(connectURL))
{
yield return webRequest.SendWebRequest();
if (webRequest.isNetworkError)
{
Debug.Log("Error: " + webRequest.error);
}
else
{
Debug.Log("Received: " + webRequest.downloadHandler.text);
}
}
}
I've also tried to add
www.chunkedTransfer = false;
and it failed too.
I checked access.log. It showed
- - [16/Oct/2020:11:09:40 +0800] "POST /practice/connect.php HTTP/1.1" 200 281 "-" "UnityPlayer/2018.4.27f1 (UnityWebRequest/1.0, libcurl/7.52.0-DEV)"
I also used Debug.Log(objectName);
to make sure that value was sent from select.cs to connectPHP.cs and got [11:20:15] Object001 UnityEngine.Debug.Log(Object)
.
I've been stuck for days. I really don't know what's wrong with my code. Hope this is clear enough to explain what I've wanted to do. Any help is appreciated.
UPDATE: Still did not successfully send objectName to my PHP. I'm thinking about not using XAMPP and reinstalling Apache and PHP because I noticed that I installed PHP in my C drive before and installed XAMPP in D drive which also had PHP recently. I did not edit my PATH in environmental variables when I first installed PHP and I could still use PHP right now without it. I'm wondering if that could interfere with my connection between PHP and unity. I'm also wondering about change the version of unity to rule out the possibility that it's the bug of 2018.4. I didn't find anyone else had the same problem with me using 2018.4 though.