« 1 2 3 4 5 6
Autor Zpráva
Jan Tvrdík
Profil
Kubo2:
v rozsiahlejšej aplikácii sa ti pri znovupoužívaní premenných môže omylom stať
V rozsáhlejší aplikaci bys především
a) neměl globální proměnné používat vůbec
b) je mít definované na jenom místě a jasně zdokumentované
c) použít jen jednu (typicky nazvanou $registry podle registry pattern).

U takhle triviální aplikace si lze vystačit s variantou (b).
Joker
Profil
Alphard:
Když se dívám na kódy začátečníků i lehce pokročilých, zdají se mi jak z minulého století, ale pak si řeknu, že kromě studia zdrojových kódů frameworků nemají začátačníci v podstatě žádné zdroje, které studovat. Chtěl jsem vytvořit kód, který by mohl třeba i inspirovat středně pokročilé uživatele, ne jen 101. polovičaté řešení.

S tímhle souhlasím.
Vzniká dilema, jestli preferovat kód srozumitelný i úplnému začátečníkovi, nebo kvalitní řešení problému.
Vidím prostor i pro tu druhou skupinu. Ostatně natolik zjednodušený kód, že ho okamžitě pochopí i úplný začátečník není (mimo třeba ukázky v základním kurzu) ideál.
Ideálně by kód neměl být tak jednoduchý, aby i začátečník všechno hned chápal, protože pak se z toho nic nenaučí. Jen by zase neměl být tak složitý, aby začátečník hned hodil flintu do žita a vzdal snahu ho pochopit.
Jan Tvrdík
Profil
Zkusil jsem to rozšířit do stavu, na kterém je možné reálně stavět jednoduché weby, což znamená především rozdělení do více souborů a implementace registrace. bitbucket.org/JanTvrdik/djpw-php-faq-login
Jan Tvrdík
Profil
Věci, které podle mě nejsou vyřešeny moc dobře:

1) Aplikace chyby vypisuje nezávisle na tom, zda se nachází na produkčním serveru. Lepší by bylo je na produkčním serveru logovat, což ale vyžaduje více kódu a začátečníky to může mást.
2) S tím souvisí i ošetřování chyb mysqli, zapnul jsem alespoň vyhazování warningů, což ale v kombinaci s bodem (1) může způsobit více problémů, než užitku. Možná by bylo lepší místo warningů vyhazovat výjimky (MYSQLI_REPORT_STRICT), aby došlo k zastavení aplikace.
3) Konstrukce is_string($_POST['username']) && is_string($_POST['password']) vypadá dost těžkopádně, ale netuším, jak to v čistém PHP lépe řešit.
4) Formuláře nemají žádnou validaci.
5) Aplikace nijak neřeší, zda vstupní řetězce jsou validní UTF-8 sekvence.
6) Aplikace nijak neřeší CSRF, konkrétně logout.php je reálně zranitelný.
Alphard
Profil
Mně se to docela líbí jako nějaký sandbox pro začátečníky. Nejsem si jist, jestli to nemalou část lidí hledajících jednoduché přihlášení (rozuměj pokud možno kopírovatelné jedním Ctrl+C/V do vlastních stránek) neodradí, ale určitě odkáži. Už dříve mě napadlo, že čtenářům nabídnu více verzí (ta moje původní bude do budoucna zřejmě okomentovaná na pehapku), ať si každý vybere podle své pokročilosti a zájmu.

K tvému kódu:
- Funkce password_* bude ještě nějaký pátek dělat problémy. Bylo by dobré aspoň připojit uživatelskou implementaci pro pár starších verzí.
- Jaký máš názor na vhodný přístup k databázi? Dlouhodobě se tady snažím doporučovat používání parametrizovaných databázových dotazů (ať již prepared statements, nebo aspoň na úrovní PHP layeru). Ty tam zase pracuješ s ručním escapováním a lepením dotazů. Raději bych začátečníky vedl k bezpečné a efektivní práci s databází než studiu hashovacích technik.
Jan Tvrdík
Profil
Alphard:
Jaký máš názor na vhodný přístup k databázi?
Jsem toho názoru, že bez vhodné abstrakce (třeba dibi, ještě lépe nextras/dbal co teď vyvíjím s hrachem) je nemožné přistupovat k databázi tak, aby byl kód zároveň čitelný i bezpečný. Prepared statements nic neřeší, spíš situaci ještě zhoršují.

• Skutečné prepared statements jsou (reálně) pomalejší než ruční escapování a především neumožňují řešit věci jako IN a kód, který to emuluje je tak nečitelný, že v něm programátor pravděpodobně udělá chybu. Escapování takových věcí jako identifikátory pochopitelně taky není podporování. Viz také výborný komentář Jakuba Vrány.
• Emulované prepared statements (to, co používá PDO, není-li mu explicitně řečeno aby použil skutečné prepared statements) už nejsou pomalejší, ale ostatní nevýhody zůstávají.
• Ruční escapování je děsná otrava, IN se s tím taky řeší blbě, ale pořád lépe než s prepared statements. Ale hlavně na rozdíl od prepared statements se programátor naučí explicitně escapovat data.
Alphard
Profil
Díky za názor, já totiž přemýšlím o tom, že by ten kód pracoval s dibi. Bylo by přímo součástí toho sandboxu, bez dalších komplikací pro uživatele.

Klidně piště své názory, vím že takové prosazování jedné knihovny není ideální, ale vzhledem k výhodám se mi to zdá akceptovatelné. Do názvu/popisku by se samozřejmě zmínilo, že se pracuje s dibi. Případně vytvořit 2 verze, to byl nebyl zas tak velký problém, když už si někdo řekne, že začne nový projekt líp než předtím, vedlo by ho to na lepší cestu.
lionel messi
Profil
Alphard:
případně vytvořit 2 verze, to byl nebyl zas tak velký problém.
Podľa mňa by išlo o najvhodnejšiu variantu. Pri riešení bezpečnostných problémov (a nielen vtedy) narážame na problém jednoduchosť a pochopiteľnosť verzus kvalita a bezpečnosť, pričom samozrejme najbezpečnejší je taký kód, v ktorom de facto chybu nie je možné spraviť.

Napriek tomu, že dibi (ani žiadnu podobnú knižnicu) nepoužívam (escapujem ručne v MySQLi), uznávam argumenty hovoriace v jej prospech. Na druhej strane môže kód s jej použitím pôsobiť pre programátora s minimálnymi/žiadnymi znalosťami mierne mätúco. Začiatočníci zvyčajne o podobných hotových riešeniach ani len netušia (samotné prvé kroky v PHP/MySQL nie sú úplne triviálne) a zrejme im budú pripadať príliš komplikovane a používať kód, ktorému vôbec nerozumejú, tiež nie je veľká výhra (na druhej strane samotný štart s dibi podľa dokumentácie nevyzerá pre mňa ako mierne pokročilého užívateľa so zanedbateľnými znalosťami OOP nijak hrozivo).

Väčšina menej skúsených programátorov taktiež programuje procedurálne a o OOP nepočula, prípadne len minimálne a nemá s ním praktické skúsenosti, čo pochopiteľnosť kódu dibi sťažuje. Písať kód procedurálne a k db pristupovať objektovo je samozrejme možné, ale nemyslím si, že ide o vhodnú praktiku.

Z uvedených dôvodov preferujem možnosť dvoch alternatív. Možno by malo význam vytvoriť len jednoduchú verziu pre úplných začiatočníkov a v texte sa o dibi a jej výhodách zmieniť, to by však bolo zrejme málo dôrazné poukázanie na výhody, ktoré prináša.
Amunak
Profil
Co takhle mít to bez databáze? Jednoduché zapsání do souboru i jeho parsování je velmi jednoduché, a začátečník nebude potřebovat ukládat tisíce uživatelů, aby databáze měla nějaký zásadní význam. Dokonce je možné, že když se začátečník nebude muset zabývat databází (která je i složitější na rozběhnutí, testování a klade požadavek navíc na hosting), bude se mu to lépe učit. Navíc mi přijde, že práce se soubory (která je přitom docela jednoduchá a velmi užitečná) se v PHP často přehlíží právě ve prospěch databází (jejichž problematika je přitom daleko složitější, už co se návrhu týče).

Ty pokročilejší pak můžeme rovnou odkázat na kód, který používá dibi, ideálně nějakou tu učebnici PHP, kde by se tím šlo zabývat více do hloubky. Nebo jaký byl původně důvod pro to používat databázi?
Alphard
Profil
Joker [#2]:
Díky, aspoň díky tobě si nepřipadám sám proti všem :-)

Jan Tvrdík [#6]:
Ale hlavně na rozdíl od prepared statements se programátor naučí explicitně escapovat data.
Nebo taky ne...
Jak jsem uváděl výše, na tom tvém kódu se mi nelíbí používání funkcí password_*, první člověk, kterému jsem to zkusil poradit, se na tomto bodě zasekl. Nemyslím si, že tady musíme pořádat hon na klasické hashovací funkce, jejich použití není vhodné, ale je více intuitivní, shodnost lze ověřit i pohledem, lépe se kód ladí a funguje i na starších verzích. Začátečníkům, kteří budou vytvářet přihlášní podle FAQ kódu, to bude stačit.

lionel messi [#8]:
Začátečníci používají to, co uvidí jako první, byť by správné použití daného nástroje bylo složitější. Začínám se vzdávat snahy učit lidi něco nového, uznávám, že jsem neodhadl čtenáře a že je to nezajímá, nikomu nevnucuji frameworky apod., ale dobrý databázový layer je asi jediná knihovna, kterou by podle mě měl používat každý, kdo v PHP pracuje s databází. Když se v dibi použije statický přístup dibi::query(), tak téměř není třeba vědět, co je to objekt.

Amunak [#9]:
Předtím mě to ani nenapadlo, databázi beru jako samozřejmost, nicméně zároveň jako ukázka práce se soubory by to bylo hezké. Problém vidím v tom, že ve chvíli, kdy to naimplementuji jednoduše, se tady objeví nejmenovaný Honza a poukáže na problémy s atomicitou. A když to udělám složitěji, bude to zase složité...

Takže jak? Vzledem k tomu, že Honzův kód pracuje s databází jen v jednom souboru bitbucket.org/JanTvrdik/djpw-php-faq-login/src/a7758612f638460be771057f4ff4909d01e1feab/common/users.php?at=master, uměl bych si představit, že tyto funkce budou naimplementované až 3x, pomocí souborů, mysqli a dibi, přičemž požadovaná verze se zvolí includováním vhodného souboru. Do konce února nechávám čas na poslední připomínky, případně návrh konkrétních kódů (zatím děkuji hlavně Honzovi).
Jan Tvrdík
Profil
Alphard:
(…) klasické hashovací funkce, jejich použití není vhodné, ale je více intuitivní
Naopak password_hash a password_verify je mnohem logičtější než md5.

ukázka práce se soubory by to bylo hezké
Problém je, že se soubory lze buď pracovat špatně (neřešit možné chyby a atomicitu) nebo je kód nečitelný.

Honzův kód pracuje s databází jen v jednom souboru
Ještě v init.php probíhá připojení k databázi, čímž se to trochu komplikuje.
Amunak
Profil
Nemyslím si, že je potřeba řešit atomicitu u práce sse soubory. Valná většina nováčků bude dělat systém, kde budou jedinými uživateli, a na problémy s atomicitou nenarazí. Určitě nebude problém připsat k tomu poznámku, že to není vhodné řešení pro větší množství uživatelů (což soubory nejsou celkově), ale pokud se tím někdo něco naučí, bral bych to jako plus.
Holi-cz
Profil *
Hezký den,

4. příspěvek obsahuje odkaz na blog Davida Grudla, ale na starou doménu. Článek je nyní zde.
Alphard
Profil
Díky, opraveno. Zároveň jsem tentýž blog smazal z prvního příspěvku, kam jsem přidal odkazy na nikic's Blog a Best PHP Framework for 2015 - SitePoint Survey Results (ne že bych čekal, že to někdo bude číst).

A když už jsem začal dělat úpravy, přeskládal jsem některé příspěvky. Hlavně proto, aby sandboxový obsah dával smysl. Nyní je vše rozděleno do skupin:
• Materiály ke studiu PHP
• Tematicky zaměřené odkazy
• Řešení nejčastějších chyb
• Jak něco udělat
• Komunikace mezi javascriptem a PHP
• Konfigurace PHP
• Správné kódování v PHP
• Zastaralé (deprecated) funkce

V sandboxu to vypadá asi takhle


Některé kódy, které nadále nepovažuji za vhodné nebo užitečné, jsem vyčlenil a ve FAQ jsou pouze odkazy. V tomto vyčleňování budu možná ještě pokračovat.

Protože se některé příspěvky přesunuly, smazal jsem starý rozcestník. Zřejmě se rozbilo několik starých odkazů vedených na čísla příspěvků, ale snad převáží výhody. Pokud něco odkazujete, odkazujte prosím přímo na nadpisy, každý z nich má svoji kotvu.
« 1 2 3 4 5 6

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: