За последние 24 часа нас посетили 18629 программистов и 1702 робота. Сейчас ищут 898 программистов ...

DBSimple Where and/or.. или как я придумал php active record

Тема в разделе "PHP и базы данных", создана пользователем jov27384, 5 ноя 2010.

  1. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    Собственно вся проблема в том что не могу найти как это красиво сделать
    PHP:
    1.  
    2. <?php
    3. function loadThis($where)
    4. {
    5.      $this->salf_array = @$this->db->selectRow('SELECT * FROM ?# WHERE ?a', $this->table_names, $where);
    6. }
    7. ?>
    8.  
    Если передать что то типа
    PHP:
    1.  
    2. <?php
    3. loadThis(array('userid'=>'UserName'));
    4. ?>
    5.  
    То все в порядке запрос получится следующий
    [sql]
    SELECT * FROM users WHERE `userid` = 'UserName'
    [/sql]
    Но если
    PHP:
    1.  
    2. <?php
    3. loadThis(array('userid'=>'UserName', 'password'=>'scret_password'));
    4. ?>
    5.  
    То получится не красиво
    [sql]
    SELECT * FROM users WHERE `userid` = 'UserName', `password` = 'scret_password'
    [/sql]
    Что совсем не устраивает ни сервер не меня....
    А мне нужно чтобы была возможность передать и AND и OR и переменное количество условий?????
    Т.Е. стандартное решение с макроподстановкой (WHERE 1=1 {......}) не устраивает по причине "переменное количество условий"
    Помогите, может кто знает красивое решение???
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    ты о чем?
     
  3. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    [sql]
    SELECT * FROM users WHERE `userid` = 'UserName', `password` = 'scret_password'
    SELECT * FROM users WHERE `userid` = 'UserName' AND `password` = 'scret_password'
    [/sql]

    Обрати внимание на AND в запросе.
     
  4. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    =) дык обрати внимание на мой вопрос: ты о чем? может я просто не в теме, ты расскажи. Просто я не понимаю твоего вопроса. Если тебе надо АНД поставить, дык ты поставь, в чем беда? :D
     
  5. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    Беда в том что в DBSimple работа построена на плейсхолдерах (довольно таки удобно) и я не знаю и не нашел в доках как эти конструкции использовать чтобы давать DBSimple массив а она в него вместо запятых в нужном месте AND или OR ставила.
     
  6. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    jov27384
    блин, а кто тебя дернул на эту бдсимпл? чем mysqli не угодил?

    ладно, молчу. Личное дело каждого с чем... и в какую дырку.
     
  7. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    =) Удобная она, да и время на "своё" не хочется тратить, а тут блин - засада на самом интересном месте хоть бери да сам пиши....
     
  8. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    jov27384
    открой файл с классом и найди где и как это делается, если нету допиши, если не можешь полностью сам составляй запрос
     
  9. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    jov27384
    удобная? о_О
    чем запись
    'SELECT * FROM ?# WHERE ?a', $переменная_раз, $переменная_два
    проще чем
    "SELECT * FROM $переменная_раз WHERE $переменная_два"? =)
    кроме простоты получения геморроя упомянутого в первом сообщении?

    не, я все. я молчу.
     
  10. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    Там не просто переменная, там массив.
    Сейчас класс выложу.
     
  11. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    PHP:
    1.  
    2. <?php
    3. /**
    4.  * Description of MyObject
    5.  *
    6.  * @author oleg
    7.  */
    8. class MyObject {
    9.     //Массив с полями обьекта
    10.     protected $salf_array;
    11.     //Ссылка на обьект
    12.     protected $db;
    13.     //Условие по умолчанию
    14.     protected $default_where;
    15.     //Имя таблицы
    16.     private $table_names;
    17.     //Список полей защищенных от записи
    18.     private $protected_fields;
    19.  
    20.     public function __construct(DbSimple_Generic_Database $db, $default_where) {
    21.         $this->db = &$db;
    22.         $this->default_where = $default_where;
    23.         $this->protected_fields = array();
    24.         $this->table_names = array();
    25.     }
    26.  
    27.     public function __get($name) {
    28.         if($name == "salf_array")
    29.             return $this->salf_array;
    30.         elseif(isset ($this->salf_array[$name]))
    31.             return $this->salf_array[$name];
    32.         else
    33.             return false;
    34.     }
    35.     public function __set($name, $value) {
    36.         if(array_search($name, $this->protected_fields, true))
    37.                 return false;
    38.         elseif(isset ($this->salf_array[$name])) {
    39.             $this->salf_array[$name] = $value;
    40.             return true;
    41.         }
    42.         else
    43.             return false;
    44.     }
    45.  
    46.     protected function addProtectedField($field_name)
    47.     {
    48.         $this->protected_fields[] = $field_name;
    49.     }
    50.  
    51.     protected function addTableName($table_name)
    52.     {
    53.         $this->table_names[] = $table_name;
    54.     }
    55.  
    56.     protected function loadThis()
    57.     {
    58.         $this->salf_array = @$this->db->selectRow('SELECT * FROM ?# WHERE ?a', $this->table_names, $this->default_where);
    59.     }
    60.  
    61.     protected function safeThis()
    62.     {
    63.         @$this->db->query('UPDATE ?# SET ?a WHERE ?a', $this->table_names, $this->getSaveSalfArray(), $this->default_where);
    64.     }
    65.  
    66.     protected function newThis()
    67.     {
    68.         @$this->db->query('INSERT INTO ?#(?#) VALUES(?a)', $this->table_names, array_keys($this->salf_array), array_values($this->salf_array));
    69.     }
    70.  
    71.     protected function deleteThis()
    72.     {
    73.         @$this->db->query('DELETE FROM ?# WHERE ?a', $this->table_names, $this->default_where);
    74.     }
    75.  
    76.     private function getSaveSalfArray()
    77.     {
    78.         $result = $this->salf_array;
    79.         for($i = 0; $i<count($this->protected_fields); $i++){
    80.             unset ($result[$this->protected_fields[$i]]);
    81.         }
    82.         return $result;
    83.     }
    84. }
    85. ?>
    86.  
     
  12. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
  13. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    У меня есть вот такие методы:

    PHP:
    1. <?php
    2.         public function getSelect($arr, $tab=null, $where=null, $numUnion=0){
    3.             if (is_array($arr)){
    4.                 if (empty($tab)  || !is_string($tab)) throw new FormatException("Не задана таблица для выбора","Неверный тип данных");
    5.                
    6.                 $fields="";
    7.                 foreach($arr as $val){
    8.                     $fields .=$this->escapeKeys($val).",";
    9.                 }
    10.                 $fields=trim($fields,",");
    11.                
    12.                 $expr=$this->getWhere($where);
    13.                
    14.                 $sql="select $fields from $tab ".$expr; //Создаем запрос
    15.             }
    16.             else{
    17.                 $sql=trim($arr."");
    18.             }
    19.             $this->checkQuery($sql, $numUnion);
    20.             return $sql;
    21.         }
    22.  
    23.         public function getWhere($where){
    24.                 if (is_array($where)) return " where ".$this->getAssignmentString($where, " and");
    25.                 if (is_int($where)) return " where id=".$where;
    26.                 if (!empty($where)) return " where ".$where;
    27.                 return'';
    28.         }
    29.  
    30.         public function getAssignmentString($arr, $delim){
    31.             $rez="";
    32.             foreach($arr as $key=>$val){
    33.                 $rez .= $this->escapeKeys($key)."=".$this->escapeString($val).$delim;
    34.             }
    35.             $rez=substr($rez,0,-strlen($delim));
    36.             return $rez;
    37.         }
    38.  
    39.         public function escapeString($str){
    40.             if (is_array($str)){
    41.                 foreach($str as $key=>$val){
    42.                     $str[$key]=$this->escapeString($val);
    43.                 }
    44.                 return $str;
    45.             }
    46.             if (is_null($str)) return "NULL";
    47.             if (is_string($str)) return "'".$this->escape($str)."'";
    48.             return $str;
    49.         }
    50.  
    51.         public function escapeKeys($key){
    52.             if ($key==="*") return "*";
    53.             return $this->LKS.$key.$this->RKS;
    54.         }
    55.  
     
  14. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    Спасибо, интересно, но не решает вопрос о более сложном WHERE, т.е. более сложный придется писать и эскейпить.
    Сейчас сижу велосипед придумываю, зацените:

    PHP:
    1.  
    2. <?php
    3.  
    4. $query = array(
    5.     'type'=>'query',
    6.     'statement'=>'select',
    7.     'query'=>array(
    8.         'select_option'=>'', //[DISTINCT | DISTINCTROW | ALL]
    9.         'field_names'=>'*', // '*' | массив с именами полей | асоциативный массив для псемдонимов
    10.         'teble_names'=>'users', //или массив с именами таблиц
    11.         'where'=>array(
    12.             array('user_id'=>586, 'first'),
    13.             array('password'=>md5('суперсекретныйпароль'), 'operation'=>'and'),
    14.             array('active'=>'true', 'operation'=>'and')
    15.         )
    16.     )
    17.     );
    18.  
    19. print_r($query);
    20.  
    21. $query = new SQLQuery($query);
    22.  
    23. print $query->getSQLQuery();
    24.  
    25. ?>
    26.  
     
  15. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    Застрял на вопросе а как при помощи этого сделать что то вроде:
    [sql]
    SELECT * FROM `table` WHERE 1=1 AND (`int1`-`int2`)>225
    [/sql]
     
  16. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Может стоит взять некую ORM?
     
  17. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    Млин во я велосипедист.....
    Сейчас читаю код Doctrine и вижу что они написали то что я так долго выдумывал....

    Вечно так, что ни придумаю, то уже кто то написал... ))))
     
  18. Зверь

    Зверь Активный пользователь

    С нами с:
    2 ноя 2010
    Сообщения:
    80
    Симпатии:
    0
    Адрес:
    Екатеринбург
    jov27384
    Я бы тебе посоветовал сразу начать изучать класс работы с БД PDO, т.к. если я не ошибаюсь он один из самых современных (если я не прав поправьте) и позволяет работать с разными БД, а не только с mysql. Написать свой класс конечно полезно для общего развития, но на практике лучше применять, что-то более проверенное. Под проверкой я подразумеваю то, что написано не только вами, а несколькими людьми и признано также несколькими, причем более опытными чем вы (это не про себя, а про тех кто создал и пользуется).
    По изучайте лучше PDO, придумать какое-нибудь расширение для него.
     
  19. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    Друзья, прежде чем что либо сказать, пожалуйста, прочтите все что написано выше и постарайтесь вникнуть в суть вопроса.
    Спасибо.
     
  20. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    А вот собственно та замудренная штука что я выдумывал... (только её у меня украли))) )
    http://www.phpactiverecord.org/
     
  21. pohapecoder

    pohapecoder Активный пользователь

    С нами с:
    16 окт 2010
    Сообщения:
    63
    Симпатии:
    0
    ну ты и лошара!
     
  22. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    Сам в шоке.
     
  23. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    PHP:
    1.     <?php
    2. class Zapis {
    3.        
    4.         /**
    5.          * Объект для работы с БД.
    6.          * @var object
    7.          */
    8.         protected $db;
    9.        
    10.        
    11.         /**
    12.          * Имя таблицы, из которой беруться записи.
    13.          * @var string
    14.          */
    15.         protected $table;
    16.  
    17.         /**
    18.          * Имя поля с идентификатором.
    19.          * @var string
    20.          */
    21.         protected $idField;
    22.        
    23.         /**
    24.          * Массив полей записи. Ключи - имена полей.
    25.          * @var array
    26.          */
    27.         protected $fields=array();
    28.  
    29.         /**
    30.          * Массив полей пустой записи. Ключи - имена полей.
    31.          * @var array
    32.          */
    33.         protected $emptyFields=array("id"=>-1);
    34.        
    35.        
    36.         /**
    37.          * Конструктор.
    38.          *
    39.          * @param string $table Имя таблицы, из которой беруться записи.
    40.          * @param mixed $id Если задан этот параметр, то запись инициализируется соответствующей строчкой из таблицы.
    41.          *              Если это строка или число, то считается идентификатором записи.
    42.          *              Если это массив, то ключи - имена полей, значения - значения полей.
    43.          *              По сути $id передается в {@link Zapis::select()}
    44.          * @param string $idField Имя поля идентификатора.
    45.          * @param object $db Объект для работы с БД.
    46.          */
    47.         public function __construct($table, $id=null, $idField='id', $db=null){
    48.             $this->db=$db ? $db : SQLDBFactory::getDB();
    49.             if (is_array($id)){
    50.                 $dbId=$id;
    51.             }elseif(!is_null($id)){
    52.                 $dbId=$this->db->escapeString($id);
    53.             }
    54.             $this->table=$table;
    55.             $this->idField=$idField;
    56.             if(!is_null($id)){
    57.                 $this->select($dbId);
    58.             }          
    59.            
    60.         }
    61.        
    62.         /**
    63.          * Магическое получение значения поля.
    64.          *
    65.          * @param string $var Имя поля
    66.          * @return mixed Значение поля
    67.          */
    68.         public function __get($var){
    69.             $method="get".ucfirst($var);
    70.             if (method_exists($this, $method)){
    71.                 return $this->$method();
    72.             }
    73.             return $this->fields[$var];
    74.         }
    75.        
    76.         /**
    77.          * Магическая запись значения поля.
    78.          *
    79.          * @param string $var Имя поля
    80.          * @param mixed $val Значение поля
    81.          */
    82.         public function __set($var, $val){
    83.             $method="set".ucfirst($var);
    84.             if (method_exists($this, $method)){
    85.                 $this->$method($val);
    86.             }else{
    87.                 $this->fields[$var]=$val;
    88.             }
    89.         }
    90.        
    91.         /**
    92.          * Подготовка с сериализации
    93.          */
    94.         public function __sleep(){
    95.             return array("table", "idField", "fields", "emptyFields");
    96.         }
    97.        
    98.         /**
    99.          * Восстановление соединения при десериализации.
    100.          */
    101.         public function __wakeup(){
    102.             $this->db=SQLDBFactory::getDB();
    103.         }
    104.        
    105.         /**
    106.          * Сбрасывает данные о полях записи.
    107.          */
    108.         public function reset(){
    109.             $this->fields=array();
    110.         }
    111.        
    112.         /**
    113.          * Выбор записи по идентификатору
    114.          *
    115.          * @param mixed $fields Если это строка или число, считается идентификатором записи.
    116.          *                  Если это массив, то ключи - имена полей, значения - значения полей.
    117.          */
    118.         public function select($fields){
    119.             if (is_null($fields) || is_object($fields)){
    120.                 $this->fields=$this->emptyFields;
    121.                 return;
    122.             }
    123.             if (!is_array($fields)){
    124.                 $dbFields=array($this->idField=>$fields);
    125.             }else{
    126.                 $dbFields=$fields;
    127.             }
    128.             $row=$this->db->getAssoc(array("*"), $this->table, $dbFields);
    129.             $this->fields= $row ? $row : $this->emptyFields;
    130.         }
    131.        
    132.         /**
    133.          * Вставка записи в таблицу.
    134.          *
    135.          * Вставляет текущую запись в таблицу.
    136.          * Затем выбирает ее в текущий объект.
    137.          * Это нужно для заполнения значений по умолчанию и прочих значений, которые выставляются самой СУБД.
    138.          */
    139.         public function insert(){
    140.             $fields=$this->fields;
    141.             if (isset($fields[$this->idField])){
    142.                 unset($fields[$this->idField]);
    143.             }
    144.             $newId=$this->db->insert($fields, $this->table);
    145.             $this->select($newId+0);
    146.         }
    147.        
    148.         /**
    149.          * Обновляет информацию в таблице в соответствии с данными объекта.
    150.          */
    151.         public function update(){
    152.             $fields=$this->fields;
    153.             if (isset($fields[$this->idField])){
    154.                 $id=$fields[$this->idField];
    155.                 unset($fields[$this->idField]);
    156.             }
    157.             $this->db->update($fields, $this->table, array($this->idField=>$id));
    158.             $fields[$this->idField]=$id;
    159.         }
    160.        
    161.         /**
    162.          * Обновляет существующую запись или вставляет новую если запись не существует.
    163.          */
    164.         public function insertOrUpdate(){
    165.             if ($this->id==-1){
    166.                 $this->insert();
    167.             }else{
    168.                 $this->update();
    169.             }                              
    170.         }
    171.  
    172.         /**
    173.          * Выбирает существующую запись или вставляет новую если запись не существует.
    174.          *
    175.          * @param mixed $fields Если это строка или число, считается идентификатором записи.
    176.          *                  Если это массив, то ключи - имена полей, значения - значения полей.
    177.          */
    178.         public function selectOrInsert($fields){
    179.             $this->select($fields);
    180.             if (!$this->exists()){
    181.                 $this->fields=$fields;
    182.                 $this->insert();
    183.             }                              
    184.         }
    185.        
    186.         /**
    187.          * Удаляет запись из таблицы.
    188.          */
    189.         public function delete(){
    190.             $this->db->delete($this->table, array($this->idField=>$this->id));
    191.         }
    192.        
    193.         /**
    194.          * Определяет определен ли объект записью из базы.
    195.          *
    196.          * @return bool true - если объект соответствует записи в базе, false - в противном случае.
    197.          */
    198.         public function exists(){
    199.             return $this->id!=-1;
    200.         }
    201.        
    202.     }
     
  24. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    Поясни, пожалуйста, что за код(в смысле чей)???
    Твой или откуда еще?
     
  25. jov27384

    jov27384 Активный пользователь

    С нами с:
    14 сен 2009
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Тюмень
    У меня была идея в следующем
    два исходных класса
    Object
    и
    Objects

    Т.е. при работе с одним конкретным объектом берем
    PHP:
    1.  
    2. <?php
    3. class User extends Object .....
    4. User->userName = 'Пользователь';
    5. User->saveUser();
    6. ?>
    7.  
    И т.д.

    А при работе с множеством объектов

    Users extends Objects .....

    Ну и вытекающие
    PHP:
    1.  
    2. <?php
    3. //Представление
    4. $pepresentation = new Pepresentation((array('userid'=>'Имя пользователя'));
    5. //Запрос
    6. Users->setPepresentation($pepresentation);
    7. //вывод
    8. print Users->getHTMLtable();
    9. ?>
    10.  
    Генерация форм и т.д.