I'm getting some trouble with parsing the output of MySQL query in order to feed Highcharts. The biggest problem is that I would hawe 100+ data series, and I would like to don't refer to each column name in the parsing process, now the desired output would be something like that:
[
{'name':'TS','data':[4349,4375]}
{'name':'time1','data':[503,573]}
{'name':'time2','data':[500,506]}
{'name':'time3','data':[508,649]}
]
But I'm stuck with this output, where all the data are printed in the only first array:
[
{'name':'TS','data':[4349,503,573,500,4375,506,508,649,]}
{'name':'time1','data':[]}
{'name':'time2','data':[]}
{'name':'time3','data':[]}
]
The PHP code that I'm using is the following:
<?php
try {
$con= new PDO('mysql:host=localhost;dbname=test', "root", "");
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query = "SELECT TIME_TO_SEC(TS) as TS, TIME_TO_SEC(time1) as time1, TIME_TO_SEC(time2) as time2, TIME_TO_SEC(time3) as time3 FROM time ORDER BY TS";
//first pass just gets the column names
print "[";
$result = $con->query($query);
//return only the first row (we only need field names)
$row = $result->fetch(PDO::FETCH_ASSOC);
//second query gets the data
$data = $con->query($query);
$data->setFetchMode(PDO::FETCH_ASSOC);
foreach ($row as $field => $value){
print "{'name':'$field','data':[";
foreach($data as $row){
foreach ($row as $name=>$value){
print " $value,";
}
}
print "]}";
}
print "]";
}
catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
?>
Any suggestion to how to solve that problem?
Looks like you're using $row multiple times causing the loops to create errors.
Rename your inner $row variable to something else, e.g. $innerData.
foreach ($row as $field => $value){
print "{'name':'$field','data':[";
foreach($data as $innerData){
foreach ($innerData as $name=>$innerValue){
print " $innerValue,";
}
}
print "]}";
}
But there seem to be more problems in your code.
You query the database with the $query, 2 times. You you would get 2 same result sets. Did you miss to insert the second query statement ?
Please include the results the queries will produce in mysql, without php. This way I can improve my answer or other may help you too.
Related
The code below works as written provided a name in the database is entered in the search box. If a name not in the data base is entered, the error 'Warning: Invalid argument supplied for foreach() ….. on line 201.' Rather than this generic error I want something like “No Results” to display. Any suggestions anyone? I am aware that this question has been asked before but none of the answers seem to match the type of output I am using here.
enter code here
<?php
include 'connect.php';
if (isset($_POST['submit-keyword'])) {
$keyword = $_POST['keyword'];
}
try {
//first pass just gets the column names
print "<table>";
$result = $con->query("SELECT * FROM Bath_Wells_NBR WHERE Founder LIKE '%$keyword%' ORDER BY DATE");
//return only the first row (we only need field names)
$row = $result->fetch(PDO::FETCH_ASSOC);
print " <tr>";
foreach ($row as $field => $value){
print " <th>$field</th>";
}
// end foreach
print " </tr>";
//second query gets the data
$data = $con->query("SELECT * FROM Bath_Wells_NBR WHERE Founder LIKE '%$keyword%' ORDER BY DATE");
$data->setFetchMode(PDO::FETCH_ASSOC);
foreach($data as $row){
print " <tr>";
foreach ($row as $name=>$value){
print " <td>$value</td>";
} // end field loop
print " </tr>";
} // end record loop
print "</table>";
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
} // end try
?>
the first thing you need to do is make use of the PDO object and actually use the prepared statement to avoid sql injection like this:
$keyword = '%' . $keyword . '%';
$q = $con->prepare("SELECT * FROM Bath_Wells_NBR WHERE Founder LIKE :keyword ORDER BY DATE");
$q->bindParam(':keyword',$keyword,PDO::PARAM_STR);
$q->execute();
//here we will use fetchAll to get the full dataset of results, or an empty array
$result = $q->fetchAll();
Now you have $result which is an array either of your data, or empty so you can solve your problem by saying:
if(count($result) < 1) {
//output an error message
} else {
//output your table
}
Now you have your solution, let's streamline the code a bit. Remember, programmers want DRY code, so we don't want to do the same query twice. Lets assume our result count was greater than 0 so we are inside our else block.
{
//get all the array keys from the first entry in the result. These are the column names from the database which we want to use for our headings
$headings = array_keys($result[0]);
//now we want to do the same thing to each element, i.e. wrap it in html tags so let's make use of array_walk. We use the & symbol to pass the values by reference so we can amend them
array_walk($headings, function(&$field, &$key) {
$field = <th>$field</th>
});
//so now we have an array of table headings, so lets quickly implode them, we don't want to write a whole loop for this
echo <tr> . implode('',$headings) . </tr>;
now you can do your original loop and just output the values hey presto, dryer simpler code! You could also try and experiment with array_walk_recursive and see if you can do the same to the values for your nested loop, after all you just want to wrap them in <td> tags!
Note, I've not tested this so code, but you should be able to use it pretty much as it is, just have a little play and experiment with it.
happy coding!
Hello im trying out PDO and im stucked in a weird situation.
$statement->fetch()
returns me the desired results, but when i try to fetch em , while doesnt seem to work. I tried use $statement->fetchAll() with foreach but it doesnt work either.
I also tried fetch(PDO::FETCH_ASSOC) but again no luck. AM i doing something wrong ?
$pdoObject = new PDO("mysql:host=$dbhost;dbname=$dbname;", $dbuser, $dbpass);
$pdoObject -> exec("set names utf8");
$sql="SELECT * from prokiriksi_clean where name=:name";
$statement = $pdoObject->prepare($sql);
$statement->execute(array(':name' =>$clean));
$testyo=$statement->fetch();
var_dump($testyo); //returns array
if ($statement->fetch()){
echo 'inside if'; //it is printed
while ($record = $statement->fetch()) {
var_dump($record); //doesnt print
echo 'inside while'; //doesnt print
}
}
The problem is that you don't save the results of your first $statement->fetch(), so you skip the first row of your results. Given the way you have written your query, it looks like you only have one row, so you have nothing to loop over after that first row. Thus, the while never runs.
Remove the if and just do the while ($record = $statement->fetch()) loop:
while ($record = $statement->fetch()) {
var_dump($record);
echo 'inside while';
}
If you need to verify that you have any results before doing the loop, you can use the procedure described in the documentation or simply use a counter to see if the loop ran, like this:
$rows = 0;
while ($record = $statement->fetch()) {
var_dump($record);
echo 'inside while';
$rows++;
}
if ($rows) {
echo "Processed $rows rows\n";
} else {
echo "Oops! No data!\n";
}
When doing your if statement, you're fetching the result of your query, so you cannot fetch it a second time. Check this thread to perform multiple fetches: PDO multiple fetching of same query
Hi I'm getting confused as to how to display results with foreach loops. It seems there are slight differences depending on the structure of the array? ie if its a simple array, associative or multi-dimensional? I have looked at other answers for this site but I am still very much confused.
i have connected to mysql db with this code
try
{
$pdo = new PDO('mysql:host=localhost;dbname=****', '*****',
'*****');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec('SET NAMES "utf8"');
}
catch (PDOException $e)
{
$error = 'Unable to connect to the database server.' . $e->getMessage;
echo $error;
exit();
}
//next i want to retrieve the 'id' and 'name' from a db table...
$results = $pdo->query('select id, name FROM author');
//now I want to display those results on the page... i tried a foreach loop...
foreach ($results as $result) {
echo $result;
}
//but this just displays error message...
Parse error: syntax error, unexpected '$results' (T_VARIABLE), expecting '(' in C:\xampp\htdocs\Connect\admin\authors\test.php on line 6
Please help as im very confused. I just want to know how to display results from a db query like this with a foreach, and what rules apply when displaying different kinds of results from such queries.
I think it involves writing a foreach something like this ....
foreach ($results as $result=> $item) {
echo $item;
}
but i dont undertsand this either.
Any simplified approach to this would be greatly appreciated as I have been stuck on this for some time.
Thanks Rob.
$result is an array not the string.
$stmt = $pdo->prepare("SELECT id, name FROM author");
$stmt->execute();
$results = $stmt->fetchAll();
foreach ($results as $result) {
echo $result['id'];
echo $result['name'];
}
or print the array like this,
foreach ($results as $result) {
print_r($result);
}
You could try it with prepared statements, I always do even if I am not injecting parameters, keeps things a bit clearer.
$stmt = $pdo->prepare('select id, name FROM author');
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
print_r($row);
}
You can use the statement fetch method, and with the constant PDO::FETCH_ASSOC to ensure each row is an associative array.
If you're just looking to SELECT something from a database, below is the general format of what you'll need:
try {
//First, you initialise a connection to the database (in this case I'm using *constants*).
$dbh = new PDO('mysql:host=localhost; dbname='.DB_NAME, DB_USER, DB_PASS);
//Secondly, we'll prepare our query - SELECT the id and name FROM table author
$stmt = $dbh->prepare("SELECT id, name FROM author");
// Then we must execute the query
$stmt->execute();
// After execution, we must perform some function to get the results
// This function fetches ALL the results as an array so we can loop
// through them with foreach.
// (Other methods include a while loop and "fetch()" for one row at a time)
$results = $stmt->fetchAll();
// Then we just loop through everything
foreach ($results as $row) {
echo $row['id'];
echo $row['name'];
}
} catch (PDOException $e) {
echo $e->getMessage();
}
Please see the below code.
I am trying to retrieve the most recent two "element_value"s from my database table and then put them into a different table, with one column each. I can do this part with a mysql insert statement if I can get them into variables within the PHP, at the moment I have them being echoed out to the screen instead.
Does anyone know please how I can get them into two separate variables instead?
Thanks!
//Connect to database
$con=mysqli_connect("localhost","user","pass","dbname");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL database: " . mysqli_connect_error();
}
//Query the database
$result = mysqli_query($con, 'SELECT element_value FROM wp_formmaker_submits ORDER BY id DESC LIMIT 2;');
//Process the results
if (mysqli_num_rows($result) > 0) {
while ( $dataValue = mysqli_fetch_row($result))
echo "<p>".$dataValue[0]."</p>";
}
Change :
while ($dataValue = mysqli_fetch_row($result))
echo "<p>".$dataValue[0]."</p>";
To this :
$values = null;
while ($dataValue = mysqli_fetch_assoc($result))
{
$values[] = $dataValue['element_value'];
}
print_r($values);
This will store your values in an array, I've added print_r at the end just so you can see the resulting data structure.
If you want to display them in an array again, you can do this :
foreach ($values as $value)
{
echo "<p>".$value."</p>";
}
I've changed your fetch_row method for fetch_assoc, an explanation can be found here : https://stackoverflow.com/a/9540590/2483649
I want to run a query using PDO, based on data in the URL paramater (yes, I know that this is prone to attacks, but its internal code for a utility).
$user = 'USER';
$pass = 'PASSWORD';
$dsn = 'mysql:dbname=PRODUCTS;host=HOST';
try {
$productDB = new PDO($dsn, $user, $pass);
$productDB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
$msg = 'PDO ERROR' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
die($msg);
}
if(isset($_GET['cat']))
{
$cat = $_GET['cat'];
print "cat = $cat <br>";
$products = $productDB->prepare('SELECT * FROM products WHERE cat_id LIKE ?');
$products->execute(array($cat));
$rows = $products->rowCount();
print "$rows rows returned";
?>
<table border="1">
<tr>
<td>product_id</td>
<td>product_name</td>
</tr>
<?php
foreach ($products->fetchAll() as $row) {
$id = $row['product_id'];
$product_name = $row['product_name'];
print "<tr>";
print "<th scope=\"row\"><b>$id</b></th>";
print "<td> $product_name </td>";
print "<tr>";
}
print "</table>";
}
?>
When I run this code, it prints the correct number of rows depending on the query, but does not populate the table.
I have also tried replacing the prepare and execute lines with:
$products = $productDB->query("SELECT * FROM products WHERE cat_id LIKE $cat");
Which returns the correct row count, but doesn't otherwise help.
And finally, I've tried replacing the foreach line with something like:
$rows = $products->fetchAll();
foreach ($rows as $row) {
My attempts to do the same with a fixed query all work fine, but I am having trouble working out how to place a variable element in a query, and then iterate over the results.
You're not doing anything to store the result:
$products->execute(array($cat));
needs to go in a variable:
$result = $products->execute(array($cat));
Then, instead of calling $products->fetchAll(), use $results->fetchAll():
foreach ($result->fetchAll() as $row)
I find it easier to use a $query variable (for prepare, etc) and then get the result into something like $result or $product. Makes the code a bit easier to read.
Try this (If I understood correctly) :
$products = $productDB->prepare("SELECT * FROM products WHERE cat_id LIKE :cat");
// Now, you can either do this :
$products->bindParam('cat', '%'.$cat.'%');
$products->execute();
// or you can call execute with an associative array of your parameterized query.
$products->execute(array('cat' => '%'.$cat.'%'));
// Then, get all the results like this :
$rows = $products->fetchAll();
foreach ($rows as $row) {
// Do work here ..
}
// Or, like this :
while ($row = $products->fetch(PDO::FETCH_ASSOC)) {
// Do work here ..
}
I personaly prefer the while, because you don't fetch the whole query in one var, reducing the amount of memory needed.
I also recommend you to use the FETCH_* parameter, to get only the kind of array you want.
By the way, you need to know that rowCount should not be used to count the rows returned by a SELECT. As said by php.net :
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.