Using ZF2 Event manager to save a model I have been reading about ZF2 EventManager for some time now and I wonder what you'd think about this approach.

class Model_Member extends App_Model_Model
{
    protected $_data = array(
        'ID' =&gt; null,
        'UserName' =&gt; null,
        'Password' =&gt; null,
        'EmailAddress' =&gt; null,
        'CreatedOn' =&gt; null,
        'Status' =&gt; 0,
        'PasswordResetHash' =&gt; null,
        'Role' =&gt; 'member'
    );
    const EVENT_SAVE = 'save';
    const EVENT_POSTSAVE = 'post.save';
    public function init()
    {
        $this-&gt;events()-&gt;attach(self::EVENT_SAVE, array('Service_Member', 'save'));
    }
    public function save()
    {
        $id = $this-&gt;events()-&gt;trigger(self::EVENT_SAVE, $this)-&gt;last();
        $this-&gt;ID = $id;
        $this-&gt;events()-&gt;trigger(self::EVENT_POSTSAVE, $this);
    }
}


And of course there is Service_Member

public function save($event)
{
    // Get the member from the event
    $member = $event-&gt;getTarget();
    // If there is no id, save, otherwise update
    if (!$member-&gt;ID) {
        $id = $this-&gt;doSave($member);
        $event-&gt;setParam('id', $id);
        return $id;
    } else {
        return $this-&gt;doUpdate($member);
    }
}
public function doSave(Model_Member $member)
{
    // Check if username is taken
    if ($this-&gt;checkIfExists('UserName', $member-&gt;UserName)) {
        throw new App_Exception_UserNameExists('This username is already taken.');
    }

    // Check if email address already registered
    if ($this-&gt;checkIfExists('EmailAddress', $member-&gt;EmailAddress)) {
        throw new App_Exception_EmailAddressExists('This email is already registered.');
    }

    // Set default values
    $member-&gt;CreatedOn = date('Y-m-d H:i:s');

    // Encrypt password
    $member-&gt;Password = sha1($member-&gt;Password);

    // Get the data and save. Return the member with new ID
    $data = $member-&gt;_toArray();
    unset($data['ID']);
    $this-&gt;getWriteDb()-&gt;insert('members', $data);
    $id = $this-&gt;getWriteDb()-&gt;lastInsertId();
    return $id;
}


Do you think this is an acceptable approach?
I haven't used PHP recently, just a few, mostly minor notes:



// Encrypt password
$member-&gt;Password = sha1($member-&gt;Password);



You might want to use a salt here to make your hashing stronger.

$this-&gt;getWriteDb()-&gt;insert('members', $data);
$id = $this-&gt;getWriteDb()-&gt;lastInsertId();



If that's possible, insert could return the ID. It would eliminate temporal coupling (users can't call the methods in the wrong order).

(Clean Code by Robert C. Martin, G31: Hidden Temporal Couplings, p302)

'Status' =&gt; 0,



0 is a magic number here. What could it mean? A named constants would express the intent.
These comments are rather redundant, the code is clear and says the same:


// Check if username is taken
if ($this-&gt;checkIfExists('UserName', $member-&gt;UserName)) {
    throw new App_Exception_UserNameExists('This username is already taken.');
}

// Check if email address already registered
if ($this-&gt;checkIfExists('EmailAddress', $member-&gt;EmailAddress)) {
    throw new App_Exception_EmailAddressExists('This email is already registered.');
}



...


// Get the member from the event
$member = $event-&gt;getTarget();



(Clean Code by Robert C. Martin, Redundant Comments, p60)
Btw, are you sure that you need two different type of exceptions here? Wouldn't be the same exception type with different messages enough?
Use private instead of protected if possible:


protected $_data = array(



Should I always use the private access modifier for class fields?; Item 13 of Effective Java 2nd Edition: Minimize the accessibility of classes and members.

class Model_Member extends App_Model_Model



The class name is weird a little bit. Model of a model? App also too generic, something more descriptive would be better.

$member-&gt;CreatedOn = date('Y-m-d H:i:s');



Wouldn't be better using DateTime objects here?