Note that there are some explanatory texts on larger screens.

plurals
  1. POProgramming Paradigms: Strongly Typed parameter with Inheritance
    primarykey
    data
    text
    <p><em>Warning: might cause TL:DR</em></p> <p>I am working with PHP 5.3.10 and have the following problem. I do have an abstract class <code>DataMapper</code>, which is extended for the specific <code>DataModel</code> I want to persist. The following code does this trick:</p> <pre><code>abstract class DataMapper { public abstract function findById($id); public abstract function fetchAll(); public abstract function save(IModel $model); // DISCUSSION /* more helper functions here */ } class PersonMapper extends DataMapper { public function findById($id) { /* ...magic ... */ } public function fetchAll() { /* ...magic ... */ } public function save(IModel $model) { /* ...magic ... */ } // DISCUSSION } interface IModel { public function setOptions(array $options); public function toArray(); } abstract class Model implements IModel { protected $_fields = array(); protected $_data = array(); public function setOptions(array $options) { /* ...magic ... */ } public function toArray() { /* ...magic ... */ } public function __construct(array $options = null) { /* ...magic ... */ } public function __set($name, $value) { /* ...magic ... */ } public function __get($name) { /* ...magic ... */ } } class PersonModel extends Model { protected $_fields = array('id', 'name', 'passhash', /*...*/); public function setId($value) { /* ...Validation happening... */ $this-&gt;_data['id'] = $value; return $this; } public function checkPassword($password) { /* ...magic... */ } } </code></pre> <p>This works fine, but is really quirky for my feeling.</p> <p>As you can see, I've used an interface <code>IModel</code> to be able to tell the DataMapper, that it does need a certain set of parameters and methods. However, some Models do have extra methods needed by the corresponding DataMapper - in the example, a <code>checkPassword()</code> method, which is used test a password against the stored hash value. This method may also instruct the DataMapper to rehash the just tested password and update it due to new requirements (e.g. an increased difficulty for a password hash function).</p> <p>So what I actually want is to change the signature of PersonMapper to <code>PersonMapper::save(PersonModel $model)</code> - and e.g. in another DataMapper to<code>PostMapper::save(PostModel $model)</code>, etc. This is due to these DataMappers needing a certain signature. So my ideal solution looks like this:</p> <pre><code>abstract class DataMapper { public abstract function findById($id); public abstract function fetchAll(); public abstract function save(Model $model); // UPDATED } class PersonMapper extends DataMapper { public function findById($id) { /* ...magic... */ } public function fetchAll() { /* ...magic... */ } public function save(PersonModel $model) { /* ...magic... */ } // UPDATED } abstract class Model { /* ...unchanged... */ } class PersonModel extends Model { /* ...unchanged... */ } </code></pre> <p>Notice the Update save-Methods in the abstract class and its implementation. Since <code>PersonModel</code> is inherited from <code>Model</code>, thus obviously having a common base set of signatures, I would expect this to work just fine. But it doesn't - PHP complains about a changed interface in the childclass PersonMapper</p> <p><strong>My Questions:</strong></p> <ul> <li>Is there another solution working with PHP 5.3.10 that expresses the relationship better?</li> <li>Does it work in a later version of PHP, so that it might be worth upgrading the server?</li> </ul>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload