Прежде всего вы должны принять во внимание:
- Хорошей общей модели не существует. Каждому проекту нужна своя модель.
- легко читаемый, управляемый код
- не повторяйте один и тот же код (или запросы), поэтому, если у вас есть функция для определенной задачи и вы хотите, чтобы она была упорядочена другим способом, измените саму функцию и не клонируйте ее
- Использование сложных структур данных, таких как массивы или объекты, для отправки данных в функцию, поэтому вам не нужно всегда изменять параметры, необходимые для функции
- использование ресурсов. Чем больше вы хотите, чтобы это было вокруг, общее решение, тем больше ресурсов он будет использовать.
Насколько сильно будет зависеть производительность, если я выберу * только в том случае, если вызывающей функции может понадобиться какая-либо информация из списка?
Это зависит от загрузки вашего сайта. Большую часть времени (если вы не тянете большие большие двоичные объекты и текст) * все в порядке, но когда ресурсов мало, вы должны указать столбцы. Таким образом, вы можете сэкономить время ввода-вывода.
Я чувствую, что это делает модель чрезвычайно раздутой и очень связанной, создавая много дублированного кода. Может быть лучше иметь такую модель;
Может быть попробовать это:
Прежде всего, для сложных запросов я использую этот класс, который я создал давно для MySQL. Это очень помогает.
class sqlAssembler
{
private $data = array();
var $S = array();
var $F = array();
var $W = array();
var $G = array();
var $H = array();
var $O = array();
var $L = array();
//Clause abbreviations
var $clauselist = array
(
'S' => 'SELECT',
'F' => 'FROM',
'W' => 'WHERE',
'G' => 'GROUP BY',
'H' => 'HAVING',
'O' => 'ORDER BY',
'L' => 'LIMIT'
);
//Default clause separators
var $clausesep = array
(
'S' => ',',
'F' => ',',
'W' => ' AND ',
'G' => ',',
'H' => ' AND ',
'O' => ',',
'L' => ''
);
function gen()
{
$tmp = '';
foreach ( $this->clauselist as $area => $clause )
{
if ( count($this->{$area}) )
{
$tmp .= ($clause != 'S' ? ' ' : '') . $clause . ' ';
for ($i=0; $i < count($this->{$area}); $i++)
{
//echo $area = (string)$area;
$tmp .= $this->{$area}[$i];
} //for
} //if
} //foreach
return $tmp;
} //function
function genSection($area, $showsection = 0)
{
$tmp = '';
if ( count($this->{$area}) )
{
for ($i=0; $i < count($this->{$area}); $i++)
{
$tmp .= $this->{$area}[$i];
} //for
} //if
return $tmp;
} //function
function clear()
{
foreach ($this as $area => $v)
{
//We only care about uppercase variables... do not declare any else variable with ALL UPPERCASE since it will be purged
if (ctype_upper($area))
{
if ($area == 'L')
$this->$area = '';
else
$this->$area = array();
} //if
} //foreach
} //function
public function add($area, $str, $criteria = 1, $sep = '#')
{
if ($criteria)
{
if ($sep == '#')
$sep = $this->clausesep[$area];
//Postgres' OFFSET should be set like: $str = '25 OFFSET 0'
//Not very neat I know, but fuck it
if ($area == 'L')
{
$this->{$area} = array();
} //if
//$ref = $this->$area;
$this->{$area}[] = (count($this->$area) ? $sep : '').$str;
return count($this->$area)-1;
} //if
} //function
public function del($area,$index)
{
if ( isset($this->{$area}[$index]) )
unset($this->{$area}[$index]);
else
trigger_error("Index nr. {$index} not found in {$area}!",E_USER_ERROR);
} //function
//-*-* MAGIC CHAIN FUNCTIONS
public function S($str,$criteria = 1,$sep = '#')
{
$this->add(__FUNCTION__,$str,$criteria,$sep);
return $this;
} //function
public function F($str,$criteria = 1,$sep = '#')
{
$this->add(__FUNCTION__,$str,$criteria,$sep);
return $this;
} //function
public function W($str,$criteria = 1,$sep = '#')
{
$this->add(__FUNCTION__,$str,$criteria,$sep);
return $this;
} //function
public function G($str,$criteria = 1,$sep = '#')
{
$this->add(__FUNCTION__,$str,$criteria,$sep);
return $this;
} //function
public function H($str,$criteria = 1,$sep = '#')
{
$this->add(__FUNCTION__,$str,$criteria,$sep);
return $this;
} //function
public function O($str,$criteria = 1,$sep = '#')
{
$this->add(__FUNCTION__,$str,$criteria,$sep);
return $this;
} //function
public function L($str,$criteria = 1,$sep = '#')
{
$this->add(__FUNCTION__,$str,$criteria,$sep);
return $this;
} //function
} //_sql
Может быть попробовать это:
function getShoppingCart($d)
{
$xx = new sqlAssembler();
$xx->S('*')->
F('items')->
//Notice, that we specified a criteria... if $d['id_item'] exists it will be joined to the WHERE clause, if not it will be left out
W("(id_item > '{$d[id_item]}')",$d['id_item'])->
//Same here
O("dt DESC",$d['date'])
$sql = echo $xx->gen();
//id_item = 11, date = 2009-11-12
//$sql = "SELECT * FROM items WHERE (id_item > '11') ORDER BY dt DESC";
//id_item = null, date = null
//$sql = "SELECT * FROM items";
$data = sqlArray($sql);
//... handle data
}