警告:可能导致 TL:DR
我正在使用 PHP 5.3.10 并遇到以下问题。我确实有一个抽象类DataMapper
,它针对DataModel
我想要坚持的特定对象进行了扩展。下面的代码可以做到这一点:
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->_data['id'] = $value;
return $this;
}
public function checkPassword($password) { /* ...magic... */ }
}
这工作正常,但对我的感觉来说真的很古怪。
如您所见,我使用了一个接口IModel
来告诉 DataMapper,它确实需要一组特定的参数和方法。但是,某些模型确实具有相应 DataMapper 所需的额外方法 - 在示例中,一种checkPassword()
方法用于根据存储的哈希值测试密码。此方法还可以指示 DataMapper 重新散列刚刚测试的密码并根据新要求(例如密码散列函数的难度增加)对其进行更新。
所以我真正想要的是将 PersonMapper 的签名更改为PersonMapper::save(PersonModel $model)
- 例如在另一个 DataMapper 中更改为PostMapper::save(PostModel $model)
等。这是由于这些 DataMapper 需要某个签名。所以我理想的解决方案是这样的:
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... */ }
请注意抽象类中的 Update save-Methods 及其实现。由于PersonModel
继承自Model
,因此显然具有一组通用的基本签名,我希望这可以正常工作。但事实并非如此——PHP 抱怨子类 PersonMapper 中的接口发生了变化
我的问题:
- 是否有另一个使用 PHP 5.3.10 的解决方案可以更好地表达这种关系?
- 它是否可以在更高版本的 PHP 中工作,因此可能值得升级服务器?