Проблема с абстрактным доступом к БД

Astral Man

We Will Rock You
Проблема с абстрактным доступом к БД

Добрый день!

Я использую абстрактный доступ к БД, код взял из книги "Профессиональное РНР программирование 2-е издание"

Сначало все работало нормально (код был еще маленький), когда появилось куча функция я начал теряться.
В функциях могут быть запросы в БД вот здесь я запнулся, что нужно, создовать новый экземпляр класса БД, или исльзовать глобальную переменную с экземпляром.
Как вообще правильно пользоваться абстрактным доступом?
кажный раз открывать соединение, выполнять запрос и закрывать его?
и еще появляется варнинг типа:
Warning: mssql_close(): 35 is not a valid MS SQL-Link resource in c:\usr\apache\host\dev\include\class\db\mssql.php on line 64

Уже незнаю что делать... народ объясните плиз.

Спасибо!!!
 

Demiurg

Guest
А ты уверен что тебе нужен этот самый абстрактный доступ ?

объект должен быть один, а как его куда передавать - тебе решать. Можно сделать глобальный, можно сделать синглетон. А вот закрывать соединение не обязательно, php сам закрывает все соедтинения.
 

Astral Man

We Will Rock You
Автор оригинала: Demiurg
А ты уверен что тебе нужен этот самый абстрактный доступ ?
Я думаю абстрактный доступ надо делать сразу т.к. может поменятся БД на другую.

Можно сделать глобальный, можно сделать синглетон.
Что такое синглетон?

А сложно использовать PEAR::DB ? случайно нет доки на русском языке? а то с английским фигово :)
 

Demiurg

Guest
Проблема в том, что абстракция субд подразумевает запросы, который будут работать на всех субд, а это значит очень простые. А у каждой субд есть свои особенности от которых придется отказаться.

-~{}~ 23.07.04 10:37:

>Что такое синглетон?
http://www.phppatterns.com/index.php/article/articleview/6/1/1/
 

Astral Man

We Will Rock You
Автор оригинала: Demiurg
Проблема в том, что абстракция субд подразумевает запросы, который будут работать на всех субд, а это значит очень простые. А у каждой субд есть свои особенности от которых придется отказаться.

-~{}~ 23.07.04 10:37:

>Что такое синглетон?
http://www.phppatterns.com/index.php/article/articleview/6/1/1/
Это я понимаю, вот ты знающий человек, посоветуй как надо, писать под определенные СУБД или ограничиваться тем что дает абстрактный доступ?
И все же что такое синглетон? :)
 

Demiurg

Guest
Я привел доводы. Если есть, что возразить, я выслушаю.
Про синглетон я тоже ответил.
 

Astral Man

We Will Rock You
Автор оригинала: Demiurg
Про синглетон я тоже ответил.
Сорри сразу не заметил.
Думаю возражений нету. Спасибо.

-~{}~ 23.07.04 11:56:

Demiurg
Забыл спросить.
если я использую запросы типа:

PHP:
$db->open();
    $sql = "SELECT *
                 FROM   ".DB_PREFIX."_user
                 WHERE  login = '$login' and pass = '$password'";
$db->query($sql);
while ($result = $db->fetch_assoc()) {
    $id_user = $result['id_user'];
    $db->open();
        $sql = "SELECT *
                     FROM   ".DB_PREFIX."_mod
                     WHERE  id_user = '$id_yser'";
    $db->query($sql);
        while($result = $db->fetch_assoc()) {
            echo $result['mod']
        }
}
то нужно для каждого запроса создавать новых экземпляр?
или как?
 

Demiurg

Guest
ты читаешь, что тебе отвечают ?
объект должен быть один, если у тебя один коннект.

А то, что ты делаешь можно смело уместить в один запрос.
 

Astral Man

We Will Rock You
Автор оригинала: Demiurg
ты читаешь, что тебе отвечают ?
объект должен быть один, если у тебя один коннект.

А то, что ты делаешь можно смело уместить в один запрос.
Да это я к примеру, а как быть в этом случае:
PHP:
function main_menu()
{

    $db   = new DB(DB_HOST, DB_USER, DB_PASS, DB_NAME);
    $db2  = new DB(DB_HOST, DB_USER, DB_PASS, DB_NAME);
    
    $id_user = $_SESSION['id_user'];
    
    $db->open();
    $sql = "SELECT * 
            FROM   ".DB_PREFIX."_user_group a INNER JOIN ".DB_PREFIX."_group b
            ON     a.id_group = b.id_group
            WHERE  a.id_user = ".$id_user."
            ORDER  BY name ";
    $db->query($sql);
    
    while($result = $db->fetch_assoc()) {
        
        $name_group = $result['name'];     // Название группы меню
        $id_group[] = $result['id_group']; // Идентификатар группы
    
        echo "
            <a href=\"#\" onmouseover=\"mainMenuMouseOver('group".$result['id_group']."')\" onmouseout=\"mainMenuMouseOut('group".$result['id_group']."')\">
                ".$name_group."    
            </a>";
        
        $db2->open();
        $sql2 = "SELECT * 
                 FROM   ".DB_PREFIX."_group_mod a INNER JOIN ".DB_PREFIX."_mod b
                 ON     a.id_mod = b.id_mod
                 WHERE  a.id_group = ".$result['id_group']."
                 ORDER  BY name";
        $db2->query($sql2);
        
        echo "<div id=\"group".$result['id_group']."\" class=\"menu2\" onmouseover=\"subMenuMouseOver(this)\" onmouseout=\"subMenuMouseOut(this)\">";
        
            while($result2 = $db2->fetch_assoc()) {
            
                $id_mod   = $result2['id_mod']; // Идентификатор суб меню
                $name_mod = $result2['name'];   // Суб меню
             
                echo "<a href=\"".$_SERVER['PHP_SELF']."?mod=".$id_mod."\">".$name_mod."</a>";
            }
        
        echo "</div>";        
               
    }
    
    echo "<a href=\"".$_SERVER['PHP_SELF']."?logout=1\">Выход</a>";
    
    // Закрываем соединения
    $db->close();
    $db2->close();
}
Я понимаю что код кривой и может его читать даже никто не будет, но прошу подсказать как быть в такой ситуации?
 

Demiurg

Guest
и тут тоже можно одним запросом обойтись.
Если у тебя в классе, который работает с БД, может содиржаться только один рекордсет, то да, придется делать несколько экземпляров, что не логично. Вот тебе и еще один минус.
 

Demiurg

Guest
если ты скажешь что у тебя за таблицы и что тебе надо получить, то смогу.
 

Astral Man

We Will Rock You
group
id_group|name|status

user_group
id_group|id_user

mod
id_mod|name|sys_name|status|submod|

group_mod
id_mod|id_group

Зная ИД юзера смотрим какие группы для него доступны, выводим ссылки. Потом для каждой группы выводим ссылки меню в одтельный div (вертикальное меню получается)
Надеюсь ты меня понял.
 

Demiurg

Guest
select ..
from group
join user_group on user_group.id_group = group.id_group
left join group_mod on group_mod.id_group = group.id_group
left jon mod on mod.id_mod = group_mod.id_mod
where user_group.id_user = $user_id

примерно так, но на 100% не уверен.
 

fisher

накатила суть
че-то тут путаница имхо. сам вопрос к понятию "абстрактного доступа" имхо отношения не имеет.

офтоп:
под абстрактным доступом щас понимают две вещи: абстрактный интерфейс к вызову базовых функций (PEAR::DB) и абстрактный интерфейс операций над моделью

Автор оригинала: Demiurg
Проблема в том, что абстракция субд подразумевает запросы, который будут работать на всех субд, а это значит очень простые. А у каждой субд есть свои особенности от которых придется отказаться.
это как раз если случай #2. но все равно даже в этом контексте абстракция СУБД подразумевает не совсем запросы, а варианты использования реляционной модели. Реляционная модель - она и в африке реляционная модель, поэтому многие часто встречающиеся задачи могут быть разбиты на "паттерны" (многие, но ессно далеко не все). Я бы не сказал что они прямо уж совсем простые, но градация на "можно-нельзя"(или целессобразно-нецелесообразно) именно проходит по сложности запроса. Так вот, когда речь заходит о преобразовании этого добра уже в запросы, то часто оно должно осуществляться по своей программе для разных баз. И именно из-за таких архитектурных заморочек на практике во многих случаях выходит, что проще не морочиться, и писать отдельный dblayer для каждого предполагаемого к использованию продукта. "Некрасиво", зато быстро, и просто
 
Сверху