A little bit of information before hand on why I did it and etc… I use MySQL and PHP all the time for my job but I never got the hang of how it interacted with Lua, and how the http.post() worked. So after an hour of testing I finally got it. It's pretty simple, just sometimes a little confusing, now in many of my programs I use a MySQL database to login, especially things like login systems and chat programs as well as my Verinian Desktop Environment. There is very little about this, and I guess it's because not many people know about it? Especially for newbies. So here is my contribution to help anyone out. In this example I will show you a database login system, the PHP script and Lua script will be at the bottom to use!
Requirements:
+ Web Server (Paid will probably be better but a free one wills till work if going for free I recommend http://000webhost.com),
+ Some Lua knowledge of arrays etc. (Optional),
+ HTTP enabled in your ComputerCraft config (make sure to set the whitelist to *),
+ A MySQL database (you will need all the information for it username, password, database name, table name, etc.),
+ URL to the php file on your database?
How does it work?
Simple actually. You will have a PHP script that is made and a lua program that is also made! You will use Lua to post some data to a website url (where your PHP script it located) and then your PHP script does all the work and will check the database and then emit a response which then your lua program will catch and do what it needs.
What is contained in this Tutorial?
+ How to make a Lua script that will post and get a response,
+ A PHP script that can connect to your database and perform a look up with post data,
+ PHP will send a true or false on all cases. Except the get function! (Will be explained),
Okay so let's start with http.post() and what does it do?
It allows you to use a POST method of PHP to send up information to a page and catch what the response is (this will include any HTML in the script, so don't use it!).
What is PHP? (Straight from wikipedia :D/>)
PHP is a server-side scripting language designed for web development but also used as a general-purpose programming language.While PHP originally stood for Personal Home Page, it now stands for PHP: Hypertext Preprocessor, which is a recursive backronym. PHP code can be simply mixed with HTML code, or it can be used in combination with various templating engines and web frameworks. PHP code is usually processed by a PHP interpreter, which is usually implemented as a web server's native module or a Common Gateway Interface (CGI) executable.
In other words; it is what powers most social networks, game sites and more! PHP is unable to be seen without access to FTP (File Transfer Protocol) so you're passwords and stuff will be safe don't worry! A web server deals with the PHP first then sends a response with all your information, for example a Facebook page doesn't technically exist it uses a template and is created on the fly when you request it!
Anyway on with the tutoial!!!!
Getting a Lua script ready to test:
So in here we shall get a lua script (basic) that will communicate through the PHP script to the MySQL Database! Personally I use a variable called commands that will tell the PHP script what it needs to run instead of having many different PHP files for different jobs.
So here we shall have the following commands:
+ "login"
+ "insert"
+ "delete"
+ "get"
The login will take a username and password and check the database emitting true or false as a response if the user exists or not.
The insert will allow you to add a username and password and emit a true or false whether it worked.
The delete will accept a username and password and allow you to delete your account.
The get will grab any information that relates to that username, it will expect a password so not just anyone can see your information.
(SOMETHING TO NOTE: Passwords can be seen by the admin by logging in to whatever is used to admin the database, so use some kind of encryption I will supply a SHA256 bit hashing algorithm and usage for it which will hass your password with a GLOBAL standard of hashing!)
Writing the Lua Script (Will need URL to PHP script (obviously you haven't made it so just make an empty file for now and get the url making sure it is .php)):
So first let's get a few functions:
-- Clear the screen:
function cs()
term.clear()
term.setCursorPos(1,1)
end
-- The database function so you can use it multiple times in many programs:
function DBControl(sMode, sUser, sPass)
ModeList = {"login", "insert", "delete", "get",}
url = "YOUR_URL_TO_YOUR_PHP_SCRIPT" -- example(http://example.com/example.php)
if sMode == ModeList[1] then
-- This will post and catch login
elseif sMode == ModeList[2] then
-- This will post and catch inserting user
elseif sMode == ModeList[3] then
-- This will post and catch deleting a user
elseif sMode == ModeList[4] then
-- This will post and catch the users information
end
end
As this is an example I my PHP script will be at http://example.com/example.php (it's fake don't try to connect to it!)
Also note we shall add in the encryption at the end so for now just use user123 and pass123 for your username and password!
Okay let's make the login code in the DBControl function (Type this under the comment of the ModeList[1]):
we need to start the http.post() function like so:
local request = http.post(url, "command="..textutils.urlEncode(tostring(sMode)).."&".."username="..textutils.urlEncode(tostring(sUser)).."&".."password="..textutils.urlEncode(tostring(sPass)))
Let's look at this, the url is a variable that holds the url of your php script, then we HAVE to use textutils.urlEncode() to make it work for sending to the server, as well as using tostring() to make sure it is a string, otherwise it may error. sMode, sUser, sPass are all in there,
Under this you will put the following:
print(request.readAll())
This will display the output so you can see what is coming back, we can change this to work better after we get it all working!
Now copy the two scripts and put them for each of the sModes like so:
function DBControl(sMode, sUser, sPass)
ModeList = {"login", "insert", "delete", "get",}
url = "http://example.com/example.php"
if sMode == ModeList[1] then
local request = http.post(url, "command="..textutils.urlEncode(tostring(sMode)).."&".."username="..textutils.urlEncode(tostring(sUser)).."&".."password="..textutils.urlEncode(tostring(sPass)))
print(request.readAll())
elseif sMode == ModeList[2] then
local request = http.post(url, "command="..textutils.urlEncode(tostring(sMode)).."&".."username="..textutils.urlEncode(tostring(sUser)).."&".."password="..textutils.urlEncode(tostring(sPass)))
print(request.readAll())
elseif sMode == ModeList[3] then
local request = http.post(url, "command="..textutils.urlEncode(tostring(sMode)).."&".."username="..textutils.urlEncode(tostring(sUser)).."&".."password="..textutils.urlEncode(tostring(sPass)))
print(request.readAll())
elseif sMode == ModeList[4] then
local request = http.post(url, "command="..textutils.urlEncode(tostring(sMode)).."&".."username="..textutils.urlEncode(tostring(sUser)).."&".."password="..textutils.urlEncode(tostring(sPass)))
print(request.readAll())
end
end
Now are function is complete! So let's whip up a quick script that allows us to type in the username, password and command/mode:
print("> Testing MySQL and PHP")
print("> Username:")
write(": ")
local sUsername = read()
print("> Password:")
write(": ")
local sPassword = read()
print("> Command/Mode:")
write(": ")
local sCommand = read()
Now this will grab out inputs lets add a function underneath so it uses the DBControl function!
DBControl(sCommand, sUsername, sPassword)
Now this is working script (please note I didn't test any of this, but the code should be fine as I am at work!)
Now here is it all together and this is your Lua test program:
function cs()
term.clear()
term.setCursorPos(1,1)
end
function DBControl(sMode, sUser, sPass)
ModeList = {"login", "insert", "delete", "get",}
url = "http://example.com/example.php"
if sMode == ModeList[1] then
local request = http.post(url, "command="..textutils.urlEncode(tostring(sMode)).."&".."username="..textutils.urlEncode(tostring(sUser)).."&".."password="..textutils.urlEncode(tostring(sPass)))
print(request.readAll())
elseif sMode == ModeList[2] then
local request = http.post(url, "command="..textutils.urlEncode(tostring(sMode)).."&".."username="..textutils.urlEncode(tostring(sUser)).."&".."password="..textutils.urlEncode(tostring(sPass)))
print(request.readAll())
elseif sMode == ModeList[3] then
local request = http.post(url, "command="..textutils.urlEncode(tostring(sMode)).."&".."username="..textutils.urlEncode(tostring(sUser)).."&".."password="..textutils.urlEncode(tostring(sPass)))
print(request.readAll())
elseif sMode == ModeList[4] then
local request = http.post(url, "command="..textutils.urlEncode(tostring(sMode)).."&".."username="..textutils.urlEncode(tostring(sUser)).."&".."password="..textutils.urlEncode(tostring(sPass)))
print(request.readAll())
end
end
print("> Testing MySQL and PHP")
print("> Username:")
write(": ")
local sUsername = read()
print("> Password:")
write(": ")
local sPassword = read()
print("> Command/Mode:")
write(": ")
local sCommand = read()
DBControl(sCommand, sUsername, sPassword)
Please make sure the code for the inputs and DBControl is all under the functions as it is procedural as it does line by line, so it won't register the code until it has run through it first! So do a test and make sure the code works of course it should come back with an empty string or if there is generally a page with using that url then you will get that page's html/javascript!
Simple right?
Once this is done we need to get your database information on so if you use one.com or 000webhost.com then go to your PHPmyAdmin and go to create table and here is a walkthrough for PHPMyAdmin:
The images were too big for this Forum: So go here for the walkthrough of setting up the Table: Walkthrough
Now onto the PHP: (Please note the syntax won't highlight like Lua does because it is defaulted to Lua highlighting not PHP will include a link to the pastebin version of the Lua program and then PHP script).
PHP is a little different to Lua as you will need a semi-colon at the end of every line ( ;)/>.
So to start you will need to open up the PHP by doing:
<?php
// This is a comment similar to (--) for lua!
// This is where your code will go!
?>
Now let's get your PHP information in there:
// Database Information:
$host="your_host_name"; // Host name
$username1="your_username_for_database"; // Mysql username
$password1="your_password_for_database"; // Mysql password
$db_name="database_name"; // Database name
$tbl_users="users"; // Users Table (You just made this!)
Now this is done we shall make an error setup so if there is a problem it will tell you!
// Connect to server and select databse.
mysql_connect("$host", "$username1", "$password1")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
This will make sure the database information is correct before even trying to run some functions!
Now we need to get the POST data when it is sent up:
// Catch Post Data
$cmd = $_POST['command'];
$user = $_POST['username'];
$pass = $_POST['password'];
WARNING: You need to make a code checker to make sure someone doesn't try and send code up to try and get into your database, so here is a function I have made that needs to go at the bottom of the file WITHIN in the <?php ?> tags!:
function checkString($string) {
$string = stripslashes($string);
$string = mysql_real_escape_string($string);
return $string;
}
so to do this under the post data catching code put this:
$cmd = checkString($cmd);
$user = checkString($user);
$pass = checkString($pass);
Now that is there we can do what we must with it! So let's set up the if statement for what is gonna be run depending on the command:
if ($cmd == 'login') {
} elseif ($cmd == 'insert') {
} elseif ($cmd == 'delete') {
} elseif ($cmd == 'get') {
}
Okay this is done!Let's start with the login code:
sql = "SELECT * FROM " . $tbl_users . " WHERE username = '" . $user . "' AND password = '" . $pass . "'";
$query = mysql_query($sql);
$count = mysql_num_rows($query);
if ($count > 0) {
echo '"true"';
} else {
echo '"false"';
}
The above will select from the users table where the username and password match the $user and $pass variables! It will then run the query and check the anount of rows that come back! This should of course be 1! Unless you have two records with the same username and password, if this happens make sure you delete one so you get one! The if statement checks at least one row came back and then echo "true" or "false". The Lua program will then catch either "true" or "false" then you can set up an if statement for that in Lua but will do this after!
Now upload this file to the server or update the old file making sure its in the same place of course! Use FTP or whatever to upload! I recommend FTP as it is the easiest! FileZilla is my favourite FTP program.
This is what the PHP script SHOULD look like:
<?php
// Database Information:
$host="your_host_name"; // Host name
$username1="your_username_for_database"; // Mysql username
$password1="your_password_for_database"; // Mysql password
$db_name="database_name"; // Database name
$tbl_users="users"; // Users Table (You just made this!)
// Catch Post Data
$cmd = $_POST['command'];
$user = $_POST['username'];
$pass = $_POST['password'];
// Check post data
$cmd = checkString($cmd);
$user = checkString($user);
$pass = checkString($pass);
if ($cmd == 'login') {
sql = "SELECT * FROM " . $tbl_users . " WHERE username = '" . $user . "' AND password = '" . $pass . "'";
$query = mysql_query($sql);
$count = mysql_num_rows($query);
if ($count > 0) {
echo '"true"';
} else {
echo '"false"';
}
} elseif ($cmd == 'insert') {
} elseif ($cmd == 'delete') {
} elseif ($cmd == 'get') {
}
function checkString($string) {
$string = stripslashes($string);
$string = mysql_real_escape_string($string);
return $string;
}
?>
Now run the Lua code and type in the test username and password we made when setting up the table and see what returns if "true" returns then it is working! if "false" have another check at your code making sure it matches!
Now lets make the Get method next as this is pretty advanced as we get the information as a PHP formatted table then turn it into a Lua formatted table:
$sql="SELECT * FROM " . $tbl_name . " WHERE username = '" . $myusername . "' AND password = '" . $mypassword . "'";
$result=mysql_query($sql);
$count=mysql_num_rows($result);
if ($count == 1){
while($row = mysql_fetch_array($result)){
foreach($row as $key => $value){
if (!is_numeric ($key)){
$data[$key] = $value;
}
}
}
}else{
$data['error'] = '"false"';
}
header('Content-Type:text/json');
$total = count($data);
$count = 0;
foreach ($data as $d) {
if ($count == 0) {
echo '{' . PHP_EOL;
}
echo '"' . $d . '",' . PHP_EOL;
$count++;
if ($count == $total) {
echo '}';
}
}
So the code will select the same as the login, and make sure at least one row (record) matches then
add it to a table. or it will return "false" if none matches! If true then it will set it up into a Lua formatted array which will add the "{" infront of the code then adds each entry into a string with the "" then when there is no more information it will add the "}" to the end so it is a table and then Lua will catch this all and be able to view the code by printing it to screen!
Now lets make the delete function:
mysql_query("DELETE FROM $tbl_name WHERE username = '" . $myusername . "' AND password = '" . $mypassword . "'");
$affect_rows = mysql_affected_rows();
if ($affect_rows > 0) {
echo '"true"';
} else {
echo '"false"';
}
This will Delete from table where username and password match! Echoing "true" or "false" depending on if it works!
Now the last one is insert so simply:
mysql_query("INSERT INTO $tbl_name(username, password) VALUES('$myusername', '$mypassword')");
$affect_rows = mysql_affected_rows();
if ($affect_rows > 0) {
echo '"true"';
} else {
echo '"false"';
}
This code will insert into the users table the username and password then check for affected rows and if there is at least 1 then it will reply as "true" or "false" if it failed!
Here is all of the PHP code:
<?php
// Database Information:
$host="your_host_name"; // Host name
$username1="your_username_for_database"; // Mysql username
$password1="your_password_for_database"; // Mysql password
$db_name="database_name"; // Database name
$tbl_users="users"; // Users Table (You just made this!)
// Catch Post Data
$cmd = $_POST['command'];
$user = $_POST['username'];
$pass = $_POST['password']; // Check post data
$cmd = checkString($cmd);
$user = checkString($user);
$pass = checkString($pass);
if ($cmd == 'login') { sql = "SELECT * FROM " . $tbl_users . " WHERE username = '" . $user . "' AND password = '" . $pass . "'";
$query = mysql_query($sql);
$count = mysql_num_rows($query);
if ($count > 0) {
echo '"true"';
} else {
echo '"false"';
}} elseif ($cmd == 'insert') {
mysql_query("INSERT INTO $tbl_name(username, password) VALUES('$myusername', '$mypassword')");
$affect_rows = mysql_affected_rows();
if ($affect_rows > 0) {
echo '"true"';
} else {
echo '"false"';
}
} elseif ($cmd == 'delete') {
mysql_query("DELETE FROM $tbl_name WHERE username = '" . $myusername . "' AND password = '" . $mypassword . "'");
$affect_rows = mysql_affected_rows();
if ($affect_rows > 0) {
echo '"true"';
} else {
echo '"false"';
}
} elseif ($cmd == 'get') {
$sql="SELECT * FROM " . $tbl_name . " WHERE username = '" . $myusername . "' AND password = '" . $mypassword . "'";
$result=mysql_query($sql);
$count=mysql_num_rows($result);
if ($count == 1){
while($row = mysql_fetch_array($result)){
foreach($row as $key => $value){
if (!is_numeric ($key)){
$data[$key] = $value;
}
}
}
}else{
$data['error'] = '"false"';
}
header('Content-Type:text/json');
$total = count($data);
$count = 0; foreach ($data as $d) {
if ($count == 0) {
echo '{' . PHP_EOL;
}
echo '"' . $d . '",' . PHP_EOL;
$count++;
if ($count == $total) {
echo '}';
}
}
}
function checkString($string) {
$string = stripslashes($string);
$string = mysql_real_escape_string($string);
return $string;
}
?>
PM me if you need any extra help!
Have a project in mind? Email System? Chat System? Just send me a PM with your idea and I will be happy to help!