I am currently able to add a quantity of a product by one or reduce it by one within my cart however I'm trying to add a method whereby I can submit a quantity that I input into a text field.
To increase by one, this is the main part of the code. It is found on the index page.
echo ' Plus 1';
This is the code on the cart page to get that uniquenum and action:
if (isset($_GET['increase1'])) {
$result = 'cart_' . $_GET['increase1'];
$_SESSION[$result] = isset($_SESSION[$result]) ? $_SESSION[$result] + 1 : 0;
}
How could I get the $uniquenum variable from the index page to the cart page using a form and post or get request. If I could do this I could update a quantity. Many thanks in advance.
I'd suggest you put all code belonging to the logic of the cart into a class of it's own. You can then use it as a facade in your code:
// initialize session for Cart
$_SESSION['cart'] || $_SESSION['cart'] = new Cart();
// fetch cart from session
$cart = $_SESSION['cart'];
Then provide methods by cart that offer the functionality you're looking for, either in a simplified form:
$cart->increadeByOne($item);
Or by giving full access to encapsulation of a more differentiated level:
$cart->getItem($item)->getQuantity()->increaseBy($number);
The last example might seem to be bloated, but generally it's good to have a base Cart class so you can better handle and test your operations.
You can then bind that with your GET request:
if (isset($_GET['increase1']))
{
$cart->getItem($_GET['increase1'])->getQuantity->increaseByOne();
}
Some rough Cart and Quantity layout:
Class CartItemQuantity
{
private $item;
private $quantity = 0;
public function __construct(CartItem $item)
{
$this->item = $item;
}
public function increaseByOne()
{
$this->increaseBy(1);
}
public function decreaseByOne()
{
$this->quantity = max(0, $this->quantity - 1);
}
public function increaseBy($number)
{
$this->quantity = max(0, $this->quantity + $number);
}
public function getQuantity()
{
return $this->quantity;
}
public function setQuantity($quantity)
{
if (is_string($quantity) && ctype_digit($quantity))
{
$quantity = (int) $quantity;
}
if (!is_int($quantity))
{
throw new InvalidArgumentException('Not a valid quantity (%s).', $quantity);
}
$this->quantity = max(0, $quantity);
}
}
Class CartItem
{
private $quantity;
...
public function __construct()
{
$this->quantity = new CartItemQuantity($this);
...
}
public function getQuantity()
{
return $this->quantity;
}
}
Class CartItems
{
...
/**
* #return CartItem
*/
public function getItem($item)
{
...
return $item;
}
}
Class Cart
{
/**
* #var CartItems
*/
private $items;
...
public function increaseByOne($item)
{
$this->items->getItem($item)->getQuantity()->increaseByOne();
}
/**
* #return CartItem
*/
public function getItem($item)
{
return $this->items->getItem($item);
}
}
// next line breaks for formatting only, take them out
echo '<form action="cart.php" method="get">
<input type="hidden" name="increasewhat" value="'.$uniquenum.'">
<label for="increaseby">Increase by</label>
<input type="text" name="increaseby" value="1">
<input type="submit" name="increaseyes" value="Yes!">
</form>';
//real linebreaks from here, parameters assumed to be validated
$result = 'cart_' . $_GET['increasewhat'];
$_SESSION[$result] = (isset($_SESSION[$result]) ? $_SESSION[$result]:0)+$_GET['increaseby'];
<form action='cart.php' method='GET'>
Input quantity:<br/>
<input type='text' name='increase1'><br/>
<input type='submit' value='Increase'/>
</form>
<form name="add_to_cart" method="get" action="cart.php">
<label for="uniquenum">Quantity: </label>
<input type="text" name="uniquenum" />
<input type="submit" value="Add to cart" />
</form>
On the server side:
if (isset($_GET['uniquenum'])) {
$uniquenum = $_GET['uniquenum'];
/* Important! Check if it is an integer */
if(is_int($uniquenum)) {
$_SESSION[$result] = isset($_SESSION[$result]) ? $_SESSION[$result] + $uniquenum : 0;
} else {
echo "Invalid input!";
}
}
Related
I don't understand how to pass the InvoiceItem objects instantiated in the ProcessInvoice class back to my array for output to the page.
See output at bottom of post. It should output all 3 items in the array and the grand invoice total.
Am I using the $this keyword wrong?? How to pass back the objects to the invoiceItems array in the Invoice class?
class InvoiceItem {
private $id;
private $itemQuanity;
private $itemPrice;
private $itemDescrip;
// Getters and Setter here for above 4 attributes
public function calculateItemTotal() {
$total = $this->itemPrice * $this->itemQuanity;
return $total;
}
public function display() {
echo "Item ID: $this->id // Item Quanity: $this->itemQuanity // Item Price: $this->itemPrice // Item Description: $this->itemDescrip // Total: $$this->total<br>";
}
}
class Invoice {
private $invoiceItems;
public function __construct() {
$item = new InvoiceItem();
$this->invoiceItems = array($item);
}
public function getInvoiceItems()
{
return $this->invoiceItems;
}
public function setInvoiceItems($invoiceItems)
{
$this->invoiceItems = $invoiceItems;
return $this;
}
public function calculateInvoice() {
foreach ($this->invoiceItems as $item_y) {
$invoiceTotal = $invoiceTotal += $item_y->calculateItemTotal();
}
echo "Invoice Total: $$invoiceTotal ";
}
public function displayInvoice() {
foreach ($this->invoiceItems as $item_x) {
$item_x->display();
}
return $this->calculateInvoice();
}
}
class ProcessInvoice {
private $invoice;
public function __construct() {
$this->invoice = new Invoice();
}
public function getInvoice()
{
return $this->invoice;
}
public function setInvoice($invoice)
{
$this->invoice = $invoice;
return $this;
}
function createInvoiceItems() {
$item1 = new InvoiceItem();
$item1->setId(1);
$item1->setItemPrice(1.66);
$item1->setItemQuanity(2);
$item1->setItemDescrip("item example");
$item2 = new InvoiceItem();
$item2->setId(2);
$item2->setItemPrice(34.99);
$item2->setItemQuanity(1);
$item2->setItemDescrip("bla bla");
$item3 = new InvoiceItem();
$item3->setId(3);
$item3->setItemPrice(2.24);
$item3->setItemQuanity(1);
$item3->setItemDescrip("Another item");
// SOMETHING WRONG HERE?!
$this->invoice->setInvoiceItems($item1, $item2, $item3);
}
function runProcess() {
$invoice_x = new Invoice();
$this->createInvoiceItems();
$invoice_x->displayInvoice();
}
}
Output: (from a "test drive" class not in this post - Simply calls the runProcess() method in the ProcessInvoice class)
Item ID: // Item Quanity: // Item Price: // Item Description: // Total: $
Invoice Total: $0
If Invoice::$invoiceItems is an array, you need to add invoices to it, you are just overwriting the property.
Create:
public function addInvoiceItem(InvoiceItem $invoiceItem)
{
$this->invoiceItems[] = $invoiceItem;
return $this;
}
And if you need to add several, you call the same method several times:
$this->invoice->addInvoiceItem($item1)
->addInvoiceItem($item2)
->addInvoiceItem($item3);
Additionally, your constructor doesn't appear to make a lot of sense. Why are you creating an array with an empty InvoiceItem?
Better just do this, and start with a properly empty array:
private $invoiceItems = [];
I'm working with a player class, the code prints a form with name, lastname and location fields that have to be filled in to add a new player.
But I have a problem when printing the players since I only print the names of the players, when I try to print the data separately (name, lastname and location) I do not print anything.
session_start();
class Player {
private $players;
private $name;
private $lastname;
private $location;
public function __construct($name,$lastname,$location)
{
$this->name = $name;
$this->lastname = $lastname;
$this->location = $location;
$this->players = array();
}
public function getName()
{
return $this->name;
}
public function getLastname()
{
return $this->lastname;
}
public function getLocation()
{
return $this->location;
}
public function addPlayer($onePlayer)
{
$this->players[] = $onePlayer;
return $this;
}
public function printPlayers()
{
foreach($this->players as $player){
// just show the name¿?.
echo $player.'<br />';
// The problem is here.
/*echo $player['name'].'<br />';
echo $player['lastname'].'<br />';
echo $player['location'].'<br />';*/
}
}
public function __toString()
{
return $this->name;
return $this->lastname;
return $this->location;
}
}
function printForm()
{
echo '<FORM METHOD="POST" style="text-align: center; margin-top: 73px;">
<h2>Add Players</h2>
<label>Add the name : </label><INPUT class="form" TYPE = "text" NAME = "name"> <br>
<label>Add the lastname : </label><INPUT class="form" TYPE = "text" NAME = "lastname"> <br>
<label>Add the location : </label><INPUT class="form" TYPE = "text" NAME = "location"> <br><br>
<INPUT class="form" TYPE = "submit" VALUE = "add" name="action">
<INPUT class="form" TYPE = "submit" VALUE = "list" name="action">
</ FORM>';
}
// Load the player data of the session and if it does not exist create a new player.
function loadData()
{
return isset($_SESSION['player']) ? $_SESSION['player'] : new Player();
}
// Save the player's data in the session.
function saveData($player)
{
$_SESSION['player'] = $player;
}
printForm();
$player = loadData();
if(isset($_POST['action']))
{
switch($_POST['action'])
{
case 'add':
$player->addPlayer(new Player($_POST['name'],$_POST['lastname'],$_POST['location']));
saveData($player);
break;
case 'list':
echo '<hr />';
$player->printPlayers();
break;
}
}
It looks like in the problematic part you're trying to access private properties using array syntax. That won't work for a couple of reasons
The properties aren't accessible there because they're defined as private
You can't get them with array syntax. If they weren't private you'd need to use $player->name.
But fortunately you have also written some getters, so you should be able to use those instead, like this:
echo $player->getName();
I used array_reverse to add newly created to-dos to the top of the list. But now I am having trouble deleting them. When I click the checkbox to delete an item, it will delete the one on the opposite end of the list. Could anyone tell me the best way to reverse the order and have them delete properly? Is array_reverse the best way to accomplish this or is there a better alternative. My two files are below.
index.php
<?php
// cookies
ini_set('session.gc_maxlifetime', 172800);
session_set_cookie_params(172800);
// array('get milk', 'feed dog');
include 'TaskList.php';
$list = new TaskList('tasks');
if(isset($_POST['task'])) {
// if post task is set the user submitted a task
$list->addItem($_POST['task']);
$list->save();
}
if(isset($_POST['delete'])) {
// delete this item from the array
$keys = $_POST['delete'];
foreach($keys as $key) {
array_reverse($list->deleteItem($key));
}
$list->save();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>To Do List</title>
</head>
<body>
<h1>To Do List</h1>
<!-- Insert Items -->
<form action="index.php" method="post">
<label for="task">
Enter task: <input type="text" name="task" id="task" value="" placeholder="Enter Task Here">
</label>
<input type="submit" name="" value="Add">
</form>
<form class="" action="index.php" method="post">
<ul>
<?php foreach(array_reverse($list->items) as $key => $task): ?>
<!-- [] tell browser that it's an array and to delete more than one item at a time -->
<li><input type="checkbox" name="delete[]" value="<?php echo $key ?>"><?php echo $task; ?></li>
<?php endforeach; ?>
</ul>
<input type="submit" name="" value="Delete">
</form>
<hr>
<?php var_dump(array_reverse($list->items)) ?>
</body>
</html>
TaskList.php
<?php
class TaskList {
var $items;
var $listname;
public function __construct($listname){
session_start();
$this->listname = $listname;
if(isset($_SESSION[$this->listname])) {
$this->items = $_SESSION[$this->listname];
}
else {
$this->items = array();
}
}
public function addItem($item) {
$this->items[] = $item;
}
public function deleteItem($key) {
unset($this->items[$key]);
}
public function save() {
$_SESSION[$this->listname] = $this->items;
}
}
A for loop can be used here to keep the ordering of items in the tasklist by doing a backwards loop.
I added a convenience method in the TaskList class to easily access keys
function getKey($key) {
return $this->items[$key];
}
PHP template modified to use for loop:
<form class="" action="index.php" method="post">
<ul>
<?php
$count = count($taskList->items) - 1;
for($key=$count; $key >= 0; $key--) {
$task = $taskList->getKey($key);
?>
<li><input type="checkbox" name="delete[]" value="<?php echo $key ?>">
<?php echo $task; ?></li>
<?php } ?>
</ul>
<input type="submit" name="" value="Delete">
</form>
Reverse delete
The objective here is to remove the element at the opposite in the array. One way to do this is to get the keys for the array using array_keys and then use array_reverse on the result to give us a map of the opposite keys.
$reverseKeys = array_reverse(array_keys($arr));
// output of print_r($reverseKeys) for an array indexed from 0 to 4
Array
(
[0] => 4
[1] => 3
[2] => 2
[3] => 1
[4] => 0
)
Then we can use this map to delete the appropriate element.
if(isset($_POST['delete'])) {
// delete this item from the array
$keys = $_POST['delete'];
$reverseKeys = array_reverse(array_keys($arr));
foreach($keys as $key) {
$list->deleteItem($reverseKeys[$key]);
}
$list->save();
}
Since this question has the oop tag, I'm gonna try and focus on giving a more object-oriented approach and how the current design can be improved.
The design of the TaskList object
First, let us take a look at the TaskList object's design and see what we can improve.
Encapsulation
One of the key concept of Object-Oriented programming (the most important for some) is that of encapsulation. In a nutshell, encapsulation means that the inner workings and attributes of an object are hidden from the code that consumes the object. What this means in practice is that an object should have private properties and only expose them (some or all) via public accessors.
An accessor can either return a value with no modifications
public function getDateOfBirth() {
return $this->dateOfBirth;
}
Or perform some modifications to give more meaning to the data
public function getAge() {
// assuming $dateOfBirth is an instance of DateTime
$diff = $dateOfBirth->diff(new DateTime());
return $diff->format('%y');
}
Looking at the TaskList class, we can convert the attributes $items and $listName to private members, and create accessors for them.
class TaskList {
private $items = [];
private $listname = '';
public function __construct($listname){
/* ... */
}
public function getListName() {
return $this->listName;
}
public function getItems() {
return $this->items;
}
}
The rest of the class looks good to me; addItem(), deleteItem() and save() are all pretty self-explanatory and well contained. but what about the rest of the code? Looking at the index.php file, there are things we can refactor into TaskList. The biggest one is the foreach loop to perform a bulk delete. The TaskList class should be able to perform this action on its own without exposing it's internal structure to the rest of the code.
// rename delete to deleteOne
public function deleteOne($key) {
unset $this->items[$key];
}
public function deleteItems($keys) {
foreach($keys as $key) {
$this->deleteOne($key);
}
}
// reverse delete from earlier
public function reverseDeleteItems($keys) {
$reverseKeys = array_reverse(array_keys($arr));
foreach($keys as $key) {
$this->deleteOne($reverseKeys[$key]);
}
}
Responsibility
Antoher important principle often applied in Object-Oriented programming is that of Single Responsability. Without going into too much detail, the Single Responsability Principle (SRP) states that an object should only take care of its own data/processes, and nothing outside of that scope. Here, the responsibility of TaskList is to maintain a list of Tasks. However, it is also handling the php session in it's constructor, which falls outside of its responsibility.
index.php:
<?php
session_start()
/* ... */
TaskList.php:
class TaskList {
/* ... */
public function __construct($name) {
$this->listname = $name;
if(isset($_SESSION[$this->listname])) {
$this->items = $_SESSION[$this->listname];
}
else {
$this->items = array();
}
}
Further Improvement
There should be enough information above to help you solve your problem, but I'd like to take the opportunity to offer some suggestions.
First, the $items is a simple array, which works well now, but may cause problems in the future. An array could contain anything really, and it may not be in the right format. What you can do instead is create a Task class, and have each element of Item instantiate it. That way validating that each task has the appropriate elements becomes very easy and it also scales better.
class Task {
private $name;
private $value;
private $priority; // value from 0 to 9
private $createdAt;
private $updatedAt;
public function __construct($name, $value, $priority = 5) {
$this->name = $name;
$this->value = $value;
$this->priority = $priority;
$now = new DateTime();
$this->createdAt = $now;
$this->updatedAt = $now;
}
public function getName() {
return $this->name;
}
public function getValue() {
return $this->value;
}
public function setValue($value) {
$this->value = $value;
$this->updatedAt = new DateTime();
}
public function getPriority() {
return $this->priority;
}
public function toArray() {
return [
'name' => $this->name,
'value' => $this->value,
'priority' => $this->priority,
'createdAt' => $this->createdAt->format('Y-m-d H:i:s'),
'updatedAt' => $this->updatedAt->format('Y-m-d H:i:s'),
];
}
}
This gives you the possibility to modify the add function like so
public function addItem($name, $value, $priority = null) {
// if items must be unique
if(array_key_exists($name, $this->items)) {
throw new Exception('An item with the same name already exists');
}
$this->items[$name] = new Task($name, $value, $priority);
}
As you can see, I can now have a lot more information about each Task with minimal modifications to the TaskList class.
Additionally, you can improve TaskList even more by refactoring the saving mechanism in a TaskListRepository that will take care of getting instances of TaskList and persisting them to whatever system you prefer (MySQL, SQLite, MongoDB, .txt files, session variables).
class TaskListRepository {
public function save($list) {
/* store list */
}
public function getOne($name) {
/* fetch instance of a TaskList */
return $taskList;
}
}
You can now modify the index.php like so
<?php
session_start();
$taskListRepo = new TaskListRepository();
$taskList = $taskListRepo->getOne('myList');
$taskList->addOne('groceries', 'I need to pick up the groceries');
$taskListRepo->save($taskList);
I am trying to serialize my object "ShoppingCart.php", and the object "Item.php", but i cant, and i dont know what else to do, so i leave here my code just to see if someone could help me. My problem is that the object ShoppingCart.php has a property which stores an array of Items, and i am not really sure if i am serializing/unserializing really well the object.
I have summarized my classes so they dont include all the methods, but they still show the most representatives. If still is not clear enought i will change it again.
Thanks in advance:
<?php
class ShoppingCart implements Iterator, Countable,Serializable {
// Array stores the list of items in the cart:
protected $items = array();
// For tracking iterations:
protected $position = 0;
// For storing the IDs, as a convenience:
protected $ids = array();
// Constructor just sets the object up for usage:
function __construct() {
$this->items = array();
$this->ids = array();
}
// Adds a new item to the cart:
public function addItem(Item $item) {
// Need the item id:
$id = $item->getId();
// Throw an exception if there's no id:
if (!$id) throw new Exception('The cart requires items with unique ID values.');
// Add or update:
if (isset($this->items[$id])) {
$this->updateItem($item, $this->items[$id]['qty'] + 1);
} else {
$this->items[$id] = array('item' => $item, 'qty' => 1);
$this->ids[] = $id; // Store the id, too!
}
} // End of addItem() method.
// Changes an item already in the cart:
public function updateItem(Item $item, $qty) {
// Need the unique item id:
$id = $item->getId();
// Delete or update accordingly:
if ($qty === 0) {
$this->deleteItem($item);
} elseif ( ($qty > 0) && ($qty != $this->items[$id]['qty'])) {
$this->items[$id]['qty'] = $qty;
}
} // End of updateItem() method.
// Removes an item from the cart:
public function deleteItem(Item $item) {
// Need the unique item id:
$id = $item->getId();
// Remove it:
if (isset($this->items[$id])) {
unset($this->items[$id]);
// Remove the stored id, too:
$index = array_search($id, $this->ids);
unset($this->ids[$index]);
// Recreate that array to prevent holes:
$this->ids = array_values($this->ids);
}
} // End of deleteItem() method.
public function serialize(){
foreach ($this->items as $clave => $item)
$listaItems[$clave]=serialize($this->items['item'][$clave]);
foreach ($this-items as $clave=>$valor)
$listaCantidades[$clave]=$this->items['qty'][$clave];
return
array(
'items'=>$listaItems,
'qty'=>$listaCantidades,
'ids'=>$this->ids,
);
}
public function unserialize($data){
//$data=unserialize($data);
$this->items=array(
'items'=>$data['items'],
'qty'=>$data['qty']
);
$this->ids=$data['ids'];
foreach($this->items as $clave => $item)
$this->items[$clave]=unserialize($item);
}
} // End of ShoppingCart class.
<?php # Item.php
// This is a sample Item class.
// This class could be extended by individual applications.
class Item implements Serializable{
// Item attributes are all protected:
protected $id;
protected $name;
protected $price;
protected $description;
public function serialize(){
return serialize(
array(
'id'=>$this->id,
'name'=>$this->name,
'price'=>$this->price,
'description'=>$this->description
)
);
}
public function unserialize($data){
$data=unserialize($data);
$this->id=$data['id'];
$this->name=$data['name'];
$this->price=$data['price'];
$this->description=$data['description'];
}
// Constructor populates the attributes:
public function __construct($id, $name, $price) {
$this->id = $id;
$this->name = $name;
$this->price = $price;
}
// Method that returns the ID:
public function getId() {
return $this->id;
}
// Method that returns the name:
public function getName() {
return $this->name;
}
// Method that returns the price:
public function getPrice() {
return $this->price;
}
public function getDescription() {
return $this->description;
}
public function setDescription($descripcion){
$this->description=$descripcion;
}
} // End of Item class.
Your immediate problem is that objects implementing Serializable must return a serialised string from the serialise method. Currently you're returning an array of data. You should be doing this instead:
public function serialize() {
...
return serialize(array(...));
}
You're actually doing this correctly in your Item class. However, I don't see why you're manually serialising in the first place. You're basically replicating the default behaviour of what serialize() already does without any added benefits. Just get rid of the Serializable interface and its implementation and the default behaviour of PHP's serialisation should serve you just fine. E.g.:
$_SESSION['cart'] = $myShoppingCart;
Done. No implementation of serialize necessary in your case.
I am working on a basic shopping cart. However, it appears as though the $_SESSION variable is not properly being stored or accessed. For instance if you travel to here it will display the item name. But on refresh to cart.php without any $_GET variables it returns nothing. What am I doing wrong?
<?php
include "tickets/config.php";
if (isset ($_GET['action']) && isset($_GET['item'])) {
$cart = new Cart($_GET['item']);
if ($_GET['action'] == "addItem") {
$cart->addItem();
$cart->get_items_code();
$cart->populate();
}
if($_GET['action'] == "removeItem") {
$cart->removeItem();
$cart->get_items_code();
$cart->populate();
}
$cart->postAllItems();
}
else {
$cart = new Cart(null);
$cart->get_items_code();
$cart->populate();
$cart->postAllItems();
}
class Cart {
protected $all_items = array();
protected $request_item;
protected $content;
protected $item_obj;
public function __construct($request_item) {
$this->request_item = $request_item;
if ($this->request_item)
$this->item_obj = new Item($this->request_item);
$this->all_items = $this->getAllItems();
}
public function getAllItems() {
if ($_SESSION['cart'])
$request = $_SESSION['cart'];
else
$request = array();
return $request;
}
public function postAllItems() {
$_SESSION['cart'] = $this->all_items;
}
public function addItem () {
array_push($this->all_items, $this->item_obj);
}
public function removeItem() {
unset($this->all_items[$this->item_obj->get_item()]);
}
public function get_items_code() {
//for($i = 0; $this->all_items[$i]; $i++) {
foreach($this->all_items as $item) {
$name = $item->get_name();
$this->content .= <<<HTML
<div class="item">
$name
</div>
HTML;
}
}
public function populate() {
echo <<<HTML
<div id="list">
$this->content
<div>
HTML;
}
}
class Item {
protected $id;
protected $name;
protected $price;
protected $desc;
protected $colors;
protected $sizes;
protected $pic_url;
protected $all_info;
public function __construct($id) {
$this->id = $id;
$this->get_item_info();
}
public function get_item() {
return ($this);
}
public function get_name() {
return $this->name;
}
protected function get_item_info() {
$sql = "SELECT * FROM catalog WHERE id = ".$this->id;
$this->all_info = mysql_query($sql);
$this->all_info = mysql_fetch_array($this->all_info);
$this->name = $this->all_info['name'];
$this->price = $this->all_info['price'];
$this->desc = $this->all_info['description'];
$this->colors = $this->all_info['colors'];
$this->sizes = $this->all_info['sizes'];
$this->pic_url = $this->all_info['picture'];
}
}
?>
You need to initialize the session using the session_start()-function at the top of the page (before the contents of the sessions are modified or read).
Your code looks fine, but you must call session_start() on every page that modifies the session or reads from the session. Just putting it at the top of the page will work.
session_start();
I also recently had a problem with $_SESSION vars maintaining themselves after page redirects, which could be your problem.
Session variables will not survive a redirect from a http://www.example.com to a http://example.com redirect. So, you use redirects with relative or absolute paths, but do it without the sitename:
use
header('Location: /new_page.php');
as opposed to
header('Location: http://www.exmple.com/new_page.php')
Maybe doesn't apply here, but did trip me up quite a bit.