dynamic array in php - php

I have the next:
$students=array('student1','student2','student3','student4');
$date=array('date1','date2','date3');
$students represents the files and $date represents the columns.
For each $student and $date there is a value different.
For example:
$students['student1']$dates['date1']='value11';
$students['student1']$dates['date2']='value12';
$students['student1']$dates['date3']='value13';
$students['student2']$dates['date1']='value21';
....
.....
etc.
date1 date2 date3
student1 value11 value12 value13
student2 value21 value22 value23
student3 value31 value32 value33
I want fill the values in a table.
I want to load these values in a grid dynamically.
The count for $students and $dates change dynamically.
These values filled in a table I need to insert into database.
I need to update the values into database.
My table in database has the follow fields:
id_tabla estudiante date values
1 estudiante1 date1 value11
2 estudiante1 date2 value12
3 estudiante1 date3 value13
4 estudiante2 date1 value21
5 estudiante2 date2 value22
6 estudiante2 date3 value23
can you help me? Thanks.
The $students is genertated by a query in database.
$dates is generated by a range of the dates in php.
The idea is to do a form with text input $students x $dates where the datas should be included. With this form I should get the values datas.

You have quite a lot of requirements and without knowing the context it's not trivial to choose the right data structure. From your example I guess that you have an array with students and an array with dates. The size of the arrays can change, but you always need to attach the dates-array to each student, right?
So based on my assumption, I think you don't need to rearrange the two arrays into one. You can do your enlisted tasks with the given structure.
Outputting each student with dates in a table:
<table>
<?php foreach($students as $student) { ?>
<tr>
<td><?php echo $student; ?></td>
<?php foreach($dates as $date) { ?>
<td><?php echo $date; ?></td>
<?php } ?>
</tr>
<?php } ?>
</table>
Inserting in a database:
<?php
$insert_dates = "'" . implode("','", $dates) . "'";
foreach($students as $student) {
$qry = "INSERT INTO `students` (`name`, `date1`, `date2`, `date3`)
VALUES ('" . $student . "', " . $insert_dates . ")";
//execute query
}
Updating:
<?php
$qry = "UPDATE `students`
SET date1='".$dates[0]."', date2='".$dates[1]."', date2='".$dates[2]."'
WHERE name IN ('" . implode("','", $students) . "')";
//execute query
BUT this approach has some obvious flaws concerning the dynamic changes. So if you are going to work with databases, you should build associative arrays with the keys corresponding to the column names of the table:
$students=array();
$students[] = array('name' => 'student1');
$students[] = array('name' => 'student2');
$students[] = array('name' => 'student3');
$students[] = array('name' => 'student4');
$dates=array();
$dates[] = array('date1'=>'15/04/20', 'date2'=>'20/05/15', 'date3'=>'18/11/10');
The dynamic update query would then look like so:
$set_data = '';
foreach($dates as $key => $value) {
$set_data .= $key . "='".$value."',";
}
$set_data = substr($set_data, 0, -1); //remove last comma
$qry = "UPDATE `students`
SET " . $set_data . "
WHERE name IN ('" . implode("','", $students) . "')";
//execute query
There's a whole lot more you can achieve by playing with data structures (e.g., applying and changing the dates for each student individually, choosing the student-name as the key of the associative array so you can access each student by name, etc.). So at first you should figure out what you need the data for and then choose an appropriate structure based on that. I think you get the idea and I hope it helps!
//UPDATE
Based on your updated question, I think this could be a good approach for the structure (although I still don't know where the data comes from and how/if you can populate that array dynamically/programatically):
$students = array();
$students[] = array(
'name' => 'student1',
'dates' => array(
'date1' => 'code123kil',
'date2' => 'dadfdre145',
)
);
$students[] = array(
'name' => 'student2',
'dates' => array(
'date1' => 'daytetyeyy',
'date2' => 'dafdfe335',
'date3' => 'code123kil'
)
);
//and so on
So now, let's output it into a grid:
<table>
<?php foreach($students as $student) { ?>
<tr>
<td>Name: <?php echo $student['name']; ?></td>
<td>Dates: <?php echo implode(', ', $student['dates']); ?></td>
</tr>
<?php } ?>
</table>
Insert into a table:
<?php
foreach($students as $student) {
foreach($student['dates'] as $key => $value) {
$qry = "INSERT INTO `your_table` (`estudiante`, `date`, `values`)
VALUES ('".$student['name']."','".$key."','".$value."')";
//execute query
}
}
Update the date-values in a table for a given student
<?php
//find the given student in the array
$student_to_update = 'student2';
$student_info = null;
foreach($sudents as $student) {
if($student['name'] == $student_to_update) {
$student_info = $student;
break;
}
}
//update the student in database:
if(!is_null($student_info))
foreach($student_info['dates'] as $key => $value) {
$qry = "UPDATE `your_table`
SET `values`='".$value."'
WHERE `estudiante` = '".$student_info['name']."'
AND `date`='".$key."'";
//execute query
}
}
Update the date-values in a table for each student
<?php
foreach($students as $student) {
foreach($student['dates'] as $key => $value) {
$qry = "UPDATE `your_table`
SET `values`='".$value."'
WHERE `estudiante` = '".$student['name']."'
AND `date`='".$key."'";
//execute query
}
}

Does this help:
$students=array('student1','student2','student3','student4');
$date=array('date1','date2','date3');
$c = 0;
$countArr = count($students);
$newArr = array();
for($c = 0; $c < $countArr; $c++) {
$x = 0;
foreach($date as $val) {
$newArr[$c]["date".($x+ 1)] = $date[$x];
$x++;
}
}
echo "<pre>";
print_r($newArr);

Related

PHP MYSQL Results into a table

I have a PHP/MySQL query that returns the following:
array ( 'name' => 'Jess', 'month' => '2020-03-31 12:28:00', 'count' => '1', )
array ( 'name' => 'Bob', 'month' => '2020-04-31 12:28:00', 'count' => '2', )
array ( 'name' => 'Tom', 'month' => '2020-05-31 12:28:00', 'count' => '2', )
array ( 'name' => 'Bob', 'month' => '2020-05-31 12:28:00', 'count' => '2', )
The months return in an ordered fashion (E.g. January records are always before February records).
However, not every user will have a result every month (see above).
And I want my data to present such as this, in an html table:
Month Jess Bob Tom
March 1
April 2
May 2 2
Here is my (non working) attempt:
<?php
/*loop through all customers and print out each induvidual users performance*/
$con = mysqli_connect("localhost","root","","perfmon");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
exit();
}
//main query for customer names
if ($customers = mysqli_query($con, "SELECT Distinct(customer_name) FROM slog ORDER BY customer_name DESC;")) {
while($row=mysqli_fetch_assoc($customers))
{
$name = $row["customer_name"];
print("<b>".$name." </b><br>");
$total = 0;
$cur_month = NULL;
$namepos = array();
$th = "<th>Month</th>";
$tr = "";
$npcount = 0;
//Loop over the customer names, and pull the modified count per user.
if ($user_perf = mysqli_query($con, "select modified_by as name, created_date as month, count(modified_by) as count from slog where customer_name = '$name' group by modified_by, MONTH(created_date) order by month;")) {
while($row=mysqli_fetch_assoc($user_perf))
{
//Assign variables from mysql results
$month = date("F",strtotime($row["month"]));
$name = $row["name"];
$count = $row["count"];
$total += $row["count"];
//Only add the month once!
if($cur_month != $month){
$cur_month = $month;
$tr .= "</tr><tr><td>" . $cur_month. "</td>";
//print($cur_month . "<br>");
}
//store the username 'position' to build a table (this determines how many spaces are needed.)
if(!array_key_exists($name,$namepos))
{
$namepos[$name] = $npcount;
$npcount += 1;
$th .= "<th>" .$name . "</th>";
}
//add details to tr in correct pos
for( $i = 0; $i < $namepos[$name]; $i++){
$tr .= "<td></td>";
}
$tr .= "<td> ".$count." </td>";
//print(" ".$name . " " . $count . " <br>");
}
print("<table border='1'><tr>". $th . "</tr>" . $tr . "</table>");
print("<br>Total: ".$total." <br><br> ");
mysqli_free_result($user_perf);
}
}
mysqli_free_result($customers);
}
mysqli_close($con);
?>
Which unfortunately results in results such as this:-
What would be the best way to achieve this?
I have tried storing the position of each user in the table headers, but then it is difficult to know how many empty columns to add before and the entry (see image above).
just a quick update. I have managed to get what I desired through the following code
<?php
/*loop through all customers and print out each induvidual users performance*/
$con = mysqli_connect("localhost","root","","perfmon");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
exit();
}
//main query for customer names
if ($customers = mysqli_query($con, "SELECT Distinct(customer_name) FROM slog ORDER BY customer_name DESC;")) {
while($row=mysqli_fetch_assoc($customers))
{
//Name of customer
$name = $row["customer_name"];
//Print customer name
print("<b>".$name." </b><br>");
//Used to display total jobs
$total = 0;
$user_list = array("Month");
$monthlist = array();
$st_array = array();
//Loop over the customer names, and pull the modified count per user.
if ($user_perf = mysqli_query($con, "select modified_by as name, created_date as month, count(modified_by) as count from slog where customer_name = '$name' group by modified_by, MONTH(created_date) order by month;")) {
while($row=mysqli_fetch_assoc($user_perf))
{
$month = date("F",strtotime($row["month"]));
$name = $row["name"];
$count = $row["count"];
$total += $row["count"];
//make our left column (months)
if(!in_array($month, $monthlist)){
array_push($monthlist, $month);
}
//Collect all unqiue users, to make our headers array. also stores the order theyre in.
if(!in_array($name, $user_list)){
array_push($user_list, $name);
}
//make a 2d array of all data
$tmp = [$month, $name, $count];
array_push($st_array, $tmp);
}
/**Process fetched data **/
$row = "";
$previous_pos = 1;
$fe = True;
//Print each unique user as a table header
print("<table border='1'>");
print("<tr>");
foreach ($user_list as $th){
print("<th>".$th."</th>");
}
print("</tr>");
//Loop the month array
foreach ($monthlist as $td){
//Loop the user array
foreach ($user_list as $usr){
//Loop our "2d" array (an array containing Month,User,Count)
foreach($st_array as $array_2d){
//If we match the correct month and user, return the count value. This ensures the users return in the correct order.
if ($array_2d[0] == $td && $array_2d[1] == $usr){
//Pos - Get the current position of the selected user.
//Establish how many empty entries need to come before. E.g. User in col 1 has no empty entries infront. User in column2 has 1 entry empty infront (if column 1 is empty).
$pos = array_search($usr, $user_list);
if ($previous_pos != $pos){
$row .= str_repeat("<td>0</td>", ($pos-$previous_pos-1));
}
//Assign our previous position
$previous_pos = $pos;
//If our first entry isn't in column 1, add an extra 0.
if($pos!==1 && $fe)
$row .= "<td>0</td>";
$fe = False;
//Add the data
$row .= "<td>".($array_2d[2])."</td>"; //change to [1] for debug
}
}
}
//Print the table row.
print("<tr><td>".$td ."</td>" . $row ."</tr>");
//Reset our variables.
$row = "";
$fe=True;
$previous_pos = 1;
$first_result = True;
}
print("</table></br>");
mysqli_free_result($user_perf);
}
}
mysqli_free_result($customers);
}
mysqli_close($con);
?>
Essentially I created 3 arrays. An array of users, an array of months, and an array of all data (3d array). I use the months and users to record the order in which the tables should be presented. I then loop through my 3d array and print the relevant data.
Despite the downvotes, I would like to thank you all for offering your help. If you have any recommendations please let me know.

updating each row with previous values plus current values

sorry for the complicated heading.i am doing learning php and got stuck.i have a database table table_name
id(primary key) name ip
1 a 192.168.0.1,192.168.0.5,171.87.65 //separated by comma's
2 b 192.168.0.1,175.172.2.6,164.77.42
now i want to add an array of values ip[0] and ip[1] coming from a two different text-area to the end of the ip's of each name and just updating the ip column of each row.so it will just append new values with previous one.
name a<textarea rows="4" cols="40" name="ip[]"></textarea>
name b<textarea rows="4" cols="40" name="ip[]"></textarea>
<input type="submit" />
this is how its inserted
if(isset($_POST['submit'])) {
$ip_details = $_POST['ip'];
$values = array(
array('id' => '"1"', 'name' => '"a"', ip => '"'.$ip_details[0].'"'),
array('id' => '"2"','name' => '"b"', ip => '"'.$ip_details[1].'"'),
);
$columns = implode(', ', array_keys($values[0]));
foreach($values as $value) {
$value = implode(', ', $value);
$statement = "INSERT INTO `center_listt` (id,name,ip) VALUES ($value)";
$res=mysql_query($statement);
echo "success";
}
}
i need to update each rows of namea and b with new values coming from text-area with previous values.
i am thinking of array_push after fetching ip from table in while loop but could not really do it.warning: array_push expects parameter 1 to be array integer given its because the $row['ip'] fetched in while loop is not valid array which array_push expects.
and it will only add new values in different new rows each time which i don't want.can someone please help what to do.
<?php
if(isset($_POST['submit'])) {
//print_r($ips); die;
$i = 0;
foreach($_POST['ip_details'] as $ipaddr) {
$ips[$i] = $ips[$i].$ipaddr;
$i++;
}
$r = 1;
foreach($ips as $ip){
//echo "UPDATE center_listt SET ipdetails = '$ip' WHERE `id_center` = '$r'"; die;
if(mysql_query("UPDATE center_listt SET ipdetails = '$ip' WHERE `id_center` = '$r'")) echo "IP Address Updated <br />";
else echo 'error occurred';
$r++;
}
}
$sql="select * from center_listt";
$res=mysql_query($sql);
if(!$res) {
die('could not connect'.mysql_error());
}
while($row=mysql_fetch_assoc($res))
{
echo $row['ipdetails']; }
?>
its a bad practise to insert form values from array.you can fetch it from db bcoz if in future you want to add new form values you need to rewrite again with array values while fetching from db will only need you to insert new values in db.
my query will add ip's in your specific column in a single row only updating the ip with new values.
You could do this:
$values = array(...); // WARNING: escape `$ip_details` here!!
$to_insert = array();
foreach($values as $row) {
$to_insert[] = "(".implode(", ",$row).")";
}
$statement = "insert into `center_listt` (`id`, `name`, `ip`)
values ".implode(", ",$to_insert)."
ON DUPLICATE KEY UPDATE `ip`=concat(`ip`,',',values(`ip`))
";
mysql_query($statement);
This will perform a multi-insert (far more efficient than individual queries), and when you try to insert the same ID twice it will instead concatenate the values.
It should be noted that this is bad database design, though :p

access multidimensional array

This is sort of a follow up to my last question. Im trying to access the data of a multidimensional array so as to insert into a database. Ive been looking all over the forums as well as trying different things on my own but cant find anything that works. Here is what the array looks like:
$_POST[] = array[stake](
'stakeholder1' => array(
'partner'=> 'partner',
'meet'=> 'meet'
),
'stakeholder2' => array(
'partner'=> 'partner',
'agreement'=> 'agreement',
'train'=> 'train',
'meet'=> 'meet'
),
);
I'm trying to do somthing like ( UPDATE list WHERE stakeholder = "stakeholder1" SET partner =1, meet =1 ) depending on which stakeholder/choices were selected (theres four different options). Thanks,
This one will set 1 for checked options, and 0 for unchecked options (otherwise you will miss some data updates).
$optionsList = array('partner', 'agreement', 'train', 'meet');
$stakeHolders = array('stakeholder1', 'stakeholder2', ...);
foreach($stakeHolders as $stakeHolder)
{
$selectedOptions = $_POST[$stakeHolder];
$arInsert = array();
foreach($optionsList as $option)
$arInsert[] = '`'.$option.'` = '.intval(isset($selectedOptions[$option]));
$sql = "UPDATE list
SET ".implode(", ", $arInsert)."
WHERE stakeholder = '".mysql_real_escape_string($stakeHolder)."'";
// TODO: execute $sql (mysql_query(), or PDO call,
// or any wrapper you use for DB)
}
$query = '';
foreach ($_POST as $k => $v) {
$query .= "UPDATE list WHERE stakeholder = '$k' SET " . implode(" = 1," $v) . ",";
}
$query = substr($query, 0, -2); //Get rid of the final comma
This should give you something like what you are looking for, if I understand your database schema correctly.
If you are using PDO, you could do something like:
foreach($_POST as $stakeholder => $data) {
$sth = $dbh->prepare('UPDATE `list` SET `' . implode('` = 1, `', array_keys($data)) . '` = 1 WHERE stakeholder = ?');
$sth->execute(array($stakeholder));
}
Be sure to sanitize the user input (keys of the data...).
foreach($main_array as $key => $sub_array) {
$sql = 'UPDATE list
WHERE stakeholder = "{$key}"
SET ';
$sets = array();
foreach($sub_array as $column_value)
$sets[] = $column_value." = 1";
$sql = $sql.implode(',', $sets);
}

insert value array in database and next get(each) part of it?

I use of codeigniter. how can insert several value (array) <input name="ok[]"> in database and get they of database. (what is the best way?)
type rows in database is "VARCHAR" and "utf-8".
<input type="text" name="ok[]">
Values: (This is just one example of what I want)
ok[1] => hi, how are you?, 5426, assd, 54568
ok[2] => what, your name?, 548568a, 684a45ade
ok[3] => asdwhasdat, fine, 85as454se, 4e748sd
ok[3] => 85as454se, George, asdwhasdat, 4e748sd
Etc. ....
Now after it, i want inputs ok[1], ok[2], ok[3] together insert in a row (column) on database.
NEXT:
I want get (the second part) they of database and each they in foreach as:
how are you? fine your name? George
how is it?
$inserts = array();
foreach ($_REQUEST['ok'] as $key => $val)
{
$parts = explode(',', $val);
$inserts[] = "('" . mysql_real_escape_string($parts[1]) . "')";
}
$inserts = implode(',', $inserts);
$sql = "INSERT INTO yourtable (fieldname) VALUES $inserts;";
$result = mysql_query($sql) or die(mysql_error());

Print cascading table

I'm trying to load data from database and display it in table like here:
http://img196.imageshack.us/img196/1857/cijene.jpg
In database I have two tables:
cities (id, name)
prices (id, city1_id, city2_id, price)
For example, the printed table for 4 cities would look like this:
<table>
<tr>
<td>city1</td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> price_city1-city2</td>
<td>city2</td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> price_city1-city3</td>
<td> price_city2-city3</td>
<td>city3</td>
<td> </td>
</tr>
<tr>
<td> price_city1-city4</td>
<td> price_city2-city4</td>
<td> price_city3-city4</td>
<td>city4</td>
</tr>
</table>
Does someone know what's the PHP statement to echo this kind of tables?
// This single query gets all required data
// NOTE: this query assumes that your price data is entered
// such that from_city always alphabetically precedes to_city!
$sql =
"SELECT a.name AS from_city, b.name AS to_city, price ".
"FROM prices ".
"INNER JOIN cities AS a ON a.id=prices.city1_id ".
"INNER JOIN cities AS b ON b.id=prices.city2_id";
// connect and do query
$conn = mysql_connect($host, $user, $pass);
mysql_select_db($db, $conn);
$q = mysql_query($sql, $conn);
// Stuff all data into an array for manipulation;
// keep list of all cities mentioned
$price = array();
$cities = array();
while (($res = mysql_fetch_assoc($q)) !== false) {
$from = $res['from_city'];
$cities[ $from ] = true;
$to = $res['to_city'];
$cities[ $to ] = true;
$price[$to][$from] = $res['price'];
}
// Invert to get alphabetical list of cities
$cities = array_keys($cities);
sort($cities);
$num = count($cities);
// some utility functions
function table($rows) {
return '<table>'.join($rows).'</table>';
}
function row($cells) {
return '<tr>'.join($cells).'</tr>';
}
function cell($text) {
$text = (string) $text;
if (strlen($text)==0)
$text = ' ';
return '<td>'.$text.'</td>';
}
// The data is now in the desired order;
// produce output as HTML table
$rows = array();
for ($to = 0; $to < $num; ++$to) {
$t = $cities[$to];
$cells = array();
for ($from = 0; $from < $to; ++$from) {
$f = $cities[$from];
if isset($price[$t]) && isset($price[$t][$f])
$text = $price[$t][$f];
else
$text = '';
$cells[]= cell($text);
}
$cells[]= cell($t); // add destination-label
for ($from = $to+1; $from < $num; ++$from) // pad to proper number of cells
$cells[]= cell('');
$rows[]= row($cells);
}
$html = table($rows);
// show results!
echo $html;
I've used a very simple approach to converting the results of a query to an HTML table.
I test that $query_result is true and fetch the results as an associative array...
$query_result = mysqli_query($db, $query);
if ($query_result) {
while ($columns = mysqli_fetch_assoc($query_result)) {
echo "<tr>\n";
foreach ($columns as $name => $column) {
echo "<td>";
printf("%s",$columns[$name]);
echo "</td>\n";
}
echo "</tr>\n";
}
}
EDIT: Now I've been able to look at your table, I can see that I haven't really answered your question. The query is obviously very important. Does the question become 'how do I create a query which returns results which can be turned into a table by my simple-minded approach?'
I hope someone else has a few ideas.
This is somewhat at the edge of practicality, but I'm approaching this problem more as an exercise in "doing it right."
I would do a simple select of each table and insert in to an array:
$query1 = "SELECT * FROM cities";
$query2 = "SELECT * FROM prices";
$results1 = mysql_query( $query1 );
$results2 = mysql_query( $query2 );
while( $rows = mysql_fetch_array( $results1 ) ) $cities[] = $row['name'];
while( $rows = mysql_fetch_array( $results2 ) ) $prices[] = array(
$row['city1_id'],
$row['city2_id'],
$row['name']
);
I would then use this to dynamically create two javascript lists:
$java_array1 = "var Cities = new Array;\n";
foreach( $cities as $key=>$city ) $java_array1 .= "Cities[$key] = \"$city\";\n";
$java_array2 = "var Prices = new Array;\n";
foreach( $cities as $key=>$price ) $java_array2 .= "Prices[$key] = new Array(
\"{$price[0]}\",
\"{$price[1]}\",
\"{$price[2]}\",
);\n";
I would next output a table with carefully crafted ids for each cell. I would use code very similar to that in the first answer, but I would give each cell a unique id of "cell-<row>-<col>".
The last thing I would do would be whip up some onload javascript which would populate the table using the appropriate pairings. My javascript is quite rusty, but it would look something like this (NOTE: pseudocode follows):
n = 1;
for( var i in cities )
{
// set city names on the diagonal
document.getElementById( 'cell-'&i&'-'&i ).innerHTML = names[i];
n = n + 1;
}
for( var j in prices )
{
// use the city IDs in the prices array (see earlier code initializing
// prices array) to place the prices
document.getElementById( 'cell-'&prices[1]&'-'&prices[2] ).innerHTML = prices[0];
}
I almost certainly messed up some of that javascript; use at your own risk.
This is a lot more complex than the simpler answer given above, but this is the only way I can think of doing it so that it makes "sense." Basically, with this method, you place everything where it should be, and you don't have to worry about odd tables and weird selects.

Categories