I want to create a csv file from a SQL query that will fetch the information from the database of my Prestashop site.
The creation works well, however an essential need for the creation of my file takes me well the head.
The purpose of my file is to save the orders of the customers of the day, each line of my final table corresponds to a product of the order. I need to make sure that if the order number of the previous line is equal to the order number of the current line, that some of the fields in my line don't fill up.
How do I make the current id_order field compare to the previous one and add a condition in my csv file creation?
My php :
<?php
require_once 'dbconfig.php';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$sql = 'SELECT o.id_order ,c.id_customer, c.firstname, c.lastname, a.address1, a.address2, a.postcode, a.city,a.phone,c.email,a.phone_mobile, od.product_id,
od.product_name,od.product_quantity, od.product_price,o.total_paid_tax_incl, c.id_customer, op.date_add, op.amount, op.payment_method
FROM mod582_orders o
INNER JOIN mod582_customer c ON o.id_customer = c.id_customer
INNER JOIN mod582_address a ON o.id_address_delivery = a.id_address
INNER JOIN mod582_order_detail od ON o.id_order = od.id_order
INNER JOIN mod582_order_payment op ON o.reference = op.order_reference
WHERE CAST(o.date_add AS DATE) LIKE "2023-01%" /*CAST( curdate() AS DATE)*/;
';
$r = $pdo->query($sql);
$tab = [];
$tab[] = ['ORDNOORDER', 'ORDREFCUSORDER', 'ORDNOCOSTNUMBER','ORDNOCUSTOMER','ORDCUSTOMERCODE','ORDCUSCAT','ORDTYPE','ORDCURRENCY','ORDCURRENCYRATE','ORDDESIGNATION',
'ORDREPCODE','ORDPORT','ORDPORTTYPE','ORDPORTRATE','DEONOORDER','DEOCOMMENT','DEOCOUNTRY','DEONAME','DEOFIRSTNAME','DEOADDRESS1','DEOADDRESS2','DEOZIPCODE','DEOCITY',
'DEOPHONE','DEOMAIL','DEOPHONEPORTABLE','ODLNOORDER','ODLNOORDERLINE','ODLNOARTICLE','ODLARTDESIGN','ODLQUANTITYORDER','ODLTTCCURUPRICE','ODLCODEPARCELLEFLEU',
'PAYNUMPAYMENT','PAYNOCUSTOMER','PAYNOORDER','PAYNOCURRENCY','PAYDATEPAYMENT','PAYPAYMENTTTCCUR','PAYCURRENCYRATE','PAYCONTREPARTIE'];
$odrline = 1;
while($rs = $r->fetch(PDO::FETCH_ASSOC)){
$tab[] = [$rs['id_order'], $rs['id_order'], '17', '', 'AAA'.$rs['id_customer'],'DET','O','EUR','1','','115','D','P','17', $rs['id_order'],'','FRA', $rs['firstname'],
$rs['lastname'], $rs['address1'], $rs['address2'], $rs['postcode'], $rs['city'], $rs['phone'], $rs['email'], $rs['phone_mobile'], $rs['id_order'],$odrline,
$rs['product_id'], $rs['product_name'], $rs['product_quantity'], $rs['product_price'],'','','', $rs['id_order'],'EUR', $rs['date_add'], $rs['amount'],'1','VIR'];
}
$fichier_csv = new SplFileObject('vinistoria/commandes.csv', 'w');
foreach($tab as $ligne){
$fichier_csv->fputcsv($ligne, ';');
}
$date = date('d-m-y h:i:s');
echo "nouveau fichier commandes.csv créé à ". $date;
} catch (PDOException $e) {
die("Could not connect to the database $dbname :" . $e->getMessage());
}
?>
Exemple of my final tab :
here, if the order number is the same as the previous one, some fields are empty to indicate that it is the same order. Here is what I would like to do when creating my csv.
This appears to be a near duplicate of a question I answered previously. Is it an exam question?
Compare CSV line in php
Store the id_order in a variable and compare at the start of each loop iteration.
Something like:
$odrline = 0; // start with zero, as incremented before first written out
$prevordernumber = 0; // pick a number that is not a valid order number
// or empty string if not numeric
while($rs = $r->fetch(PDO::FETCH_ASSOC)){
// if order number has changed then increment order line
if($prevordernumber != $rs['id_order']) $odrline++;
$tab [] = ........
// update stored previous order number
$prevordernumber = $rs['id_order'];
}
// write $tab to file
$fichier_csv = new SplFileObject('vinistoria/commandes.csv', 'w');
foreach($tab as $ligne){
$fichier_csv-\>fputcsv($ligne, ';');
Related
I have the following code that allows me to generate a csv file from my database.
<?php
require_once 'dbconfig.php';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$sql = 'SELECT o.id_order ,c.id_customer, c.firstname, c.lastname, a.address1, a.address2, a.postcode, a.city,a.phone,c.email,a.phone_mobile, od.product_id, od.product_name,od.product_quantity, od.product_price,o.total_paid_tax_incl, c.id_customer, op.date_add, op.amount, op.payment_method
FROM mod582_orders o
INNER JOIN mod582_customer c ON o.id_customer = c.id_customer
INNER JOIN mod582_address a ON o.id_address_delivery = a.id_address
INNER JOIN mod582_order_detail od ON o.id_order = od.id_order
INNER JOIN mod582_order_payment op ON o.reference = op.order_reference
WHERE CAST(o.date_add AS DATE) LIKE "2023-01%" /*CAST( curdate() AS DATE)*/;
';
$r = $pdo->query($sql);
$tab = \[\];
$tab\[\] = \['ORDNOORDER', 'ORDREFCUSORDER', 'ORDNOCOSTNUMBER','ORDNOCUSTOMER','ORDCUSTOMERCODE','ORDCUSCAT','ORDTYPE','ORDCURRENCY','ORDCURRENCYRATE','ORDDESIGNATION','ORDREPCODE','ORDPORT','ORDPORTTYPE','ORDPORTRATE','DEONOORDER','DEOCOMMENT','DEOCOUNTRY','DEONAME','DEOFIRSTNAME','DEOADDRESS1','DEOADDRESS2','DEOZIPCODE','DEOCITY','DEOPHONE','DEOMAIL','DEOPHONEPORTABLE','ODLNOORDER','ODLNOORDERLINE','ODLNOARTICLE','ODLARTDESIGN','ODLQUANTITYORDER','ODLTTCCURUPRICE','ODLCODEPARCELLEFLEU','PAYNUMPAYMENT','PAYNOCUSTOMER','PAYNOORDER','PAYNOCURRENCY','PAYDATEPAYMENT','PAYPAYMENTTTCCUR','PAYCURRENCYRATE','PAYCONTREPARTIE'\];
$odrline = 1;
while($rs = $r-\>fetch(PDO::FETCH_ASSOC)){
$tab\[\] = \[$rs\['id_order'\], $rs\['id_order'\], '17', '', 'AAA'.$rs\['id_customer'\],'DET','O','EUR','1','','115','D','P','17', $rs\['id_order'\],'','FRA', $rs\['firstname'\], $rs\['lastname'\], $rs\['adress1'\], $rs\['adress2'\], $rs\['postcode'\], $rs\['city'\], $rs\['phone'\], $rs\['email'\], $rs\['phone_modile'\], $rs\['id_order'\],$odrline, $rs\['product_id'\], $rs\['product_name'\], $rs\['product_quantity'\], $rs\['product_price'\],'','','', $rs\['id_order'\],'EUR', $rs\['date_add'\], $rs\['amount'\],'1','VIR'\];
}
$fichier_csv = new SplFileObject('vinistoria/commandes.csv', 'w');
foreach($tab as $ligne){
$fichier_csv-\>fputcsv($ligne, ';');
}
$date = date('d-m-y h:i:s');
echo "nouveau fichier commandes.csv créé à ". $date;
} catch (PDOException $e) {
die("Could not connect to the database $dbname :" . $e-\>getMessage());
}
?\>
However I have some fields that need to change depending on the value of a field in the previous line of my csv.
For example :
my odrline value is 1 for all rows where the value of $rs['id_order'] is 486 but if on the next row $rs['id_order'] is 487 odrline should be 2 etc..
How can I go through my file and change the value based on a field in a previous line?
How can I go through my file and change the value based on a field in a previous line?
Rather than going through the file after it is created to change data, process the data before creating the file.
Store the id_order in a variable and compare at the start of each loop iteration.
Something like:
$odrline = 0; // start with zero, as incremented before first written out
$prevordernumber = 0; // pick a number that is not a valid order number
// or empty string if not numeric
while($rs = $r->fetch(PDO::FETCH_ASSOC)){
// if order number has changed then increment order line
if($prevordernumber != $rs['id_order']) $odrline++;
$tab [] = ........
// update stored previous order number
$prevordernumber = $rs['id_order'];
}
// write $tab to file
$fichier_csv = new SplFileObject('vinistoria/commandes.csv', 'w');
foreach($tab as $ligne){
$fichier_csv-\>fputcsv($ligne, ';');
I am a beginner programmer and I am trying to find the average user rating of vendor 2.
My steps are as follows:
1. User 'Jimmy' gives a rating of 3 to vendor 2 (ratings are out of 5)
2.TABLE vendoratings is updated
3. ratingstot.php then calculates the total sum of ratings and the number of responses for ALL vendors before updating TABLE vendortotalratings shown below
4.User 'Jimmy' clicks on 'View average user rating'
5. The values totalratings and totalno are retrieved and divided in Javascript
var average= totalratings/totalno
6. totalno is displayed to user Jimmy. END
Question
1. I need help forming the for or while loop in ratingstot.php to calculate both ratings and no. of responses belonging to vendor X before inserting them in vendortotalratings table for every vendor.
ratingstot.php
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
error_reporting(E_ERROR);
try{
//Database connection
$conn = new mysqli("localhost", "XXXXXXXX_XXX", "XXXXXXXX", "XXXXXXXX");
//Unsure how to loop this to make vendor new value every loop
for($i=0; $i<=6; $i++){
$vendor = ??
//Calculate sum of ratings from table ratings
$result = $conn->query("SELECT SUM(ratings) FROM ratings WHERE vendorid = '".$vendorid."' ");
$row = mysqli_fetch_array($result);
$totalratings = $row[0];
//Calculate no. of responses (by counting no. of rows)
$result1 = $conn->query("SELECT * FROM ratings WHERE vendorid = '" . $vendorid."' ");
$totalno = mysqli_num_rows($result);
//inserting the results into the table
$query = " UPDATE vendortotalratings SET ";
$query .= " totalratings = '". $totalratings ."', totalno='".$totalno."' ";
$query .= " WHERE vendorid = '". $vendorid ."'";
$result2 = $conn->query($query);
}
echo($outp);
}
catch(Exception $e) {
$json_out = "[".json_encode(array("result"=>0))."]";
echo $json_out;
}
?>
I have no idea how to loop this, are there any easier steps to calculate average of ratings for each vendors?
Instead of all these complicated things, you can simplify the required solution like this:
(Assumption: I'm assuming that vendorid, ratings, totalratings and totalno columns are of type INT)
Use the below statement/query to get the totalratings and totalno corresponding to each vendorid.
$result = $conn->query("SELECT vendorid, SUM(ratings) as totalratings, COUNT(userid) as totalno FROM vendorratings GROUP BY vendorid");
Now loop through the $result result set using while() loop.
while($row = $result->fetch_array()){
...
}
In each iteration of above while() loop, check if the vendorid value already exists or not. If it exists, then UPDATE the row with new totalratings and totalno, otherwise INSERT a new row comprising of vendorid, totalratings and totalno.
while($row = $result->fetch_array()){
$res = $conn->query("SELECT vendorid FROM vendortotalratings WHERE vendorid = " . $row['vendorid']);
if($res->num_rows){
// Update the existing row
$conn->query("UPDATE vendortotalratings SET totalratings = ".$row['totalratings'].", totalno = ".$row['totalno']." WHERE vendorid = ".$row['vendorid']);
echo "Affected rows: " . $conn->affected_rows . '<br />';
}else{
// Insert a new row
$res = $conn->query("INSERT INTO vendortotalratings VALUES(".$row['vendorid'].", ".$row['totalratings'].",".$row['totalno'].")");
if($res) echo "New row inserted <br />";
}
}
So the complete code of try-catch block would be like this:
// your code
try{
//Database connection
$conn = new mysqli("localhost", "XXXXXXXX_XXX", "XXXXXXXX", "XXXXXXXX");
$result = $conn->query("SELECT vendorid, SUM(ratings) as totalratings, COUNT(userid) as totalno FROM vendorratings GROUP BY vendorid");
while($row = $result->fetch_array()){
$res = $conn->query("SELECT vendorid FROM vendortotalratings WHERE vendorid = " . $row['vendorid']);
if($res->num_rows){
// Update the existing row
$conn->query("UPDATE vendortotalratings SET totalratings = ".$row['totalratings'].", totalno = ".$row['totalno']." WHERE vendorid = ".$row['vendorid']);
echo "Affected rows: " . $conn->affected_rows . '<br />';
}else{
// Insert a new row
$res = $conn->query("INSERT INTO vendortotalratings VALUES(".$row['vendorid'].", ".$row['totalratings'].",".$row['totalno'].")");
if($res) echo "New row inserted <br />";
}
}
}catch(Exception $e) {
$json_out = json_encode(array("result"=>0));
echo $json_out;
}
The question doesn't clarify how the records are first inserted in vendortotalratings table. So, assuming that there is already a record in this table for each vendor, you don't have to write a whole new loop.
Updating vendortotalratings:
SQL can take care of calculating the total ratings and their counts in a single query which can then replace the loop that you have.
UPDATE vendortotalratings vtr
INNER JOIN
(
SELECT vendorid, SUM(ratings) AS sumratings, COUNT(ratings) AS countratings
FROM vendoratings
GROUP BY vendorid
) vr
ON vtr.vendorid = vr.vendorid
SET
vtr.totalratings = vtr.totalratings + vr.sumratings
,vtr.totalno = vtr.totalno + vr.countratings
Computing averages:
As for your second question, to compute the average, you could run the following query which will give you the run-time result:
SELECT vendorid, totalratings, totalno,
CAST((totalratings/totalno) AS DECIMAL(10, 2)) AS avgrating
FROM vendortotalratings;
The variable avgrating can be accessed directly in PHP by using $row['avgrating'] if you're fetching an associative array from the results, or by using the appropriate index number, which in this case should be $row[3]
I'm trying to update a specific column through fgetcsv. But the problem is all the data are the same. Can someone help me about this? I don't know how to make the use of grade_id here because there are no grade_id in csv only in the database. And im doing it with only just file uploading.
Here's the csv. I just only want the midterm grade to be updated. But only the value 64 is inserted.
here's the result. The output should be 75,80,64 not 64,64,64
here's my database structure
here's my code
if(isset($_POST["Import"])){
$term = $_POST['term'];
$fac_code = $_POST['fac_code'];
$sch_year = $_POST['schoolyear'];
$section = $_POST['sec'];
$semester = $_POST['semester'];
$sub = $_POST['sub'];
echo $filename=$_FILES["file"]["tmp_name"];
$heading = true;
if($_FILES["file"]["size"] > 0)
{
$file = fopen($filename, "r");
while (($emapData = fgetcsv($file, 10000, ",")) !== FALSE)
{
if($heading) {
// unset the heading flag
$heading = false;
// skip the loop
continue;
}
//to get the last column
$last = end($emapData);
$sql1 ="SELECT * FROM grade WHERE subj_descr ='$sub' AND section = '$section'";
$result = mysqli_query($con, $sql1);
while($row = mysqli_fetch_array($result)){
$gradeid = $row['grade_id'];
$sql = "UPDATE grade SET midterm_grade = '$last' WHERE grade_id = '$grade_id'";
$result = mysqli_query( $con, $sql );
}
}
fclose($file);
//throws a message if data successfully imported to mysql database from excel file
echo "<script type=\"text/javascript\">
alert(\"CSV File has been successfully Imported.\");
window.location = \"homefaculty.php\"
</script>";
//close of connection
mysqli_close($con);
}
}
Your loop for updating in mysql is done just after your fetch your last value
In means in your code you do 3 loops for updating all value
$sql1 ="SELECT * FROM grade WHERE subj_descr ='$sub' AND section = '$section'";
This loop which fetch always the same result is called 3 times.
"UPDATE grade SET midterm_grade = '$last' WHERE grade_id = '$grade_id'";
In this query the grade_id comes from all the resultset
Basically you are doing this
1- get the last value of the line of CSV
2- select all records
3- update all of them with the value of 1-
4- next line
Instead of looping in all you mysql database for the SELECT, you should be able to SELECT just the record you need. I don't know if your CSV is full but do you have the grade_id in a column ? Otherwise how can you match a row of your CSV to a record in your database ?
EDIT
after discussion you said you have a unique key on section, term and subject
(You have to identify a relation between a row in CSV and a row in your database)
$last = end($emapData); //to get the last column
$section = $emapData[0]; // assuming section is the first column of CSV
$term = $emapData[1]; // assuming term is the 2nd column of CSV
$subject = $emapData[2]; // assuming subject is the 3rd column of CSV
$sql = "UPDATE grade SET midterm_grade = '$last' WHERE section = '$section' AND term = '$term' AND subject = '$subject'";
$result = mysqli_query( $con, $sql );
I am working on a data to CSV function but I'm stuck.
So far it's getting all data from two tables and putting onto a CSV file all in 1 line for each order with invoice data and customer data .
I need to also get invoice_items by ID as well (those I guess will need to be looped as might have more than 1 item but unsure how to add invoice_items to the query and also I need to set the titles as well for the columns but unsure how).
It would be awesome if it could be like this:
|invoice details customer details | invoice items
LIST ITEM
LIST ITEM
LIST ITEM
rather than
invoice details | customer details | invoice items LIST ITEM LIST ITEM
LIST ITEM
with real data and titles would look something like
id | invoice number | amount | name | address | invoice items (and
list below this part)
PHP
header("Content-type: text/csv");
// output any connection error
if ($mysqli->connect_error) {
die('Error : ('.$mysqli->connect_errno .') '. $mysqli->connect_error);
}
$file_name = 'invoice-export-'.date('d-m-Y').'.csv'; // file name
$file_path = 'downloads/'.$file_name; // file path
$file = fopen($file_path, "w"); // open a file in write mode
chmod($file_path, 0777); // set the file permission
$query_table_columns_data = "SELECT *
FROM invoices i
JOIN customers c
ON c.invoice = i.invoice
WHERE i.invoice = c.invoice
ORDER BY i.invoice";
if ($result_column_data = mysqli_query($mysqli, $query_table_columns_data)) {
// fetch table fields data
while ($column_data = $result_column_data->fetch_row()) {
$table_column_data = array();
foreach($column_data as $data) {
$table_column_data[] = $data;
}
// Format array as CSV and write to file pointer
fputcsv($file, $table_column_data, ",", '"');
}
}
If I understand you correctly, you need to join to another table to get the invoice items.
I also suspect that your current example query is joining the tables incorrectly, as you appear to be joining the customers and invoices tables based on the invoice. As I expect a customer could have many invoices, but an invoice only has one customer I would expect the invoice table to store the relevant customer id, and then do a join based on that.
As such you could get the details with something like this:-
SELECT i.id,
i.invoice_number,
i.amount,
c.name,
c.address,
ii.invoice_item
FROM invoices i
INNER JOIN customers c
ON c.id = i.customer_id
INNER JOIN invoice_items ii
ON ii.invoice_id = i.id
ORDER BY i.invoice
Note I have switched from SELECT * to selecting the column names (which I am guessing at), as SELECT * is frowned upon for various reasons. You could alias the column names if you wanted something more readable.
But you want a list of titles taken from the column names. Assuming you do not want to just hardcode these I would suggest that you switch from using mysqli_fetch_row to mysqli_fetch_assoc, which will return the column names.
You can then process the column names on the first row and output those. Something like this:-
<?php
header("Content-type: text/csv");
// output any connection error
if ($mysqli->connect_error) {
die('Error : ('.$mysqli->connect_errno .') '. $mysqli->connect_error);
}
$file_name = 'invoice-export-'.date('d-m-Y').'.csv'; // file name
$file_path = 'downloads/'.$file_name; // file path
$file = fopen($file_path, "w"); // open a file in write mode
chmod($file_path, 0777); // set the file permission
$query_table_columns_data = "SELECT i.id,
i.invoice_number,
i.amount,
c.name,
c.address,
ii.invoice_item
FROM invoices i
INNER JOIN customers c
ON c.id = i.customer_id
INNER JOIN invoice_items ii
ON ii.invoice_id = i.id
ORDER BY i.invoice";
if ($result_column_data = mysqli_query($mysqli, $query_table_columns_data))
{
// fetch table fields data
if ($column_data = $result_column_data->fetch_assoc())
{
$table_column_head = array();
$table_column_data = array();
foreach($column_data as $field_name->$data)
{
$table_column_head[] = $field_name;
$table_column_data[] = $data;
}
// Format array as CSV and write to file pointer
fputcsv($file, $table_column_head, ",", '"');
fputcsv($file, $table_column_data, ",", '"');
while ($column_data = $result_column_data->fetch_assoc())
{
$table_column_data = array();
foreach($column_data as $data)
{
$table_column_data[] = $data;
}
// Format array as CSV and write to file pointer
fputcsv($file, $table_column_data, ",", '"');
}
}
}
Expanding that a bit to only put out the invoice details on the first row for an invoice
<?php
header("Content-type: text/csv");
// output any connection error
if ($mysqli->connect_error) {
die('Error : ('.$mysqli->connect_errno .') '. $mysqli->connect_error);
}
$file_name = 'invoice-export-'.date('d-m-Y').'.csv'; // file name
$file_path = 'downloads/'.$file_name; // file path
$file = fopen($file_path, "w"); // open a file in write mode
chmod($file_path, 0777); // set the file permission
$query_table_columns_data = "SELECT i.id,
i.invoice_number,
i.amount,
c.name,
c.address,
ii.invoice_item
FROM invoices i
INNER JOIN customers c
ON c.id = i.customer_id
INNER JOIN invoice_items ii
ON ii.invoice_id = i.id
ORDER BY i.invoice";
if ($result_column_data = mysqli_query($mysqli, $query_table_columns_data))
{
// fetch table fields data
if ($column_data = $result_column_data->fetch_assoc())
{
$table_column_head = array();
$table_column_data = array();
foreach($column_data as $field_name->$data)
{
$table_column_head[] = $field_name;
$table_column_data[] = $data;
}
$prev_id = $column_data['id'];
$prev_invoice_number = $column_data['invoice_number'];
$prev_amount = $column_data['amount'];
$prev_name = $column_data['name'];
$prev_address = $column_data['address'];
// Format array as CSV and write to file pointer
fputcsv($file, $table_column_head, ",", '"');
fputcsv($file, $table_column_data, ",", '"');
while ($column_data = $result_column_data->fetch_assoc())
{
if ($prev_id == $column_data['id'] AND $prev_invoice_number == $column_data['invoice_number'] AND $prev_amount == $column_data['amount'] AND $prev_name == $column_data['name'] AND $prev_address == $column_data['address'])
{
$different_invoice = true;
}
else
{
$different_invoice = false;
$prev_id = $column_data['id'];
$prev_invoice_number = $column_data['invoice_number'];
$prev_amount = $column_data['amount'];
$prev_name = $column_data['name'];
$prev_address = $column_data['address'];
}
$table_column_data = array();
foreach($column_data as $field_name->$data)
{
$table_column_data[] = (($different_invoice or $field_name == 'invoice_item') ? $data : '');
}
// Format array as CSV and write to file pointer
fputcsv($file, $table_column_data, ",", '"');
}
}
}
I am using this PHP Code to run queries to a MySQL Database:
$i=0;
$display='[';
$stmt = $pdo_conn->prepare("SELECT * from tickets where status = :status and deleted = :deleted ");
$stmt->execute(array(':status' => 'Open', ':deleted' => ''));
$records = $stmt->fetchAll(PDO::FETCH_ASSOC);
$counter = count($records);
foreach($records as $result) {
$i++;
$stmt = $pdo_conn->prepare("SELECT * from contacts where sequence = :sequence ");
$stmt->execute(array(':sequence' => $result["contact"]));
$contact = $stmt->fetch();
$display.='{';
$display.='"customer":"'.$contact["forename"].' '.$contact["surname"].'",';
$display.='"subject":"'.$result["subject"].'"';
if($counter == $i) {
$display.='},';
} else {
$display.='}';
}
}
$display.=']';
I would ideally like the end result to show as the below:
[{"customer":"Carol","subject":"Fax not working"}{"customer":"Clive","subject":"VoIP Issues"}{"customer":"Leigh ","subject":"company Antaeus"}{"customer":"Debbie","subject":"emails"}{"customer":"Kim","subject":"Printer setup"}{"customer":"Sue ","subject":"Phone"}{"customer":"Sandra","subject":"Debbie's computer "}{"customer":"Daniel","subject":"Email Attachments"}{"customer":"Lara","subject":"Internet Issues"}]
However, at the moment it looks like:
[{"customer":"Carol","subject":"Fax not working"}{"customer":"Clive","subject":"VoIP Issues"}{"customer":"Leigh ","subject":"company Antaeus"}{"customer":"Debbie","subject":"emails"}{"customer":"Kim","subject":"Printer setup"}{"customer":"Sue ","subject":"Phone"}{"customer":"Sandra","subject":"Debbie's computer "}{"customer":"Daniel","subject":"Email Attachments"}{"customer":"Lara","subject":"Internet Issues"},]
Notice the comma on the end before the ]
How can i make sure that comma does not show at the end, I tried using the if statement in my loop with the counters ($counter and $i) but that didn't work
You can do this without any loops and a single inner join. Instead of manually constructing a JSON string, you are advised to use json_encode() to do it for you. Run a single join query, and collect the rows into a single array which is encoded as JSON..
This eliminates the need for all your other machinery - loops, and counters.
// A single join query will return everything you need from both tables.
// Customer names can be concatenated here into a single Customer field
// You only appear to need tickets.subject.
// And reading your queries, the table relation appears to be tickets.contact = contacts.sequence
$sql = '
SELECT
t.subject AS Subject,
CONCAT(c.forename, ' ', c.surname) AS Customer
FROM
tickets t
INNER JOIN contacts c ON t.contact = c.sequence
WHERE status = :status AND deleted = :deleted;
';
$stmt = $pdo_conn->prepare($sql);
if ($stmt) {
$stmt->execute(array(':status' => 'Open', ':deleted' => ''));
// Fetch all rows...
$rows = $stmt->fetchAll();
// Now $rows looks like the 2D array needed, you can directly JSON encode it
$output = json_encode($rows);
}
// Inspect it...
echo $output;
I'll point out that although you are absolutely right to be in the habit of bound parameters, there actually isn't a need for them here since the strings 'Open' and '' are static and known. You can just call a plain query() on this instead of prepare()/execute().
// No user input, static strings only, means no need for params
$sql = "
SELECT
t.subject AS Subject,
CONCAT(c.forename, ' ', c.surname) AS Customer
FROM
tickets t
INNER JOIN contacts c ON t.contact = c.sequence
WHERE status = 'Open' AND deleted = '';
";
// Just a simple query() call
$result = $pdo_conn->query($sql);
if ($result) {
$rows = $result->fetchAll();
// etc...
}