Parse JSON file in PHP and insert into SQL ---- - php

So I have been doing my research and no method seems to parse my file correctly. I have tried these two codes, my data is being inserted into sql however it is inserted 3 times with the first insertion being fine while the other 2 are blank. Here is my JSON file and code:
JSON:
[
{
"Comments": {
"Manufacturer": "--E",
"Model": "----- ----- ----",
"BIOSFamily": "---",
"BIOSDate": --/--/---8",
"SerialNumber": "---------"
}
},
{
"#ComputerSystem.v1-----------ystem": {
"/redfish/v1/Systems/1/": {
"AssetTag": " ",
"Bios": {
"#odata.id": "/redfish/v1/systems/1/bios/"
},
"BiosVersion": "U----------------)",
"Boot": {
"BootSourceOverrideMode": "-----y",
"BootSourceOverrideTarget": "None",
"BootSourceOverrideEnabled": "Disabled",
"BootSo-----------arget#Redfish.AllowableValues": [
"None",
"Cd",
"Hdd",
"Usb",
"Utilities",
"Diags",
"BiosSetup",
"Pxe",
"UefiShell"
]
Code:
<?php
$connect = mysqli_connect("reserve1",
"root", "","server_31");
$filename = "-----.json";
$data = file_get_contents($filename);
$array = json_decode($data, true);
foreach($array as $row)
{
$sql = "INSERT INTO servers (Model,
Manufacturer, BIOSFamily,
BIOSDate,
SerialNumber) VALUES
('".$row["Comments"]["Model"]."' ,
'".$row["Comments"]
["Manufacturer"]."',
'".$row["Comments"]
["BIOSFamily"]."','".$row["Comments"]
["BIOSDate"]."','".$row["Comments"]
["SerialNumber"]."')";
mysqli_query($connect, $sql);
}
echo "Data in";
?>
ERROR:" Notice: Undefined index: Comments "
other forloops i have tried are:
foreach($data as $Comments)
{
$sql =" INSERT INTO
'servers'('Manufacturer','Model',
'BIOSFamily','BIOSDate',
'SerialNumber'), VALUES('{$Comments-
>Manufacturer}', '{$Comments-
>Model}',
'{$Comments->BiosFamily}',
'{$Comments->BiosDate}',
'{$Comments-
>SerialNumber}')";
}
ERROR:" Notice: Trying to get property of non-object in"
To reiterate: the first method does get my info onto sql but does so 3 times with the last 2 entries being blank. The second method does not insert anything into my table.
EDIT:
so i tried vardump, using the file itself all i got was NULL, copy and pasting the contents and labeling it $json= ' content ' in the script i get..
C:\Users\Administrator\Desktop\Reserve1\newtry\NEWJSONP.php:16:
array (size=1)
0 =>
object(stdClass)[1]
public 'Comments' =>
object(stdClass)[2]
public 'Manufacturer' => string 'HPE' (length=3)
public 'Model' => string '-------------' (length=20)
public 'BIOSFamily' => string '---' (length=3)
public 'BIOSDate' => string '--/--/----' (length=10)
public 'SerialNumber' => string '-------' (length=10)
C:\Users\Administrator\Desktop\Reserve1\newtry\NEWJSONP.php:17:
array (size=1)
0 =>
array (size=1)
'Comments' =>
array (size=5)
'Manufacturer' => string '---' (length=3)
'Model' => string '------ ----------' (length=20)
'BIOSFamily' => string '---' (length=3)
'BIOSDate' => string '--/--/----' (length=10)
'SerialNumber' => string '-------' (length=10)

Simply index in your foreach loop the first item since $array object maintains Comments only in first position. See 0 index from var_dump output:
array (
0 =>
array (
'Comments' =>
array (
'Manufacturer' => '--E',
'Model' => '----- ----- ----',
'BIOSFamily' => '---',
'BIOSDate' => ' --/--/-- - 8 ',
'SerialNumber' => '---------',
),
),
1 =>
array (
'#ComputerSystem.v1-----------ystem' =>
...
Therefore, iterate through the Comments array and use parameterization for readability:
$connect = new mysqli($servername, $username, $password, $dbname);
// PREPARED STATEMENT
$sql = "INSERT INTO servers (Model, Manufacturer, BIOSFamily, BIOSDate, SerialNumber)
VALUES(?, ?, ?, ?, ?)";
// INDEX FIRST ITEM AT 0
foreach($array[0] as $row) {
$stmt = $connect->prepare($sql);
// BIND PARAMETERS (NO COMMENTS INDEX)
$stmt->bind_param("sssss", $row["Model"],
$row["Manufacturer"],
$row["BIOSFamily"],
$row["BIOSDate"],
$row["SerialNumber"]);
// EXECUTE STATEMENT
$result = $stmt->execute();
}

Related

Adding MySQL result in php array has duplicate values

To explain the scenario:
I have this table in MySQL DB
+-------------------------------------------------------------------------+
| message_id | client_id | admin_id | message | date_posted | read_status |
+-------------------------------------------------------------------------+
I am selecting all the messages and grouping them in a 2D Array for the same client so that the result migh look like
$messages = array(
"4" => array ("338", "4", "1", "message1", "20170904 120803", "0"),
"5" => array ("339", "5", "1", "message2", "20170904 120807","0")
);
The result I'm getting is similar but each value in the array is duplicated
array (size=12)
'message_id' => string '22' (length=2)
0 => string '22' (length=2)
'client_id' => string '14' (length=2)
1 => string '14' (length=2)
'admin_id' => string '1' (length=1)
2 => string '1' (length=1)
'message' => string 'hii I'm new to this' (length=19)
3 => string 'hii I'm new to this' (length=19)
'date_posted' => string '2017-04-22 17:17:13' (length=19)
4 => string '2017-04-22 17:17:13' (length=19)
'read_status' => string '0' (length=1)
5 => string '0' (length=1)
This is my query
$grouped_messages = array();
foreach ($connect->query("SELECT DISTINCT * FROM request ORDER BY client_id") as $row) {
var_dump($row);
$client_id = $row['client_id'];
if (!isset($grouped_messages[$client_id])) {
$grouped_messages[$client_id] = array();
}
$grouped_messages[$client_id][] = $row;
}
foreach ($grouped_messages as $client_id => $client_messages) {
echo '<div>';
echo '<p>Messages for client #' . $client_id . '</p>';
foreach ($client_messages as $message) {
foreach($message as $column) {
echo $column;
}
}
echo '</div>';
}
Any Ideas on why that is happening?
PS The same client can have multiple messages meaning multiple rows in this table that's what the code it puts all those messages from the same client into the associative array!
Fetching both numeric and text keys is a default behaviour of PDO fetch.
You can change it, in your case this should be done by setting attribute PDO::ATTR_DEFAULT_FETCH_MODE to PDO::FETCH_ASSOC:
$connect->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
Or you can do it when you instantiate new PDO object.
More modes here.

"Trying to get property of non-object" Inner Join using PDO

i try show data using PDO. But i get Error "Trying to get property of non-object".
i have a simple script.
public function tampilUserId($user_id)
{
$sql = "SELECT $this->user.*, $this->provinsi.*
FROM $this->user
INNER JOIN $this->provinsi
ON $this->user.provinsi_id=$this->provinsi.provinsi_id
WHERE user_id=:user_id";
$stmt = db::prepare($sql);
$stmt->bindParam(':user_id', $user_id);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_OBJ);
}
And this
echo $results->email_user;
print_r($result);
result
Notice: Trying to get property of non-object in C:\xampp\htdocs\laporan_app\user_views\profile.php on line 35
stdClass Object ( [user_id] => 45 [nama_dpn_user] => [nama_blkng_user] => [username_user] => adi [password_user] => $2y$10$p/8gF5BcQSooQUKRlEAiPuOSy4o1RMeXA5Ul8GTZNYZi/4wcOP3Ja [email_user] => adi#gmail.com [level_user] => mahasiswa [img_user] => [_dir_img_user] => [_size_img_user] => [provinsi_id] => [universitas_id] => )
And i try this script
echo $results['email_user'];
print_r($results);
result
Notice: Undefined index: email_user in C:\xampp\htdocs\laporan_app\user_views\profile.php on line 35
stdClass Object ( [user_id] => 45 [nama_dpn_user] => [nama_blkng_user] => [username_user] => adi [password_user] => $2y$10$p/8gF5BcQSooQUKRlEAiPuOSy4o1RMeXA5Ul8GTZNYZi/4wcOP3Ja [email_user] => adi#gmail.com [level_user] => mahasiswa [img_user] => [_dir_img_user] => [_size_img_user] => [provinsi_id] => [universitas_id] => )
Please help me, thanks before.
Merdeka! :D
In case your SQL query not contain any error its mean data was successfully pulled from database. So in your tampilUserId($user_id) function, its returning set of array from $stmt->fetchAll(PDO::FETCH_OBJ). Like below:
/* Sample from Sakila database */
array (size=603)
0 =>
object(stdClass)[11]
public 'address_id' => string '1' (length=1)
public 'address' => string '47 MySakila Drive' (length=17)
public 'address2' => null
public 'district' => string 'Alberta' (length=7)
public 'city_id' => string '300' (length=3)
public 'postal_code' => string '' (length=0)
public 'phone' => string '' (length=0)
public 'last_update' => string '2014-09-25 22:30:27' (length=19)
1 =>
object(stdClass)[12]
public 'address_id' => string '2' (length=1)
public 'address' => string '28 MySQL Boulevard' (length=18)
public 'address2' => null
public 'district' => string 'QLD' (length=3)
public 'city_id' => string '576' (length=3)
public 'postal_code' => string '' (length=0)
public 'phone' => string '' (length=0)
public 'last_update' => string '2014-09-25 22:30:09' (length=19)
more elements...
All you need to do is looping your function returned value first whereever you call it. Short example from your case:
//I dont know you put it under class or not.
$data = $YourClass->tampilUserId($user_id);
foreach ($data as $item) {
echo $item->email_user);
}
Note:
You can manually echoing your data without looping and its bad practice because you dont know the length of the array. So this is just gusessing. Taken from your case it would be.
$data = $YourClass->tampilUserId($user_id);
$data[0]->email_user; //If an object
$data[0]['email_user']; //If an array
Update:
There is suspicious thing on your query. The variable $this->user is not look like column name to me(unsure) If yes, so you have small mistake on your query. Secondly, as you said the result is null its mean something wrong or data you search not exist. I put this sample running inner join query.
Example:
Lets said i had 2 table. 1st is address and 2nd is city
|address table|
|city table|
So your sql query for joining table(from image above) should be:
SELECT adr.address_id, adr.address, adr.district, adr.city_id, c.city_id,
c.city FROM address AS adr INNER JOIN city AS c ON adr.city_id = c.city_id
WHERE c.city_id = 300 #using city id
Output:
Bring it to PHP
<?php
$pdo= new PDO('mysql:dbname=sakila;host=localhost:3306', 'user', password');
$city_id = 300; // manual set
$sql = 'SELECT adr.address_id, adr.address, adr.district, adr.city_id,
c.city_id, c.city FROM address AS adr INNER JOIN city AS c ON
adr.city_id = c.city_id WHERE c.city_id = :city_id';
$stmt = $_this->db->prepare($sql);
$stmt->bindParam(':city_id', $city_id);
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_OBJ);
?>
var_dump($data) giving a result:
Great, as it come as (object(stdClass)) so we can loop it through the array & then accessing it using -> sign.
<?php
$i = 1;
foreach ($data as $d) {
echo '<dl>';
echo '<dt>Adress '.$i++.':</dt>';
echo '<li>Address id: '.$d->address_id.'</li>';
echo '<li>Address: '.$d->address.'</li>';
echo '<li>District: '.$d->district.'</li>';
echo '<li>City id: '.$d->city_id.'</li>';
echo '<li>City name: '.$d->city.'</li>';
echo '</dl>';
}
?>
Result in browser:
Hope this will resolve your problem.

PHP MySQL Insert array

I'm having trouble with inserting the values from this array. Here example:
$arr = json_decode($_POST['dynfields'], true);
//{"dynfields":{"dynfields[0][DescRepair]":"Desc repair","dynfields[0][NestParts]":"Parts","dynfields[0][EdPrice]":"10","dynfields[0][DateRepair]":"2015-07-20","dynfields[1][DescRepair]":"Desc repair","dynfields[1][NestParts]":"Parts","dynfields[1][EdPrice]":"5","dynfields[1][DateRepair]":"2015-07-20"}}
foreach ($arr as $key => $fieldArray ) {
foreach($fieldArray as $k => $v) {
echo $k . " - " . $v . "<br>"; // result: dynfields[0][DescRepair] - Desc repair
dynfields[0] [NestParts] - Parts
dynfields[0][EdPrice] - 10
dynfields[0][DateRepair] - 2015-07-20
dynfields[1][DescRepair] - Desc repair
dynfields[1][NestParts] - Parts
dynfields[1][EdPrice] - 5
dynfields[1][DateRepair] - 2015-07-20
}
//$query = mysqli_query($mysqli, "INSERT INTO repair (DescRepair, NestParts, EdPrice, DateRepair) VALUES ('?', '?', '?', '?')") or die(mysqli_error($mysqli));
}
This is my code, but I don't know how to insert the value in db. Can you give me any suggestions. Thanks.
I did not understand very well your code, but at first your json is bad, on post, this is an example of right json:
{
"dynfields": [
{
"DescRepair": "Desc repair",
"NestParts": "Parts",
"EdPrice": "10",
"DateRepair": "2015-07-20"
},
{
"DescRepair": "Desc repair",
"NestParts": "Parts",
"EdPrice": "5",
"DateRepair": "2015-07-20"
}
]
}
Then you can make a foreach with the dynfields data:
$myvar = json_decode($json,true);
$data = $myvar['dynfields'];
foreach(array_keys($data) as $index){
var_dump($data[$index]);
}
then you will get something like this (var_dump):
array (size=4)
'DescRepair' => string 'Desc repair' (length=11)
'NestParts' => string 'Parts' (length=5)
'EdPrice' => string '10' (length=2)
'DateRepair' => string '2015-07-20' (length=10)
array (size=4)
'DescRepair' => string 'Desc repair' (length=11)
'NestParts' => string 'Parts' (length=5)
'EdPrice' => string '5' (length=1)
'DateRepair' => string '2015-07-20' (length=10)
$query = mysqli_query($mysqli, "INSERT INTO repair (DescRepair, NestParts, EdPrice, DateRepair) VALUES ('?', '?', '?', '?')") or die(mysqli_error($mysqli))
relace each ? with {$arr['xxxxx']} Where xxxxx are your array keys
make sure to well-escape the variables to prevent SQL Injection
Hint: you can use PDO or prepared statements

How to get a single value from a query result in php [duplicate]

This question already has answers here:
Single result from database using mysqli
(6 answers)
Closed 2 years ago.
I am trying to get single value from DB with single query. i mean that i already featched all values in one query from that i need to get only one column value.
$connection = mysqli_connect($servername, $username, $password, $dbname);
$query = mysqli_query( $connection,"select * from register where password='$log_in_password' AND username='$log_in_username'");
var_dump($query);
$table = mysqli_fetch_all($query,MYSQLI_ASSOC);
var_dump($table);
assume columns are
' userid useremail username password Name '
from php
var_dump($query) gives this..
object(mysqli_result)[2]
public 'current_field' => null
public 'field_count' => null
public 'lengths' => null
public 'num_rows' => null
public 'type' => null
var_dump($table) gives this
array (size=1)
0 =>
array (size=5)
'userid' => string '7' (length=1)
'useremail' => string 'demo#gmail.com' (length=16)
'username' => string 'demousername' (length=7)
'password' => string 'demopassword' (length=5)
'Name' => string 'demoname' (length=6)
so help me out with fetching only one column value's record (example insSelect * to select userid)
Your variable $table is an array, so if you want only the userid, you just have to use
$table[0]['userid']
If you want to query only the userid change you query like this :
$query = mysqli_query( $connection,"select userid from register where password='$log_in_password' AND username='$log_in_username'");
$table = mysqli_fetch_all($query,MYSQLI_ASSOC);
And the result of $table will be :
array (size=1)
0 =>
array (size=1)
'userid' => string '7' (length=1)
$table will also be an array, and to acces userid you have to use again
$table[0]['userid']
Try this
$connection = mysqli_connect($servername, $username, $password, $dbname);
$query = mysqli_query($connection, "select * from register where password='$log_in_password' AND username='$log_in_username'");
$table = null;
while ($row = mysqli_fetch_array($query)) {
$table = $row;
}
print_r($table);

Doctrine hydrated array result

I want to get Doctrine to return a hydrated array with the values being the id for the key, then all values inside an array of results (i.e. if there are multiple items with same ID, then return ID with multiple results in array).
This is the current function I do:
public static function getMedia($em, $entity, $id = NULL)
{
$dql = 'SELECT m.id, m.url, m.nb, m.lang
FROM iMT\Entity\Media m INDEX BY m.id JOIN iMT\Entity\\' . $entity . ' r WITH m.id = r.id';
if($id) {
$dql .= " WHERE r.id = ?1";
}
$q = $em->createQuery($dql);
if($id) {
$q->setParameter(1, $id);
}
return $q->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
}
Which returns:
array (size=44)
479600 =>
array (size=4)
'id' => int 479600
'url' => string 'pois/479600/Nonna.JPG' (length=48)
'nb' => null
'lang' => string 'fr' (length=2)
479615 =>
array (size=4)
'id' => int 479615
'url' => string 'pois/479615/Tramways.jpg' (length=51)
'nb' => null
'lang' => string 'fr' (length=2)
479580 =>
array (size=4)
'id' => int 479580
'url' => string 'pois/479580/ATLAS.jpg' (length=48)
'nb' => null
'lang' => string 'fr' (length=2)
479581 =>
array (size=4)
'id' => int 479581
'url' => string 'pois/479581/P'tit_sushi.jpg' (length=54)
'nb' => null
'lang' => string 'fr' (length=2)
However, I need the output to be:
array (size=44)
479600 =>
array (size=2)
array (size=4)
'id' => int 479600
'url' => string 'pois/479600/Nonna.JPG' (length=48)
'nb' => null
'lang' => string 'fr' (length=2)
array (size=4)
'id' => int 479600
'url' => string 'pois/479600/OtherPic.JPG' (length=48)
'nb' => null
'lang' => string 'fr' (length=2)
Would I need to create my own AbstractQuery::HYDRATE_ARRAY or is there something available that does what I need?
I'm using the result by checking if it contains a key that matches the ID of the current item (e.g. if(isset($data[$item])) // where $item = 479600 then output images), maybe there's a better way to check for the results?
EDIT
I've updated my function to return:
$result = $q->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
$data = array();
$count = count($result);
for($i = 0; $i < $count; $i++) {
if(!isset($data[$result[$i]['id']])) {
$data[$result[$i]['id']] = array(
$result[$i]
);
} else {
$data[$result[$i]['id']][] = $result[$i];
}
}
return $data;
Which returns something more to what I want:
array (size=44)
479600 =>
array (size=1)
0 =>
array (size=4)
'id' => int 479600
'url' => string 'pois/479600/Nonna.JPG' (length=48)
'nb' => null
'lang' => string 'fr' (length=2)
479577 =>
array (size=2)
0 =>
array (size=4)
'id' => int 479577
'url' => string 'pois/479577/AOMC.JPG' (length=47)
'nb' => null
'lang' => string 'fr' (length=2)
1 =>
array (size=4)
'id' => int 479577
'url' => string 'pois/479577/Buffet AOMC.jpg' (length=54)
'nb' => null
'lang' => string 'fr' (length=2)
Can this be improved? Is there any Doctrine functions that can help, or should I leave my for() loop?
The problem with using INDEX BY together with a JOIN is that the result that doctrine gives you might not contain all data that's fetched from the database.
In your case the database might return multiple rows containing the same value for m.id (because of the JOIN). But each subsequent row containing the same value for m.id will overwrite the previous one (because of the INDEX BY m.id).
Doctrine does not come with a hydrator that can solve this problem out of the box. You shall indeed need to implement your own. Read more about creating custom hydration modes.
Alternative
Another solution would be to not use INDEX BY in this case.
You could write a repository method that translates the result given by Doctrine to the array you want to have. Other parts of your application can then call that repository method.
This is probably easier than creating a custom hydration mode.
Update
The translation can look like this:
$data = array();
foreach ($q->getArrayResult() as $row) {
if (!isset($data[$row['id']])) {
$data[$row['id']] = array();
}
$data[$row['id']][] = $row;
}
return $data;

Categories