Android add multiple MYSQL rows using PHP - php

Basically I know how to add one row to an external mysql database using android. Now im looking to add multiple rows at once. Heres my code so far.
PHP Script
<?php
$host="db4free.net"; //replace with database hostname
$username="xxxxxx"; //replace with database username
$password="xxxxxxx"; //replace with database password
$db_name="xxxxxxx"; //replace with database name
$con=mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
/* Get the value in the whichfunction parameter
sent from the android application which will
determine the fucntion to call. */
$getFunctionToCall = $_POST['whichfunction'];
/* Depending on the value of the whichfunction
parameter switch to call different function */
switch ($getFunctionToCall){
case "AddUser":
echo AddUser($_POST['name'],$_POST['password']);
break;
}
/* Function to add user to the user table */
function AddUser($name,$password){
$sql = "insert into users(name,password) values('$name','$password')";
if(mysql_query($sql)){
return 1; // Return 1 for success;
}else{
return 2;// Return 2 for database error;
}
}
?>
Android Method
protected void SendToPhpFile() {
ArrayList<NameValuePair> pp = new ArrayList<NameValuePair>();
pp.add(new BasicNameValuePair("whichfunction", "AddUser"));
String[] names = {"David","Jimmy","Shane"};
String[] passwords = {"mypass1","mypass2","mypass3"};
for (int i=0;i<names.length;i++){
pp.add(new BasicNameValuePair("names[]", String.valueOf(names[i])));
pp.add(new BasicNameValuePair("passwords[]", String.valueOf(passwords[i])));
}
try{
status = "";
status = CustomHttpClient.executeHttpPost(ConnectBase.link, pp);
String res=status.toString();
res= res.replaceAll("\\s+","");
/* Depending on value you return if insert was successful */
if(res.equals("1")){
Toaster("Data successfully added.");
}else{
Toaster(status);
}
}catch(Exception e){
Toaster("Data successfully added: " + e.toString());
}
}
So I think I have the android size more or less sorted but I'm not 100%. If you guys could come up with a solution to how I've started that would be great. I've got zero experience with php so don't really know where to start when adding more than 1 row.
Thank you

Something like this maybe?
INSERT INTO table (name, password ) VALUES ('Name1', 'Password1'), ('Name2', 'Password2'),('Name3', 'Password3'), ('Name4', 'Password4')

Using mysqli you can not only avoid deprecated mysql functions but you can easily loop over insert values using prepared statements.
Referencing
In the following example we will be inserting usernames and passwords into the database in a safe and efficient way.
$x = array(array('bob','mypasswordlol'),array('your_mother','knitting5000'));
$stmt = $mysqli->prepare("INSERT INTO table (`username`, `password`) VALUES (?, ?)");
foreach ( $x AS $k => $value) {
$stmt->bind_param($stmt, "ss", $value[0], $value[1]);
$stmt->execute();
}
// close your connection
Hopefully this helps. Prepared statements are the bees knees when it comes to mysqli. It will help you prevent database injection and increase performance as well!

Related

PHP code no longer works when switching to mysqli

I'm trying to convert some php code that uses mysql into mysqli code. I'm not sure why it doesn't work - I didn't write the original code and am not that comfortable with the hash part of it, and it seems to be where the issue is. As I show in the code below, the "error" part gets echo'ed so it's something to do with the hash strings, but I don't really understand why changing to mysqli has broken the code. Both versions of the code are below, and the original code works. I deleted the variables (host name, etc.) but otherwise this is the code I am working with.
Mysql Code:
// Send variables for the MySQL database class.
function db_connect($db_name)
{
$host_name = "";
$user_name = "";
$password = "";
$db_link = mysql_connect($host_name, $user_name, $password) //attempt to connect to the database
or die("Could not connect to $host_name" . mysql_connect_error());
mysql_select_db($db_name) //attempt to select the database
or die("Could not select database $db_name");
return $db_link;
}
$db_link = db_connect(""); //connect to the database using db_connect function
// Strings must be escaped to prevent SQL injection attack.
$name = mysql_real_escape_string($_GET['name'], $db_link);
$score = mysql_real_escape_string($_GET['score'], $db_link);
$hash = $_GET['hash'];
$secretKey=""; # Change this value to match the value stored in the client javascript below
$real_hash = md5($name . $score . $secretKey);
if($real_hash == $hash) {
// Send variables for the MySQL database class.
$query = "insert into scores values (NULL, '$name', '$score');";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
}
Mysqli code (doesn't work):
// Send variables for the MySQL database class.
function db_connect($db_name)
{
$host_name = "";
$user_name = "";
$password = "";
$db_link = mysqli_connect($host_name, $user_name, $password) //attempt to connect to the database
or die("Could not connect to $host_name" . mysqli_connect_error());
mysqli_select_db($db_link, $db_name) //attempt to select the database
or die("Could not select database $db_name");
return $db_link;
}
$db_link = db_connect(""); //connect to the database using db_connect function
// Strings must be escaped to prevent SQL injection attack.
$name = mysqli_real_escape_string($_GET['name'], $db_link);
$score = mysqli_real_escape_string($_GET['score'], $db_link);
$hash = $_GET['hash'];
$secretKey=""; # Change this value to match the value stored in the client javascript below
$real_hash = md5($name . $score . $secretKey);
if($real_hash == $hash) {
// Send variables for the MySQL database class.
$query = "INSERT INTO `scores` VALUES (NULL, '$name', '$score');";
$result = mysqli_query($db_link, $query) or die('Query failed: ' . mysqli_error($db_link));
echo $result;
}
else {
echo "error"; //added for testing. This part gets echoed.
}
mysqli_close($db_link); //close the database connection
One notable "gotchu" is that the argument order is not the same between mysql_real_escape_string and mysqli_real_escape_string, so you need to swap those arguments in your conversion.
$name = mysqli_real_escape_string($db_link, $_GET['name']);
$score = mysqli_real_escape_string($db_link, $_GET['score']);
It's good that you're taking the time to convert, though do convert fully to the object-oriented interface if mysqli is what you want to use:
// Send variables for the MySQL database class.
function db_connect($db_name)
{
$host_name = "";
$user_name = "";
$password = "";
// Enable exceptions
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$db = new mysqli($host_name, $user_name, $password);
$db->select_db($db_name);
return $db;
}
$db = db_connect(""); //connect to the database using db_connect function
$secretKey=""; # Change this value to match the value stored in the client javascript below
$real_hash = md5($name . $score . $secretKey);
if($real_hash == $_GET['hash']) {
// Don't include ; inside queries run through PHP, that's only
// necessary when using interactive MySQL shells.
// Specify the columns you're inserting into, don't leave them ambiguous
// ALWAYS use prepared statements with placeholder values
$stmt = $db->prepare("INSERT INTO `scores` (name, score) VALUES (?, ?)");
$stmt->bind_param("ss", $_GET['name'], $_GET['score']);
$result = $stmt->execute();
echo $result;
}
else {
echo "error"; //added for testing. This part gets echoed.
}
// Should use a connection pool here
$db->close();
The key here is to use prepared statements with placeholder values and to always specify which columns you're actually inserting into. You don't want a minor schema change to completely break your code.
The first step to solving a complex problem is to eliminate all of the mess from the solution so the mistakes become more obvious.
The last if statement is controlling whether the mysql query gets run or not. Since you say this script is echoing "error" form the else portion of that statement, it looks like the hashes don't match.
The $hash variable is getting passed in on the URL string in $_GET['hash']. I suggest echo'ing $_GET['hash'] and $real_hash (after its computed by the call to MD5) and verify that they're not identical strings.
My hunch is that the $secretKey value doesn't match the key that's being used to generate the hash that's passed in in $_GET['hash']. As the comment there hints at, the $secretKey value has to match the value that's used in the Javascript, or the hashes won't match.
Also, you may find that there's a difference in Javascript's md5 implementation compared to PHP's. They may be encoding the same input but are returning slightly different hashes.
Edit: It could also be a character encoding difference between Javascript and PHP, so the input strings are seen as different (thus generating different hashes). See: identical md5 for JS and PHP and Generate the same MD5 using javascript and PHP.
You're also using the values of $name and $score after they've been escaped though mysqli_real_string_escape, so I'd suggest making sure Javascript portion is handling that escaping as well (so the input strings match) and that the msqli escape function is still behaving identically to the previous version. I'd suggest echo'ing the values of $name and $score and make sure they match what the Javascript side is using too. If you're running the newer code on a different server, you may need to set the character set to match the old server. See the "default character set" warning at http://php.net/manual/en/mysqli.real-escape-string.php.

base64_decode not working for PHP

I currently am trying to store images from an Android application. The app converts the image from the ImageView object into a byte array and then uses Android's built in Base64.encodeToString function so that I could pass it within a HTTP Post Request to my PHP script(which conducts the Insert to Database logic).
For some reason, if in my PHP Script I try to call base64_decode before storing the image as a MEDIUMBLOB, the whole insertion process fails but if I skip the base64_decode within the PHP script, the insertion works successfully. Could anyone explain to me why? Been debugging for hours but can't seem to find out the reason
I was thinking that decoding it would help me save storage space on the DB. I'm aware of not storing images in DBs and using paths and stuff but for my current purpose, I've chosen to store it in the DB as it's much more convenient for me (it's not a huge scalable project as I am just developing something to run for a small study).
Thanks in advance!
<?php
/*
* Following code will create a new product row
* All product details are read from HTTP Post Request
*/
// array for JSON response
$response = array();
// check for required fields
if (isset($_POST['username']) && isset($_POST['drinkName']) && isset($_POST['caption']) && isset($_POST['photo']) )
{
$username = $_POST['username'];
$drinkName = $_POST['drinkName'];
$caption = $_POST['caption'];
$photoRaw = $_POST['photo'];
$photo = base64_decode($photoRaw);
// include db connect class
require_once __DIR__ . '/db_connect.php';
// connecting to db
$db = new DB_CONNECT();
// mysql inserting a new row
$result = mysql_query("INSERT INTO Memories(username, drinkName, caption, photo) VALUES('$username', '$drinkName', '$caption', '$photo')");
// check if row inserted or not
if ($result) {
// successfully inserted into database
$response["success"] = 1;
$response["message"] = "Product successfully created.";
// echoing JSON response
echo json_encode($response);
} else {
// failed to insert row
$response["success"] = 0;
$response["message"] = "Oops! An error occurred.";
// echoing JSON response
echo json_encode($response);
}
} else {
// required field is missing
$response["success"] = 0;
$response["message"] = "Required field(s) is missing";
// echoing JSON response
echo json_encode($response);
}
?>
What you have described is a problem with how you are trying to insert the raw binary data into the database. When you say it works as base64, that is because base64 generally won't have a single-quote character in it which would break the sql query you show you are using.
To escape the value using those old mysql_* functions, you would use mysql_escape_string...
Please do not use that old mysql method!
You should migrate to mysqli which has been around for many years (your server should support it). Since it looks like your DB_CONNECT method is built around the old mysql, you will have to restructure that for mysqli. Its not too difficult.
I can provide you with an example of how to do the mysqli insert using a safely prepared statement:
$mysqli = new mysqli("localhost", "my_user", "my_password", "db_name");// db connect
$stmt = $mysqli->prepare("INSERT INTO Memories (username, drinkName, caption, photo)
VALUES(?,?,?,?)");
$stmt->bind_param("ssss", $username, $drinkName, $caption, $photo);
$stmt->execute();
This treats the last value as a straight passthrough as a 'string' into your MEDIUMBLOB field to be inserted safely (as well as safely handle the other three variables protecting you from sql injection attacks).
An alternate way to send binary data in, in packets, is this method:
$mysqli = new mysqli("localhost", "my_user", "my_password", "db_name");// db connect
$stmt = $mysqli->prepare("INSERT INTO Memories (username, drinkName, caption, photo)
VALUES(?,?,?,?)");
$null = NULL; // this is just a holder to bind on
$stmt->bind_param("sssb", $username, $drinkName, $caption, $null); // note the 'b'
$stmt->send_long_data(3,$photo); // 3 indicates the 4th bound variable
$stmt->execute();
Some notes:
If your images are bigger than the max_allowed_packet of mysql, you will run into some errors in that regard.
If your field is a BLOB it would only hold an image < 64kb. If its MEDIUMBLOB it will hold a 16mb image, but you risk run over max_allowed_packet.
If you run over the packet issue, you would need to build a packet loop to pass smaller chunks through the send_long_data function.

How to select a column for a MySQL table and compare it with a PHP variable

I am trying to compare a MySQL table column which I have imported to my script and compare it with a PHP value which I have defined.
I am trying to make an if loop that checks if any of the values in the column are equal to the variable.
// Connect to database containing order information
$servername = "server";
$username = "user";
$password = "pass";
// Create connection
$conn = new mysqli($servername,$username,$password);
// Check connection
if ($conn->connect_error)
{
die("Connection failed: " . $conn->connect_error);
}
// define variables and set to empty values
$name = $ordernumber = "";
// Load up data from the form
$ordernumber = ($_POST['order_number']);
// Get SQL info
$sql = "SELECT order_number FROM p_orders;";
if ($conn->query($sql) === TRUE)
{
echo "Checked Orders.....";
}
else
{
echo "Failed to check orders, please contact Support for assistance" . $conn->error;
}
// Checking Script
if ($ordernumber === $orders)
{
echo "Order Number Found.... Let's Select a Seat";
}
else
{
echo "Your Order was not found, either you did not order a reservation ticket, have not waited 3 days or you entered the number wrong. If issues persist then please contact Support."
};
The end part of the script should be like this...
$stmt = $mysqli->stmt_init();
if ($stmt->prepare('SELECT order_number FROM p_orders WHERE orderID = ?')) {
$stmt->bind_param('s',$_POST['order_number']); // i if order number is int
$stmt->execute();
$stmt->bind_result($order_number);
$stmt->fetch();
if (!empty($order_number))
echo "Order Number Found.... Let's Select a Seat";
}else {
echo "Your Order was not found...";
}
$stmt->close();
}
$mysqli->close();
...note that the query now looks for only the records that match and note the use of prepared statement to make safe the post variable from SQL Injection.
The reason to collect only the matching items from SQL is otherwise, if you have a million records, the database would return all of them and then PHP will need to loop through them (this can cause maximum execution, memory and other errors). Instead databases where built to look things up like this - note an index on this field would be good and also use of a "youtube style" id is recommended, which is why I've assumed the use of a string for it's instead of a number as the variable minght imply - and it's not the "id" which is good for a number of reasons... I've added a link to explain "youtube style" id which I'll not go into detail here but there is a lot of win in using that :)
UPDATED based on...
http://php.net/manual/en/mysqli-stmt.prepare.php
MySQL prepared statement vs normal query. Gains & Losses
https://www.youtube.com/watch?v=gocwRvLhDf8 (Will YouTube Ever Run Out Of Video IDs?)
Preferably use a WHERE clause searching for the order id and mysqli prepared statement, like below.
$mysqli = new mysqli("localhost", "my_user", "my_password", "my_db");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$name = "";
// Load up data from the form
$ordernumber = $_POST['order_number'];
/* create a prepared statement */
if ($stmt = $mysqli->prepare("SELECT COUNT(*) FROM p_orders WHERE orderID=?")) {
/* bind parameters for markers */
$stmt->bind_param("i", $ordernumber ); // "i" if order number is integer, "s" if string
/* execute query */
$stmt->execute();
/* bind result variables */
$stmt->bind_result($counter);
/* fetch value */
$stmt->fetch();
if ($counter>0) { // if order id is in array or id's
echo "Order Number Found.... Let's Select a Seat";
} else {
echo "Your Order was not found, either you did not order a reservation ticket, have not waited 3 days or you entered the number wrong. If issues persist then please contact Support."
}
/* close statement */
$stmt->close();
}
/* close connection */
$mysqli->close();

PHP and MYSQL AES_Encrypt Issues

A client of mine wants clients names to be encrypted in the database, don't ask why they are just intent of it so I have been trying to do MySQL AES_Encrypt and AES_Decrypt using PHP so I would REALLY appreciate some help...
Encrypt Code
function addname ($name, $refid) {
include("../config.php");
// Open up a new MySQLi connection to the MySQL database
mysql_connect($dbHost, $dbUsername, $dbPassword);
mysql_select_db($dbTable);
$code = substr($output, 0, 8);
if (!isset($refid)) {
$refid = "ERROR";
}
$query = "INSERT INTO `clients` (fname, code, refid, active) VALUES (AES_ENCRYPT('$fname', UNHEX('F3229A0B371ED2D9441B830D21A390C3')), '$code', '$refid', 0)";
$runQuery = mysql_query($query);
if ($runQuery != true) {
return mysql_error();
} else {
return $code;
}
}
Decrypt Code
function decryptname() {
$input=947270;
include("config.php");
// Open up a new MySQLi connection to the MySQL database
mysql_connect($dbHost, $dbUsername, $dbPassword);
mysql_select_db($dbTable);
// Build the query
$sqlToRun = "SELECT * FROM `clients` WHERE code='$input' AND active=0";
// Run it
$check = mysql_query($sqlToRun);
while($row = mysql_fetch_array($check)) {
$encryptedname = $row['fname'];
$decryptedname = mysql_query("AES_DECRYPT('$encryptedname', UNHEX('F3229A0B371ED2D9441B830D21A390C3'))");
$check2 = $row['fname'];
}
mysql_close();
if (!isset($check2)) {
$check2 = "wow there is no check2";
}
exit($check2);
}
decryptname();
The Problem
MySQL Database shows the following value, which to be looks normal
e309367d1867c3273a8f8b298ed8beb3
Basically when ever I don't include the $decryptedname I get the following as a output
ã6}gÃ':‹)ŽØ¾³
If I do include it, I get a blank screen and no PHP or MySQL Errors?
Some More Information
The database column structure for names is
varbinary(9999)
If anyone can help me I would really appreciate it, if you need more info please ask!
UPDATE
I ran the following command in SQL and it returned NULL
SELECT AES_DECRYPT('password', "UNHEX('F3229A0B371ED2D9441B830D21A390C3')") FROM passwords WHERE code=947270
Take a look at PHP AES encrypt / decrypt, that should help you a lot.
Don't encrypt using MySQL, use PHP instead. You don't want queries taking any longer than they currently do performing reads & writes on the database.
I was having similar problems. My encrypted data field was a CHAR field. I read somewhere online (https://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html) that mysql may be cropping trailing blanks from the data and as a result corrupting it for the decrypt. Using a BLOB instead solved my problem.

Need to store the latitude and longitude values generated from android app into mySQL database using PHP

I have made an tracking app in android which successfully generates latitude and longitude
but I need to store lat and long in my external mySQL database using PHP.
I am using value type "decimal(10,7)" for lat and long in DB.
Any ideas how to store lat and long generated from android into my external mySQL database using PHP?
My PHP CODE
<?php
$lat = $_GET['lat'];
$lng = $_GET['lng'];
$sender=$_POST['sender'];
$hostname = 'localhost';
$username = 'xxxx';
$password = 'xxxxxxx';
$conn = mysql_connect($hostname,$username,$password) or die('Error Please Try Again.');
if ($conn) {
mysql_select_db("android track", $conn);
$query2 = "INSERT INTO coor VALUES(NULL,'$sender','$lat','$lng')";
if (mysql_query($query2, $conn))
echo "Data Insertion Successful";
else
echo "Oops". mysql_error() ;
}
mysql_close();
?>
You can submit the mLatand mLongvariables to the server using the code below:
String storeURL = "http://www.yourdomain.com/yourscript.php?lat=" + mLat + "&long=" + mLong;
URL getURL;
getURL = new URL(storeURL);
URLConnection connection = getURL.openConnection();
connection.connect();
InputStream input = new BufferedInputStream(getURL.openStream());
OutputStream output = new ByteArrayOutputStream();
byte data[] = new byte[1024];
while ((count = input.read(data)) != -1) {
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
String downloadResult = output.toString();
Log.i("LOG", downloadResult); //Your php-script can, for example, "echo("OK");" if the storing was successful
You still need to take care of error-handling (no network connection, etc.), of course.
Ok, few things before I rewrite your code...
You are opening yourself up to SQL Injection attacks, because you
aren't using prepared statements.
The mysql PHP interface is deprecated and mysqli or PDO ought to be
used instead.
I'm assuming you're passing the NULL for a primary key on the coordinates table. Don't
do that, instead, mark it as auto increment and specify your columns explicitly in
SQL.
What is the create table statement for the coordinates table? Paste the results of SHOW
CREATE TABLE coordinates into your question. I suspect you're passing a value of null
in a column that's a primary key and can never be null.

Categories