Generic MySQL Select All Function - php

I write a lot of SELECT * FROM... kind of queries in my web sites. I'd like to write a function that looks after this for me so I can call on it more quickly, without using more advanced techniques like PDO and OOP. Im just confused on how I would call the data I retrieve from the database, particularly when looping through the array's results.
I'd love something like this:
function selectAll($tableName, $limitAmount) {
global $dbConnection;
$query = mysql_query("SELECT * FROM $tableName ORDER BY id LIMIT $limitAmount");
$row_result = mysql_fetch_assoc($query);
return $row_result;
}
Say it was a bunch of news posts. Id like to loop through the results in one of the typical ways:
// CALL THE FUNCTION
selectAll('news_table', '10');
// SOMEHOW LOOP THROUGH RESULTS??
do {
echo "<h2>".$row_result['title']."</h2>";
} while ($row_result = mysql_fetch_assoc($query));
Obviously this isn't how I loop through the bespoke results of a function. Im not even sure if my function is correct.
Any help is greatly appreciated.
EDIT: Forgot to return a result inside the function and call the actual function. My bad. Updated now.

There is no point in having such a function called like yours.
Just make it like this
function fetchAll($query) {
$res = mysql_query($query) or trigger_error("db: ".mysql_error()." in ".$query);
$a = array();
if ($res) {
while($row = mysql_fetch_assoc($res)) $a[]=$row;
}
return $a;
}
and use it with whatever query:
$data = fetchAll("SELECT * FROM news_table ORDER BY id LIMIT 10");
foreach ($data as $row) {
echo $row['title'];
}
An SQL query being a powerful program itself. Do not reduce it's power to silly selects.
Use SQL to represent data processing logic and this helper function to avoid repetitions.

Related

symfony2 doctrine fetch while without creating complete array of results

I am looking to export to a csv file using doctrine. However the data is likely to be quite large. Therefore I dont want to ouput to the results to a complete array. I want to traverse the results iteratively.
I have tried looking here
doctrine docs
The PHP looks something like this
$result = mysql_query("SELECT * FROM bigtable");
while($row = mysql_fetch_assoc($result)) {
// do code iteratively here
}
Not sure how you do the same thing in doctrine for symfony2
This is from the doctrine documentation about batch processing:
$q = $this->_em->createQuery('select u from MyProject\Model\User u');
$iterableResult = $q->iterate();
foreach ($iterableResult AS $row) {
// do stuff with the data in the row, $row[0] is always the object
// detach from Doctrine, so that it can be Garbage-Collected immediately
$this->_em->detach($row[0]);
}
'select u ....is the equivalent to your SELECT * ...
$result = mysql_query("SELECT * FROM bigtable");
while($row = mysql_fetch_assoc($result)) {
// do code iteratively here
}
is Flat PHP and symfony2/doctrine is designed to avoid it. http://symfony.com/doc/2.0/book/from_flat_php_to_symfony2.html
kudos to Dirk his answer is correct. If you want to iterat eover entity models then thats the way to go. Sometimes you may not have a model mapped setup for the sql results you are returning. If you want to do it over a raw sql file then this is how I did it. I would be interested to hear more thoughts.
You pass the doctrine connection into the class via your controller
Controller
function indexAction(){
$className = new ClassName($this->getDoctrine()->getEntityManager());
}
You can then create raw sql lookup
Entity
function __construct($entity){
$this->connection = $entity->getConnection();
}
function saveToCSV
{
$stmt = $this->connection->prepare("SELECT * FROM bitTableExample ");
$stmt->execute();
while($row = $stmt->fetch()){
// append to csv file
}
}

Which is the best approach for displaying multiple mysql rows in php? (fetch then display or fetch ALL then display)

as the question states.
I have implemented a function wherein it fetches multiple rows from a database (*1) and then (*2) instantiate each row as an Object. After instantiation, the Objects are then stored into an array and then return the result to caller function and then iterates through the result array and displays each Object and add html formatting for each.
Here is the snippet of the code:
function find_all() {
//(*1) Fetch 30 comments from DB
$sql = 'SELECT * FROM comments';
$sql .= ' ORDER BY datetime DESC LIMIT 30';
return find_by_sql($sql);
}
function find_by_sql($sql='') {
global $database;
$result_set = $database->query($sql);
$object_array = array();
while($row = $database->fetch_array($result_set)) {
//(*2) Instantiate each row to a Comment object
// and then stores each comment to an object array
$object_array[] = Comment::instantiate($row);
}
return $object_array;
}
//(*3) Format and display each result.
$comments = find_all();
foreach ( $comments as $comment ) {
// Not sure if syntax is correct.. anyhow..
echo "<li>$comment->get_text()</li>";
}
However, I like the above approach since it's cleaner, easier to read, maintainable, and more OOP. But the problem is it takes a longer time to display than just simply iterating through each result than display each result once it's fetched, like so:
while ($row = mysql_fetch_array($sql)) {
echo "<li>$row['text']</li>";
}
I know the reason behind why it is slow. What I want to know is there a better way to solve the problem above?
While caching might be a good idea, it won't help because I need an updated list every time the list is fetched.
I think it can be a little faster if the script gets only the part you are interested in the result set, because fetch_array() returns 2 arrays with the same result set: associative, and numeric.
By adding MYSQLI_ASSOC (if you use mysqli): mysqli_fetch_array($result, MYSQLI_ASSOC), or try with mysql_fetch_assoc(), the script receives only the associative array.
You can test in pmpMyAdmin to see the diferences.

PHP Variable - Multiply pages

I have a functions.php page, I have included in ALL my other php pages. What I want is a function in my functions.php page, I can use in all the other pages.
I have tried this:
function getSetting()
{
$r=mysql_query("SELECT * FROM settings");
if(mysql_num_rows($r) == 0)
return false;
else
$sdata=mysql_fetch_assoc($r);
return $sdata;
}
The thing I want to, I want to get the data from the row next to the name in the following picture: http://awesomescreenshot.com/0bci8x472
Example:
If I write $sdata['sitename'], I want it to output "ptcify"
Thanks!
Try using mysql_fetch_array() with MYSQL_ASSOC as documented at this link http://www.php.net/manual/en/function.mysql-fetch-array.php.
There are a lot of things you could do to further improve your code implementation i.e OOP, using better database abstraction libraries(even switching to PDO insted of PHP_MYSQL is an improvement), but this should work straight of the bat.
Most questions usually have a ? in them somewhere, to indicate an actual question. I'm not sure what the problem with your code is, but I'm guessing you're only getting a single "setting" result - if that query returns multiple rows, you have to loop over the result set and get each row, THEN return:
$r = mysql_query(...) or die(mysql_error());
$sdata = array()
while ($row = mysql_fetch_assoc($r)) {
$sdata[] = $row;
}
return $sdata
edit
$sql = "SELECT setting_name, setting_value FROM settings"
$result = mysql_query($sql) or die(mysql_error());
$sdata = array();
while($row = mysql_fetch_assoc($result)) {
$sdata[$row['setting_name']] = $row['setting_value'];
}
return $sdata;

PHP mySQL - Can you return an associated array with a number index?

I have this method in my db class
public function query($queryString)
{
if (!$this->_connected) $this->_connectToDb(); //connect to database
$results = mysql_query($queryString, $this->_dbLink) or trigger_error(mysql_error());
return mysql_num_rows($results) > 0 ? mysql_fetch_assoc($results) : false;
}
This works great for queries that return 1 row, but how can I get an array returned something like this?
$array[0]['name'] = 'jim'
$array[0]['id'] = 120
$array[1]['name'] = 'judith'
$array[1]['ID'] = 121
Now I know I could use a while loop to insert this data into the array like so, but I was wondering if PHP could do this with an internal function? I havn't been able to find on the docs what I'm after.
The reason I don't want to run the while within the method is because I am going to reiterate back over the array when it's returned, and I'd rather not run through the results twice (for performance reasons).
Is there a way to do this? Do I have a problem with my general query method design?
Thank you muchly!
public function query($queryString)
{
if (!$this->_connected) $this->_connectToDb(); //connect to database
$results = mysql_query($queryString, $this->_dbLink) or trigger_error(mysql_error());
$data = array();
while($row = mysql_fetch_assoc($results))
{
$data[] = $row;
}
return $data;
}
this will always return an array.
EDIT:
I didn't read the question well.
If you realy don't want to use the loop then I would do this:
public function query($queryString)
{
if (!$this->_connected) $this->_connectToDb(); //connect to database
return mysql_query($queryString, $this->_dbLink) or trigger_error(mysql_error());
}
then loop over it, however I would just use the loop.
You might also want to look at the PDO extension. You can load the entire result set into an array or you can loop using foreach.
<?php
$db = new PDO($connection_string, $username, $password);
$result = $db->query($queryString);
foreach($result as $row) {
// do something
}
// or
$result = $db->query($queryString);
$result_array = $result->fetchAll(PDO::FETCH_ASSOC);
?>
Most people use a while() loop in the query to do exactly what you want and then loop over the array to process it.
However, you're right: it wastes memory, which could be a problem with a large dataset. An alternative is for your query method to return the resultset resource. Then your while loop can use that to fetch each row as it requires it.
To abstract that away, I would suggest another class to do that for you. Then your query call would return a new instance of that class which has the MySQL resultset resource as an instance variable and packages up the mysql_fetch_assoc() call.
Look at PEAR::MDB2 (Quickstart Cheatsheet). It provides lots of different functions for doing something like this. It also does not tie you down into using MySQL specific functions because it is a database abstraction layer.
$result = $db->queryRow($query, MDB2_FETCHMODE_ASSOC);
There are other abstraction layers such as ADO as well.
thanks for the ideas. I have a function that returns an associative array from the sql (used in Moodle).
$results = get_records_sql($sql);
//to create a numerically indexed array:
$data = array();
foreach ($results as $row)
{
$data[] = $row;
}
return $data;
}

Pass result of mysql_fetch_object() to a function does not work

I have the following problem:
public function row2Partner($row){
echo $row->PartnerID;
}
public function main(){
$query = "SELECT PartnerID, PartnerName FROM Partner";
$result = mysql_query($query);
$this->row2Partner(mysql_fetch_object($result));
}
This gives me the error in row2Partner():
Trying to get property of non-object
But $row is an Object! And if I do
echo $row->PartnerID in the main function, it works.
Any ideas?
Thx,
Martin
If your result returns more than one row, your object is going to be multi-dimensional. I'm pretty sure you can do something like this if you just want to echo the first one:
public function row2Partner($row){ echo $row[0]->PartnerID; }
If you are looking for only one result, I would also limit my query to just one...
SELECT PartnerID, PartnerName FROM Partner LIMIT 1
If you want to echo out all your rows (in the case of multiple) results, you can do this:
public function row2Partner($row){
foreach($row as $result) {
echo $result->PartnerID;
}
}
Hope that helps.
PS
Just as a sidenote, I tend to like to use associative arrays when dealing with MySQL results--it just makes more sense to me. In this case, you would just do this instead:
mysql_fetch_assoc($result)
Are you sure that mysql_query() has executed the query successfully, and also that there is actually a row being returned? It might be worth checking it, e.g.
//check query executed ok
if ($result = mysql_query($query)) {
//check there is actually a row
if ($row = mysql_fetch_object($result)) {
$this->row2Partner($row);
} else {
//no data
}
} else {
//error
die(mysql_error());
}
Best thing I can think of is that you may need to pass by reference rather than by value. Change your function declaration to
public function row2Partner(&$row)
Hope that helps,
David

Categories