Reputation: 658
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.
Upvotes: 1
Views: 745
Reputation: 522195
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.
Upvotes: 2