I'd like to select entries inside of a function and use the results in a while statement outside of the function.
This is what I have...
public function getPractices($dbh) {
$practices = $dbh->prepare("SELECT * FROM `practices`");
$practices->execute();
return $practices;
}
I would like to then do something like...
$practices = new SomethingDumbthing;
$practices->getPractices($dbh);
while ($row = $practices->fetch(PDO::FETCH_ASSOC)) {
Do stuff
}
While messing around, I got it to partially work, except for the fact that it was looping over the same row.
Any pointers?
In your example, you never actually use the statement.
$practices = new Class;
// this returns an object, but you don't save it to anything!
// try $data = $practices->getPractices($dbh);
$practices->getPractices($dbh);
// so now, you are calling fetch on your class, not on the database results!
while ($row = $practices->fetch(PDO::FETCH_ASSOC)) {
Do stuff
}
Related
after reading like 5 hours on Google I can't fix something with MySQLI.
I spent all my life programming in MySQL, and now I am trying to update my knowledge using mysqli but I have some troubles.
I have a little function called news_Default() like this:
<?php
Class Test extends DB{
public function news_Default(){
$query = $this->db->query('SELECT * FROM news');
if($query->num_rows == 0)
return false;
else
return $query->fetch_object();
}
}
?>
And I used in this way:
<?php
while($new = $panel->news_Default()){
print_r($new);
}
?>
In MySQL, when I return the object, I can use it with 'while' or 'foreach' loop without problems, but the real problem is here, with mysqli.
When I used the 'while' (second codeblock), it loops 6,000 times (I used a $counter++ to test it), and when I used foreach, it loops exactly 7 times. In my table called 'news' I have only two records. So, how can I return the object and use it outside without having this problems? Because when I use it inside the class like $new = $query->fetch_object() works perfect.
You are doing sql query every time when you are calling news_Default.
Examle for fixing it.
Class Test extends DB{
private $_cached_news = null; // let's store our query result
public function news_Default(){
if ($this->_cached_news === null){ // not stored?
$this->_cached_news = $this->db->query('SELECT * FROM news');} // let's query
$return = $query->fetch_object(); // get next object
if (!$return) // there is no objects anymore?
$this->_cached_news = null; // let's clear our result
return $return;
}
}
I have a function to run a query from database. Then, it will be called by 2 other functions.
function query(){
$query= // get data from database;
return $query;
}
function show_something(){
$data = query();
//do something
}
function show_else(){
$data = query();
//do something else
}
The function query() is called twice. I guess it would do the query job every time the function is called unless the result is cached. Would anybody correct me if I am wrong?
Yes, it will be called twice. You can cache the result if you want, using static variables.
If you are expecting the same query to be pulled each time (ie, no variables change) you might be better off using an object along these lines:
class checkSomethingOrOther
{
public $myVariable;
public function __get($name)
{
if (!array_key_exists($name, $this->myVariable))
{
$this->myVariable=query();
}
return $this-myVariable;
}
}
This will simply check to see if the variable is set, if not, it grabs the data and returns it, otherwise, just returns it.
You could simply do something like this:
Set an indicator to mark if the query is first or repeated.
Before querying, check indicator.
Code:
$fresh = true; // fresh results wanted
function query(){
global $fresh;
if($fresh){
$query= // get data from database;
$bar = $query; // cache the $query value for next uses..
$$fresh = false; // set the indicator that query is cached.
}else{ // this is repeated query
$query = $bar; //we had set the $bar last time
}
return $query;
}
function show_something(){
//first time query, $query will be fetched from database,
// also $fresh will be set to false
$data = query();
//do something
}
function show_else(){
//repeated query, cached value will be returned.
$data = query();
//do something else
}
$foo = true; // if you want fresh results, set $fresh to true before query
function show_fresh(){
//results will be fresh, because we have set $fresh to true again.
$data = query();
//do something else
}
No, that is correct; your function unconditionally performs an explicit query, therefore it will perform it each time it is called.
The database could have changed in between the function calls. Even if they're called immediately one after the other.
So, yes, the query will run twice; because the result may be different.
Unless you implement some caching mechanism.
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.
Can you do that? I just tried but it doesnt seem to work.
I have dbc.php included at top of my page, and in dbc.php at the bottom i created this function:
function getUserInfo($id) {
$thaString = mysql_query("SELECT * FROM users WHERE id = '$id'");
$thaString2 = mysql_query("SELECT * FROM users_profile WHERE uID = '$id'");
$showUR = mysql_fetch_array($thaString);
$showURP = mysql_fetch_array($thaString2);
}
So it would be easier for me to call them instead of running the queries all the time when i need them in other pages..
But when i try to do:
getUserInfo($showInfo["bID"]);
echo $showUR["full_name"];
I dont get any result, is there a smarter way to do this, if so how?
It's an issue of scope: $showUR is set inside getUserInfo(), so it's not available to the echo outside the function. There are lots of potential modifications you could make, but you may want to assign your values into an array and then return that array:
function getUserInfo($id) {
$user = array();
$thaString = mysql_query("SELECT * FROM users WHERE id = '$id'");
$thaString2 = mysql_query("SELECT * FROM users_profile WHERE uID = '$id'");
$user['showUR'] = mysql_fetch_array($thaString);
$user['showURP'] = mysql_fetch_array($thaString2);
return $user;
}
$user = getUserInfo($showInfo["bID"]);
echo $user['showUR']["full_name"];
Your functions have to return something for the values to be used, or $showUR and $showURP will just get lost once the function exits (ie: the scope will change). Something like:
function someFunc($arg) {
return "Hello, I am {$arg}";
}
$showUR = someFunc('name');
echo $showUR;
And please don't call stuff $thaString. First because it's a misnomer (mysql_query() doesn't return a string, it returns a resource or a boolean), Second because "tha" is so lame.
Let your function return the variable.
And then use $showUR = getUserInfo(...)
If you declare them outside the function, and then as globals inside the function you should be able to use them as you are now.
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;
}