Handle POST request in JSON format - php

I'm trying to handle a POST request from a web service. It's sending an HTTP POST request like this:
{
"latitude":"12.232",
"longitude":"123.323"
}
It's posting to a PHP file on my server. I know that it is hitting the file for sure. However, I'm not getting the data.
In my PHP, I have this (leaving out a bunch of stuff:
$json = file_get_contents('php://input');
$obj = json_decode($json);
$mine ="sixteen"; //using this for a test
$sql = "INSERT INTO rr_emergency (random) VALUES('$obj');";
$result = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
This makes no change to my database.
If I do this instead:
$sql = "INSERT INTO rr_emergency (random) VALUES('$mine');";
Then "sixteen" is added in the right spot in a new row in my table each time the webservice calls my PHP. This is how I know I'm receiving data.
NOTE: I was trying to simply add $obj into my table just to see the data format that's returned before I tried to properly parse it and put everything where it belongs.
What am I doing wrong here? I think the problem is here ($json = file_get_contents('php://input');), but not sure what else to try.
Thanks.

So there's a few problems
$obj = json_decode($json);
This will return an object. You want an array
$obj = json_decode($json, true);
Then your PDO is incorrect
$sql = "INSERT INTO rr_emergency (random) VALUES(:val);";
$prep = $dbh->prepare($sql);
foreach($obj as $row) $prep->execute([':val' => $row]);
This will insert your data correctly (using a prepared statement) and loop over the JSON return data

You're trying to insert an object, when you really need a string. use:
$obj = json_decode($json, true)
$obj_str = implode(", ", $obj);
$sql = "INSERT INTO rr_emergency (random) VALUES('$obj_str');";
After I posted the above, you added:
I was trying to simply add $obj into my table just to see the data
format
Objects do not inherently convert to strings, so putting $obj within your query doesn't work. The way I store objects in my DB when I've needed to, is to store the JSON notation directly.
$json = file_get_contents("php://input");
$sql = "INSERT INTO rr_emergency (random) VALUES('$json')";
You lose the ability to perform filtering and selecting operations within the object, but it's an effective way to pack away data that you won't need the DB to parse through.
If you need well formatted, easy to read structure:
$obj = json_decode($json);
$obj_str = print_r($obj,true); //store formatted string
$sql = "INSERT INTO rr_emergency (random) VALUES('$obj_str');";
If as you said, all you need to do is "just see the data format", I suggest echoing to the screen or writing to a log file; do one of the following. To print to screen:
print_r($obj);
To write to file:
$filepath = "/path/to/file.txt"
file_put_contents($filepath,print_r($obj,true));
Important note
Entering text directly into your DB queries without escaping it makes you vulnerable to SQL injection attacks. Use prepared statements instead.

Related

How to insert new rows into database from a submitted json string?

I am not able decode and insert the array data in PHP. I tried to functions like decode and foreach, but nothing work.
The $_POST['area'] data:
[area] => [{"text":"DATA1"},{"text":"DATA2"},*,{"text":"DATA3"}]
I am new to PHP, how can I insert these rows of data into my database with pdo's prepared statements?
$area = $_POST['area'];
foreach ($area as $data) {
echo json_decode($data);
}
echo json_decode($area);
However it does not echo.
Ultimately, I want to use the data in this:
$stmt = $con->prepare(INSERT INTO `table` (`areas`) VALUES(:data));
$stmt->execute(array($data));
First things first, you have an invalid json string because of the *,.
$_POST['area'] = '[{"text":"DATA1"},{"text":"DATA2"},*,{"text":"DATA3"}]';
// uh oh, not valid json -----^^
So I'll assume that this is a posting error and run with the following input data:
$_POST['area'] = '[{"text":"DATA1"},{"text":"DATA2"},{"text":"DATA3"}]';
This means that before you can iterate $_POST['area'], you must json_decode() it. (Demo)
An unchanging prepared statement should be declared before entering the loop -- it is designed to be used over and over.
The binding of values to placeholders and the execution of the query is to be done inside the loop.
$stmt = $con->prepare(INSERT INTO `table` (`areas`) VALUES(?));
foreach (json_decode($_POST['area']) as $obj) {
$stmt->execute([$obj->text]);
}
Your json format is incorrect. To do json_decode(); you need correct json format
$post['area'] = [{"text":"DATA1"},{"text":"DATA2"},*,{"text":"DATA3"}];
changed it to
$post['area'] = [{"text":"DATA1"},{"text":"DATA2"},{"text":"DATA3"}];
then do
$ex = json_decode($data, true);
Use This:
$area = json_decode($_POST['area'],true);
You can't echo an array in PHP. You have to use the var_dump() function to do that.
Have a good day ;).

Decoding and accessing a json dictionary array in PHP

I have the following json file which I'm sending through my mobile application to PHP and on the PHP side I want to Decode it and insert it into a mysql database.
[{"Address":"Somewhere ",
"Area":"Somwhe",
"CreatedBy":null,
"CreatedDate":"\/Date(1419786831365+0530)\/",
"Distance":0,
"EditedDate":"\/Date(-62135596800000+0000)\/",
"Latitude":12.903999947011471,
"Longitude":77.607999974861741,
"Phone1":"80372899",
"Phone2":"993729927",
"Response":null,
"StoreDescriptions":[],
"StoreName":"First"},
{"Address":"Addwmsj",
"Area":"Sbnns",
"CreatedBy":null,
"CreatedDate":"\/Date(1419786863657+0530)\/",
"Distance":0,
"EditedDate":"\/Date(-62135596800000+0000)\/",
"Latitude":12.960867136716843,
"Longitude":77.647689711302519,
"Phone1":"799268299",
"Phone2":"68393973738",
"Response":"Waiting",
"StoreDescriptions":[{"LongNBQuantity":862,
"MeetDate":"\/Date(1419786915048+0530)\/",
"MeetSummary":"Meeting",
"Response":"Negative",
"StoreName":"Ssxond",
"id":1
},
{"LongNBQuantity":8862,
"MeetDate":"\/Date(1419786927673+0530)\/",
"MeetSummary":"Pjsjsbsj",
"Response":"Waiting",
"StoreName":"Ssxond",
"id":2}],
"StoreName":"Ssxond"},
{"Address":"Sumwhere",
"Area":"Righthere",
"CreatedBy":null,
"CreatedDate":"\/Date(1419953186686+0530)\/",
"Distance":0,
"EditedDate":"\/Date(-62135596800000+0000)\/",
"Latitude":12.903999947011471,
"Longitude":77.607999974861741,
"Phone1":"872737288",
"Phone2":"663838828",
"Response":null,
"StoreDescriptions":[],
"StoreName":"NewEntry"}]
As we can see in this I have Array of objects [{},{},{}...{}] and the complexity increases when one of these objects have array of objects like {"abc":"bcd","storedesc":[{},{},{},....{}]} , so this is a little complex when compared to the simple jsons.
My code is not working. Can anybody guide me in the right direction. Thanks
$json = file_get_contents('php://input');
$result = json_decode($json,true);
/*
Database connection setup done here.
*/
foreach ($result as $key => $value) {
if($value){
$sql = "INSERT INTO StoreInfo(name,created_date,edited_date,address,area,ph_num1,ph_num2,response,latitude,longitude) VALUES ($value->StoreName,$value->CreatedDate,'hellyeah',$value->Address,$value->Area,$value->Phone1,$value->Phone2,$value->Response,$value->Longitude,$value->Latitude)";
if($conn->query($sql) === TRUE){
echo "New record inserted";
}
}
}
There are couple of reasons, this not works.
Because you are using the true flag, when you are decoding the JSON, you will get back only arrays, and as I see, you want to use objects in your querys.
In your query do not wrap your wariables with quotes.
So it will be something like this, but please, see my NOTE section!
$sql = "INSERT INTO StoreInfo (name,created_date,edited_date,address,area,
ph_num1,ph_num2,response,latitude,longitude)
VALUES ('".$value["StoreName"]."','".$value["CreatedDate"]."','hellyeah',
'".$value["Address"]."','".$value["Area"]."','".$value["Phone1"]."',
'".$value["Phone2"]."'
,'".$value["Response"]."','".$value["Longitude"]."','".$value["Latitude"]."')";
NOTE
Please escape your variables comes from outside, or use prepared statements to avoid sql injection!
By $result = json_decode($json,true); it is converted to array. true parameter in json_decode() convert JSON to array(). So you should access value by $value['CreatedDate'] instead of $value->CreatedDate and so on.
foreach ($result as $key => $value) {
if($value){
$sql = "INSERT INTO StoreInfo(name,created_date,edited_date,address,area,ph_num1,ph_num2,response,latitude,longitude) VALUES ('".$value['StoreName']."','".$value['CreatedDate']."','hellyeah','".$value['Address']."','".$value['Area']."','".$value['Phone1']."','".$value['Phone2']."','".$value['Response']."','".$value['Longitude']."','".$value['Latitude']."')";
if($conn->query($sql) === TRUE){
echo "New record inserted";
}
}
}
Reference:
json_decode()

How to store multiple parameters passed as POST in database

I have passed JSON encoded parameters by POST which we have captured and decoded in another PHP file. I have used the following code to do that.
$entityBody = file_get_contents('php://input');
$entityBody = json_decode($entityBody, true);
I have passed the JSON encoded parameters as follows:
{
"id": "5",
"name": "abcd",
"imei": "1234"
}
Actually the number of parameters I am passing by POST may be 15 to 20 which I am going to insert in a table i.e. each of them is a field in the table in mysql database. I am new to JSON and PHP. What method I know is that get value of each parameter after checking whether it is set like following:
if(isset($entityBody['id']))
...
elseif(isset(...))
...
It is clear there will be many if and else when there are many parameters. So is there any way so that I can store the parameters in table in more efficient way. If anyone helps me in doing that I will be really grateful.
use json_decode function to parse the json to an array or object.
$a = json_decode($entityBody);
$a->id;
refer http://php.net/manual/en/function.json-decode.php
If you're using prepared statements you could do something like this. Please note that you should consider how you implement something like this, and change it to suit your needs.
$json = '{"id": "5","name": "abcd","imei": "1234"}';
$array = json_decode($json, true);
if (!count($array) > 0) {
throw new Exception('No params set.');
}
$allowedKeys = array('id','name','imei'); // could be hard coded, or something like: SELECT * FROM yourdb.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = yourtable
$queryParams = array();
foreach ($array as $key => $value) {
if (in_array($key, $allowedKeys)) {
$queryParams['keys'][] = $key;
$queryParams['values'][] = $value;
}
}
print_r($queryParams);
$query = 'INSERT INTO yourtable (' . implode(', ', $queryParams['keys']) . ') VALUES (?' . str_repeat(',?', count($queryParams['values'])-1) . ')';
print_r($query); // INSERT INTO yourtable (id, name, imei) VALUES (?,?,?)
Then you can just execute it with the $queryParams['values'] as the values :)
There's however no need to insert "id" if you're using auto increment, it will possibly just end up in some strange errors.

Creating a json array using concat with MySql

I'm creating a json array from MySql data using concat like this:
$id = '5705';
$sql = 'select concat("{""type:""colName"",""id"":""$id""}") as myJson from table where etc.;
$stmt = $conn->prepare($sql);
What's happening is, instead of getting data from colName from the table and the value of $id, I'm getting the result as it is in $sql. How do I break out of it and get colName and $id's value?
Current Result
{""type:""colName"",""id"":""$id""}
Desired Result
{""type:""novice"",""id"":""5705""}
//Here novice is data from colName, and 5705 is the value of $id
Please DON'T DO THAT. Trying to format data into JSON in your SQL will be fragile as encoding things into JSON is subtly more tricky that you would expect and you will inevitably get it wrong.
You should use the json_encode function in PHP. It will work reliably whereas your code will almost certainly break.
$dataArray = array();
while($statement->fetch()){
$data = array();
$data['type'] = $typeColumn;
$data['id'] = $id;
$dataArray[] = $data;
}
json_encode($dataArray, JSON_HEX_QUOT);
Also, formatting data to send to a client really shouldn't be part of an SQL query.
You need a better concatenation either in query and php
'select concat("{""type:"",colName,"",""id"":""'.$id.'""}")
Despite it is not really needed you could surround column name with backticks `
Your variables inside your string are not substituted with their values, as you got single quotes. Double quoted strings will expand variables with their values
Thus, you could invert your quotes, like this, in order to get the actual values of your variables:
$sql = "select concat('...')"

This REGEXP echos one thing, but enters into MySQL another. Why?

I have a query that when I test it with "echo", works well:
$url = "http://search.twitter.com/search.json?q=&ands=&phrase=&ors=&nots=RT%2C+%40&tag=andyasks&lang=all&from=amcafee&to=&ref=&near=&within=15&units=mi&since=&until=&rpp=50";
$contents = file_get_contents($url);
$decode = json_decode($contents, true);
foreach($decode['results'] as $current) {
if(preg_match("/\?/", "$current[text]")){
echo $current[text]."<br />";
}
}
But when I change it to this to create a DB, it loses one record:
$url = "http://search.twitter.com/search.json?q=&ands=&phrase=&ors=&nots=RT%2C+%40&tag=andyasks&lang=all&from=amcafee&to=&ref=&near=&within=15&units=mi&since=&until=&rpp=50";
$contents = file_get_contents($url);
$decode = json_decode($contents, true);
foreach($decode['results'] as $current) {
$query = "INSERT IGNORE INTO andyasks (questions, date, user) VALUES ('$current[text]','$current[created_at]','Andy')";
if(preg_match("/\?/", "$current[text]")){
mysql_query($query);
}
}
Specifically, the Tweet it's skipping over is "amcafee: #andyasks What should Enterprise 2.0 conference attendees be sure to do while they're in Boston later this month? #e2conf". This echos from the first one, but is left out on the DB INSERT. Any thoughts?
There's a single quote in the string that it doesn't insert (my _emphasis_ added):
"amcafee: #andyasks What should Enterprise 2.0 conference attendees be sure to do while they**_'_**re in Boston later this month? #e2conf"
The bare single-quote is interpreted by MySQL as the end of the first value, and it turns the rest of the query into gibberish. You need to escape single quotes (i.e. turn "they're" into "they\'re" so that MySQL knows that the single quote is part of your string. Incidentally, single-quote tricks are the main source of SQL injection attacks, so you should always be wary of single-quotes.
If you're using the mysql extension, you should always use the mysql_real_escape_string function on any untrusted data:
$url = "http://search.twitter.com/search.jsonq=&ands=&phrase=&ors=&nots=RT%2C+%40&tag=andyasks&lang=all&from=amcafee&to=&ref=&near=&within=15&units=mi&since=&until=&rpp=50";
$contents = file_get_contents($url);
$decode = json_decode($contents, true);
foreach($decode['results'] as $current)
{
$query = "INSERT IGNORE INTO andyasks (questions, date, user) VALUES ('$current[text]','$current[created_at]','Andy')";
if(preg_match("/\?/", "$current[text]"))
{
mysql_real_escape_string($query);
mysql_query($query);
}
}
PHP/MySQL Debugging Tips
When you're echoing out debug statements, make sure you view the source of your HTML page to see what's actually being sent to mysql.
While viewing the source of your echo'd page, copy and paste the SQL query directly into the mysql console (or phpMyAdmin if you're using it) and see what happens.
Consider using a logging function instead of echoing out mysql statements. Here's a brain dead logger you can use
class BrainDeadLogger {
static public function log($output, $file='/tmp/test.txt') {
file_put_contents($file,"$output\n",FILE_APPEND);
}
}
BrainDeadLogger::log($sql);
And then monitor the log with something like
tail -f /tmp/test.txt
on the Unix command line. You can downloadTail for Windows, which should work similarly.

Categories