title: How to validate domain object data before database operations?
body: <p>I'll use an abstract (and simple) example to illustrate the question: <code>CarDomainObject</code>, as follows: (example mysql data types are listed beside the members)</p>
  
  <pre><code>class carDomainObject extends DomainObjectAbstract {
  
      public $uid;                //int
      public $make;               //varchar
      public $model;              //varchar
      public $productionDate;     //timestamp
      public $doors;              //tinyint
  
  }
  </code></pre>
  
  <p>
  
  <pre><code>class DomainObjectAbstract {
  
      public function setData(array $data=array())
      {
          foreach ($data as $key =&gt; $value)
          {
              if ( ! empty($key))
              {
                 $this-&gt;$key = $value;
              }
          }
      }
  
      //if $val is not passed, checks for ANY set value,
      //  else checks that $this-&gt;$val is set (dirty)
      public function isDirty($val=false)
      {
          foreach(get_object_vars($this) as $key =&gt; $property)
          {
              if( ! is_null($property) &amp;&amp; ( ! $val || $key == $val))
              {
                  return true;
              }
          }
          return false;
      }
  
  }
  </code></pre>
  
  <p>Say that we want to insert a new car into the database, so we set some values:</p>
  
  <pre><code>$carDomainObject-&gt;setData(array('make' =&gt; 'ford', 'model' =&gt; 'taurus'));
  </code></pre>
  
  <p>Now the values that aren't set will still be <code>NULL</code>, which works well for the <code>isDirty()</code> method. What this schema doesn't work for is when inserting an object (that's been initialized like above, with only certain values) into the database, where <code>NULL</code> might not be a valid value for the column.</p>
  
  <p><strong>So, my question is:</strong> How can we validate that each of the data pieces within the domain object is ready for DB insertion? The way I see it there's a few options:</p>
  
  <ol>
  <li><p>If we use default values for the member variables (<code>0</code> for an int, <code>''</code> for a varchar, etc), then <code>isDirty()</code> becomes more complex, because a null check wouldn't be sufficient. However, checking that the data is able to be inserted becomes trivial because the default values could be inserted without issue </p></li>
  <li><p>If we stick with <code>NULL</code> as the default values, then <code>isDirty()</code> stays fairly trivial, but ensuring the data is ready for the DB becomes complex.</p></li>
  <li><p>Validate each variable individually, which would get ugly very quickly depending on the DO.</p></li>
  <li><p>Use default values within MySQL - Not really an option for me, but a valid option in general</p></li>
  </ol>