I would like to set a key to parent value of my array.
my output is a parent value and a array ;
"parent":{
'A'=>value,
'B'=>value
}
output (To read output copy/paste into http://json.parser.online.fr/):
{"7916":{"id":"1168","GoodMainCode":"7916","title":"\u0632\u064a\u0631\u062f\u0633\u062a\u064a \u0637\u0644\u0642\u064a CLIP BOARD","author":" ","publisher":"\u0641\u0642\u064a\u0647\u064a \u0645\u0647\u0631","translator":" ","price":"20625","isbn":" ","amount":"0","year_of_publish":"0","period_print":"0"},"7989":{"id":"16827","GoodMainCode":"7989","title":"\u064a\u062f\u0643 \u0627\u062a\u0648\u062f5\u0645\u064a\u0644 \u0643\u0648\u0647 \u0646\u0648\u0631B6","author":" ","publisher":"","translator":" ","price":"108025","isbn":" ","amount":61,"year_of_publish":"0","period_print":"0"},"8350":{"id":"1225","GoodMainCode":"8350","title":"\u064a\u062f\u0643 \u0627\u062a\u0648\u062f\u0637\u0631\u0627\u062d\u064a2\u0645\u064a\u0644JBN","author":" ","publisher":"","translator":" ","price":"3375","isbn":" ","amount":"0","year_of_publish":"0","period_print":"0"}}
now, I want to set a key to 7916,7989,8350 . like :
"mykey"=>"parent":{
'A'=>value,
'B'=>value
}
how can I do that?
my function :
while($row = $stmt->fetch()){
$arr = array(
'id'=>persian_sql_to_php($row['row1']),
'GoodMainCode'=>persian_sql_to_php($row['GoodMainCode']),
'title'=> persian_sql_to_php($row['GoodName']),
'author'=>persian_sql_to_php($row['moalef']),
'publisher'=>persian_sql_to_php($row['Nasher']),
'translator'=>persian_sql_to_php($row['Motarjem']),
'price'=>persian_sql_to_php($row['SellPrice1']),
'isbn'=>persian_sql_to_php($row['ISBN']),
'amount'=>persian_sql_to_php($row['Amount']),
'year_of_publish'=>persian_sql_to_php($row['SaleChap']),
'period_print'=>persian_sql_to_php($row['NobateChap'])
);
array_push($mjson,$arr);
}
foreach($mjson as $v){
if(!isset($result[$v['GoodMainCode']])){
$result[$v['GoodMainCode']] = $v;
}
else
$result[$v['GoodMainCode']]['amount'] += $v['amount'];
}
You're doing a generic push operation, which lets php figure out what the key should be. You need to explicitly set the key:
while($row = ...) {
$arr[$row['row1']] = $row;
^^^^^^^^^^^^---id value from database
}
As long as that row1 value is the primary key for the record you're fetching, you'll end up with an array entry for every row. If row ISN'T unique, this would overwrite previous values with the new row.
Related
I'm reporting on appointment activity and have included a function to export the raw data behind the KPIs. This raw data is stored as a CSV and I need to check for potentially duplicate consultations that have been entered.
Each row of data is assigned a unique visit ID based on the patients ID and the appointment ID. The raw data contains 30 columns of data, the duplicate check only needs to be performed on 7 of these. I have imported the CSV and created an array as below for first record and then append rest on.
$mds = array(
$unique_visit_id => array(
$appt_date,
$dob,
$site,
$CCG,
$GP,
$appt_type,
$treatment_scheme
)
);
What I need is to scan the $mds array and return an array containing just the $unique_visit_id for any duplicate arrays.
e.g. keys 1111, 2222 and 5555 all references arrays that contain the same value for all seven values, then I would need 2222 and 5555 returned.
I've tried search but not coming up with anything that is working.
Thanks
This is what I've gone with, still validating (data set is very big) but seems to be functioning as expected so far
$handle = fopen("../reports/mds_full_export.csv", "r");
$visits = array();
while($data = fgetcsv($handle,0,',','"') !== FALSE){
$key = $data['unique_visit_id'];
$value = $data['$appt_date'].$data['$dob'].$data['$site'].$data['$CCG'].$data['$GP'].$data['$appt_type'].$data['$treatment_scheme'];
$visits[$key] = $value;
}
$visits = asort($visits);
$previous = "";
$dupes = array();
foreach($visits as $id => $visit){
if(strcmp($previous, $visit) == 0){
$dupes[] = $id;
}
$previous = $visit;
}
return $dupes;
I am pretty new to PHP, but have tried searching for other questions similar to mine and been unable to find anything that is close enough to my situation to help me solve this.
I am trying to code a web page that allows users to select as many or as few items as they would like to order. The item values are identical to their Primary Key in the Item table.
Once submitted, each different item value should be input into the same row of a database table based on the date{pk}. Within that row, there are numerous columns: Item1ID, Item2ID, Item3ID, etc.
So far, the value of each item selected is assigned to a new array. However, I cannot simply input the array values into a column -- I need each array index to be placed into a sequential column. The code is below:
$date = new DateTime();
$td = $date->format('Y-m-d');
$x = 1;
$checkedItems = $_POST['Item'];
$count = count($checkedItems);
echo $count;
$foodID = "Item".$x."ID";
While($x<=$count){
if(isset($_POST['Item'])){
if (is_array($_POST['Item'])) {
foreach($_POST['Item'] as $values){
$selectedFoods = substr($values,0,4);
$addFoodOrderQuery= sprintf("UPDATE WeeklyBasketFoodOrder SET '%s' = %s WHERE `foodOrderDate` = '%s'",
$foodID, $selectedFoods, $td);
$result= mysqli_query($db, $addFoodOrderQuery);
}
}
} else {
$values = $_POST['Item'];
echo "You have not selected any items to order.";
}
$x++;
}
If you need any further clarification, please let me know. After submitting the code, the database item#ID tables are different, but they are now empty instead of "NULL."
I originally was satisfied with the following in order to update row 1 and row 2 to the same value (status=1)
if ($_POST){
$sql ="UPDATE table SET status = 1,
WHERE id IN (1,2 );";
db()->query($sql);
if(db()->query($sql)){
echo "<b>Good</b>";
}
else{
echo "<b>No Good</b>";
}
}
But now I want to update with different values, ie- row 1 to status 1, row 2 to status 2, and row 3 to status 3.
Off the bat, I know I need to
1. Use an array and loop through it three times.
2. pass in the array value into the $sql
I figure it would be something like this but I am still learning PHP..
$array_id = array(1, 2, 3);
$array_status = array(1, 2, 3);
if ($_POST){
$sql ="UPDATE table SET status = $array_status
WHERE id = $array_id;";
db()->query($sql);
if(db()->query($sql)){
echo "<b>Update Successful</b>";
}
else{
echo "<b>Update Unsuccessful</b>";
}
}
How would I go about making this happen?
You can loop through the arrays using a for loop and exec a query for each one (Radu Vlad answer), or you can build a long query and execute it once, something like this:
if ($_POST){
$sql = ""; // Blank string
$len = count($array_id); // Number of iterations
for ($i = 0; $i < $l; $i++) { // Enter the loop
$sql .= "UPDATE
table
SET
status = {$array_status[$i]}
WHERE id = {$array_id[$i]};"; // Append the query
}
db()->query($sql);
if(db()->query($sql)){
echo "<b>Update Successful</b>";
}
else{
echo "<b>Update Unsuccessful</b>";
}
}
When the val of $i is 0, then $array_id[$i] will print the first element, when $i is 1, $array_id[$i] will print the second element, and so on.
Using .= you append text to a string. By the end of the loop, $sql will be a string with 3 queries ('UPDATE ... SET ...; UPDATE ... SET ...; UPDATE ... SET ...;').
Not sure if it's the best way, though. But you get the idea.
If yow want the status to be equal to the id, do this (single query):
UPDATE table SET status=id WHERE id IN (1,2,3);
Of course you can use some math, like:
UPDATE table SET status=(id+1)*2 WHERE id IN (1,2,3);
You didn't really explain why you need that, so
try1(childish): set status = id
"UPDATE table SET status = id"
It's a bad practice, and only you could understand what those numbers are. Plus if id is auto-increment, status will be auto-increment too, you will have a duplicate column. If status has only 3 values posible, you should not do this.
try2(basic): do 3 updates, or actually, do as many as you need with a for
if ($_POST){
$status = 1;
for ($i = 1; $i <= 3; $i++){
$sql ="UPDATE table
SET status = $status
WHERE id = $i;";
db()->query($sql);
$status++;
}
A better way bacause you have more control over the status. Of course the second try is irrelevant if you have only that 3 values. This one assumes you will change the $status variable inside the for loop, in concordance with the $i (id)
try3(mature): set one or 2 arrays with the concordance between id and status, so that either $arr[$id] will have the value of status and the key will be the id, or $arr1[$i] will have the value of id, and $arr2[$i] will have the value of status
the example will have only one array(also called map, because you map a value based on another value)
if ($_POST){
$status_array = array(1 => 1,2 => 2,3 => 3);
for ($i = 1; $i <= 3; $i++){
$sql ="UPDATE table
SET status = $status_array[$i]
WHERE id = $i;";
db()->query($sql);
}
Also, this works because the array is consistent. If you do not have an consistent array you should either work with 2 arrays, or try a foreach with key->value instead of for
I would suggest you to use the following code:
$theArray = array("1" => "1","2" => "2","3" => "3"); // The scheme is ID => Status
$errorMsg = false; // Our default assumption is that no error occured
foreach($theArray as $key => $value) {
$sql = "UPDATE table SET status =".$value." WHERE id = ".$key;
if(!db() -> query($sql)) { // Execute the query and check whether it failed
$errorMsg = "Query for ID ".$key." failed.";
break; // When the query failed we exit the loop and echo the error message
}
}
if($errorMsg) { // If an error occured (errorMsg is no longer false) we echo it here
echo $errorMsg;
}
Basically you do just create one array $theArray, which contains key => value pairs of the IDs and the statuses you want to give them. Afterwards, you loop through this array, execute the db() -> query() for each key => value pair and check whether it failed or not. If a query failed, you break the loop and output the error message.
Advantages:
Instead of using two arrays ($array_id, $array_status) I do use only one associative array $theArray. The advantage here is that you only have one instead of two arrays and that you can extend the number of rows you'd like to change without changing your code. Just extend the array.
The array $theArray does not need to be in a chronological order and you can give each ID independently of the other IDs a status.
You are executing the db() -> query($sql) in your code two times. This is not very efficient and redundant. Instead you can execute the command only once and immediately check whether it failed or not based on its return value inside the if().
The errorMsg I am creating in the code let you know which query failed so it gives you a more detailed information for debugging.
If you want to update multiple rows (in single query) using the INSERT syntax, you can do this:
REPLACE table(id,status) VALUES(1,1),(2,2),(3,3)
Notice that id must be Primary Key or Unique, otherwise the REPLACE will insert a new row.
Notice also that REPLACE isn't SQL standard, and works only in MySQL.
How can I get the record values in the database to be sorted like this in an array. Supose I am adding the day no.
array
[0] => array=>'id'=>'26' 'date'=>'26'
[1] => array=>'id'=>'27' 'date'=>'27',
array=>'id'=>'28' 'date'=>'27',
array=>'id'=>'29' 'date'=>'27'
[2] => array=>'id'=>'30' 'date'=>'29'
[3] => array=>'id'=>'31' 'date'=>'31',
array=>'id'=>'32' 'date'=>'31',
array=>'id'=>'33' 'date'=>'31'
Basically, I want to add an array to the same index if the next id contains a record with the same date (day no) of the month. Otherwise add it normally.
Right now, My function is adding the rows of the record without sorting it in the format I want it to be in.
The reason I want it to be in this format is because, I need to run the foreach, and if 1 day contains 2 records, then it will append another <li> into my unordered list.
public function getArticles()
{
$sql = 'CALL getArticles()';
$articles = Array();
if (Model::getConnection()->multi_query($sql)) {
do {
if ($result = Model::getConnection()->store_result()) {
while ($row = $result->fetch_assoc()) {
array_push($articles,$row);
}
$result->free();
}
} while (Model::getConnection()->next_result());
}
return $articles;
}
I don't recognize what some of your code is doing, but I think this is the important part.
while ($row = $result->fetch_assoc()) {
if (!isset($articles[$row['date']])) {
$articles[$row['date']] = array();
}
$articles[$row['date']][] = $row;
}
The only difference will be that your array will be keyed on the date instead of incrementing from zero. If you really want it reindexed, you can do...
array_values($articles);
As savinger pointed out, there is alot of functionality in your code which I don't really know, so I've included comments to indicate whereabouts the process is:
// Start of your loop
// $value is what you're getting from the DB...
$array_search = array_search($value,$main_array);
if($array_search)
{
// If this value already exists, we need to add
// this value in +1 of its current value
$main_array[$array_search][] = $value + 1;
}
else
{
// Make a new array key and add in the value
$main_array[] = $value;
}
// End of your loop
I previously designed the website I'm working on so that I'd just query the database for the information I needed per-page, but after implementing a feature that required every cell from every table on every page (oh boy), I realized for optimization purposes I should combine it into a single large database query and throw each table into an array, thus cutting down on SQL calls.
The problem comes in where I want this array to include skipped IDs (primary key) in the database. I'll try and avoid having missing rows/IDs of course, but I won't be managing this data and I want the system to be smart enough to account for any problems like this.
My method starts off simple enough:
//Run query
$localityResult = mysql_query("SELECT id,name FROM localities");
$localityMax = mysql_fetch_array(mysql_query("SELECT max(id) FROM localities"));
$localityMax = $localityMax[0];
//Assign table to array
for ($i=1;$i<$localityMax+1;$i++)
{
$row = mysql_fetch_assoc($localityResult);
$localityData["id"][$i] = $row["id"];
$localityData["name"][$i] = $row["name"];
}
//Output
for ($i=1;$i<$localityMax+1;$i++)
{
echo $i.". ";
echo $localityData["id"][$i]." - ";
echo $localityData["name"][$i];
echo "<br />\n";
}
Two notes:
Yes, I should probably move that $localityMax check to a PHP loop.
I'm intentionally skipping the first array key.
The problem here is that any missed key in the database isn't accounted for, so it ends up outputting like this (sample table):
1 - Tok
2 - Juneau
3 - Anchorage
4 - Nashville
7 - Chattanooga
8 - Memphis
-
-
I want to write "Error" or NULL or something when the row isn't found, then continue on without interrupting things. I've found I can check if $i is less than $row[$i] to see if the row was skipped, but I'm not sure how to correct it at that point.
I can provide more information or a sample database dump if needed. I've just been stuck on this problem for hours and hours, nothing I've tried is working. I would really appreciate your assistance, and general feedback if I'm making any terrible mistakes. Thank you!
Edit: I've solved it! First, iterate through the array to set a NULL value or "Error" message. Then, in the assignations, set $i to $row["id"] right after the mysql_fetch_assoc() call. The full code looks like this:
//Run query
$localityResult = mysql_query("SELECT id,name FROM localities");
$localityMax = mysql_fetch_array(mysql_query("SELECT max(id) FROM localities"));
$localityMax = $localityMax[0];
//Reset
for ($i=1;$i<$localityMax+1;$i++)
{
$localityData["id"][$i] = NULL;
$localityData["name"][$i] = "Error";
}
//Assign table to array
for ($i=1;$i<$localityMax+1;$i++)
{
$row = mysql_fetch_assoc($localityResult);
$i = $row["id"];
$localityData["id"][$i] = $row["id"];
$localityData["name"][$i] = $row["name"];
}
//Output
for ($i=1;$i<$localityMax+1;$i++)
{
echo $i.". ";
echo $localityData["id"][$i]." - ";
echo $localityData["name"][$i];
echo "<br />\n";
}
Thanks for the help all!
Primary keys must be unique in MySQL, so you would get a maximum of one possible blank ID since MySQL would not allow duplicate data to be inserted.
If you were working with a column that is not a primary or unique key, your query would need to be the only thing that would change:
SELECT id, name FROM localities WHERE id != "";
or
SELECT id, name FROM localities WHERE NOT ISNULL(id);
EDIT: Created a new answer based on clarification from OP.
If you have a numeric sequence that you want to keep unbroken, and there may be missing rows from the database table, you can use the following (simple) code to give you what you need. Using the same method, your $i = ... could actually be set to the first ID in the sequence from the DB if you don't want to start at ID: 1.
$result = mysql_query('SELECT id, name FROM localities ORDER BY id');
$data = array();
while ($row = mysql_fetch_assoc($result)) {
$data[(int) $row['id']] = array(
'id' => $row['id'],
'name' => $row['name'],
);
}
// This saves a query to the database and a second for loop.
end($data); // move the internal pointer to the end of the array
$max = key($data); // fetch the key of the item the internal pointer is set to
for ($i = 1; $i < $max + 1; $i++) {
if (!isset($data[$i])) {
$data[$i] = array(
'id' => NULL,
'name' => 'Erorr: Missing',
);
}
echo "$i. {$data[$id]['id']} - {$data[$id]['name']}<br />\n";
}
After you've gotten your $localityResult, you could put all of the id's in an array, then before you echo $localityDataStuff, check to see
if(in_array($i, $your_locality_id_array)) {
// do your echoing
} else {
// echo your not found message
}
To make $your_locality_id_array:
$locality_id_array = array();
foreach($localityResult as $locality) {
$locality_id_array[] = $locality['id'];
}