I'm upgrading all my mysql_* to PDO. I can handle simple SELECTs and INSERTs. But I have one complex SELECT using nested loops that I am making a dog's dinner of. I'll post the mysql_* code, which outputs a two-column table with total registrations at A1 level in the first column and total registrations at A1 level who have paid in brackets in the second column.
-------------------------
Smithsville : A1 | |
10 | (7) |
-------------------------
Grange : A1 | |
4 | (4) |
-------------------------
Beau Ridge : A1 | |
23 | (16)|
-------------------------
Jonesboro : A1 | |
9 | (9) |
-------------------------
Lexing : A1 | |
3 | (1) |
-------------------------
In the full application further tables are genertated across the page for the other levels.
$levels = array('A1', 'A2', 'B1', 'B2');
$centres = array('Smithsville', 'Grange', 'Plateau Ridge', 'Jonesboro', 'Lexing');
for ($j = 0; $j < 1; $j++) /* Does not loop; selects only A1 in queries below*/
{
for ($k=0; $k<5; $k++) /* Cycles through the centres */
{
$show_count = mysql_query("SELECT COUNT(Centre)
FROM exam
WHERE exam.Centre='".$centres[$k]."'
AND exam.Level='".$levels[$j]."'");
$show_paid = mysql_query("SELECT COUNT(Centre)
FROM exam
JOIN personal
ON exam.P_ID=personal.P_ID
WHERE personal.Paid='1'
AND exam.Centre='".$centres[$k]."'
AND exam.Level='".$levels[$j]."'");
$result_rows = mysql_num_rows($show_count);
$result_rows2 = mysql_num_rows($show_paid);
if ($result_rows == 0)
{ echo 'No registrations';}
if ($result_rows2 == 0)
{ echo 'No payments';}
echo '<table class="Font3White">
<tr class="Title">
<td class="width8">'.$centres[$k].' : '.$levels[$j].'</td>
<tr>';
while (($row = mysql_fetch_row($show_count)) && ($row2 = mysql_fetch_row($show_paid)))
{
foreach ($row as $key => $value)
{
echo '<td>';
echo $value;
echo '</td>';
}
foreach ($row2 as $key2 => $value2)
{
echo '<td> (';
echo $value2;
echo ')</td>';
}
echo '</tr>';
}
echo '</table>';
}
}
My PDO attempt is
for ($j = 0; $j < 1; $j++) /* Does not loop; selects only A1 */
{
for ($k=0; $k<5; $k++) /* Cycles through the centres */
{
/*//////////////////////////*/
/* Prepares statements */
/*//////////////////////////*/
$stmt1 = $db->query("SELECT COUNT(Centre)
FROM exam
WHERE exam.Centre=:centre
AND exam.Level=:level");
$stmt2 = $db->query("SELECT COUNT(Centre)
FROM exam
JOIN personal
ON exam.P_ID=personal.P_ID
WHERE personal.Paid='1'
AND exam.Centre=:centre
AND exam.Level=:level");
/*/////////////////////*/
/* Binds parameters */
/*/////////////////////*/
$stmt1->bindParam(':centre', $centre, PDO::PARAM_STR);
$stmt1->bindParam(':level', $level, PDO::PARAM_STR);
$stmt2->bindParam(':centre', $centre, PDO::PARAM_STR);
$stmt2->bindParam(':level', $level, PDO::PARAM_STR);
/*//////////////////////////*/
/* Executes statements */
/*//////////////////////////*/
$stmt1->execute(array($centre, $level));
$stmt2->execute(array($centre, $level));
echo '<table class="Font3White">
<tr class="Title">
<td class="width8">'.$centres[$k].' > '.$levels[$j].'</td>
<tr>';
while (($row = $stmt1->fetch(PDO::FETCH_ASSOC)) && ($row2 = $stmt2->fetch(PDO::FETCH_ASSOC)))
{
foreach ($row as $key => $value)
{
echo '<td>';
echo $value;
echo '</td>';
}
foreach ($row2 as $key2 => $value2)
{
echo '<td> (';
echo $value2;
echo ')</td>';
}
echo '</tr>';
}
echo '</table>';
}
}
I know this is terrible but I hope it can be worked with.
I know it's wrong to make you the dirty work, but that's it.
I made some changes to your code, so compare mine with yours.
Hope it helps you.
$levels = array('A1', 'A2', 'B1', 'B2');
$centres = array('Smithsville', 'Grange', 'Plateau Ridge', 'Jonesboro', 'Lexing');
foreach ($levels as $level) {
foreach ($centres as $centre) {
// As you said, PREPARE
$stmt1 = $db->prepare("SELECT COUNT(Centre)
FROM exam
WHERE exam.Centre=:centre
AND exam.Level=:level");
$stmt2 = $db->prepare("SELECT COUNT(Centre)
FROM exam
JOIN personal
ON exam.P_ID=personal.P_ID
WHERE personal.Paid='1'
AND exam.Centre=:centre
AND exam.Level=:level");
$stmt1->bindParam(':centre', $centre, PDO::PARAM_STR);
$stmt1->bindParam(':level', $level, PDO::PARAM_STR);
$stmt2->bindParam(':centre', $centre, PDO::PARAM_STR);
$stmt2->bindParam(':level', $level, PDO::PARAM_STR);
//You don't need to pass parameters here just on PDOStatement::bindParam
$stmt1->execute();
$stmt2->execute();
echo '<table class="Font3White">
<tr class="Title">
<td class="width8">' . $centre . ' > ' . $level . '</td>
<tr>';
// Fetch stuffs
$row = $stmt1->fetch(PDO::FETCH_ASSOC);
$row2 = $stmt2->fetch(PDO::FETCH_ASSOC);
// Don't use while with PDOStatement::fetch, use fetchAll then foreach it.
if ($row && $row2) {
foreach ($row as $key /* <= Do you need it? */ => $value) {
echo '<td>';
echo $value;
echo '</td>';
}
foreach ($row2 as $key2 /* <= Do you need it? */ => $value2) {
echo '<td> (';
echo $value2;
echo ')</td>';
}
echo '</tr>';
}
echo '</table>';
}
}
Can you show us how you set $centre and $level variables? Maybe they are arrays, not strings? If they are - you may have to create new variable and assign value from array to it. Like this:
$value_to_bind = $centres[$k];
Execute does not need parameters if you used bindParam() before.
I never tried to run 2 queries with same parameter names and same variables binded to them. Maybe this is a problem?
Related
Error
Defined array in the controller, then transformed to the model which uses the implode function.
Problem = Data are inserted in the sql table in the same column. Eg: Coke,Pepsi,Slice (1 column)
t_id| product_name | unit | cost
1 | Coke,Pepsi,Slice | 5 | 1000
Solution Wanted = Data should be inserted in multiple column such as
t_id| product_name | unit | cost
1 | Coke | 5 | 1000
2 | Pepsi | 2 | 500
3 | Slice | 3 | 600
View
<div class="col-lg-6">
<?php
$getNameValue = $this->session->userdata('nameValue');
echo '<h3>' .$getNameValue['name'] .' paid Rs ' .$getNameValue['cash_amount']. '</h3>';
$getValue = $this->session->userdata('sessiondata');
if ($getValue != NULL){
echo '<table class="table table-bordered table-striped">';
echo '<tr>';
echo '<td><strong>Product Name</strong></td>';
echo '<td><strong>Unit</strong></td>';
echo '<td><strong>Cost</strong></td>';
echo "<form method='post' action=''>";
foreach ($getValue as $row)
{
echo '<tr>';
echo '<td><input type="hidden" name="allProduct[product_name][]" value="'.$row['product_name'].'">' .$row['product_name']. '</td>';
echo '<td><input type="hidden" name="allProduct[unit][]" value="'.$row['unit'].'">' .$row['unit'].'</td>';
echo '<td><input type="hidden" name="allProduct[cost][]" value="'.$row['cost'].'">' .$row['cost'].'</td>';
echo '</tr>';
}
echo '<tr><td></td><td><td><button type="submit" class="btn btn-success">POST</button></td></td></tr>';
echo "</form>";
echo '</table>';
}
?>
</div>
Controller
public function newSystemBatch($getBatch)
{
if ($data = $this->input->post('systemProduct')) {
$data['batch_id'] = $getBatch;
if (isset($data['sum'])) {
$data['cost'] = $data['cost'] / $data['unit'];
unset($data['sum']);
}
$productName = $data['product_name'];
$unit = $data['unit'];
$cost = $data['cost'];
$getValue = $this->session->userdata('sessiondata');
$getValue[] = array(
'product_name' => $productName,
'unit' => $unit,
'cost' => $cost
);
$this->session->set_userdata('sessiondata', $getValue);
$this->session->set_flashdata('message', $data);
redirect('inventory/newSystemMessage/' . $getBatch['batch_id']);
}
if ($data = $this->input->post('allProduct')) {
$this->header();
$this->footer();
$this->transaction->addNew($data);
$this->load->view("admin/newSystemTable", $data);
}
else {
$this->header();
$data['action'] = 'System';
$data['users_id'] = $this->user->users_id;
$this->load->view("admin/newSystemTable", $data);
$this->footer();
}
}
Model
function addNew($data)
{
if(is_array($data['product_name'])) $data['product_name'] = implode(",", $data['product_name']);
if(is_array($data['unit'])) $data['unit'] = implode(",", $data['unit']);
if(is_array($data['cost'])) $data['cost'] = implode(",", $data['cost']);
$this->db->insert('try', $data);
}
Model:
function addNew($data)
{
// Test that all all sub arrays are equal size
$length = array_unique(array_map('count', $data));
if (count($length) == 1) {
$length = current($length);
$keys = array_keys($data);
$res = array();
for($i = 0; $i < $length; $i++)
foreach($keys as $key)
$res[$i][$key] = $data[$key][$i];
$this->db->insert_batch('try', $res);
}
else {
// incorrect data
return false;
}
return true;
}
I have a mysql database (plattenkiste) with bandnames
id | kuenstler
1 | Aerosmith
2 | Beck
3 | Metallica
4 | Slayer
5 | Zappa, Frank
Now i want an output in alphabetical Order with directlinks and index-letters, showing only the index-letters with bandnames.
Like
Directlinks: A|B|M|S|Z
A
Aerosmith
B
Beck
M
Metallica
S
Slayer
Z
Zappa, Frank
I have a "quick and dirty" code that does what i want:
$abc = "0123456789AÄBCDEFGHIJKLMNOÖPQRSTUÜVWXYZ";
for($i=0; $i<strlen($abc); $i++){
$char = substr($abc, $i, 1);
$query = "SELECT kuenstler FROM plattenkiste WHERE kuenstler LIKE '$char%'";
$ergebnis = $mysqli->query($query);
$num = $ergebnis->num_rows;
if ($num != 0){
echo "<a href='#$char'>$char</a> | ";
}}
for($i=0; $i<strlen($abc); $i++){
$char = substr($abc, $i, 1);
$query = "SELECT kuenstler FROM plattenkiste WHERE kuenstler LIKE '$char%'";
$ergebnis = $mysqli->query($query);
$num = $ergebnis->num_rows;
if ($num != 0){
echo "<h4 id='$char'>$char</h4>";
while($row = $ergebnis->fetch_object()){
echo $row->kuenstler . '<br />';
}
}
}
Is there a shorter, more clean way to get this done?
You can have MySQL do much of the grunt for you, by both sorting the results and (for the initial list) providing only the initial characters. Then you merely need have PHP loop over the resultsets and output the necessary HTML (for the second list, adding a header whenever it encounters a new initial character).
If your plattenkiste.kuenstler column has a case sensitive collation then you may wish to explicitly specify a case insensitive collation in the ORDER BY clauses.
$query = 'SELECT DISTINCT UCASE(LEFT(kuenstler, 1)) AS char
FROM plattenkiste
ORDER BY kuenstler';
$ergebnis = $mysqli->query($query);
if ($ergebnis) {
while ($row = $ergebnis->fetch_object()) {
$char = htmlentities($row->char);
echo "<a href='#$char'>$char</a> | ";
}
}
$query = 'SELECT kuenstler FROM plattenkiste ORDER BY kuenstler';
$ergebnis = $mysqli->query($query);
if ($ergebnis) {
$row = $ergebnis->fetch_object();
while ($row) {
$c = $row->kuenstler[0];
$char = htmlentities(strtoupper($c));
echo "<h4 id='$char'>$char</h4>";
do {
echo htmlentities($row->kuenstler), '<br />';
} while ($row = $ergebnis->fetch_object() and $row->kuenstler[0] == $c);
}
}
I've had to do things like this before as well. The easiest option is to just loop through your results and build a series of arrays...
$artists = $mysqli->query(
'SELECT kuenstler FROM Lattenkiste ORDER BY kuenstler ASC'
);
$letters = array();
// get the results and sort them into arrays
while($artist = $artists->fetch_object()) {
// ge the first letter
$firstLetter = strtoupper($artist->kuenstler{0});
// if we don't have a key for it, make it
if (!isset($letters[$firstLetter])) {
$letters[$firstLetter] = array();
}
$letters[$firstLetter] = $artist->kuenstler;
}
// output the headings
echo '<ul class="directlinks">';
foreach (array_keys($letters) as $letter) {
echo '<li>' . $letter . '</li>';
}
echo '</ul>';
// now output each set of letters
foreach (array_keys($letters) as $letter) {
echo '<h4 id="' . $letter . '">' . $letter . '</h4>';
echo '<ul class="artists">';
foreach ($letters[$letter] as $kuenstler) {
echo '<li>' . $kuenstler . '</li>';
}
echo '</ul>';
}
<table border="2">
<?php
foreach($array1 as $value)
{
echo '<tr><td>';
echo $value;
echo '</td></tr>';
}
?>
</table>
I have more array: array2,array3.
The above code only executes values of array1 but I want all the values of all array in the same table in separate columns!
array1 | array2 | array3
------------------------
| |
| |
| |
| |
I want something like this...
I tried modifying the code but no idea how to do it correctly.
$data = mysql_query(" SELECT * FROM user_pokemon_db WHERE user_id = '".$id."' ");
while($rows = mysql_fetch_assoc($data)) {
$db_id = $rows['id'];
$array[] = $db_id;
$level = $rows['level'];
$array1[] = $level;
$exp = $rows['exp'];
$array2[] = $exp;
$pkmn_id = $rows['pkmn_id'];
$data1 = mysql_query(" SELECT * FROM pokemons WHERE pk_id = '".$pkmn_id."' ");
while($rows = mysql_fetch_assoc($data1)) {
$poke = $rows['path']; $array3[] = $poke;
}
}
The above code fetches data from database and adds it to different arrays!
When you create your array, you don't specify keys, so they are generated automaticaly. So you can work on keys for your for loop instead of using a foreach in values:
We can see in your code that $array3 is longuer than the others. So we will base on it:
foreach($array3 as $key => $value)
{
if (isset($array1[$key])){
echo '<tr><td>'.$array1[$key].'</td>';
}else{
echo '<tr><td></td>';
}
if (isset($array2[$key])){
echo '<td>'.$array2[$key].'</td>';
}else{
echo '<td></td>';
}
echo '<td>'.$array3[$key].'</td></tr>';
}
It should work
try making a function that calls itself in the end. not sure if I got the syntax right here, but this should work.
$i = 0;
function test($i){
if($i < ar1.lenght && $i < ar2.lenght && $i< ar3.lenght){
echo "<tr><td>";
echo ar1[$i];
echo "</td><td>";
echo ar2[$i];
echo "</td><td>";
echo ar3[$i];
echo "</td></tr>";
$i++;
//calls itself with an incremented $i
test($i);
}//else do nothing.
}
--edit forgot some tags
I would like make:
aaa | bbb | ccc | ddd etc
1 | 1 | 1 | 1
2 | 2 | 2 | 2
3 | 3 | 3 | 3
etc
for aaa, bbb etc i use FOREACH
<table><tr>
foreach ($data as $d){
echo "<td>" . $d . "</td>";
}
</tr>
for ($i = 0; $i < 20; $i++){
echo "<tr><td>" . $i . "</td></tr>";
}
but this working not ok. how can i use loop FOR for all data from foreach?
I think you can generate your table like this:
$columns = array('aaa','bbb','ccc','ddd');
$num_cols = count($columns);
echo "<table>";
echo "<tr>";
foreach($columns as $col)
{
echo "<td>$col</td>";
}
echo "</tr>";
for($i=1;$i<20;$i++)
{
echo "<tr>";
for($j=0;$j<$num_cols;$j++)
{
echo "<td>$i</td>";
}
echo "</tr>";
}
echo "</table>";
In general depends on what $data looks like.
<?php
$data = array('aaa', 'bbb', 'ccc', 'ddd'); // Assuming that $data is a columns storage
$rows = 10; // $rows = count($data); if you wish to have same number of columns and rows
echo '<table>';
echo '<tr>';
foreach ($data AS $item)
{
echo '<td>' . $item . '</td>';
}
echo '</tr>';
for ($idx = 0; $idx < $rows; $idx++)
{
echo '<tr>';
for ($col = 1, $col_num = count($data); $col <= $col_num; $col++)
{
echo '<td>' . $idx . '</td>';
}
echo '</tr>';
}
echo '</table>';
?>
P.S. haven't tested the code.
I have an Array of Arrays and Want to create a Tabular data layout. This is not the exact code, as how their generated is quite the cluster (Coming from COBOL interaction) but this should give me enough to make it work if someone can think of a clean way to code this.
array(
Array(847.0, 97010, 11)
Array(847.0, 97012, 10)
Array(847.1, 97010, 08)
Array(847.1, 97012, 14)
)
So I want to put these into a Table that looks something like
97010 97012
847.0 11 10
847.1 08 14
The first 2 elements of the arrays will always be the two axis and the 3rd the contents of the table.
Any Suggestions? thanks!
$table = array();
$columns = array();
// copy the array (x, y, value) into a table
// keeping track of the unique column names as we go
foreach ($dataSet as $point) {
// provided sample data used floats, ensure it is a string
$x = strval($point[0]);
$y = strval($point[1]);
$data = $point[2];
if (!isset($table[$x])) {
$table[$x] = array();
}
$table[$x][$y] = $data;
// quick and dirty style 'unique on insert'
$columns[$y] = true;
}
// switch the column names from title => true to just titles
$columns = array_flip($columns);
// Display the table
echo '<table>';
// Header row
echo '<tr>';
echo '<th> </th>';
foreach ($columns as $columnTitle) {
echo '<th>' . $columnTitle . '</th>';
}
echo '</tr>';
// Bulk of the table
foreach ($table as $rowTitle => $row) {
echo '<tr>';
echo '<th>' . $rowTitle . '</th>';
foreach ($columns as $columnTitle => $junk) {
if (isset($row[$columnTitle]) {
echo '<td>' . $row[$columnTitle] . '</td>';
} else {
// Handle sparse tables gracefully.
echo '<td> </td>';
}
}
echo '</tr>';
}
echo '</table>';
From what I understood:
$arr[847.0][97010] = '11';
$arr[847.0][97012] = '10';
$arr[847.1][97010] = '08';
$arr[847.1][97012] = '14';
And you may create a table:
$result = "<table>";
foreach($arr as $row_key => $row) {
$result .= "<tr>";
foreach($row as $column_key => $data) {
$result .= "<td>".$data."</td>";
}
$result .= "</tr>";
}
$result .= "</table>";
echo $result;