Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
SanjayCZ
Člen
Avatar
SanjayCZ:13.4.2020 5:08

Zdravím,
mám v databázi uložené uživatele co mají různé role... Role jsou uložené v array() a každý uživatel jich má několik... Já potřebuji vypsat všechny uživatele, co mají pouze roli B... Uživatel který má roli A i B se vypsat nemá.

Zkoušel jsem to tímto způsobem, ale vždy mi to vypíše všechny uživatele s rolí B vč. těch kteří mají roli A i B.

<?php
                $dotaz = mysql_query("SELECT * FROM users")  or die (mysql_error());

                while($a = mysql_fetch_object($dotaz)){

                        $roles = unserialize($a->roles);

                        if (is_array($roles)) {
                                foreach($roles as $klic => $role){

                                        if ($role == "a"){

                                                continue;

                                        }else if($role == "b") {

                                                echo $a->username;
                                        }
                                }
                        }
                }

?>

Poraďte mi prosím kde dělám chybu, popřípadě jak to mám vyřešit a proč nefunguje tento způsob.
Předem moc děkuji za všechny rady.

Editováno 13.4.2020 5:09
Odpovědět
13.4.2020 5:08
I s malou znalostí html, dokážeš napsat velký web.
Avatar
Milan Turyna
Tvůrce
Avatar
Milan Turyna:13.4.2020 10:30

Nebylo by lepší vytahovat z databáze vytahovat pouze to co chceš? Tím myslím:

SELECT * FROM users WHERE role='b'

A poté už to jen vypsat a v PHP nic neřešit.

Něco málo od problému, nepoužívej mysql_query ale použij nějaký ovladač (pdo, mysqli, z mé zkušenosti doporučuji pdo) kde bys měl vyřešený určitý věci (sql injection..) a mohl bys vše dělat jednoduše. Například v PDO dotaz vypadá takto:

$dotaz = $pdo->prepare("SELECT jmeno, prijmeni FROM uzivatele WHERE id = ?");
$vysledek = $dotaz->execute(array($idUzivatele));
Nahoru Odpovědět
13.4.2020 10:30
Řeš pouze to, co dokážeš ovlivnit.
Avatar
SanjayCZ
Člen
Avatar
Odpovídá na Milan Turyna
SanjayCZ:13.4.2020 13:59

Milan Turyna bohužel v databázi jsou role uložené takto

serialize(Array('a','b','c'));

tabulka pak vypadá nějak takto

id username roles
1 Jan array(A, B, C)
2 Jana array(B, D)
3 Pavel array(B)
4 Karel array(A, C, D)

A já potřebuji vypsat jen toho co má roli B, ale nemá roli A (ostatní role mě nezajímají) což jsou Jana a Pavel, takže toto

SELECT * FROM users WHERE role='b'

nefunguje...
Ale děkuji.

Jinak děkuji za doporučení PDO (abych pravdu řekl ani to neznám) bohužel pro mě v současné chvíli nemá smysl to měnit, celí web je už udělaný přes mysql_query, ale do budoucna určitě vyzkouším.

Nahoru Odpovědět
13.4.2020 13:59
I s malou znalostí html, dokážeš napsat velký web.
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:21.4.2020 7:58

To mas uplne blbe.

Pokud tech roli nemas moc, tak se pouziva sql typ SET nebo tabulka, nikoliv STRING.
https://dev.mysql.com/…/en/set.html

Pokud tam mas string, pak musis vedet, jak serialize zapisuje data a pak bys nejspis pro vyhledavani pouzil LIKE
https://dev.mysql.com/…atching.html
https://www.tutorialspoint.com/…e-clause.htm

WHERE a LIKE '%b%'

No, a normalni clovek by pouzil extra tabulku a join, group by group_concat, treba.

role
1, a
2, b
3, c

uzivatele
1, tomas
2, jan

role_uzivatel (id_uzivatel, id_role)
1, 1
1, 2

SELECT
    c.name_uzivatel,
    b.name_role
FROM
    role_uzivatel a
    LEFT JOIN role b ON b.id_role=a.id_role
    LEFT JOIN uzivatel c ON a.id_uzivatel=b.id_uzivatel
WHERE b.name_role='b'
Editováno 21.4.2020 7:59
 
Nahoru Odpovědět
21.4.2020 7:58
Avatar

Člen
Avatar
:21.4.2020 10:38

Máš zle navrhnutú databázu a tak sa aj pokúšaš naprosto nevhodným spôsobom zisťovať role užívateľa.

Riešenie je, že tie roles nebudeš mať v tabuľke users. Ten stĺpec odtiaľ treba vymazať. Tabuľka ostane vyzerať zhruba takto:

id username
1 Jan
2 Jana
3 Pavel
4 Karel

Následne založíš tabuľku roles v ktorej budú stĺpce ID a ROLE. A tam vložíš všetky role ktoré potrebuješ. Napríklad:

id role
1 A
2 B
3 C
4 D

A budeš potrebovať tabuľku, nazvi ju napríklad users_roles, v ktorej bude povedané ktorý užívateľ má pridelené ktoré práva. Napríklad užívateľ mal práva A, B, C a tak tam dáš tri riadky s id užívateľa a id príslušných práv. Rovnako pre ostatných troch užívateľov.

userid roleid
1 1
1 2
1 3
2 2
2 4
3 2
4 1
4 3
4 4

Hotovo. Odteraz nepotrebuješ ten while cyklus a keď chceš vypísať len užívateľov s právom B, SQL príkaz ako tento ti rovno vráti príslušných užívateľov:

SELECT u.*
FROM   users u
JOIN   users_roles ur ON u.id = ur.userid
JOIN   roles r ON ur.roleid = r.id
WHERE  r.roleid = 2

Takto sa to robí v praxi. Užívateľov máš zvlášť, role máš zvlášť, a v "medzitabuľke" users_roles si udržuješ vzťah medzi users a ich roles. Takže keď chceš napríklad užívateľovi Pavel pridať aj právo C, všetko čo musíš urobiť je toto:

INSERT INTO users_roles VALUES (3, 3)

Čiže užívateľovi s id 3 (Pavel) pridáš právo s id 3 (C)...

Ak Ti to celé ešte stále nedáva zmysel, tak predbiehaš udalosti a nemal by si to ani len skúšať urobiť, ale mal by si miesto toho ísť na kurz MySQL, pretože tu chýbajú úplne základné znalosti z tvorby databáz.

PS: Dátový typ SET sa ani nepokúšaj použiť, ide proti normálovým pravidlám.

Editováno 21.4.2020 10:40
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
21.4.2020 10:38
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 5.