Example:
class UserStorage {
public function addUser(User $user) { //saves to db }
}
class User {
public function setName($name);
}
What if I add a user to the user storage and later change that user object? In this case you might argue that user objects only should be stored on __destruct. But sometimes this isn't an option (eg imagine the user is displayed and updated afterwards).
I agree with Peter, the above model seems a little quirky to me and I would recommend against implicit save to the datastore.
Additionally, a pattern to use is something like:
class UserStorage {
$_user;
function addUser(User user, commit = true) {
if (commit) {
// save to db
} else {
// populate your internal instance
$_user = user;
}
}
}
So if you have multiple updates of a User object in the execution of your PHP application, you can use
addUser(user,false)
all the way until the very last call to
addUser(user)
This will alleviate the need for multiple inserts/updates to the DB.
However, your problem of where in the application to decide to finally save to db remains, and is more about logical flow than object representation. It may be helpful to have a end() function in the script that persists all your objects to the db.
Implicit writes to the database are probably a bad idea. That should be an explicit, controlled operation.
Your pattern is a little weird to me, but I think this how you'd want to do it
class UserStorage
{
const ACTION_INSERT = 'INSERT';
const ACTION_UPDATE = 'UDPATE';
public function addUser(User $user)
{
$this->saveUser($user, self::ACTION_INSERT);
}
public function updateUser(User $user)
{
$this->saveUser($user, self::ACTION_UPDATE);
}
protected function saveUser(User $user, $action)
{
switch ($action) {
case self::ACTION_INSERT:
// INSERT query
break;
case self::ACTION_UPDATE:
// UPDATE query
break;
default:
throw new Exception('Unsupported action');
}
}
}
class User
{
public function setName($name)
{
// whatever
}
}
$userStorage = new UserStorage();
$user = new User();
$userStorage->addUser($user);
$user->setName('Peter');
try {
$userStorage->updateUser($user);
} catch (Exception $e) {
echo "There was an error saving this user: " . $e->getMessage();
}
But Personally I'm not crazy about this class design. There are some well-established patterns for this that are less confusing, such as ActiveRecord.