Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.10.2012, 13:03   #1
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
Восклицание Простая ORM, что тут можна сделать по другому?

Доброго времени суток.
Пытаюсь почистить и оптимизировать класс для работы с базой данных.

Вот например кусок кода где выполняется подключение и выбирается драйвер базы данных.

PHP код:
Class ORM{
        protected static 
$_table;
        protected static 
$_id;
        private 
$_driver;
        static private 
$_instance;
        
        public static function 
factory($table=NULL$id=NULL){
            if(!empty(
$table) || self::$_table!=$table && !empty($table)){
                    
self::$_table $table;
            }
            if(empty(
self::$_id) && !empty($id) || self::$_id != $id && !empty($table))self::$_id $id;

           
// проверяем актуальность экземпляра
           
if (!isset(self::$_instance)) { 
                
self::$_instance = new ORM
            }
            
            if(!empty(
$transaction)){
                if(
$transaction!==self::$_handle){
                }
            }

            
// возвращаем созданный или существующий экземпляр
            
return self::$_instance;
        }

    private 
$_handle null;
    
    private function 
__construct(){

        
$dbase Config::Ini(APPLICATION_PATH.'/configs/dbase.ini''dbase'1);

        
$driver "Driver_".$dbase['driver'];

           if(
file_exists(LIBRARY_PATH."/Kernel/Database/Driver.php")){
               include_once(
LIBRARY_PATH."/Kernel/Database/Driver.php");
                
$this->_driver = new $driver;
            
                    
$this->_handle $this->_driver->Connect($dbase);
                    
$this->_driver->Query("SET NAMES utf8"$this->_handle);
                    
$this->_driver->Select_db($dbase['database'], $this->_handle);
            }else{
                 throw new 
Exception('Драйвер не найден');
            }
    } 
пример использования:
PHP код:
ORM::factory('users')->и дальше какието действия 
иногда бывает что используется вот такой вариант
PHP код:
ORM::factory() 
тоесть не указывается ни имя таблицы ни айди.

И иногда все это начинает бесится и не очищает например переменную с именем таблицы и тогда начинает искать совсем в другой таблице то чего там нет.

Что подскажите? ((

PS: знаю что не нужно было обзывать так функцию factory(), но так уж сложилось что название осталось старое
dem66 вне форума Ответить с цитированием
Старый 14.10.2012, 15:00   #2
Cronos20
Форумчанин
 
Регистрация: 08.07.2010
Сообщений: 679
По умолчанию

Приводите примеры, когда скрипт ведет себя неправильно. Я не уверен, что вы везде в своем ORM правильно используете статические переменные класса .. даже тут встречается
self::$_handle и $this->_handle
... ох уж это php, когда оно будет кидать не warning, а error
И в чем например смысл вызова такого : ORM::factory() ?
А вот это совсем бред ...сами хоть прочитайте еще раз))
Код:
if(!empty($table) || self::$_table!=$table && !empty($table))
Тут скорее всего ваши проблемы
Будьте более строги в коде - никаких входящих $table по дефолту NULL !!
И в любом случае присваивать self::$_table = $table;

Последний раз редактировалось Cronos20; 14.10.2012 в 15:04.
Cronos20 вне форума Ответить с цитированием
Старый 14.10.2012, 15:37   #3
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
По умолчанию

по поводу конструктора.

Он же стартует самый первый и ему какая разница статические методы или нет.
результат соединения записывается в $this->_handle ну и далее используется уже в других методах, которые не статичны.

Или я чтото не догнал?

Привожу пример кода (рабочий):

ORM (запись в базу):
PHP код:
private $_construkt = array();

public function 
__set($key$var){
         if(
$key[0]!="_"){
                
$this->_construkt[$key] = $var;
          }
}

public function 
flush(){
        
$sql="INSERT INTO ".self::$_table."(`".implode("`,`"array_keys($this->_construkt))."`) values('".implode("','"array_values($this->_construkt))."')";
        
$sql str_replace("'',""NULL,",$sql);

                
$this->_construkt NULL;
                
                if(
$this->_driver->Query($sql$this->_handle)==true){
                    return 
true;
                }else{
                    return 
false;
                }

Использование:

PHP код:
    $orm ORM::factory('user');
    
$orm->name 'Петров';
    
$orm->age 100;
    
$orm->flush(); 
А можна вот так:
PHP код:
    $orm ORM::factory('user');
    
$orm->name 'Петров';
    
$orm->age 100;
    
$orm->flush();
    
    
$orm->name 'Сидоров';
    
$orm->age 150;
    
$orm->flush(); 
Можно созлать запрос вручную
PHP код:
    ORM::factory()->prepare("INSERT INTO `user`(`name`,`age`) VALUES('Петров','100'),('Сидоров','150')")->execute(); 
PHP код:
public function prepare($sql$param=NULL){
        if(isset(
$param)){
            
$sql str_replace('?'"'".implode("','"array_values($param))."'"$sql);
        }
        if(
strtolower(substr(trim($sql),0,6))=='insert'){
            
preg_match_all("|\([^>]+\)|U"$sql$result);
            
$polya explode(','$result[0][0]);
            
$data explode(','$result[0][1]);

            if(
count($polya)>count($data)){
                
trigger_error("в структуре SQL запроса. Количество столбцов с данными больше чем указаное количество столбцов<br><font color='red'>".implode(", "array_values($polya))."</font> > количества столбцов с данными"E_USER_WARNING);
                exit;
            }
            if(
count($polya)<count($data)){
                
trigger_error("в структуре SQL запроса. Количество столбцов с данными меньше чем указаное количество столбцов<br><font color='red'>".implode(", "array_values($polya))."</font> < количества столбцов с данными"E_USER_WARNING);
                exit;
            }
        }

        
$this->_sql $sql;
                
        return 
$this;
    }
public function 
execute(){
        if(
$this->_driver->Query($this->_sql$this->_handle)==true){
            
$this->_sql NULL;
            return 
true;
        }else{
            
$this->_sql NULL;
            return 
false;
        }

В prepare есть доп возможности которые я не использую, поэтому и не описываю накой таи $param, $polya и т.д.

Как бы это на пальцах обяснить.. Лучше выложу готовый код и позже напишу примеры, array_keys($this-
Вложения
Тип файла: txt Driver.txt (2.3 Кб, 130 просмотров)
Тип файла: txt Orm.txt (19.8 Кб, 135 просмотров)
dem66 вне форума Ответить с цитированием
Старый 14.10.2012, 16:15   #4
frommars
Форумчанин
 
Регистрация: 02.07.2011
Сообщений: 144
По умолчанию

а чем PDO не угодил?
frommars вне форума Ответить с цитированием
Старый 14.10.2012, 17:48   #5
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
По умолчанию

нуу.... тема не про pdo
dem66 вне форума Ответить с цитированием
Старый 14.10.2012, 18:17   #6
Cronos20
Форумчанин
 
Регистрация: 08.07.2010
Сообщений: 679
По умолчанию

Ну я ж написал .. проверьте условие, чтобы было хотя бы так
Код:
public static function factory($table=NULL, $id=NULL){
            if($table !== null)
		self::$_table = $table;
Еще не обнаружил, где там у вас соединение закрывается .. ну это так.
Cronos20 вне форума Ответить с цитированием
Старый 14.10.2012, 18:35   #7
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
По умолчанию

а оно и не знакрывалось. просто так как это синглтон то оно же тут получается держится до завершения работы скрипта. когда первый раз подключается и идентификатор записывается в $this->_handle

Или я неправ?

если закрывать то это же при каждом запкросе к базе оно будет постоянно создаватся

PS: спасибо за помощь, уже исправляю

PSSS: Переделал

Теперь выглядит так:

PHP код:
public static function factory($table=NULL$id=NULL){
            if(
$table !== null){
                    
self::$_table $table;
                    
                    if(
$id != null){self::$_id $id;}
            }
            
           
// проверяем актуальность экземпляра
           
if (!isset(self::$_instance)) { 
                
self::$_instance = new ORM
            }

            
// возвращаем созданный или существующий экземпляр
            
return self::$_instance;
        } 
Но теперь вопрос, а что если я сделаю так:

ORM::factory('user')
// тут какието действия. имя таблицы записывается в self::$_table

теперь для чего то другого делаю

ORM::factory()
//делаю какието действия. Но хоть и имя таблицы не передано оно всеравно хранится в self::$_table и потом может вылезти боком. например бывали случаи когда указываю новое имя таблыцы а старое, хранящееся в self::$_table оно тупо не переписывало и искало в другой таблыце которая была указана ранее. вот поэтому я там и делал столько проверок.


и не совсем понятно это:

Цитата:
Сообщение от Cronos20 Посмотреть сообщение
....статические переменные класса .. даже тут встречается
self::$_handle и $this->_handle
ведь метод фактори создает экземпляр своего же класа и возвращает его для дальнейшей работы. Обычный же синглтон

фактори статичный ну и саписывает данные в статичные свойства. Когда вернет екземпляр с ним же уже можно будет работать через $this. Или я опять чтото не догоняю? (

Последний раз редактировалось dem66; 14.10.2012 в 18:53.
dem66 вне форума Ответить с цитированием
Старый 14.10.2012, 23:05   #8
9i.
Форумчанин
 
Регистрация: 29.09.2011
Сообщений: 103
По умолчанию

this используется для обычных свойств класса, а self для статических вот в чем разница, а не в том кто и что возвращает.
дальше статическая переменная хранится вне зависимости от количества объектов которые вы создаете, то-есть если Вы вначале передали свойство user, а в следующий раз ничего не передаете то понятно, что в вашей статической переменной будет тот самый user, а это происходит потому, что вы здесь
Код:
            if($table !== null){ 
                    self::$_table = $table; 
                     
                    if($id != null){self::$_id = $id;} 
            }
делаете, дословно ЕСЛИ имя таблицы задано присвоить имя таблицы ИНАЧЕ использовать то, что храниться в статической переменной table. Такая-же ситуация и с id
9i. вне форума Ответить с цитированием
Старый 14.10.2012, 23:34   #9
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
По умолчанию

Цитата:
Сообщение от 9i. Посмотреть сообщение
this используется для обычных свойств класса, а self для статических вот в чем разница, а не в том кто и что возвращает.
дальше статическая переменная хранится вне зависимости от количества объектов которые вы создаете, то-есть если Вы вначале передали свойство user, а в следующий раз ничего не передаете то понятно, что в вашей статической переменной будет тот самый user
ну это я как бы знаю, видно я не так выразился, я немножко о другом говорил.

вы пишите что если первый раз передаю название таблыцы то оно записывается и будех хранится и используется тогда когда я ничено не передам. НО я ведь говорил о том что и когда указываю название таблыцы то предыдущий вариант оно может не перезаписать. такое бывало когда не добавил те условия о которых говорили выше.

Поэтому я и проверял тут:
PHP код:
if(!empty($table) || self::$_table!=$table && !empty($table)) 
1. если название таблицы передано то однозначно перезаписываем _table
2. если переданое название таблицы совпадает с тем что в _table

ойй...

кажись нашел свою ошибку..
должно быть чтото типа этого:
PHP код:
if(!empty($table) && empty(self::$_table) || self::$_table!=$table && !empty($table)) 
1. если название таблицы передано и _table пустое то перезаписываем _table
2. если переданое название таблицы совпадает с тем что в _table

Просьба поправить если не так.

-------------------------------

А что скажите по поводу формирования условий запроса?
PHP код:
public function Where($where$velue=NULL){

            if(
is_array($where)){
                foreach(
$where as $key=>$value){
                    
$this->Build($key$value,  "AND");
                }
            }else{
                
$this->Build($where$velue,  "AND");
            }
                
            return 
$this;
}
public function 
Build($str$str2$type){
            
$tmp explode(" "$str);
            
$array = array();

            foreach(
$tmp as $val){
                if(!empty(
$val)){
                   
$array[] = $val;
                }
            }

              if(
substr_count($array[0],'.')==0){
                  
$pole '`'.$array[0].'`';
              }else{
                  
$pole $array[0];
              }

              if(
substr_count($str2,' ')>&& substr_count($str2,'.')>|| substr_count($str2,' ')==&& substr_count($str2,'.')==0){
                  
$data "'".$str2."'";
              }elseif(
substr_count($str2,' ')==&& substr_count($str2,'.')==1){
                  
$data $str2;
              }elseif(
substr_count($str2,' ')==&& substr_count($str2,'.')>=2){
                  
$data $str2;
              }else{
                  
$data "`".$str2."`";
              }

              if(!isset(
$array[1])){
                  
$uslov '=';
              }else{
                  
$uslov $array[1];
              }

              if(empty(
$this->_where)){
                  
$nach " WHERE ";
              }elseif(!empty(
$this->_where) && $type!="OR"){
                  
$nach " AND ";
              }else{
                  
$nach " OR ";
              }
              
                  switch(
$type){
                      case(
"AND"):
                          
$this->_where .= $nach.$pole.$uslov.$data;
                      break;
                      case(
"OR"):
                          
$this->_where .= $nach.$pole.$uslov.$data;
                      break;
                      case(
"IN"):
                          
$this->_where .= $nach.$pole." IN (".$data.")";
                      break;
                      case(
"LIKE"):
                          
$this->_where .= $nach.$pole." LIKE ".$data;
                      break;
                  }
          

Составляется запрос так:

PHP код:
....->Where('id',5)->... 
после сборки запрос будет иметь следующий вид:

Код:
WHERE `id` = '5'
или

PHP код:
....->Where(array('age'=>">= 10",'age'=>"<= 20",'avtiv'=>1))->... 
после сборки запрос будет иметь следующий вид:

Код:
WHERE `age` >= '10'  AND `age` <= '10'  AND `avtiv`='1'
или так

PHP код:
....->Where(array('age'=>"10",'avtiv'=>1))->... 
после сборки запрос будет иметь следующий вид:

Код:
WHERE `age` = '10' AND `avtiv`='1'
________

substr_count тут доля того чтоб з нать есть ли точка или нет. Например для запросов с джойнами.

PHP код:
....->Where('razdel.id''content.razdel'))->... 
после сборки запрос будет иметь следующий вид:

Код:
WHERE razdel.id = content.razdel

Последний раз редактировалось dem66; 15.10.2012 в 14:55.
dem66 вне форума Ответить с цитированием
Старый 16.10.2012, 15:57   #10
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
По умолчанию

ауу. так что с темой. вижу пока не создам новое сообщение никто в тему не заглянет, да простят меня модераторы
dem66 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ORM валидация в Kohana Anoobis PHP 2 10.06.2011 15:12
Я где-то читал, что на C можна писать драйвера, а ОС без асма, только с C можно? pufystyj Свободное общение 31 01.03.2011 20:03
Что тут сделать нужно Rastislav Паскаль, Turbo Pascal, PascalABC.NET 9 08.10.2010 19:45
Зацените кому не лень сайт и напишите что туда можна еще добавить Антон112 Помощь студентам 8 27.03.2010 09:09
Что то не работает посмотрите и есле можна исправте Krumyura Общие вопросы C/C++ 7 11.03.2010 20:14