How specific should your functions be in Zend_Model?
if someone could help me with a conceptual question it would be great: Suppose I have a model that deals with a table called Persons. Normally I would have a standard fetch function like this:
public function fetchPersonById($person_id)
{
$result = 0;
if ((int)$person_id > 0) {
$select = $this->select()
->from($this->_name, array('Id' => 'Person_Id',
'Name' => 'Person_Name',
'Age' => 'Person_Age',
'Sex' => 'Person_Sex'));
->where('Person_Id = ?', $person_id);
$result = $this->fetchRow($select);
}
return $result;
}
Now suppose for some reason I need to fetch a person's Sex by it's Name.. and later on it's age by it's name. Would you them add different functions like:
public function fetchPersonSexByName($person_name)
{
// ...
->from($this->_name, array('Sex' => 'Person_Sex');
->where('Person_Name = ?', $person_name); ...
// ...
}
and so on... After a while you could see yourself with thousands of short methods like this.. Are you guys that specific or you wether pull the whole record (fetchall) and than later in the code just keep the column you want to use? On this case wouldn't you be breaking the whole MVC because if I want to get someone's Sex my model (or whoeve is calling the function) would need to know the columns name in the database?
I also tought about doing something more generic like
public function $this->fetchColumnA_By_ColumnB_ColumnBValue($columnA_name,
$columnB_nam开发者_运维问答e, $columnA_name)
{
//...
}
And than have my short methods to be calling this more flexible column. So that I would have something like:
public function fetchPersonSexByName($person_name)
{
//...
$this->fetchColumnA_By_ColumnB_ColumnBValue('sex', 'name', 'martin');
}
Anyway.. How do you guys approach this probably common issue?
I would tend to do a version of your last generic example. The generic method would be protected (or even private) and your more specific (public) methods would call this. To avoid code repetition.
However, I'm not sure how generic I would go. May be just...
protected function _fetchColumnById($id, $column) {...}
protected function _fetchColumnByName($name, $column) {...}
...but this would depend on the requirements.
you could see yourself with thousands of short methods
If you think you'll get to 1000's of requests, then it might be better to read the whole record(s) and cache this somehow?
What you could do is make a magic __call function in your model or in his parent.
If some method doesn't exist it will go thru that magic function. Something like:
class Model_Test {
public function __call($method, $args) {
if(preg_match('/fetch([a-zA-Z]+)by([a-zA-Z]+)/i', $method, $result)) {
$fetch = $result[1];
$column = $result[2];
echo 'SELECT ' . $fetch . ' FROM test WHERE ' . $column . ' = "' . (string)$args[0] . '"';
//build your query here and make sure you make it secure with bind param, etc.
} else {
//call parent __call? Or throw an error?
}
}
}
$model = new Model_test();
$model->fetchSexByName('martin');
Just a quick example, offcourse you need to work it out. Success!
精彩评论