Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [ZF] ACL z bazy danych
Forum PHP.pl > Forum > PHP > Frameworki
wixer
Witam,
Jestem początkujący jeśli chodzi o Zend Framework. Chciałbym pobierać uprawnienia do danej strony ( np. http://localhost/content/view/Hello-world z bazy danych podczas jej ładowania,
i załóżmy: użytkownik jest zalogowany, wchodzi na ową stronę oraz posiada uprawnienia oglądania - wyświetla mu się strona.

Uprawnienia byłby zapisane w bazie danych ( każdy artykuł ma inne uprawnienia ) oraz ładowane przy odpalaniu strony. Ustawianie wszystkich $this->allow(..., ...); dla każdego zasobu odpada - jest raczej nieefektywne przy dużej ilości uprawnień-stron.

pozdrawiam
Sabistik
Cytat
Ustawianie wszystkich $this->allow(..., ...); dla każdego zasobu odpada - jest raczej nieefektywne przy dużej ilości uprawnień-stron.

No to jak niby chcesz ustawić bez ustawiania? <: Cacheuj obiekt acl i tyle. Jeśli jednak chcesz trzymać w db to też nie ma problemu - rozszerz sobie odpowiednio Zend_Acl gdzie będziesz pobierał i dodawał do obiektu odpowiednie role i resource.
MarcinTryka
możesz obiekt ACL (jak i dowolną inną zmienną) "zserializować" poleceniem:
string serialize ( mixed $value )" title="Zobacz w manualu PHP" target="_manual
Wtedy z takiej zmiennej robi się ciąg znaków które wrzucasz w pole bazy typu text
Jak je odczytasz, to używasz funkcji:
mixed unserialize ( string $str )" title="Zobacz w manualu PHP" target="_manual
Która zwróci Ci dokładnie ten sam obiekt który zserializowałeś poprzednio.

Nie wiem czy tak należy robić (niech się mądrzejsi wypowiedzą), gdyż dopiero poznaję ACL i nie dokońca rozumiem jak to powinno się w praktyce budować.

BTW, ma ktoś jakiś solidny tutorial? Chodzi mi o sytuację gdy jako administrator wybieram i nadaję użytkownikom konkretne uprawnienia. Jak narazie trafiam tylko na jakieś proste przykłady gdzie wszystko jest definiowane w kodzie php i jest kilka ról, przypisanych do konkretnych użytkowników. A ja wolę zobaczyć przemyślany kod niż pisać wszystko na 5 sposobów od początku.
Sabistik
Bezsensu tongue.gif po co trzymać zserializowany obiekt w db, to ja nie wiem. Jak już serializować to zapisać w pliku. W ogóle to prościej użyć do tego Zend_Cache.
MarcinTryka
Nie twierdzę że nie.

A w przypadku opisanym przeze mnie? Nadaję użytkownikowi prawa w panelu administracyjnym (bądź prawa zwykłego usera automatycznie przy rejestracji) i taki obiekt serializuje i wrzucam do bazy. User się loguje i razem z resztą danych wrzucam "rozserializowany" obiekt do zmiennej sesji, gdzie trzymany jest do momentu wylogowania. Wszystko ładnie siedzi, tam gdzie powinno, łatwo mogę się dostać do obiektu acl dla danego usera...
Choć jak mówię, jeszcze nie do końca to wszystko widzę, a i do cachu jeszcze nie nabrałem zaufania (wpraw) smile.gif
eai
A ja postanowiłem ten problem rozwiązać pisząc swój własny ACL, nie jest to dużo roboty jak się wydaje.
Sabistik
A co w Twoim ACLu jest lepszego od ZF-owego ? :P
eai
Jest bardziej wydajny. Normalnie musze napisać plugin który z bazy danych wczyta mi wszystkie zasoby, przywileje a następnie utworzy obiekty Zend_Acl_Resource, Zend_Acl_Role i załaduje wszystko do obiektu Zend_Acl. Pytanie tylko jedno: podczas wywołania jednej instancji po co mi mi ładować wszystkie zasoby (nawet tylko dla jednej osoby, nie mówie o ładowaniu wszystkich zasobów dla wszystkich użytkowników). Rozumiem że czasem odwołujemy się do innego kontrolera (renderując np widget) ale ja potrzebuje pobrać te informacje o dostępie (allow/deny) w momencie próby uzyskania dostępu do tego określonego obszaru. Jeśli Zend w przyszłości rozszerzy ACL o możliwość używania jakiś sterowników do przechowywania tych danych w bazie lub na plikach to wtedy z niego skorzystam, dla mnie liczy się przede wszystkim wydajność aplikacji. Jeśli coś jest nie potrzebne to po co to ładować i nie potrzebnie zużywać pamięć. Mówie tu o rzeczach które naprawde naprawdę nie są nam potrzebne.
MarcinTryka
ale po co za każdym razem to tworzyć? Robisz to raz (+ ew. przy zmianie uprawnien) i serializujesz dane do stringa i wrzucasz do bazy. Później czytasz taka zmienna z bazy i masz już wszystko pododawane.

Pisanie swoich modułów ma jedną zasadniczą wadę. Nigdy do końca nie wiesz czy faktycznie to co robisz jest praktyczne, i czy przy jakiejś zmianie w innym serwisie nie trzeba będzie tego wszystkiego przerabiać gdyż na początku przy innych założeniach dało się to zrobić efektywniej w taki a taki sposób, Korzystając z modułów frameworka zwłaszcza tych które są od dawna i są jako tako przetestowane) byćmoże czasem musisz zrobić troszkę więcej, ale dzięki temu kod jest bardzo elastyczny, gdyż ten kod przetestowało już tysiące programistów na całym swiecie.

Ja co jakiś czas mam nieprzjemność przerabiania jakichś programów po dawnym rogramiście. Facet robił programy OO , wszystko po swojemu i tylko on wie gdzie co się znajduje. W tej chwili siedzę już dzień nad jakąś głupotą, ale nie ma się jak połapać, bo tak naprawde tylko on zna ten swój framework. A pewnie jest wydajnieszy niż ZF...
eai
ACL nie jest dość skomplikowanym modułem, pozatym serializowanie mija się z celem. Załóżmy mm ok 80 tyś użytkowników na stronie, ok 40 kontrolerów każdy po 4 akcje, i 4 przywileje typu zezwalaj na komentarz, zezwalaj na branie udziału w czymś tam (różne przywileje) itd...

Pomyśl sobie ile by pamięci to zżerało gdyby z każdym wywołaniem strony pobierał wszystkie dane i ładował do ACL. Załóżmy że co 10 minut rejestruje się nowy użytkownik i musze od nowa serializować cały ten shit, poza tym żeby mieć taki serial, muszę zrobić zapytanie i przejechać po tabeli z użytkownikami potem po tabeli z ich uprawnieniami potem to wszystko załadować do ACL a na koniec zserializować.... Nie obraź się ale twój pomysł jest w tym wypadku beznadziejny.

Dla mnie rozwiązanie jest jedno, jak Zend napisze sterownik do ACL (do przechowywania danych), i te dane będą pobierane w miare optymalnie nie wszystkie na raz, to wtedy tym się zainteresuje. Do tego czasu oprę o swój własny ACL.


Nasuwa się pytanie: Po co na siłe stosować Zend_ACL questionmark.gif Zend_ACL nie jest skomplikowany czy jakoś bardzo rozbudowany, że jest jakiś nadzwyczajny... jak narazie jest to dość prosta implementacja.
Sabistik
A co ma ilość userów do ACL ? W obiekcie trzymasz tylko role i resource więc to co Ty bredzisz... Nie wiem jaką Ty masz tą implementacje :) Tyle ile Ty wymieniłeś resourców to jest nic. Poza tym jak wspomniałem wyżej używamy cache, więc nie tworzymy obiektu po każdym requeście.
eai
Trzymając wszystko ładnie w tabelach mam łatwiejszą możliwość wyszukiwania pod różnymi kryteriami, łatwiej się tym zarządza, co jest trudne mając zserializowany obiekt ACL w pliku lub w bazie. Nie muszę za każdym razem serializować i deserializować chcąc dodać nowy zasób, lub przywilej grupie czy użytkownikowi. Poza tym po co mam pchać dane zwrócone z bazy do obiektu ACL jak ACL może sam sobie pobrać z bazy poprzez $acl->isAllowed('someUser', 'someResource'), używając Zendowskiego musiałbym wcześniej załadować to do obiektu. A po cholere się tak bawić?
MarcinTryka
Cytat(eai @ 7.03.2008, 14:12:15 ) *
Trzymając wszystko ładnie w tabelach mam łatwiejszą możliwość wyszukiwania pod różnymi kryteriami, łatwiej się tym zarządza, co jest trudne mając zserializowany obiekt ACL w pliku lub w bazie. Nie muszę za każdym razem serializować i deserializować chcąc dodać nowy zasób,

Tu masz rację. Jeżeli chciałbyś wyswietlić liste osób mających dostęp do danego zasobu, to trzeba odserializowac pokolei, choć tak naprawdę wcale nie każdy uzytkownik z 80tys musi mieć swój acl. Ja tworzę grupy. W praktyce wychodzi kilka grup i jak trzeba coś takiego zrobić to jest to znacznie krótszy czas. Ponadto wydajność przy tak rzadkich czynnościach jest sprawą drugorzędną najważniejsze aby dało się szybko i wygodnie sprawdzać czy dany user ma dostęp do danego zasobu.

Cytat(eai @ 7.03.2008, 14:12:15 ) *
lub przywilej grupie czy użytkownikowi. Poza tym po co mam pchać dane zwrócone z bazy do obiektu ACL jak ACL może sam sobie pobrać z bazy poprzez $acl->isAllowed('someUser', 'someResource'), używając Zendowskiego musiałbym wcześniej załadować to do obiektu. A po cholere się tak bawić?


Przytoczono tu dwa przyklady użycia:
1) [mój] Tworzę obiekt acl dla użytkownika/grupy i wrzucam zserializowany do bazy.
Odczytuję z bazy, odserializowuje i wrzucam do sesji. Wczytałem wszystkie zasoby dla jednego usera, ale mogę o nich zapomnieć. Tak samo jak o komunikowaniu się z bazą
2) cacheujemy wszystko, skrypt przy starcie odczytuje z pliku.
Twój sposób wcale tak bardzo wydajny być nie musi. Faktem jest że pobierasz z bazy tylko jedną konkretną informację, ale musisz pobierać ją przy kazdym wyświetleniu strony. Tzn. user wchodzi na stronę (z tych 40 kontrolerów każdy po 4 akcje, i 4 przywileje), przechodzi na drugą, trzecią, dwudziestą, wraca do czwartej itd...

Za każdym razem trzeba się połączyć z baza danych. I tak naprawdę choćby trzeba było wyciągnąć połowe przywilei, to i tak przy tylu połączeniach wyszukiwanie będzie trwało znacznie dłużej niż jesli wyciągnę jedno pole z całym acl-em usera lub grupy.

Wydaje mi się ponadto, ze jak się pomnoży to razy te 80 tyś użyszkodników to prędzej się będzie odczyt z bazy zapychał niż zabraknie ramu na przechowywanie acl-a w sesji. Z ciekawości jak znajdę chwilkę, to zserializuję taką zmienną (ACL, 40x4x4=320 przywileje) zapiszę do pliku i sprawdzę rozmiar, ile to zajmuję. stawiam, ze nie więcej niż 5 kilobajtów.
wixer
Dziękuję wszystkim za odpowiedzi. Teraz trochę mi się rozjaśniła sprawa z ACL aczkolwiek muszę przetestować Zend_ACL przy większej ilości zasobów m.in dla forum - chociaż tu wydaje mi się, że rozwiązanie eai będzie lepsze.

pozdrawiam serdecznie
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.