For a school assignment I'm trying to split stockitems with product details like colour and size in the title into groups of stockitems with different variants. I've got as far as having them all split, but I just can't figure out how to add this information to the $stockItem array. ($stockItem is inside the array $stockItemGroup which is inside the array $stockItemGroups).
When I try to add information to the array inside the loop, I cannot access that information outside the loop. If I use print_r on the entire array after this loop has completed the new information is not displayed.
for($i = 0; $i < count($stockItemGroup); $i++){
$stockItem = $stockItemGroup[$i];
$restString = str_replace($similarString, "", $stockItem['StockItemName']);
$colour = getColour($restString, $allColours);
$restVariant = getRestVariant($restString, $allColours);
$stockItemGroup[$i]['Colour'] = $colour;
$stockItemGroup[$i]['RestVariant'] = $restVariant;
$stockItemGroup[$i]['NewItemName'] = createNewItemName($colour, $restVariant, $stockItem['StockItemName']);
}
I have tried both in a foreach and a for loop (I read that a foreach does some copying, so I thought that might cause it). but to no avail.
I have also obviously tried
$stockItem['Colour'] = $colour;
$stockItem['RestVariant'] = $restVariant;
$stockItem['NewItemName'] = createNewItemName($colour,
$restVariant,
$stockItem['StockItemName']);
But that did not change anything either.
I am a total Php noob, so it might be very obvious, any help would be appreciated.
EDIT:
this loop is inside a method which is called in this loop:
$stockItemGroups = getStockItemGroups();
foreach ($stockItemGroups as $stockItemGroup){
addVariants($stockItemGroup);
//writeNewGroup($stockItemGroup);
}
foreach ($stockItemGroups as &$stockItemGroup){ Pass the array as a reference – RiggsFolly
Related
Alright, So I'm redoing my question so people can understand what I'm trying to do.
Search.php
<?php
$getItems = file_get_contents('Items.json');
if(isset($_GET['searchVal'])){
$getItems2 = json_decode($getItems, true);
$data2 = array("items" => array(array()));
foreach($getItems2['items'] as $data){
if(strpos($data['name'], $_GET['searchVal'])){
$data2 = array("items" => array(array($data)));
}
}
echo json_encode($data2,JSON_UNESCAPED_SLASHES);
} else{
echo $getItems;
}
Problem: Doesn't get all items which have that name, gets only one.
Search is done, now I have to fix somehow to get all items which match the name. How could I do that?
You have the following inside a loop:
$data2 = array(...)
...and then you reference $data2 outside the loop.
Of course, it will only contain the last entry, because that line is overwriting $data2 with new data each time the loop iterates.
If you want to keep all the records from the loop, use
$data2[] = array(...)
instead.
[EDIT]
Further guessing as to what you actually want your JSON to look like, I guess you want all the records to be in the items array?
So in that case, let's rewrite your $data2 line, as follows:
$data2['items'][] = array($data);
This will add all the data arrays to your items array in $data2. I will note that your array structure is really convoluted -- too many nested arrays, which makes it difficult to be sure I'm giving you the answer you want even now, but hopefully if it isn't exactly right, it will show you the direction you need to go.
You'll also want to have an additional line at the top of your code to initialise $data2, like this:
$data2 = array('items'=>array());
This should be somewhere at the top of the code, before $data2 is used, and outside of the loop.
I am trying to create a multidimensional array at run-time that queries and stores several MySQL results. For instance, let us say we have a table like so (is fictional, so please don't pick at the example):
**store--tag--color--size**
1--101--blue--s
2--102--red--s
2--103--yellow -- m
3--104--blue--m
The need is to create an multi-d array that will store all the products per store. The result I would like is:
$storeArray = array[[[101],[blue],[s]],[[102,103],[red,yellow],[s,m]],[[104],[blue],[m]]];
here is the code I have:
$counter = 0;
foreach($storeIDs as $item){
$result = mysql_query('select whatever');
$rows = mysql_num_rows($result);
for($i=0;$i<$rows;$i++){
$tag[$i] = mysql_result();
$color[$i] = mysql_result();
$size[$i] = mysql_result();
}
$tempArray = array($tag,$,$color,$size);
$storeArray[$counter] = $tempArray;
unset($tempArray);
$counter++;
}
The problem is, even though I have unset $tempArray, the third loop which should capture just
[[104],[blue],[m]]
actually stores
[[104,103],[blue,yellow],[m,m]].
I've tried setting $tempArray to array(), or array(array()). The data from the second loop always spills over into ANY future iteration that is of smaller size.
How can I get $storeArray to look like the goal above?
Thank you
You're unsetting $tmpArray, but it looks like you may need to also unset $tag, $color, and $size as well. There are better approaches with a slightly different data structure, but as is, have you tried this?
unset($tempArray,$tag,$color,$size);
Effectively, you might set $tag[0] and $tag[1] in a loop that has two items. Then, for a loop that has one item you update $tag[0], but $tag[1] remains set.
I want to initialize array(in my case it's multidimensional) and I want to retrieve reference to a separate variable so i could access it via that variable.
For example to achieve this im writing two lines
$multidimensional[$some_key] = array();
$item = &$multidimensional[$some_key];
This thing works just fine, but if I wanted to do this in one like I had tried:
$item = &$multidimensional[$some_key] = array(); // syntax error
Question is there a way to do this in single line?
How about:
$item = &($multidimensional[$some_key] = array());
?
I've got strange thing, it's probably simple but I can't find a solution for it. Here is part of the code:
$counter = 0;
$autoload_view_instace = new Logic_InvoiceCostData;
$sub_view_cost = array();
foreach($invoceCostData as $data)
{
$counter++;
$parm = $autoload_view_instace->edit_view_data($autoload_view, $data, $counter);
array_push( $sub_view_cost, $parm);
}
The loop calls the edit_view_data method which returns an object with some values. That object should be placed at the end of the array in each iteration without changing values of objects previously added. But after each iteration, all objects in the array have the same value as the newly added object.
apparently the array_push syntax is correct.. and it should work .. however you can do the same thing using.
$sub_view_cost[]=$parm ;
and make sure each time $parm get the correct value
I'm parsing a document for several different values, with PHP and Xpath. I'm throwing the results/matches of my Xpath queries into an array. So for example, I build my $prices array like this:
$prices = array();
$result = $xpath->query("//div[#class='the-price']");
foreach ($result as $object) {
$prices[] = $object->nodeValue; }
Once I have my array built, I loop through and throw the values into some HTML like this:
$i = 0;
foreach ($links as $link) {
echo <<<EOF
<div class="the-product">
<div class="the-name"><a title="{$names[$i]}" href="{$link}" target="blank">{$names[$i]}</a></div>
<br />
<div class="the-image"><a title="{$names[$i]}" href="{$link}" target="blank"><img src="{$images[$i]}" /></a></div>
<br />
<div class="the-current-price">Price is: <br> {$prices[$i]}</div>
</div>
EOF;
$i++; }
The problem is, some items in the original document that I'm parsing don't have a price, as in, they don't even contain <div class='the-price'>, so my Xpath isn't finding a value, and isn't inserting a value into the $prices array. I end up returning 20 products, and an array which contains only 17 keys/values, leading to Notice: Undefined offset errors all over the place.
So my question is, how can I account for items that are missing key values and throwing off my arrays? Can I insert dummy values into the array for these items? I've tried as many different solutions as I can think of. Mainly, IF statements within my foreach loops, but nothing seems to work.
Thank you
I suggest you look for an element inside your html which is always present in your "price"-loop. After you find this object you start looking for the "price" element, if there is none, you insert an empty string, etc. into your array.
Instead of directly looking for the the-price elements, look for the containing the-product. Loop on those, then do a subquery using those nodes as the starting context. That way you get all of the the-product nodes, plus the prices for those that have them.
e.g.
$products = array();
$products = $xpath->query("//div[#class='the-product']");
$found = 0 ;
foreach ($products as $product) {
$products[$found] = array();
$price = $xpath->query("//div[#class='the-price']", $product);
if ($price->length > 0) {
$products[$found] = $price->item(0)->nodeValue;
}
$found++;
}
If you don't want to show the products that don't have a price attached to them you could check if $prices[$i] is set first.
foreach($links AS $link){
if(isset($prices[$i])){
// echo content
}
}
Or if you wanted to fill it will dummy values you could say
$prices = array_merge($prices,
array_fill(count($prices), count($links)-count($prices),0));
And that would insert 0 as a dummy value for any remaining values. array_fill starts off by taking the first index of the array (so we start one after the amount of keys in $prices), then how many we need to fill, so we subtract how many are in $prices from how many are in $links, then we fill it with the dummy value 0.
Alternatively you could use the same logic in the first example and just apply that by saying:
echo isset($prices[$i]) ? $prices[$i] : '0';
Hard to understand the relation between $links and $prices with the code shown. Since you are building the $prices array without any relation to the $links array, I don't see how you would do this.
Is $links also built via xpath? If so, is 'the-price' div always nested within the DOM element used to populate $links?
If it is you could nest your xpath query to find the price within the query used to find the links and use a counter to match the two.
i.e.
$links_result = $xpath->query('path-to-link')
$i = 0
foreach ($links_result as $link_object) {
$links[$i] = $link_object->nodeValue;
// pass $link_object as context reference to xpath query looking for price
$price_result = $xpath->query('path-to-price-within-link-node', $link_object);
if (false !== $price_result) {
$prices[$i] = $price_result->nodeValue;
} else {
$prices[$i] = 0; // or whatever value you want to show to indicate that no price was available.
}
$i++;
}
Obviously, there could be additional handling in there to verify that only one price value exists per link node and so forth, but that is basic idea.