Php looping through two arrays - php

I'm posting data from a web page to a php page with Ajax. It's working fine.
I get my data from the $_POST, loop through the values and create an array called checklist.
if($_POST != ''):
$dataset = $_POST['data'];
$checklist = array();
$eventid='';
foreach ($dataset as $i => $row)
{
$uid = $row['box-id'];
$state = $row['box-state'] ;
$eventid = $row['e_id'];
$checklist[] = array('uid'=>$uid,
'state'=> $state);
}
Checklist has two fields, a uid and a state.
I then run a script that generates another array, called $updates. It loops through a different set of objects and outputs the data to populate the variables for $updates. The structure of $updates is as such.
$updates[] = array('uid'=>$uid,
'state'=> $state,
'class' => $class,
'container' => $button_cont,
'closer' => $button_closer);
What I would like to do is to compare $updates with $checklist.
I'd like to know the most efficient way to match the records by the uid and compare the state. If the state matches, I'd like to do nothing.
I've read a few of the articles on looping and search, but I'm thinking I've been looking at this for too long because it's Greek to me. Thanks for assistance.

save the checklist like -
$checklist[$uid] = $state;
same for updates
$updates[$uid] = array('state'=> $state,
'class' => $class,
'container' => $button_cont,
'closer' => $button_closer);
then start the loop
foreach ($updates as $key => $update) {
if ($update['state'] == $checklist[$key]) {
//your action
}//compare the values
}
$key will be the uid.hope it will help you

Related

Getting a an array from for loop and use another for loop with that array in PHP

I have a for loop, and will form two arrays in the loo
foreach ($data as $key => $value) {
........
........
$user_insert[] = [
'keyy' => $value,
'key' => $value,
....
...
...
];
$someArray1[] = [
/*'user_id' => $insert_id,*/
'key1' => $value1,
'keyy' => $value,
.......
........
];
}
the count of $user_insert[] array is 4, the count of $someArray1 is 15.
after this for loop, I need to insert $user_insert array data to the database and use that inserted_id to insert next array $someArray1
foreach($user_insert as $insert_user){
$unique_user_insert = array_unique($insert_user);
//dd($unique_user_insert);
$insert_id = DB::table('users')->insertGetId($unique_user_insert);
foreach ($someArray1 as $someArray) {
$someArray['user_id'] = $insert_id;
DB::table('table_name')->insert($someArray);
}
}
So the problem here is the data in the second loop is inserting 60 times(4 * 15). I need to insert only 15 rows.
The data($someArray1) is coming from the first for loop, but I need to add a user_id to that array which I get after the insert operation in second for loop.
So how can i insert only 15 rows.
I'm going to assume that you are able to access your $someArray1 using the $insert_id value to find the appropriate user data.
foreach($user_insert as $insert_user){
$unique_user_insert = array_unique($insert_user);
$insert_id = DB::table('users')->insertGetId($unique_user_insert);
// Get the user information you need as $someArray1 should be user_id=>data
$userData = $someArray[$insert_id];
$userData['user_id'] = $insert_id;
// No need for an inner loop, just access the necessary properties of the loop you created earlier.
DB::table('table_name')->insert($userData);
}
Your tags indicate that you are using Laravel 5 too. If you are using the eloquent ORM, some of the insertion and ID retrieval can be cleaned up by creating Models for your DB tables.
Actually, each time you process a line from $user_insert, you loop over $someArray1 instead of fetching just the line you need.
The thing is to understand the line you need. As much as I can understand your piece of code, I would say the easiest (most readable) way of doing it is by using a for loop, not a foreach one :
for( $i = 0, $iMax = count( $user_insert ); $i < $iMax; ++$i ){
$insert_user = $user_insert[$i];
// Put your `$user_insert` insert code here
$someArray1[$i]['user_id'] = $insert_id;
DB::table('table_name')->insert( $someArray[$i] ); // Note the [$i] here
}
You also may do that with foreach by requesting indices :
foreach( $user_insert as $i => $insert_user ){
$unique_user_insert = array_unique($insert_user);
//dd($unique_user_insert);
$insert_id = DB::table('users')->insertGetId($unique_user_insert);
// Now use $i requested above :
$someArray1[$i]['user_id'] = $insert_id;
DB::table( 'table_name' )->insert( $someArray1[$i] );
}

query inside while loop only shows 1 result

i'm making a while loop in php and it all goes well but the problem is that
I don't only want to get the id of the user but also some other stuff that is inside another table, so when I go ahead and make a query inside this while loop and select everything from that second table (where the id is equal to the id of the result from the first query), it only returns 1 result...
So this is the code that I currently have:
public function getFriends($id)
{
global $params;
$get = $this->db->select("{$this->DB['data']['friends']['tbl']}", "*",
array(
"{$this->DB['data']['friends']['one']}" => $id
)
);
if($get)
{
while($key = $get->fetch())
{
$query = $this->db->query("SELECT * FROM {$this->DB['data']['users']['tbl']}
WHERE {$this->DB['data']['users']['id']} = :id",
array(
"id" => $key->{$this->DB['data']['friends']['two']}
)
);
while($row = $query->fetch())
{
$params["user_friends"][] = [
"id" => $key->{$this->DB['data']['friends']['two']},
"name" => $row->{$this->DB['data']['users']['username']},
"look" => $row->{$this->DB['data']['users']['figure']}
];
}
}
}
else
{
$params["update_error"] = $params["lang_no_friends"];
}
}
Thanks in advance!
Please help me out!
In the absence of answers, I don't know what db framework you are using behind the scenese...PDO, mysqli_, or (hopefully not) mysql_. But, in any case, the problem might be that your second query stops the first from continuing. I would use PDO->fetchAll() to get them all...but you say you can't do that...so, looping the first and loading those results into an array is the first thing I would do to see if this is the problem:
public function getFriends($id)
{
global $params;
$get = $this->db->select("{$this->DB['data']['friends']['tbl']}", "*",
array(
"{$this->DB['data']['friends']['one']}" => $id
)
);
$firstResults = array();
if( $get ) {
while( $key = $get->fetch() ) {
$firstResults[] = $key;
}
}
else
{
$params["update_error"] = $params["lang_no_friends"];
}
foreach( $firstResults AS $key )
{
$query = $this->db->query("SELECT * FROM {$this->DB['data']['users']['tbl']}
WHERE {$this->DB['data']['users']['id']} = :id",
array(
"id" => $key->{$this->DB['data']['friends']['two']}
)
);
while($row = $query->fetch())
{
$params["user_friends"][] = [
"id" => $key->{$this->DB['data']['friends']['two']},
"name" => $row->{$this->DB['data']['users']['username']},
"look" => $row->{$this->DB['data']['users']['figure']}
];
}
}
}
If this doesn't work, then we need more data...e.g. what is the query generated? When you run it manually does it return more than one result? If you get rid of the inner-query, does this fix it? etc.
The first step when diagnosing PHP and Mysql issues is to add lines to your code that tell you what each line is doing (declare each time a loop is entered; when each mysql query is run, spit out the query string) so you can narrow down where the problem is. Often this makes you feel stupid in retrospect: "Duh, this query didn't return anything because I formatted the record ID wrong" and so forth.
The code snippet you've provided above isn't super helpful to me. I'm a troubleshooter (not a parser) so I need diagnostic data (not straight code) to be of any more help than this.

How will PHP Web Service read JSON

My JSON is
{"users":[{"UserName":"user1","FullName":"Name One"},
{"UserName":"user2","FullName":"Name Two"}]}
My PHP is
<?php
include '../inc/connect.php';
include '../inc/class/mysql.class.php';
$data = file_get_contents('php://input');
$array = json_decode($data, true);
$rows = array();
foreach ($array['users'] as $parentvalue)
foreach ($parentvalue as $key => $value)
$rows[] = "('" . $value . "', '" . $value . "')";
$values = implode(",", $rows);
try
{
$count = mysql_query("INSERT INTO users (UserName, FullName) VALUES $values") or die(mysql_error());
}
catch(PDOException $e) { //later
}
?>
The structure of the array is
Array
(
[users] => Array
(
[0] => Array
(
[FullName] => Name One
[UserName] => user1
)
[1] => Array
(
[FullName] => Name Two
[UserName] => user2
)
)
)
Instead of inserting the data:
**user1 - Name One
**user2 - Name Two
to MySQL...
It inserts
**user1 - user1
**Name One - Name One
**user2 - user2
**Name Two - Name Two
Please help!
/********EDIT (prev answer below)*********/
Here is my new code. I have modified your JSON structure based on your comments.
//added addresses as an example (no the postcodes aren't real :P)
$json='{
"users":[
{"UserName":"user1","FullName":"Name One"},
{"UserName":"user2","FullName":"Name 2"}
],
"addresses":[
{"HouseNumber":"1","PostCode":"LS1 1PS"},
{"HouseNumber": "23", "PostCode": "LS1 2PS"}
]
}';
$data=json_decode($json);
//loop over each 'table'
foreach ($data as $table_name=>$data_array){
$table_name=mysql_real_escape_string($table_name);
//loop over each 'row' in table
foreach($data_array as $current_obj){
$current_sql="INSERT INTO ".$table_name." SET ";
$row=array();
//loop through 'row' data and get 'column' name and value.
foreach($current_obj as $name=>$value){
$row[]='`'.mysql_real_escape_string($name).'` = "'.mysql_real_escape_string($value).'"';
}
$current_sql.=implode(',',$row);
mysql_query($current_sql);
unset($current_sql,$name,$value);
}
}
Now, while this code will do what you asked I probably wouldn't use it myself. I would have different endpoints in your web service for the different tables (and use GET,POST,PUT etc http requests to determine action - see REST web services) - Although its more work, clearly defined actions make debugging easier and your application more secure (as you'll know exactly what its doing and what to).
As for authentication, thats a whole issue on its own that I can't really go into here. Please don't think I mean this in an offensive way, but as you're new to development I would advise spending more time learning before trying to make anything production ready - to protect you and your customers more than anything.
Anyway, I hope this helps.
Regards
Ryan
/******* OLD ANSWER - LEFT HERE FOR CLARITY****************/
I believe you don't need the second loop. This is what I have (modify to suit your needs):
$json='{"users":[{"UserName":"user1","FullName":"Name One"},{"UserName":"user2","FullName":"Name 2"}]}';
$data = json_decode($json);
$rows = array();
foreach ($data->users as $user_obj){
$rows[]='("'.$user_obj->UserName.'","'.$user_obj->FullName.'")';
}
$values = implode(",", $rows);
echo "INSERT INTO users (UserName, FullName) VALUES ".$values;
Also, I would advise that you make use of prepared statements or at the very least mysql_real_escape_string.
Hope this helps,
Ryan :)
(P.s I stopped json_decode converting objects to arrays as it feel it is helpful to know when a data structure is supposed to be iterable and when it is not - feel free to change it back if you like.)
I slightly improved your code, for readability's sake. The very first thing you'd realize is that you're dealing with two problems here : one is parsing JSON response, and the second one is inserting records into a table:
$json = '{"users":[{"UserName":"user1","FullName":"Name One"},
{"UserName":"user2","FullName":"Name Two"}]}';
$values = buildArray($json);
insertValues($values);
function buildArray($json) {
$result = array();
$array = array_values(json_decode($json, true));
foreach ($array as $index => $nestedArray) {
foreach($nestedArray as $index => $value) {
$result[] = $value;
}
}
return $result;
}
function insertValues(array $values) {
foreach($values as $index => $array) {
$query = sprintf("INSERT INTO `users` (`UserName`, `FullName`) VALUES ('%s', '%s')",
mysql_real_escape_string($array['UserName']),
mysql_real_escape_string($array['FullName']),
);
if (!mysql_unbuffered_query($query)) {
return false;
}
}
return true;
}

Elegant Efficient way of inserting into a lot of tables MySQL

I am making a survey and currently the database has 19 tables and roughly 100 columns. All of them will be inserted to as they are required fields. I am looking for an Elegant and Efficient way of inserting into that many tables and columns. So far what I have come up with is to create a multidimensional array that contains the first key as the table name and the second key as the column name with the field. Something like below:
$tableArray = array(
'ownerTable' => array(
'firstNameRow' => $firstName,
'lastNameRow' => $lastName
),
'dealerTable' => array(
'dealerNameRow' => $dealerName,
'dealerCityRow' => $dealerCity
)
);
foreach($tableArray as $row => $key) {
foreach($tableArray[$row] as $row1) {
$sql = "(INSERT INTO $tableArray[$key] ($tableArray[$row]) VALUES ($row1)";
}
}
I didn't test this code but I am thinking something along those lines would work. I think one problem I see with this is a separate INSERT for each column instead of one INSERT for each table. I can always work on writing the code to just load all the values from the array at once to solve this problem but before I start getting to carried away I want to make sure I am not making a big mistake and waste time if there is a better way to do it.
$tableArray = array(
'ownerTable' => array(
'firstNameRow' => $firstName,
'lastNameRow' => $lastName
),
'dealerTable' => array(
'dealerNameRow' => $dealerName,
'dealerCityRow' => $dealerCity
)
);
//it's for bulj query execution in single statment;
$i=1;
$sql="";
foreach($tableArray as $row => $key) {
foreach($tableArray[$row] as $row1) {
//here you can update i value as per row for execution
if($i<=25)
{
$sql = $sql + "(INSERT INTO $tableArray[$key] ($tableArray[$row]) VALUES ($row1);";
}
else
{
//execute sql statement here;
$i=0;
$sql="";
}
}
}

Looping through database to get details, then send email with said values

I am bringing in brochures selected by visitors, and they can select multiple brochures. After three days they are meant to get an email reminding them of the brochures they have chosen.
Here is what I have so far:
$time_query = "SELECT * FROM users WHERE time < (now() - INTERVAL 1 minute)"; //" //GROUP BY time does group them into an array... well.. it doesnt display duplicate timestamps, so assume it saves it to an array'";
$time_query_result = mysql_query($time_query, $db) or
die("Could not execute sql: $time_query");
$users = array();
while($row = mysql_fetch_array($time_query_result)) {
if (!array_key_exists($users[$row["id"]], $users)) {
$users[$row["id"]] = array('email' => $row["email"], 'brochures' => array());
$users[$row["id"]]["brochures"] = array('b' => $row["brochures"], 't' => $row["time"]);
}
}
foreach ($users as $user) {
$text = '<html><body><p>Brochure reminder</p>';
$i = 0;
foreach ($user["brochures"] as $brochure) {
$text .= 'Brochures:<br />'.$i++ . $row["b"];
}
$text .= '</body></html>';
mail($user["email"], $subject, $text, $headers);
}
I am getting numbers through the emails instead of brochure names, and I think its something to do with the array_key_exists fuinction.
Each time a user selects a brochure, it creates its own row in the DB, and the idea was to pull in the multiple brochures a user selected at a time (by the time column), as many users can select brochures over a time period.
Any help would be appreciated :)
In your 'while' loop, you're creating a new 'brochures' element in your 'users' array, when I think you're wanting to append to it.
if (!array_key_exists($row["id"], $users)) {
$users[$row["id"]] = array('email' => $row["email"], 'brochures' => array());
}
$users[$row["id"]]["brochures"][] = array('b' => $row["brochures"], 't' => $row["time"]);
then in your 'foreach', you will want to use the brochure variable:
foreach ($user["brochures"] as $brochure) {
$text .= 'Brochures:<br />'.$i++ . $brochure["b"];
}
Your current code builds an array of users containing another array with the index 'brochures'. This array will always contain tow values.
{
'b' => $row["brochures"]
't' => $row["time"])
}
Regarding this fact the following statements doesn't make sense:
foreach ($user["brochures"] as $brochure) {
}
All you do is iterate over the two values with the index 'b' and 't'. If you want to iterate over a collection of brochures you need to adapt your code.
On the other hand you have a few important mistakes:
foreach ($user["brochures"] as $brochure) {
$text .= 'Brochures:<br />'.$i++ . $row["b"];
}
Why use a foreach if you don't even use the $brochure variable?
$text .= 'Brochures:<br />'.$i++ . $row["b"];
$row contains the last row, which is definitively not what you wanted. In fact, $row is out of scope, in a serious programming language you would see this.
$row["id"]
You use this about three times. So why not store it in a variable $id? Accessing arrays with indexes is a more expensive operation than simply accessing a variable.
In general I strongly encourage you to switch to an object oriented approach so you get rid of these ugly array in array in array solution...

Categories