You need to be aware of scope. functions don't have access to standard variables unless you either pass them to the function or globalize them in the function. Ideally you pass what you need to the function.
In your case you're expecting a function - an isolated process - to work as a constantly running program... or something of the sort. Perhaps what you need to do is reconsider what you expect from tally($product)
...
<?php
function tally($product)
{
$tax = 0.08;
$total_price = 0;
$total_tax = 0;
$total_shipping = 0;
$grand_total = 0;
if($product == 'Candle Holder'){
$price = 11.95;
$shipping = 0;
$total_price += $price;
$total_tax += $tax * $price;
$total_shipping += $shipping * $price;
$grand_total = ($total_price + $total_tax + $total_shipping);
}
else if($product == 'Coffee Table'){
$price = 99.50;
$shipping = 0.10;
$total_price += $price;
$total_tax += $tax * $price;
$total_shipping += $shipping * $price;
$grand_total = ($total_price + $total_tax + $total_shipping);
}
else if($product == 'Floor Lamp'){
$price = 44.99;
$shipping = 0.10;
$total_price += $price;
$total_tax += $tax * $price;
$total_shipping += $shipping * $price;
$grand_total = ($total_price + $total_tax + $total_shipping);
}
return $grand_total;
}
$grand_total = 0;
$grand_total += tally('Candle Holder');
$grand_total += tally('Floor Lamp');
?>
<ul>
<li>Candle Holder: $<?php echo tally('Candle Holder'); ?></li>
<li>Floor Lamp: $<?php echo tally('Floor Lamp'); ?></li>
<li>Total: $<?php echo $grand_total; ?></li>
</ul>
In this example you can see I use $grand_total inside and outside the function. They are unrelated. The function does not know about the outside $grand_total because it is not within its scope.
This function is used for only one thing - tally the total for that product. It's up to you to compound the results for each product. You could write a function to tally all, or a class to handle it all, but that's another subject. This example just explains why it is not doing what you are asking for