What is the problem with my mysql array extraction below:
$mysql_array = mysql_query("SELECT * FROM table1 WHERE uid1='$uid1'");
$array = array();
while($row = mysql_fetch_assoc($mysql_array)){
$array[] = $row;
}
$array = array_unique($array);
$array = array_reverse($array);
$emails = array();
$numbers = array();
foreach($array as $row){
$uid2 = $row['uid2'];
$number = number($uid2);
if(strlen($number) > 9){
$numbers[] = array('uid2' => $uid2, 'number' => $number);
}
else{
$email = email($uid2);
$emails[] = array('uid2' => $uid2, 'email' => $email);
}
}
$numbers = array_unique($numbers);
$emails = array_unique($emails);
var_dump($numbers);
var_dump($emails);
There must be something I need to do to convert the "Resource" from mysql into an array.
There must be a problem with the above code.
This is what I am getting on the var_dumps: array(0) { }
and array(1) { [0]=> array(2) { ["uid2"]=> NULL ["email"]=> NULL } }
Look at this foreach:
foreach($array as $uid2){
$uid2 = $array['uid2'];
$number = number($yfbid);
if(strlen($number) > 9){
$numbers[] = array('uid2' => $uid2, 'number' => $number);
}
else{
$email = email($uid2);
$yfbid[] = array('uid2' => $uid2, 'email' => $email);
}
}
You iterate all positions of array and call them $uid2. Then, in the first line you do $uid2 = $array['uid2'];. You loose your array position.
Maybe you wanted something like:
$var = $uid2['uid2'];
I think this is what you're trying to do:
$result = mysql_query("SELECT DISTINCT * FROM table1 WHERE uid1 = '{$uid1}' ORDER BY /* insert column name here, followed by ASC or DESC */");
$table = array();
while ($row = mysql_fetch_assoc($result))
$table[] = $row;
// at this point, each entry in the $table array is one row from 'table1'.
// shouldn't need to do array_unique or array_reverse with the modified SQL query above.
$numbers = $emails = array();
foreach ($table as $row)
{
$number = number($row["uid2"]);
if (strlen($number) > 9 && !in_array($numbers[$row["uid2"]], $number, true))
$numbers[$row["uid2"]][] = $number;
else
{
$email = email($row["uid2"]);
if (!in_array($emails[$row["uid2"]], $email, true))
$emails[$row["uid2"]][] = $email;
}
}
// shouldn't need to do array_unique with the if-statements above
var_dump($numbers);
var_dump($emails);
EDIT Answering question from comments:
Based on the logic you are using, the result will probably be the same. My example above will allow this scenario for $numbers, while your example will not:
array(2)
{
[123] => array(2)
{
[0] => 1234567890, // same as $numbers[456][0]
[1] => 9876543210
},
[456] => array(1)
{
[0] => 1234567890 // same as $numbers[123][0]
}
}
But based on the way that $number is generated based on $uid2, you probably won't see any difference. What I mean is that, if number(123) returns 1234567890, then number(456) probably will not return 1234567890, so you probably wouldn't ever run into a scenario where you would see a difference.
EDIT 2 After thinking about this some more, I'm betting that your code can be greatly simplified to this:
// only selecting uid2 from the table
$result = mysql_query("SELECT DISTINCT uid2 FROM table1 WHERE uid1 = '{$uid1}' ORDER BY /* insert column name here, followed by ASC or DESC */");
$output = array();
while (list($uid2) = mysql_fetch_row($result))
{
$number = number($uid2);
if (strlen($number) > 9)
$output[$uid2]["number"] = $number;
else
$output[$uid2]["email"] = email($uid2);
}
var_dump($output);
LAST EDIT (Hopefully):
// only selecting uid2 from the table
$result = mysql_query("SELECT DISTINCT uid2 FROM table1 WHERE uid1 = '{$uid1}' ORDER BY /* insert column name here, followed by ASC or DESC */");
$numbers = $emails = array();
while (list($uid2) = mysql_fetch_row($result))
{
$number = number($uid2);
if (strlen($number) > 9)
$numbers[$uid2] = $number;
else
$emails[$uid2] = email($uid2);
}
var_dump($numbers);
var_dump($emails);
foreach($array as $uid2){
$uid2 = $array['uid2'];
makes no sense. Loop over each element in $array and assign the elements to $uid2 sequentially, then kill that assigned and pull a fixed value from the same array?
As well, where is $yfbid set? From your code sample, it's undefined, and you try to convert this undefined value to a number, then check the string length of that number. Why not just strlen($yfbid) and let PHP handle the conversion?
Related
I want to sort a returned value from a while loop here is my code
public function Getter($stream){
$sql1 = "SELECT reg_no FROM hs_registration ";
$sql1.= "JOIN hs_students USING(reg_no) WHERE class_id = 2";
$result1 = $database->query($sql1);
$num1 = $database->num_rows($result1);
if($num1 > 0){
$records = array();
$number_of_sub = getNoSub();
while($row = mysqli_fetch_array($result1)){
//return individual score
$total = $this->totalScoreSpreadSheet($row['reg_no'], $stream);
$flyAvg = $total / $number_of_sub;
$records[] = number_format($flyAvg,2).' '.$row['reg_no'];
}
}
return $records;
}
$averages = Getter($stream);
foreach ($averages as $avg){
echo $avg
}
Please, I want to sort the output based on the avg with the students reg_no appended to it
Output
54.20 FMS34
91.00 FMS51
72.16 FMS64
44.81 FMS23
68.52 FMS30
48.65 FMS37
My desired output is
Output
91.00 FMS51
72.16 FMS64
68.52 FMS30
54.20 FMS34
48.65 FMS37
44.81 FMS23
If your leading numbers are always two digits, then a decimal point, the two digits, then rsort($records); would suffice.
If they might be anything else, then keep a separate sorting array, then use array_multisort() to modify the $records.
public function Getter($stream): array
{
$sql = "SELECT reg_no
FROM hs_registration
JOIN hs_students USING(reg_no)
WHERE class_id = 2";
$flyAvgs = [];
$records = [];
$number_of_sub = getNoSub();
foreach ($database->query($sql) as $row) {
$total = $this->totalScoreSpreadSheet($row['reg_no'], $stream);
$flyAvg = $total / $number_of_sub;
$flyAvgs[] = $flyAvg;
$records[] = number_format($flyAvg, 2) . ' ' . $row['reg_no'];
}
array_multisort($flyAvgs, SORT_DESC, $records);
return $records;
}
I have a SQLite3 database which contains 4 tables with 9 rows each.
I've tried to do each one of the arrays one-by-one, with basically the same code as below (everything in the foreach loop), and it worked fine. I guess I just made some stupid mistakes (I don't really use PHP, this is pretty much the only project I've used it in). I tried to fix it, but somehow PHP is not really friendly today.
Currently the code below returns a JSON with 4 empty arrays.
<?php
header('Content-type: application/json');
$db = new PDO('sqlite:whad.db')or die('Could not open database');
$arDaniel = array();
$arAndi = array();
$arDave = array();
$arSimon = array();
for ($j=0; $j < 4; $j++) {
$name;
$arr;
if (j == 0) {
$name = 'Daniel';
$arr = $arDaniel;
}
elseif (j == 1) {
$name = 'Andi';
$arr = $arAndi;
}
elseif (j == 2) {
$name = 'Dave';
$arr = $arDave;
}
elseif (j == 3) {
$name = 'Simon';
$arr = $arSimon;
}
$query = "SELECT Datum, ID, RR, RL, KB, BD, SD, KH, Reihenfolge FROM $name ORDER BY date(Datum)";
$i = 1;
foreach($res = $db->query($query) as $value) {
$curr = array();
array_push($curr["Datum"] = $value[0]);
array_push($curr["ID"] = $value[1]);
array_push($curr["RR"] = $value[2]);
array_push($curr["RL"] = $value[3]);
array_push($curr["KB"] = $value[4]);
array_push($curr["BD"] = $value[5]);
array_push($curr["SD"] = $value[6]);
array_push($curr["KH"] = $value[7]);
array_push($curr["Reihenfolge"] = $value[8]);
array_push($arr[$i] = $curr);
$i++;
}
}
$json = array(
"Daniel" => $arDaniel,
"Andi" => $arAndi,
"Dave" => $arDave,
"Simon" => $arSimon
);
echo json_encode($json);
$db = NULL;
?>
EDIT: Removed quotes around $curr.
You have many unnecassary variables with the same data.
You simply could do the following
<?php
header('Content-type: application/json');
$db = new PDO('sqlite:whad.db')or die('Could not open database');
$json = array(
"Daniel" => array(),
"Andi" => array(),
"Dave" => array(),
"Simon" => array()
);
foreach($json as $name => &$arr){
$query = "SELECT Datum, ID, RR, RL, KB, BD, SD, KH, Reihenfolge FROM $name ORDER BY date(Datum)";
$stmt = $db->query($query);
//now comes the trick, that you tell pdo to fecth them already as array
$arr = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
unset($arr);
echo json_encode($json);
?>
Look at the first example here: http://php.net/manual/de/pdostatement.fetchall.php
Also note the & before $arr, which will handle the $arr variable as reference (also the unset, because after the last pass, it would still be set, this is just good style to clean up)
Update:
As in the other answer you have to use PDO::FETCH_ASSOC to get an array with only the index names.
There are more than one error in your code:
$arDaniel = array();
$arAndi = array();
$arDave = array();
$arSimon = array();
for ($j=0; $j < 4; $j++) {
$name; # <---
$arr; # <---
This sort of ‘declaration’ in php is unnecessary, you can remove $name and $arr (it's not an error, btw);
if (j == 0) { # <---
In the for loop you use $j, you can't use j here: replace it with $j (in php variables are ever prepended by $);
$name = 'Daniel';
$arr = $arDaniel; # <---
By this assignment, you want change the original array, but with this assignment by value, you in fact create a copy of $arDaniel, and new elements are added only to $arr, not to $arDaniel; to do this, you have to do an assignment by reference through & keyword: replace this (and following similar) line with $arr = &$arDaniel;
}
elseif (j == 1) { # <--- see above
$name = 'Andi';
$arr = $arAndi; # <--- see above
}
elseif (j == 2) { # <--- see above
$name = 'Dave';
$arr = $arDave; # <--- see above
}
elseif (j == 3) { # <--- see above
$name = 'Simon';
$arr = $arSimon; # <--- see above
}
$query = "SELECT Datum, ID, RR, RL, KB, BD, SD, KH, Reihenfolge FROM $name ORDER BY date(Datum)";
$i = 1; # <---
The query is formally correct, but I don't know your table structure. $i = 1; is unnecessary (see below);
foreach($res = $db->query($query) as $value) {
$curr = array();
array_push($curr["Datum"] = $value[0]); # <---
array_push($curr["ID"] = $value[1]); # <---
array_push($curr["RR"] = $value[2]); # <---
array_push($curr["RL"] = $value[3]); # <---
array_push($curr["KB"] = $value[4]); # <---
array_push($curr["BD"] = $value[5]); # <---
array_push($curr["SD"] = $value[6]); # <---
array_push($curr["KH"] = $value[7]); # <---
array_push($curr["Reihenfolge"] = $value[8]); # <---
array_push($arr[$i] = $curr); # <---
$i++; # <---
}
}
The array_push syntax is not correct (see manual page): the correct syntax is array_push( $existentArray, $newElement ). In addition, you can't use array_push to add an associative value, you can use it only for numeric key. Change $curr assignments simply in $curr['Datum'] = $value[0]; etc...
To append $curr to $arr, you have to change the line in array_push( $arr, $curr ) or (better, as php recommends if only one element is appended) $arr[] = $curr;. After these changes, the $i++; line can be deleted.
$json = array(
"Daniel" => $arDaniel,
"Andi" => $arAndi,
"Dave" => $arDave,
"Simon" => $arSimon
);
echo json_encode($json);
$db = NULL;
Now your script is clean (I hope).
Your script remain a bit redundant. You can simplify it in this way:
$array = array( 'Daniel'=>array(), 'Andi'=>array(), 'Dave'=>array(), 'Simon'=>array() );
foreach( $array as $key => &$val )
{
$query = "SELECT Datum, ID, RR, RL, KB, BD, SD, KH, Reihenfolge FROM $key ORDER BY date(Datum)";
$result = $db->query( $query );
$val = $result->fetchAll( PDO::FETCH_ASSOC );
}
$json = json_encode( $array );
echo $json;
By this way, you init an array with names as key, then, in a foreach loop by reference (&$val) you perform a sql query searching in table $key and you fetch all results directly in array (in this example the values are stored as associative arrays, like in your example, but you can use PDO::FETCH_OBJ to store data as object). At the end, you encode the array end echo it.
Edit:
I see a previous answer nearly identical to mine...
BTW, I leave mine because I have spent a lot of time to explain various errors...
This is my code
mysql_select_db("my_db", $con);
$result = mysql_query("SELECT title,text,date FROM news limit 5");
is there any way to extract title,text,date from $result and put them into 3 dimensional array?
What about
$result = mysql_query("SELECT title,text,date FROM news limit 5");
$array = array();
$i = 0;
while( $row = mysql_fetch_assoc( $result ) {
$array[$i] = array();
// i'm just guessing at what sort of array you want
$array[$i][$row['title'] = array( 'text' => $row['text'], 'date' => $row['date'] );
$i++;
}
I'd be interested to know what the ... you need a three-dimensional array for but ok:
$dim = array();
$result = mysql_query(...);
while ( $row = mysql_fetch_assoc($result) )
// Whatever you want to save in that particular bucket,
// I'll be using the result set
$dim[$row['title']][$row['text']][$row['date']] = $row;
Strange, ...
If we are already guessing, here is mine:
$results = array();
while(($row = mysql_fetch_assoc($result))) {
$results[] = $row;
}
which will create an array like this:
array(array('title' => 'foo',
'text' => 'bar',
'date' => 'baz'),
//...
)
I think what you're after is actually a two-dimensional array (in which the second dimension has three elements). (Correct me if I'm wrong.)
One of the comments under the documentation of mysql_fetch_array has an answer to this:
(Disclamer: This code is unnecessarily verbose. I prefer not changing it though as I have copied it from the above web-page. For improvements, I refer to the comments.)
<?php
function mysql_fetch_rowsarr($result, $numass=MYSQL_BOTH) {
$i=0;
$keys=array_keys(mysql_fetch_array($result, $numass));
mysql_data_seek($result, 0);
while ($row = mysql_fetch_array($result, $numass)) {
foreach ($keys as $speckey) {
$got[$i][$speckey]=$row[$speckey];
}
$i++;
}
return $got;
}
?>
You should then be able to use this function as
<?
mysql_select_db("my_db", $con);
$result = mysql_query("SELECT title,text,date FROM news limit 5");
$arr = mysql_fetch_rowsarr($result);
$row_2_title = $arr[2]['title'];
?>
this is continued from another question i asked:
Listing out JSON data?
my search only returns 1 item, im pretty sure the problem lies somewhere in my php, im not too sure if im adding to the array properly, or it could be the javascript wich you can see on the above link, but i doubt it.
my php code:
function mytheme_ajax_response() {
$search = $_GET["search_text"];
$result = db_query("SELECT nid FROM {node} WHERE title LIKE '%s%' AND type = 'product_collection'", $search);
$noder = array();
while ($record = db_fetch_object($result)) {
$noder[] = $record;
}
$matches = array();
$i = 0;
foreach ($noder as $row) {
$node = node_load($row->nid);
$termlink = db_fetch_object(db_query("SELECT tid FROM {term_node} WHERE nid = %d", $row->nid));
$matches[$i]['title'] = $node->title;
$matches[$i]['link'] = $termlink->tid;
}
++$i;
$hits = array();
$hits['matches'] = $matches;
print json_encode($hits);
exit();
}
You appear to be incrementing your $i variable AFTER the foreach loop. Therefore, $i is always 0 throughout your loop, so you are always setting the title and link values for $matches[0].
Try this:
function mytheme_ajax_response() {
$search = $_GET["search_text"];
$result = db_query("SELECT nid FROM {node} WHERE title LIKE '%s%' AND type = 'product_collection'", $search);
$noder = array();
while ($record = db_fetch_object($result)) {
$noder[] = $record;
}
$matches = array();
foreach ($noder as $row) {
$node = node_load($row->nid);
$termlink = db_fetch_object(db_query("SELECT tid FROM {term_node} WHERE nid = %d", $row->nid));
$matches[] = array('title' => $node->title, 'link' => $termlink->tid);
}
$hits = array();
$hits['matches'] = $matches;
print json_encode($hits);
exit();
}
The $i wasn't incrementing the code as it was outside the foreach loop. By making a second array as above you don't need it anyway... (hope this works)...
I have an array of my inventory (ITEMS A & B)
Items A & B are sold as sets of 1 x A & 2 x B.
The items also have various properties which don't affect how they are distributed into sets.
For example:
$inventory=array(
array("A","PINK"),
array("A","MAUVE"),
array("A","ORANGE"),
array("A","GREY"),
array("B","RED"),
array("B","BLUE"),
array("B","YELLOW"),
array("B","GREEN"),
array("B","BLACK")
);
I want to redistribute the array $inventory to create $set(s) such that
$set[0] => Array
(
[0] => array(A,PINK)
[1] => array(B,RED)
[2] => array(B,BLUE)
)
$set[1] => Array
(
[0] => array(A,MAUVE)
[1] => array(B,YELLOW)
[2] => array(B,GREEN)
)
$set[2] => Array
(
[0] => array(A,ORANGE)
[1] => array(B,BLACK)
[2] => NULL
)
$set[3] => Array
(
[0] => array(A,GREY)
[1] => NULL
[2] => NULL
)
As you can see. The items are redistributed in the order in which they appear in the inventory to create a set of 1 x A & 2 x B. The colour doesn't matter when creating the set. But I need to be able to find out what colour went into which set after the $set array is created. Sets are created until all inventory is exhausted. Where an inventory item doesn't exist to go into a set, a NULL value is inserted.
Thanks in advance!
I've assumed that all A's come before all B's:
$inventory=array(
array("A","PINK"),
array("A","MAUVE"),
array("A","ORANGE"),
array("A","GREY"),
array("B","RED"),
array("B","BLUE"),
array("B","YELLOW"),
array("B","GREEN"),
array("B","BLACK")
);
for($b_start_index = 0;$b_start_index<count($inventory);$b_start_index++) {
if($inventory[$b_start_index][0] == 'B') {
break;
}
}
$set = array();
for($i=0,$j=$b_start_index;$i!=$b_start_index;$i++,$j+=2) {
isset($inventory[$j])?$temp1=$inventory[$j]:$temp1 = null;
isset($inventory[$j+1])?$temp2=$inventory[$j+1]:$temp2 = null;
$set[] = array( $inventory[$i], $temp1, $temp2);
}
To make it easier to use your array, you should make it something like this
$inv['A'] = array(
'PINK',
'MAUVE',
'ORANGE',
'GREY'
);
$inv['B'] = array(
'RED',
'BLUE',
'YELLOW',
'GREEN',
'BLACK'
);
This way you can loop through them separately.
$createdSets = $setsRecord = $bTemp = array();
$bMarker = 1;
$aIndex = $bIndex = 0;
foreach($inv['A'] as $singles){
$bTemp[] = $singles;
$setsRecord[$singles][] = $aIndex;
for($i=$bIndex; $i < ($bMarker*2); ++$i) {
//echo $bIndex.' - '.($bMarker*2).'<br/>';
if(empty($inv['B'][$i])) {
$bTemp[] = 'null';
} else {
$bTemp[] = $inv['B'][$i];
$setsRecord[$inv['B'][$i]][] = $aIndex;
}
}
$createdSets[] = $bTemp;
$bTemp = array();
++$bMarker;
++$aIndex;
$bIndex = $bIndex + 2;
}
echo '<pre>';
print_r($createdSets);
print_r($setsRecord);
echo '</pre>';
To turn your array into an associative array, something like this can be done
<?php
$inventory=array(
array("A","PINK"),
array("A","MAUVE"),
array("A","ORANGE"),
array("A","GREY"),
array("B","RED"),
array("B","BLUE"),
array("B","YELLOW"),
array("B","GREEN"),
array("B","BLACK")
);
$inv = array();
foreach($inventory as $item){
$inv[$item[0]][] = $item[1];
}
echo '<pre>';
print_r($inv);
echo '</pre>';
Maybe you can use this function, assuming that:
... $inventory is already sorted (all A come before B)
... $inventory is a numeric array staring at index zero
// $set is the collection to which the generated sets are appended
// $inventory is your inventory, see the assumptions above
// $aCount - the number of A elements in a set
// $bCount - the number of B elements in a set
function makeSets(array &$sets, array $inventory, $aCount, $bCount) {
// extract $aItems from $inventory and shorten $inventory by $aCount
$aItems = array_splice($inventory, 0, $aCount);
$bItems = array();
// iterate over $inventory until a B item is found
foreach($inventory as $index => $item) {
if($item[0] == 'B') {
// extract $bItems from $inventory and shorten $inventory by $bCount
// break out of foreach loop after that
$bItems = array_splice($inventory, $index, $bCount);
break;
}
}
// append $aItems and $bItems to $sets, padd this array with null if
// less then $aCount + $bCount added
$sets[] = array_pad(array_merge($aItems, $bItems), $aCount + $bCount, null);
// if there are still values left in $inventory, call 'makeSets' again
if(count($inventory) > 0) makeSets($sets, $inventory, $aCount, $bCount);
}
$sets = array();
makeSets($sets, $inventory, 1, 2);
print_r($sets);
Since you mentioned that you dont have that much experience with arrays, here are the links to the php documentation for the functions I used in the above code:
array_splice — Remove a portion of the array and replace it with something else
array_merge — Merge one or more arrays
array_pad — Pad array to the specified length with a value
This code sorts inventory without any assumption on inventory ordering. You can specify pattern (in $aPattern), and order is obeyed. It also fills lacking entries with given default value.
<?php
# config
$aInventory=array(
array("A","PINK"),
array("A","MAUVE"),
array("A","ORANGE"),
array("A","GREY"),
array("B","RED"),
array("B","BLUE"),
array("B","YELLOW"),
array("B","GREEN"),
array("B","BLACK"),
array("C","cRED"),
array("C","cBLUE"),
array("C","cYELLOW"),
array("C","cGREEN"),
array("C","cBLACK")
);
$aPattern = array('A','B','A','C');
$mDefault = null;
# preparation
$aCounter = array_count_values($aPattern);
$aCurrentCounter = $aCurrentIndex = array_fill_keys(array_unique($aPattern),0);
$aPositions = array();
$aFill = array();
foreach ($aPattern as $nPosition=>$sElement){
$aPositions[$sElement] = array_keys($aPattern, $sElement);
$aFill[$sElement] = array_fill_keys($aPositions[$sElement], $mDefault);
} // foreach
$nTotalLine = count ($aPattern);
$aResult = array();
# main loop
foreach ($aInventory as $aItem){
$sElement = $aItem[0];
$nNeed = $aCounter[$sElement];
$nHas = $aCurrentCounter[$sElement];
if ($nHas == $nNeed){
$aCurrentIndex[$sElement]++;
$aCurrentCounter[$sElement] = 1;
} else {
$aCurrentCounter[$sElement]++;
} // if
$nCurrentIndex = $aCurrentIndex[$sElement];
if (!isset($aResult[$nCurrentIndex])){
$aResult[$nCurrentIndex] = array();
} // if
$nCurrentPosition = $aPositions[$sElement][$aCurrentCounter[$sElement]-1];
$aResult[$nCurrentIndex][$nCurrentPosition] = $aItem;
} // foreach
foreach ($aResult as &$aLine){
if (count($aLine)<$nTotalLine){
foreach ($aPositions as $sElement=>$aElementPositions){
$nCurrentElements = count(array_keys($aLine,$sElement));
if ($aCounter[$sElement] != $nCurrentElements){
$aLine = $aLine + $aFill[$sElement];
} // if
} // foreach
} // if
ksort($aLine);
# add empty items here
} // foreach
# output
var_dump($aResult);
Generic solution that requires you to specify a pattern of the form
$pattern = array('A','B','B');
The output will be in
$result = array();
The code :
// Convert to associative array
$inv = array();
foreach($inventory as $item)
$inv[$item[0]][] = $item[1];
// Position counters : int -> int
$count = array_fill(0, count($pattern),0);
$out = 0; // Number of counters that are "out" == "too far"
// Progression
while($out < count($count))
{
$elem = array();
// Select and increment corresponding counter
foreach($pattern as $i => $pat)
{
$elem[] = $inv[ $pat ][ $count[$i]++ ];
if($count[$i] == count($inv[$pat]))
$out++;
}
$result[] = $elem;
}