I want to have a SelectAll function which takes in a few arguments (class, table, sort field, and sort order.) The comments explain what is going on (or what is supposed to.)
public static function SelectAll($class, $table, $sort_field, $sort_order = "ASC")
{
/* First, the function performs a MySQL query using the provided arguments. */
$query = "SELECT * FROM " .$table. " ORDER BY " .$sort_field. " " .$sort_order;
$result = mysql_query($query);
/* Next, the function dynamically gathers the appropriate number and names of properties. */
$num_fields = mysql_num_fields($result);
for($i=0; $i < ($num_fields); $i++)
{
$fetch = mysql_fetch_field($result, $i);
$properties[$i] = "'".$fetch->name."'";
}
/*echo [$properties[0]; echo "<br />";}*/
/* Finally, the function produces and returns an array of constructed objects. */
while($row = mysql_fetch_assoc($result))
{
for($i=0; $i < ($num_fields); $i++)
{
$args[$i] = $row[$properties[$i]];
}
$array[] = call_user_func_array(new $class, $args);
} return $array; }
Now, the problem I am having is that $row[$properties[$i]] results in 'undefined index.'
Right after the function gathers the number/names of the fields and stores them in an array, I can echo the value of $properties[0] and it shows as it should, 'id', but $row[~anything here~] will simply not work unless I manually enter the value, such as $row['id']. As you can imagine very frustrating and confusing.
Why won't this work? Are there any solutions, or alternate ways of accomplishing this function?
As I see your $properties[$i] array items have quoted values like "'id'",
so $row[$properties[$i]] <==> $row["'id'"] != $row["id"];
And you might want to check $result === false after $result = mysql_query($query);
Anyway, I think you could replace your function to this (unless you constructed it for demonstration only):
public static function SelectAll($class, $method_name, $table, $sort_field, $sort_order = "ASC"){
/* First, the function performs a MySQL query using the provided arguments. */
$query = "SELECT * FROM " .$table. " ORDER BY " .$sort_field. " " .$sort_order;
$result = mysql_query($query);
while($row = mysql_fetch_array($result))
$array[] = call_user_func_array(array($class,'__construct'), $row);
return $array;
}
Related
I am trying to test a few scripts that I would normally get from an SQL database but for testing offline I am just creating an array.
Here is what I have right now;
$result = array
(
array("name"=>"Toby", "q1"=>"1"),
array("name"=>"Phelps", "q1"=>"1"),
array("name"=>"Davies", "q1"=>"1"),
array("name"=>"Keith", "q1"=>"1"),
);
$resultnum = count($result);
echo "<b>Question 1</b> <br/><br/>";
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$name = $row['name'];
$answer = $row['q1'];
$q1answer = 1;
if($answer == $q1answer) {
echo $name . " got this right! <br/>";
} else {
echo $name . " got this wrong! <br/>";
}
}
}
How can I get this to work the same as though it was getting the array from an SQL query instead of just my array, for some reason I can't find a way to get this to run.
You can wrap the array in an anonymous class. Single uses like this are a main reason they exist.
$result = new class {
private $data = array
(
array("name"=>"Toby", "q1"=>"1"),
array("name"=>"Phelps", "q1"=>"1"),
array("name"=>"Davies", "q1"=>"1"),
array("name"=>"Keith", "q1"=>"1"),
);
private $data_index = 0;
public $num_rows;
public function __construct() {
$this->num_rows = count($this->data);
}
public function fetch_assoc() {
if (isset($this->data[$this->data_index])) {
$index = $this->data_index++;
return $this->data[$index];
}
}
};
Similar to the earlier answer, I propose a class. Here I would actually name the class, and pass the data to the constructor. The iteration over the array can be done with the current and next methods:
class ResultSet {
private $array = [];
public $num_rows = 0;
public function __construct($data) {
$this->array = $data;
$this->num_rows = count($this->array);
}
public function fetch_assoc() {
$val = current($this->array);
next($this->array);
return $val;
}
}
Until there it would be fixed. You would play with the data in the following:
$result = new ResultSet([
["name"=>"Toby", "q1"=>"1"],
["name"=>"Phelps", "q1"=>"1"],
["name"=>"Davies", "q1"=>"1"],
["name"=>"Keith", "q1"=>"1"],
]);
I did not implement support for count($result) as I don't think that is supported on real mysqli result sets either. You get the count via ->num_rows (like you also do).
Here's my current code:
function get_coins() {
global $conn;
$new_sql = "SELECT * FROM marketcaps ORDER BY cap DESC LIMIT 25";
$new_result = $conn->query($new_sql);
while ($row = $new_result->fetch_assoc()) {
$id = $row["id"];
$coin = $row["coin"];
$cap = $row["cap"];
echo $coin . '~USD,';
}
}
$coins = get_coins();
Here's what I can't figure out:
The line $coins = get_coins(); is echoing all of the data from my function and I don't understand why. I know that my function has this line: echo $coin . '~USD,';
But why is it echoing when I add $coins = get_coins();?
Shouldn't I have to add this instead?
$coins = get_coins();
$echo coins;
Basically I don't want to echo anything, I just want to assign the output to a variable. Is there a simple way to do that?
You need to add a return statement to your function, and as you are dealing with multiple rows, collate them into an array (index by ID).
http://php.net/manual/en/function.return.php
function get_coins()
{
global $conn;
$coins = array();
$new_sql = "SELECT * FROM marketcaps ORDER BY cap DESC LIMIT 25";
if( $new_result = $conn->query($new_sql) )
{
while( $row = $new_result->fetch_assoc() )
{
$coins[ $row["id"] ] = $row["coin"] . '~USD,';
}
}
return ( !empty( $coins ) ) ? $coins : null;
}
Here are the principles that I have baked in with my solution which returns the full resultset array:
Don't use global, pass $conn as a parameter to the function.
Don't declare single use variables, unless it dramatically improves readability or assists in the debugging process.
Only query for the specific columns and rows that you intend to process.
Suggested Code:
function get_coins($conn): array {
return $sql
->query("SELECT id,coin,cap
FROM marketcaps
ORDER BY cap DESC
LIMIT 25")
->fetch_all(MYSQLI_ASSOC);
}
foreach (get_coins($conn) as $row) {
// ... reference $row['id'] , $row['coin'] , $row['cap'] during your processes
}
I have some data in a database column called "gcmregid".
I access this data by calling:
public function getAllUsers() {
$r = mysql_query("select * FROM table");
while ($row = mysql_fetch_array($r)) {
$result = array(
'gcmregid' => $row["gcmregid"]
);
}
return $result;
}
Correct me if I'm wrong, but this should deliver an array, due to result = array?
I took this logic from here: Getting Resource id #3 Error in MySql
.Then I thaught using a loop would be helpful, such as:
$userCount = $db->getUserCount(); // counting said table
$registation_ids = array(); // again create array
for($i=0; $i < $userCount; $i++)
{
$gcmRegId = $db->getGCMRegID($selUsers[$i]);
$row = mysql_fetch_assoc($gcmRegId);
//Add RegIds retrieved from DB to $registration_ids
array_push($registation_ids, $row['gcmregid']); // this creates an array consisting of gcmregid s ?
}
It doesn't work either.
Any input would be really appreciated right now...
Thanks
I'm not sure what's going wrong, but if the problem is that it's returning a single item: that's because you keep making a new array with every iteration, discarding the old one. If you want to collect all the rows, make a new array outside of the loop and then add the results to it:
public function getAllUsers() {
$r = mysql_query("select * FROM table");
$result = array();
while ($row = mysql_fetch_array($r)) {
$result[] = array (
'gcmregid' => $row["gcmregid"]
);
}
return $result;
}
You should consider working more on how you name your functions. If you are trying to get gcmregid, the method should not say getAllUsers. Anyway, did you try the following:
public function get_gcmregid() {
$query_result = mysql_query("select * FROM table");
$row = mysql_fetch_array($query_result);
return $result[0]['gcmregid'];
}
OR if you are trying to get all gcmregid in one shot:
public function get_gcmregid() {
$query_result = mysql_query("select * FROM table");
$i=0;
while ($row = mysql_fetch_array($query_result)){
$result[$i++] = $row['gcmregid'];
}
return $result;
}
I am trying to make a function which converts a mysql query result in to an array
In the function below i'm assuming to have fields isbn, title and rank but this will not always be the case.
Is there a way to retrieve a fields name along with the value without actually knowing any of this information prior? so that this function can be used with any mysql query result.
function
function mysqlToArray($result){
$arr = array();
$numRows = mysql_num_rows($result);//count
if($numRows>0){
for($i=0; $i<$numRows; $i++){
$arr[] = array(
"isbn" => mysql_result($result, $i, "isbn"),
"title" => mysql_result($result, $i, "title"),
"rank" => mysql_result($result, $i, "rank"),
);
}
}
return $arr;
}
example in use
function getProfitableBooks(){
$q = "SELECT isbn, title, rank FROM ".TBL_BOOKS;
$result = mysql_query($q, $this->connection);
if(!$result || (mysql_numrows($result) < 1)){
return null;
}
return $this->mysqlToArray($result);
}
Try looking at this mysql_fetch_array
There is a great PHP function for this mysql_fetch_array
You can view examples mysql_fetch_array in the PHP manual.
Try something like this to get the names of the cols.
my $table = 'name';
my $sth = $dbh->prepare("SELECT * FROM $table WHERE 1=0;");
$sth->execute;
my #cols = #{$sth->{NAME}}; # or NAME_lc if needed
$sth->finish;
foreach ( #cols ) {
printf( "Note: col : %s\n", $_ );
}
Did you check the PHP manual?
mysql_fetch_assoc will be helpful here:
function mysqlToArray($result)
{
$arr = array();
while($arr[] = mysql_fetch_assoc($result));
return $arr;
}
I was wondering if someone could point me in the right direction with a coding issue Im having.
I am running a while loop in PHP comparing a post code to another and each run of the loop generates distance data. What Id like to do is then sort this data and display it.
Usually I'd throw everything into a MySQL database then sort that way but I think thats over kill.
Here's an example of the loop :
while($row = mysql_fetch_array($result))
{
$info = get_driving_information($_POST['customerpostcode'], $row[instructor_postcode]);
echo $row['instructor_name'] . " - " . $info['distance'];
}
I know this is probably PHP 101 but Ive never had to do anything like this before and am not sure how.
Thanks in advance for reading,
Rik
I think this is what you mean:
$rows = array();
while($row = mysql_fetch_array($result))
{
$info = get_driving_information($_POST['customerpostcode'], $row[instructor_postcode]);
$row['distance'] = $info['distance']; // store it in the array
$rows[] = $row;
}
Then use usort to sort the $rows array by the distance key.
What I'd recommend here is storing each distance result in an array and then apply a sort to the array. For example:
$distances = array();
while($row = mysql_fetch_array($result))
{
$info = get_driving_information($_POST['customerpostcode'], $row[instructor_postcode]);
$distances[$info['distance']] = $row['instructor_name'] . " - " . $info['distance'];
}
if(ksort($distances)) {
foreach($distances as $key=>$value) {
echo $value;
}
}
Note that my solution will not work for you if an exact distance appears more than once in the array; If that seems likely then you might need a different array-based solution.
For more information on array sorting, see Sorting Arrays in the PHP manual.
$data = array();
while($row = mysql_fetch_assoc($result)) {
$info = get_driving_information($_POST['customerpostcode'], $row['instructor_postcode']);
$data[$row['instructor_name']] = $info['distance'];
}
asort($data);
foreach ($data as $instructor => $distance) echo "$instructor - $distance<br />\n";
This will sort by instructor name. If you need to sort by distance, just reverse the way data is stored in the temporary array, I.E. $data[$row['distance']] = $info['instructor_name'];.
This will not work if the value you use as the temporary array key appears more than once, for that you would have to use array_multisort().
$data = $instructors = $distances = array();
for ($i = 0; $row = mysql_fetch_assoc($result); $i++) {
$info = get_driving_information($_POST['customerpostcode'], $row['instructor_postcode']);
$instructors[$i] = $row['instructor_name'];
$distances[$i] = $row['distance'];
$data[$i] = array('instructor'=>$row['instructor_name'],'distance'=>$info['distance']);
}
array_multisort($instructors,SORT_DESC,$distances,SORT_ASC,$data);
foreach ($data as $entry) echo "{$entry['instructor']} - {$entry['distance']}<br />\n";
This will work even if you have same instructor_name or distances several time in the array. Additionally buy modifying cmp() function you can sort whole thing by any other criteria.
$drivers = array();//initialising an array
while($row = mysql_fetch_array($result))
{
$info = get_driving_information($_POST['customerpostcode'], $row[instructor_postcode]);
$drivers[]=row;//adding new item to array
}
$drivers = usort($drivers,'cmp'); // sorting array using custom comparison function "cmp()"
foreach ($drivers as $driver) //printing results
echo $driver['instructor_name'] . " - " . $driver['distance'];
//custom comparison function
function cmp($a, $b) //returns +1 if $a > $b, -1 if $a < $b, else returns 0
{
if ($a['distance']>$b['distance'])
return 1;
if ($a['distance']<$b['distance'])
return -1;
return 0;
//quicker solution is to "return $a['distance']-$b['distance'];"
}