Weird incremented query result in a while - php

I don't understand why the result of the '$taille' array begin to the key [1] instead of key [0]? So it s displaying 3 results instead of 4 (occulting the first result)...
<?php
$req = $bdd->prepare('SELECT size FROM tailles_produits WHERE id_produit = ?');
$req->execute(array($_GET['id']));
$donnees = $req->fetch();
$numb_taille = array();
$taille = array();
$i = 0;
while($donnees = $req->fetch())
{
$i++;
$taille[$i] = $donnees['size'];
$numb_taille['total'] = $i;
}
$total = $numb_taille['total'];
echo '<pre>';
print_r ($taille);
echo '</pre>';
$req->closeCursor();
?>
Which gives
ARRAY
(
[1] => S
[2] => M
[3] => L
)
Instead of
ARRAY
(
[1] => XS
[2] => S
[3] => M
[4] => L
)
Can anyone help me with this pleas?

PHP arrays start with 0, so all you need to do is move your i++ down until after you're done using the data from that index
<?php
$req = $bdd->prepare('SELECT size FROM tailles_produits WHERE id_produit = ?');
$req->execute(array($_GET['id']));
$donnees = $req->fetch();
$numb_taille = array();
$taille = array();
$i = 0;
while($donnees = $req->fetch())
{
$taille[$i] = $donnees['size'];
$numb_taille['total'] = $i;
$i++; //iterate after your calculations are done
}
$total = $numb_taille['total'];
echo '<pre>';
print_r ($taille);
echo '</pre>';
$req->closeCursor();
?>

The problem is that you have an extra
$donnees = $req->fetch();
statement before the loop that fills in $taille. So the data from the first row is being fetched but not stored in the array.

It is because you increment $i before using it as a key for the new array item.
Do the increment at the end of your while loop.

Related

How do I print a specific value within a 2D array in PHP, that's not entirely 2D?

I have an array in PHP which is established from my database, which will be formatted as such:
[ "Folder1",
["Content1", "Content2", "Content3"],
"Folder2",
["Content1", "Content2", "Content3"]
]
I have the current code for this process
<?php
$sql = ("SELECT FlashCardFolderName, FlashCardSetName FROM FlashCardFolders, FlashCardSets WHERE FlashCardFolderUserID = " . $_SESSION["id"] . " AND FlashCardSetFlashCardFolderID = FlashCardFolderID ORDER BY FlashCardFolderName");
$result = $db->get_con()->query($sql);
if($result->num_rows > 0){
$temp = "";
$foldersAndSets = array();
$tempSet = array();
while ($row = $result->fetch_assoc()){
if($temp===$row["FlashCardFolderName"]){
array_push($tempSet, $row["FlashCardSetName"]);
} else{
array_push($foldersAndSets, $tempSet);
$tempSet = array();
array_push($foldersAndSets, $row["FlashCardFolderName"]);
array_push($tempSet, $row["FlashCardSetName"]);;
$temp = $row["FlashCardFolderName"];
}
}
array_push($foldersAndSets, $tempSet);
array_shift($foldersAndSets);
echo json_encode($foldersAndSets);
} else{
echo "<h6>Looks like there's nothing here...</h6>";
}
$length = sizeof($foldersAndSets);
for ($i = 0; $i < $length; $i++){
$secondDimension = sizeof($foldersAndSets[$i+1]);
for($j = 0; $j < $foldersAndSets; $j++) {
echo "$foldersAndSets[$i][$j+1]";
}
}
?>
But it seems it's not working the way I want it to. Any ideas as to what I could be doing wrong?
First of all I'm suggestion to you to make a useful format of your input data, I mean it would be better to reformat your input array. For example, with structure like Folder -> array of Contents:
$reformatted = [];
$tmp = '';
foreach($foldersAndSets as $ind=>$txt){
if ($ind % 2 == 0){ // if this is a 1-st, 3-rd, 5-th etc value -> Folders
$reformatted[$txt] = [];
$tmp = $txt;
} else { // if this is a 2-nd, 4-th etc value -> Content
$reformatted[$tmp] = $txt;
}
}
This will create an array like:
Array
(
[Folder1] => Array
(
[0] => Content1
[1] => Content2
[2] => Content3
)
[Folder2] => Array
(
[0] => Content1
[1] => Content2
[2] => Content3
)
)
With this array you can work in further. Now you can get any value you need with help of a simple foreach loop:
foreach($reformatted as $fold=>$cont){
echo $fold.PHP_EOL.PHP_EOL;
foreach($cont as $item){
echo $item.PHP_EOL;
}
echo PHP_EOL;
}
Output:
Folder1
Content1
Content2
Content3
Folder2
Content1
Content2
Content3
Demo
Note: you can replace your second part(from $length = sizeof($foldersAndSets); and below) of code with this.

Combining certain strings in an array based on positive matches against mySQL table

I have a multidimensional array composed of strings of various length as follow:
$a =
Array ( [0]
Array ( [0] AQWER, [1] CFG, [2] JUHTYREWQ, [3] K, [4] LO ),
Array [1]
Array ( [0] VFG, [1] yhtredw, [2] koeutydjwiq, [3] bg, [4] hytefs, [5] M),
Array [2]
Array ( [0] BHTWQ, [1] BH, [2] NJUy))
Equally, I have a mySQL table containing the following values
myTable
AQWER
CFG
JUHTYREWQ_K_LO
VFG
yhtredw
bg_hytefs
BHTWQ
BH_ NJUy
Desired outcome
I am trying to test and reformulate the array based on matches in the SQL table so that it looks like this:
$a =
Array ( [0]
Array ( [0] AQWER, [1] CFG, [2] JUHTYREWQ_K_LO ),
Array [1]
Array ( [0] VFG, [1] yhtredw, [2] koeutydjwiq, [3] bg_hytefs, [5] M),
Array [2]
Array ( [0] BHTWQ, [1] BH_NJUy))
And to still show values that have not been found (e.g. koeutydjwiq)
What I have tried so far:
I received great help in helping me manipulate $a so as to be able to test 1 string, 2 strings and 3 strings combinations.
However my code does not successfully pick up string combinations (that are definitely there in both the Array and the Table) and as a result, does not reformat the original array $a and I can't quite figure out why.
In fact more specifically, when calling the print_r($para) in the IF statements, I get .........
Here is my code:
foreach ($a as $val) {
for ($i=0; $i<count($val); $i++) {
// A_B_C
if (isset($val[$i+2])) {
$exagon = array();
$exagon = $val[$i] . '_' . $val[$i+1] . '_' . $val[$i+2];
$conn = mysqli_connect("localhost:8889","root","root","myDB");
$query = "SELECT * FROM `myTable` WHERE LIST = '".$exagon."'";
$para = array(
);
$result = mysqli_query($conn, $query);
//echo $result;
while($row = mysqli_fetch_array($result)) {
$para[] = array($row['LIST']);
}
if (isset($para) && !empty($para)) {
print_r($para);
array_splice($a, $i, $i+2, $para);
$i=$i+2;
}
else {
unset($para);
unset($exagon);
}
}
// A_B
elseif (isset($val[$i+1])) {
$exagon = array();
$exagon = $val[$i] . '_' . $val[$i+1];
$conn = mysqli_connect("localhost:8889","root","root","myDB");
$query = "SELECT * FROM `myTable` WHERE LIST = '".$exagon."'";
$para = array(
);
$result = mysqli_query($conn, $query);
while($row = mysqli_fetch_array($result)) {
$para[] = array($row['LIST']);
}
if (isset($para) && !empty($para)) {
print_r($para);
array_splice($a, $i, $i+1, $para);
$i=$i+1;
}
else {
unset($para);
}
}
// A
else {
echo $val[$i];
}
}
}
Admittedly, through research, I have found posts and manuals to guide me on using array_splice and calling out variables in a SQL query but it is quite possible multiple errors are present in this code
Please use below code. theses dynamic array also it's work check with your array data it's working fine
$conn = mysqli_connect("localhost:8889","root","root","myDB");
//These will create commbination
$finalArray = array();
$sampleArray = array(array('AQWER','CFG','JUHTYREWQ','K','LO'),array('mno','xxy','kkl'));
foreach($sampleArray as $key=>$val){
$combincationArr = array();
foreach($val as $k1=>$v1){
$combincationArr[] = $v1;
$prevStr = $v1;
for ($i=($k1+1); $i<(count($val)); $i++) {
$prevStr .= '_'.$val[$i];
$combincationArr[] = $prevStr;
}
}
if(!empty($combincationArr)){
$finalArray[$key] = $combincationArr;
}
}
$destArr = array();
foreach($finalArray as $key=>$val){
if(!empty($val)){
$para = array();
$query = "SELECT * FROM `myTable` WHERE FIND_IN_SET (LIST,'". implode(',', $val)."')";
$result = mysqli_query($conn, $query);
while($row = mysqli_fetch_array($result)) {
$para[] = array($row['LIST']);
}
$destArr[] = $para;
}
}
echo "<pre>";print_r($destArr);die;

Using foreach in a while loop

Problem: I have a foreach loop in a while loop. for each row selected from the database the foreach loop has to done. but when I echo $row it seems like it immedieatly puts out all the rows and then afterwards goes trough the foreach just once. I've read through the manuals but it did not help me unfortunately.
Code:
$conn = oci_connect('login', 'pass', '127.0.0.1/xe');
$stid = oci_parse($conn, 'select TOKEN, SECRET from TOKENS');
oci_execute($stid);
$time=20:00
while(($row = oci_fetch_row($stid)) != false) {
$fitbit->setOAuthDetails($row[0], $row[1]);
//retreive steps. (with date and time)
$steps = $fitbit->getTimeSeries('steps', '2015-06-01', '2015-07-01');
$n=0;
foreach ($steps as $value){
$sqlArray[$n]['dateTime']=$value->dateTime;
$sqlArray[$n]['time'] = $time;
$sqlArray[$n]['steps'] = $value->value;
$n++;
}
}
It's probably me overlooking something but I hope my question can be answered.
Updated code:
$time="12:00";
$n=0;
$x=0;
while(($row = oci_fetch_row($stid)) != false) {
$sqlArray[$n]['token'] = $row[0];
$sqlArray[$n]['secret'] = $row[1];
echo 'hoi';
$fitbit->setOAuthDetails($sqlArray[$n]['token'], $sqlArray[$n]['secret']);
//retreive steps. (with date and time)
$steps = $fitbit->getTimeSeries('steps', '2015-06-01', '2015-07-01');
foreach ($steps as $value){
$sqlArray[$n][$x]['dateTime']=$value->dateTime;
$sqlArray[$n][$x]['time'] = $time;
$sqlArray[$n][$x]['steps'] = $value->value;
$x++;
}
//retreive calories and add to sqlArray where date matches. (used for testing now, when acces to intraday api the outcommented code below will be used.
$calories = $fitbit->getTimeSeries('caloriesOut', '2015-06-01', '2015-07-01');
$x=0;
foreach ($calories as $value){
$checkdate=$value->dateTime;
if ($sqlArray[$n][$x]['dateTime'] == $checkdate){
$sqlArray[$n][$x]['calories'] = $value->value;
}
$x++;
}
$n++;
};
Now my output is as follows:
Array
(
[0] => Array
(
[token] => token
[secret] => secret
[0] => Array
(
[dateTime] => 2015-06-01
[time] => 12:00
[steps] => 8046
[calories] => 2785
)
Which iteraties nicely over the tokens from the database. Though, After the first iteration the calories are dropped:
[1] => Array
(
[token] => token
[secret] => secret
[31] => Array
(
[dateTime] => 2015-06-01
[time] => 12:00
[steps] => 8046
)
I guess I'm doing something wrong again... I think it has to do with the $x variable, but I am not sure.
Yep it's me! I placed $x=0; in the while loop now and it works good!
Thanks for the help!
Please do like below:-
$conn = oci_connect('login', 'pass', '127.0.0.1/xe');
$stid = oci_parse($conn, 'select TOKEN, SECRET from TOKENS');
oci_execute($stid);
$time='20:00';
$new_array = array(); // create a new array
$i = 0;
while(($row = oci_fetch_row($stid)) != false) {
$new_array[$i][] = $row[0]; // assign values to that new array
$new_array[$i][] = $row[1]; // assign values to that new array
$i++;
}
$sqlArray = array(); // create another new array
$n=0;
foreach($new_array as $array){
$fitbit->setOAuthDetails($array[0], $array[1]); // iterate on first array values
//retreive steps. (with date and time)
$steps = $fitbit->getTimeSeries('steps', '2015-06-01', '2015-07-01');
$sqlArray[$n]['dateTime']=$value->dateTime; // assign value to new array
$sqlArray[$n]['time'] = $time; // assign value to new array
$sqlArray[$n]['steps'] = $value->value; // assign value to new array
$n++;
}
Now what ever you want to do do on $sqlArray which is multidimensional array and you can check it's structure by echo "<pre/>";print_r($sqlArray);
Try this:
$n=0; // Initiate $n
while(($row = oci_fetch_row($stid)) != false) {
$fitbit->setOAuthDetails($row[0], $row[1]);
$steps = $fitbit->getTimeSeries('steps', '2015-06-01', '2015-07-01');
// Dont initiate $n here
foreach ($steps as $value){
$sqlArray[$n]['dateTime']=$value->dateTime;
$sqlArray[$n]['time'] = $time;
$sqlArray[$n]['steps'] = $value->value;
// Dont increment $n here
}
$n++; // Increment $n 'outside' your foreach
}

Put values in a table from checkbox

I have a problem. I want to put dates into an array but when I make print_r() I get only the last value from checkbox.
My code is:
$id = Input::get('id');
$aObjects = Input::get('aObjects');
$iCount = count($aObjects);
for($i=0; $i < $iCount; $i++)
{
$test = array ($aGoupes = array(
'idGroupe' => $id,
'idObject' => $aObjects[$i]
));
}
echo '<pre>';
print_r($test);
echo '</pre>';
The output is:
Array
(
[0] => Array
(
[idGroupe] => 6
[idObject] => 8
)
)
So the problem is that only the last value checked from checkbox is put in this table. Please help me!! Thnx
Your problem is that you're resetting $test each time.
Try this:
$id = Input::get('id');
$aObjects = Input::get('aObjects');
$iCount = count($aObjects);
$test = array();
for ($i = 0; $i < $iCount; $i++) {
$test[] = array (
'idGroupe' => $id,
'idObject' => $aObjects[$i]
);
}
echo '<pre>';
print_r($test);
echo '</pre>';
I'm not too sure what your code is supposed to do, but the idGroupe will always be the same in each array, as you're setting it to $id which is never changed. That may well be correct, though.

How do I redistribute an array into another array of a certain "shape". PHP

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;
}

Categories