HttpRequest to execute a php script that manages a database

Hey guys,

i saw a small post about someone using the curllib to communicate with a php page and than with a database.
Where can i get the Curllib? I read its already in UE4. Im using the Launcher version.
Do i have to get the github version or can i implement curl in the launcher version too?

Take a look at the HTTPRequest, HTTPResponse classes. That abstracts away platform specifics so that it works everywhere without you having to worry about what the underlying code is doing

Hey, i saw the Http.h Header file and tried to use the HTTPModule etc, but i’m not familiar with this. Do you know where i could find something to get started?
Most of the HTTPRequest Examples aren’t matching the construct of the UE4 Classes and just copying the interesting code leads to errors ):

Here’s some code that creates a request to send an array of strings to an endpoint:

	TSharedRef<IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest();
	HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/"));
	HttpRequest->SetURL(TEXT("https://someurl.yourdomain.com/"));
	HttpRequest->SetVerb(TEXT("POST"));
	HttpRequest->SetContentAsString(TEXT("[ \"jsonString1\", \"jsonString2\" ]");
	HttpRequest->OnProcessRequestComplete().BindRaw(this, &FMyClass::OnRequestComplete);
	HttpRequest->ProcessRequest();

Hey, thank you for the example code! This is the exact thing that i could use to perform a request for a php script to do something inside a mysql database or?

And since i’m a big noob at this, would you mind telling me what class do i need to use?
Could i just make a class from inside the editor with the aactor class as a parent and put all of this inside the .cpp file?
I include the Http.h like this:

#include "Runtime/Online/HTTP/Public/Http.h"

And i’m using 4.4. Is there anything else i would need to setup to use this?

Ok and to do this i would need the github version or?
The problem is, i got my account reenabled because of the paypal free month of you, but i can’t connect my account to github with that.
I can download the newest version of the engine with the launcher but my account seems to be unsubscribed in all other ways ):

You’ll need to update your build.cs to include the proper module as a dependency.

Hm, i set it up like this, to just test if the code compiles but i get an error.

And the error:

Error	2	error LNK2019: unresolved external symbol "public: static class FHttpModule & __cdecl FHttpModule::Get(void)" (?Get@FHttpModule@@SAAEAV1@XZ) referenced in function "public: void __cdecl ATestingHTTP::StartRequest(void)" (?StartRequest@ATestingHTTP@@QEAAXXZ)	C:\Users\Cedric\Documents\Unreal Projects\Networktesting\Intermediate\ProjectFiles\TestingHTTP.cpp.obj	Networktesting

I guess thats because i did not build the Engine from source or?

EDIT: Ok i added “Http” to the module range in my .build.cs. Now its compiling. Is that enough ?

That should do it.

Hey, i’m sorry if i annoy you with my questions on that topic, but i hope to understand this.
I managed to get FAR for my skilllevel >.<
I have my MySQL Server Running and also my PhP Script.
I made a small testing script to add a username to my mysql database.
Here is my code of the php and the UE4 class:

	<title>Download Game</title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>

	<p>This is an easy test.</p>
<?php
	$user = null;
	
	$user = $_POST['user'];
	
	$verbindung = mysql_connect("localhost","root","***") or die ("Connection refused");
	
	if($verbindung)
	{
		$selDB = mysql_select_db("accounts") or die ("No such database");
		
		if($selDB)
		{	
			$sql = "INSERT INTO users (name) VALUES('{$user}')";
			$result = mysql_query($sql) OR die("Error: $sql   
".mysql_error());
    		}
    	}
    ?>
    </body>

And the class:

#include "Networktesting.h"
#include "Runtime/Online/HTTP/Public/Http.h" 
#include "TestingHTTP.h"


ATestingHTTP::ATestingHTTP(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{

}


void ATestingHTTP::StartRequest()
{
	TSharedRef <IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest();
	HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/"));
	HttpRequest->SetURL(TEXT("http://127.0.0.1/test.php"));
	HttpRequest->SetVerb(TEXT("POST"));
	HttpRequest->SetContentAsString(TEXT("[ \"Harry\" ]"));
	HttpRequest->OnProcessRequestComplete().BindUObject(this, &ATestingHTTP::OnRequestComplete);
	
	
	if (!HttpRequest->ProcessRequest())
	{
		GEngine->AddOnScreenDebugMessage(1, 5.0f, FColor::Green, TEXT("Request failed at start!"));
	}



}

void ATestingHTTP::OnRequestComplete(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
	FString MessageBody = "";
	if (!Response.IsValid())
	{
		MessageBody = "{\"success\":\"Error: Unable to process HTTP Request!\"}";
		GEngine->AddOnScreenDebugMessage(1, 5.0f, FColor::Green, TEXT("Request failed!"));
	}
	else if (EHttpResponseCodes::IsOk(Response->GetResponseCode()))
	{
		MessageBody = Response->GetContentAsString();
		GEngine->AddOnScreenDebugMessage(1, 5.0f, FColor::Green, TEXT("Request success!"));
	}
	else
	{
		GEngine->AddOnScreenDebugMessage(1, 5.0f, FColor::Green, TEXT("Request error!"));
		MessageBody = FString::Printf(TEXT("{\"success\":\"HTTP Error: %d\"}"), Response->GetResponseCode());
	}
	
}

void ATestingHTTP::BeginPlay()
{
	Super::BeginPlay();
	//GEngine->AddOnScreenDebugMessage(1, 5.0f, FColor::Green, TEXT("Request failed!"));
	StartRequest();

}

So overall its working. I dont get an error when using the scripts but i only get empty content in my database. I dont know if this is because i dont use correct, but at least i got a connection working and that makes me happy! Do you know why i get empty inserts? I can see that something new is in the table but its just “” not “Harry”.

Ok it was the application/ line.
I found something from Rama with
“application/x-www-form-urlencoded”.

Could someone explain what this application is and how i need to change my php code to run with the application? :X

PS: Wow, i can even use this function in a blueprint and set the POST String inside a blueprint. Thats pretty amazing. Why isn’t there a tutorial on this? I cant believe that no one wants to connects its game over a php with its database :X

Hm, is there a way that i send UE4 some data in the response?
Like values from the Database or somelike a bool to tell that the Login was successful?

Application/ is the correct content type for the code I posted. Your php app needs to have the proper accepts. However, this topic is too huge to dig into. I recommend you read up on REST & php.

I will be creating a REST example in the future.

Ok, i didn’t know that i need to use the echos to get data back. On Stackoverflow they told me to get rid of the html code inside and only use echos for what i need to submit to the game.
Thanks Joe! I’m looking forward to that example.

Very cool thread! I learned a lot from this. But I have two more questions:

  • How do I pass the Value of “Response->GetContentAsString()” back to the StartRequest()-Function?
  • How do I close the connection?

Help would be greatly appreciated!

How do I close the connection?

The request object automatically closes the connection once it is done receiving the payload.

How do I pass the Value of “Response->GetContentAsString()” back to the StartRequest()-Function?

You need to create a new HTTP request object. Their life span is meant to be for a single request/response pair. Once you have that:

NewRequest->SetContentAsString(OldResponse->GetContentAsString());

Thanks Joe!

The connection closes automatically? That is very convenient! :slight_smile:

The “new request” thing however confuses me. Sry, I am a programming noob.

Can’t I just save the Response-Result in a global variable and delete it as soon as it is passed to the StartResponse()-Function. Or is there a danger of getting overwritten (by for example another request)?

At the moment im saving it to a variable of my character. I tried to return it but this function cant have a return value i guess.
I guess you can make variables in your httpclass and set them to the resonse . However, the changes only aplly after the tick ends. So if you call the request and something that uses the response in the same tick, it doesnt work because the response value only gezs applied at the end of the tick.

At the moment i send a simple with a username and a password. My php echo is false or the ID of the account in my database.
I havr a login button in my UMG widget that calls the function. Due to the tick thing, i cant check the echo in the same tick, so i let the eventgraph check it the whole time with the event tick…

Thx man! :slight_smile:

Please sanitize the $sql variable with the mysql_real_escape_string() function. This code is subject to SQL injection.