PHP variable scope confused - php

Hello
Here is my code.... THe problem is at $product variable.
Is there any way to fix this?
It is defined two times and causes problem overwrites
THE PROBLEM UPDATED
$productsIDs = array();
foreach ($rowsProducts as &$product) {
$product["features"] = &$productsFeatures[$product["product_id"]];
$productsIDs[] = $product["product_id"];
}
//GET STOCK FEATURES
$sqlIds=implode(",",$productsIDs);
$sql="SELECT * FROM eshop_products_stock WHERE product_id IN ($sqlIds)";
$productsStock = $db->getRecordSet($sql);
$sql="SELECT * FROM `eshop_features_valuestr` WHERE feature_id IN ".
"(SELECT DISTINCT feature1_id FROM eshop_products_stock WHERE product_id IN ($sqlIds))" .
" AND language_code='$lang'";
$productsSizes = $db->getRecordSet($sql);
$sql="SELECT * FROM `eshop_features_valuestr` WHERE feature_id IN ".
"(SELECT DISTINCT feature2_id FROM eshop_products_stock WHERE product_id IN ($sqlIds))".
" AND language_code='$lang'";;
$productsColors = $db->getRecordSet($sql);
$productsSizesV=array();
foreach($productsSizes as $size)
{
$productsSizesV[$size["value"]]=$size["title"];
}
$productsColorsV=array();
foreach($productsColors as $color)
{
$productsColorsV[$color["value"]]=$color["title"];
}
//Group by product stock
$productsStockV=array();
$product="";
foreach($productsStock as $product)
{
$productsStockV[$product["product_id"]]["sizes"][]=$product["feature1_value"];
$productsStockV[$product["product_id"]]["colors"][]=$product["feature2_value"];
}

You should unset $product after the foreach loop:
foreach ($rowsProducts as &$product) {
$product["features"] = &$productsFeatures[$product["product_id"]];
$productsIDs[] = $product["product_id"];
}
unset($product);

You've encountered a very nice php WTF:
foreach ($rowsProducts as &$product) makes $product a reference. Not only for the loop but forever. If you then use a foreach using $product as the loop variable later (or do anything writing to $product), it will overwrite the last item of the first foreach loop.
Simply use foreach ($rowsProducts as $key => $product) and assign $rowsProducts[$key] = $product; at the end of your loop body if you changed anything.
Another solution would be calling unset($product); after your first loop to get rid of the reference. But generally not using reference loops is safer as you cannot forget to unset.

Related

Adding dynamic array to the end of a static array PHP

I've got the following code which is within a sql loop to determine how many rows i output onto a spreadsheet. Basically without pasting the full thing as it's quite a lengthy statement, the top SQL statement will return 60 rows, which will contain the variables I enter into the original $data1 array.
$stmt2= $mysqV1->prepare("SELECT DISTINCT master_recipe, recipe, matl_id, comp_length, comp_width, comp_tck from components where recipe > 0 and matl_id > 0 order BY CAST(recipe AS UNSIGNED) ASC" );
foreach ($result2 as $key2=>$value2)
{
$data1[]=(array("Master Recipe"=>$master_recipe,"Recipe"=>$recipe,"Recipe Name"=>$recipe_name,"Material"=>$material,"Length"=>$comp_length,"Width"=>$comp_width,"Thickness"=>$comp_tck));
}
I then have a further nested loop (inside the original $result2 loop) which will determine how many elements i add to that array, as the value will change from record to record. I have tried to declare an array then use array push and array merge but neither of them seem to do what i want.
$temp7 = array($master_recipe);
$stmt7= $mysqV1->prepare("Select * from machine where master_recipe = ? order by route_header_id asc" );
$stmt7->execute($temp7);
$result7=$stmt7->fetchAll();
foreach ($result7 as $key7=>$value7)
{
$station_id = $value7['route_header_id'];
$time_taken = $value7['time_hrs'];
$a[] = (array("StationID"=>$time_taken));
array_push($data1,$a);
}
So what I would like this to do is add the contents of $a to the end of $data1 to give me 1 array value which then prints out to my spreadsheet(the print part is already working for the $data1 array) but it's not adding the $a to it.
Final result I would like to end up something like this for the value in $data1
$data1[]=(array("Master Recipe"=>$master_recipe,"Recipe"=>$recipe,"Recipe Name"=>$recipe_name,"Material"=>$material,"Length"=>$comp_length,"Width"=>$comp_width,"Thickness"=>$comp_tck,"$station_id1"=>$time_taken,"$station_id2"=>$time_taken2,"$station_id3"=>$time_taken3));
Put the row that you're adding to $data1 in the $a variable, then you can add new elements to that row before you push it into $data1.
foreach ($result2 as $value2) {
$master_recipe = $value2['master_recipe'];
$recipe = $value2['recipe'];
...
$a = array("Master Recipe"=>$master_recipe,"Recipe"=>$recipe,"Recipe Name"=>$recipe_name,"Material"=>$material,"Length"=>$comp_length,"Width"=>$comp_width,"Thickness"=>$comp_tck);
$temp7 = array($master_recipe);
$stmt7= $mysqV1->prepare("Select route_header_id, time_hrs from machine where master_recipe = ? order by route_header_id asc" );
$stmt7->execute($temp7);
while ($value7 = $stmt7->fetch())
{
$station_id = $value7['route_header_id'];
$time_taken = $value7['time_hrs'];
$a[$station_id] = $time_taken;
}
$data1[] = $a;
}
What if you change your initial set of $data1 to this:
$data1= array(
"Master Recipe"=>$master_recipe,
"Recipe"=>$recipe,
"Recipe Nme"=>$recipe_name,
"Material"=>$material,
"Length"=>$comp_length,
"Width"=>$comp_width,
"Thickness"=>$comp_tck
);
then, in your loop..
foreach ($result7 as $key7=>$value7)
{
$station_id = $value7['route_header_id'];
$time_taken = $value7['time_hrs'];
$data1[$station_id] = $time_taken;
}

Trying to create a PHP foreach loop that loops through an array to call an API and output into MySQL

I've just added a loop to code I already have working. I'm pretty sure what's giving me the trouble, and that is one of the following pieces of code:
First I have:
$teams = array(ARI, ATL, BAL, BUF, CAR, CHI, CIN, CLE, DAL, DEN, DET, GB, HOU, IND, JAC, KC, MIA, MIN, NE, NO, NYG, NYJ, OAK, PHI, PIT, SD, SEA, SF, STL, TB, TEN, WAS);
foreach ($teams as $value) {
$query_string = 'api_key='.$api_key.'&team=$value'; // Change team/month
Is this the right way to set up $query_string to a $value that's changing as the loop runs?
Later inside the loop I have:
$sql = "CREATE TABLE $value . _GAMES ( ". // Creating a new table for each team
Is this the right way to concatenate the $value variable being changed by the loop with the rest of what I want the table name to be? (i.e. I want the first loop to create the table ARI_GAMES.
Change the $query_string to
$teams = array('ARI', 'ATL', 'BAL', 'BUF');
foreach ($teams as $value) {
$query_string = 'api_key='.$api_key.'&team='.$value;
}
Using quotes and curly brackets will be good
$teams = array('ARI', 'ATL', 'BAL', 'BUF');
foreach ($teams as $value) {
$query_string = "api_key={$api_key}&team={$value}";
//sql
$sql = "CREATE TABLE {$value}_GAMES (.... ";
}
I think my dear friend you need little more to learn regarding PHP arrays.
First your $teams array must be an array with strings which are the names of the teams as follows(Note: I have shorten the list of teams array):
$teams = array("ARI", "ATL", "BAL", "BUF", "CAR", "CHI", "CIN", "CLE", "DAL", "DEN", "DET");
So then you need to understand how the PHP concatenation works. For an example, it goes as follows:
$someVar = 5;
$concatenateVar = $someVar.' myOtherStringHere '.$someVar;
echo $concatenatedVar;
will print out following line:
5 myOtherStringHere 5
However I've written the required code specifically for your question. Please try to understand it and learn from it.
<?php
$teams = array("ARI", "ATL", "BAL", "BUF", "CAR", "CHI", "CIN", "CLE", "DAL", "DEN", "DET");
$api_key = "API_KEY_HERE";
foreach ($teams as $value) {
echo "start of another foreach-loop round<br/>";
$query_string = 'api_key = '.$api_key.' team = '.$value;
echo $query_string;
echo "<br/>";
$sql = "CREATE TABLE $value._GAMES ( "; // Creating a new table for each team
echo $sql;
echo "<br/>end of a foreach-loop round<br/>";
}
?>

Removing an item from an array during a foreach loop

I have the following foreach being performed in PHP.
What I would like to do is instead of the $invalid_ids[] = $product_id; building and then looping around that, I would instead like to remove the entry from array that is being looped around as I'm looping around it..
For example:
If the current $product_id fails any of the test, delete the item from the $current_list array and proceed to the next iteration of the foreach loop.
I tried to do an unset($product_id) while the foreach loop header looked like this: foreach ($current_list as &$product_id) {, but the item item is still in the array.
Does anyone have any ideas on how I can go about doing this?
foreach ($current_list as $product_id) {
// Test 1 - Is the product still active?
// How to test? - Search for a product in the (only active) products table
$valid = $db->Execute("SELECT * FROM " . TABLE_PRODUCTS . " WHERE products_id = " . $product_id . " AND products_status = 1");
// Our line to check if this is okay.
if ($valid->RecordCount <= 0) { // We didn't find an active item.
$invalid_ids[] = $product_id;
}
// Test 2 - Is the product sold out?
if ($valid->fields['products_quantity'] <= 0 and STOCK_ALLOW_CHECKOUT == "false") { // We found a sold out item and it is not okay to checkout.
$invalid_ids[] = $product_id;
}
// Test 3 - Does the product have an image?
if (empty($valid->fields['products_image'])) { // Self explanatory.
$invalid_ids[] = $product_id;
}
}
$product_id isn't the actual data in the array, it's a copy of it. You would need to unset the item from $current_list.
I'm don't know how $current_list is stored, but something like unset($current_list['current_item'] would do the trick. You can use key to select the current_item key in the array.
A similar way of iterating the Array, where you can get the array key, from the PHP key docs...
while ($fruit_name = current($array)) {
if ($fruit_name == 'apple') {
echo key($array).'<br />';
}
next($array);
}
Untested, but something like this...
while ($product_id = current($current_list)) {
// Do your checks on $product_id, and if it needs deleting...
$keyToDelete = key($array);
unset($current_list[$keyToDelete]);
next($current_list);
}
I think this simple code may help you
let's say we have an array of integers and we want to remove all the items that are equal to "2" inside of the foreach loop
$array = [1,2,1,2,1,2,1];
foreach ($array as $key => $value)
{
if($value==2)
unset($array[$key]);
}
var_dump($array);
this shows the following result
array (size=4)
0 => int 1
2 => int 1
4 => int 1
6 => int 1

How to exclude data from an array?

On a product page I want to show 4 other products selected randomly, but never the product that is already being displayed. The product id of the displayed one is $_product->getId() and all the products go into a $result[] array like this:
foreach($collection as $product){
$result[]=$product->getId();
}
I'm using $need = array_rand($result, 4); to get the ids of the 4 random products, but it might include the id of the product on display. How do I exclude $_product->getId() from the $need[] array? Thank you.
Don't put id of the product you don't want to show into $result:
$currentProductId = $_product->getId();
foreach ($collection as $product) {
if ($product->getId() != $currentProductId) $result[] = $product->getId();
}
Is it acceptable to just not put the current product ID in the array?
foreach($collection as $product) {
if( $product != $_product) $result[] = $product->getId();
}
You might generate your random numbers first, like so:
$rands = array();
while ($monkey == false){
$banana = rand(0,4);
if (in_array($banana, $rands) && $banana != $_product->getId()){ $rands[] = $banana; }
if (sizeOf($rands) == 4){
$monkey = true;
}
}
Then you could pipe them through your product grabber. Obviously, you'd need to figure out the bounds for rand yourself but you know more about your app than I do. Picking your numbers first is much cheaper computationally than pulling records and THEN checking to make sure that they're unique.
Of course, if this is database-backed, you could solve it much more elegantly by writing a new query.
If you use the product id as the index $result[] in result, you can remove the current product from the $result array with unset() before making the call to array_rand() like so:
foreach($collection as $product){
$result[$product->getId()] = $product->getId();
}
unset($result[$_product->getId()]);
$need = array_rand($result, 4);
This approach saves you from having to use the values in $need to look up the product id in your $result[] array, since the values in $need will be your product ids.

How do I get CustomerName from an Order?

I had added a custom option Complete in action dropdown(sales->orders). It's working fine and order status changes to complete successfully.
I am integrating all orders with Salesforce. I have need of all of order details by orderid. Item details and grand total is fetched successfully.
Can anyone please help to fetch Customer name and his/her company name how submitted order. Below is my complete code to fetch order details:
$order = Mage::getModel('sales/order')->load($orderId);
$items = $order->getAllItems();
$_totalData = $order->getData();
$_grand = $_totalData['grand_total'];
$custname = $_totalData->getCustomerName();
$itemcount=count($items);
foreach ($items as $itemId => $item)
{
$sObject2->Item_name__c = $item->getName();
$sObject2->Unit_price__c = $item->getPrice();
$sObject2->Sku__c = $item->getSku();
$sObject2->Quantity__c = $item->getQtyToInvoice();
}
try this
$order->getCustomerName()
You probably don't need to cast $order->getData() to a new variable. This will only serve to chew up memory, especially since there is only one element you need from that data, which can be retrieved with a less intensive method.
Instead, try it this way:
$order = Mage::getModel('sales/order')->load($orderId);
$_grand = $order->getGrandTotal();
$custname = $order->getCustomerName();
foreach ($order->getAllItems() as $itemId => $item)
{
// Do stuff
}
if $order->getCustomerName() doesn't work for you, try:
$order->getBillingAddress()->getName();
$custname = $Order->getCustomer()->getName();

Categories