Manualai.lt Forumas

PHP ir SQL => PHP ir SQL - Pavyzdžiai => Temą pradėjo: @Jonas 2013-09-01 10:15:12 am

Antraštė: [ TVS ] Praktikos tikslais
Parašė: @Jonas 2013-09-01 10:15:12 am
Sveiki, taigi vasarą kūriau tokį kaip ir tvs praktikos tikslais, o dabar jį atiduodu jums, nes nesugalvoju ką su juo daryti, ir be to kursiu dar vieną tik tobulesnį. Taigi šis tvs susideda iš :

Taip pat prisegu sql failą( pagrindinis vartotojas turintis admin yra John, password:159357 ).
Viskas daryta su naujausia bootstrap versija, taipogi naudota php, jquery, html. Leidžiu keisti, ir savo reikmėms naudoti ši tvs, taipogi prašau įvertinti ir pasakyti padarytas klaidas, nors jo nebetobulinsiu, bet noriu žinoti, kad ateityje nekartoti klaidų. Dėkoju, kad skaitėte.
Antraštė: Ats: [ TVS ] Praktikos tikslais
Parašė: justinas 2013-09-01 16:28:02 pm
MD5 naudojimas slaptažodžiui hešuoti, slaptažodžio ilgio ribojimas, extract() kvietimas ant $_POST (tuo labiau, kad po to vis tiek argumentus imi iš $_POST ir savo extract() niekur nepanaudoji), if'ų piramidė... Visa tai jau pakankamai siaubinga. Bet ČIA:
$connection->query("INSERT INTO `users` (`Username`, `Fullname`, `Password`, `Email`, `Birthdate`) VALUES ('".$_POST['username']."', '".$_POST['fullname']."', '".$_POST['password']."', '".$_POST['email']."', '".$birthdate."')");kas per nesąmonė? Naudoji PDO, bet nebindini parametrų, o tiesiog kiši juos į užklausą, kaip yra? Taigi elementariausia SQL injekcija... Tada ir tas PDO naudojimas niekinis, jei vis tiek palieki kritines spragas.

Iš smulkesnių nesąmonių: kokio velnio naudoti md5 tikrinant vartotojo vardą? Kam statinį HTML išvedinėti su echo? Kam visiškai atskiras admin, su savo moduliais? Ir išvis, ne moduliai, o includinami kodo gabalai.

Dėka extract() sėkmingai prisijungiau kaip administratorius tiesiog pridėjęs į formą tokią eilutę:
<input type="text" class="form-control" name="_SESSION[Name]" value="John">

O taip pat kodėl sesijoje saugomas vartotojo vardas, o ne ID? Jei jau yra ID, tai pagal jį unikaliai identifikuok vartotoją, o ne pagal vardą :)

Draugiškai siūlau perskaityti:
http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers (http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers)
http://www.phptherightway.com/ (http://www.phptherightway.com/)

O kitiems – jokiu būdu nenaudoti šios TVS productione...
Antraštė: Ats: [ TVS ] Praktikos tikslais
Parašė: @Jonas 2013-09-01 19:22:22 pm
Esu labai dėkingas už tavo duotus patarimus, ateityje tikrai jais pasinaudosiu. Nesakiau, kad jis tobulas, todėl ir kūriau praktikos tikslais.
Antraštė: Ats: [ TVS ] Praktikos tikslais
Parašė: @Jonas 2013-09-02 15:16:12 pm
Norėjau paklausti, ar teisingai daryčiau jei naudočiau tokią funkciją :


function query($query, $parameters)
{

global $connection;
try{
$q = $connection->prepare($query);
$q->execute($parameters);
return $q;
} catch(PDOException $ex){

echo $ex;
}

}


O naudočiau taip :

query("SELET * FROM SOMEWHERE WHERE SOMETHING = ? AND SOMETHING = ?", array($somedata, $somedata));
Jei ne, tai parašyk jei gali kaip turėtų būti. ( Ši funkcija manau palengvintų darbą ).
Antraštė: Ats: [ TVS ] Praktikos tikslais
Parašė: justinas 2013-09-02 16:52:29 pm
Hm. Na, pirmiausiai, tai globalus kintamasis... Galėtum sukurti savo klasę tam (ar praplėsti PDO esamą connection, ar kokia ten ji bebūtų), ir pridėti savo metodą ten. Kartu connectioną turėtum toje klasėje (instancijoje), nereiktų pasikliauti globalu, kad jis ten tikrai bus.

O antra – tai ar tikrai tikrai tikrai tikrai TIKRAI norėsi visada su klaida tvarkytis taip pat (tiesiog išvesti)? Nes dabar tavo funkcija nepalieka jokio pasirinkimo. Juk daug geriau tiesiog palikti exceptioną, lai kyla (arba throwinti vėl pačiam) ir su juo tvarkytis kiekvienu atveju savaip. Realiai productione tu turėtum išvis nerodyti PHP klaidų vartotojui, o loginti kažkur sau tyliai. Vartotojui tereik pasakyti „įvyko klaida“ :)
Antraštė: Ats: [ TVS ] Praktikos tikslais
Parašė: @Jonas 2013-09-02 18:33:12 pm
Galėtum parodyti, kaip tvarkytis su erroru kiekvienu atveju kitaip ?
Antraštė: Ats: [ TVS ] Praktikos tikslais
Parašė: vitalikaz 2013-09-03 09:15:02 am
Galėtum parodyti, kaip tvarkytis su erroru kiekvienu atveju kitaip ?

Try'int ir catchint kiekvienu atveju, o ne bendrai funkcijoje. Siūlau pasidomėt Exception'ais (http://php.net/manual/en/language.exceptions.php).
Antraštė: Ats: [ TVS ] Praktikos tikslais
Parašė: justinas 2013-09-03 22:00:17 pm
Galėtum parodyti, kaip tvarkytis su erroru kiekvienu atveju kitaip ?
Lygiai taip pat, kaip dabar darai išvedimą – try/catch/finally mechanizmas :) Kaip sakė vitalikaz, pasidomėk exceptionais – tai yra tikrų tikriausias tvarkymasis su klaidomis (ne, "or die()" nėra geriau...). Keista, kad rašant ir nesuprantant, ką rašai, dar nekilo noras pasidomėti, kas per try/catch. :)
Antraštė: Ats: [ TVS ] Praktikos tikslais
Parašė: @Jonas 2013-09-04 13:27:42 pm
Aš suprantu, kas tai yra,  tesiog nesupratau, ką turėjai omenyje sakydamas kiekvienu atveju tvarkytis kitaip.
Antraštė: Ats: [ TVS ] Praktikos tikslais
Parašė: justinas 2013-09-04 16:31:38 pm
Aš suprantu, kas tai yra,  tesiog nesupratau, ką turėjai omenyje sakydamas kiekvienu atveju tvarkytis kitaip.

??? Nebūtinai visur kitaip, tiesiog tu turi kuo išorinesniam (:D) levely turėti tą kontrolę, ką daryti konkrečiu atveju... Tavo funkcijos darbas yra tik supaprastinti užklausos siuntimą, ne ji turi nuspręsti, ką daryti kilus klaidai. Dabartiniu atveju tu ne tik išvedi iš karto, bet niekaip neiškeli klaidos aukščiau ir neturėsi jos toje programos dalyje, kurioje kvieti query()...

Jei tau tinka, kad vartotojui mėtosi errorai su echo belekaip ir belekur – tai ok. Eisi prie MVC, frameworko ar kitokios normalios struktūros – išvedinėti iš Controllerio netgi nelabai logiškai galėsi.

Na ok, tarkim pirma užklausa bet kokiame requeste tavo TVS yra saito pavadinimas (nežinau, ar tai iš tikrųjų saugoma DB tavo TVS'e, nesigilinau). Jei saito pavadinimo nustatymo DB nėra, tai galbūt jis dar nebuvo įvestas, o gal net lentelės nesukurtos... Tokiu atveju gali nuspręsti, kad TVS negali veikti visiškai, scriptą iškart killinti su kokiu nors error pranešimu ir net nevykdyti to, kad ir kas ten bebūtų toliau...

O tarkim koks nors kitas variantas nebus toks kritinis (klaida išmesta tik kokioj nors vienoje dalyje, kuri atskira nuo kitų ir kitoms vykti netrukdo). Tokiu atveju tiesiog nerodai tos dalies. Klaidą sau, žinoma, loggini.

Ir dar kartą: vartotojas tikrų klaidų pranešimų neturėtų matyti: kai kada tai gali net būti pavojinga. Išvedi jam "Atsiprašome, įvyko klaida.", o užsirašai, kas ten buvo, tik sau. Jei dar nori padaryti lengvesnį sprendimą ir sau, ir vartotojui, priskiri klaidai kokį unikalų ID, jį išvedi vartotojui kartu su pranešimu (ir sau užloggini klaidą irgi su tuo ID). Jis kreipiasi į tave, duoda tau ID ir tu atseki, kuri būtent klaida iš kelių buvo jo.

Čia to pavyzdys YouTube (http://files.myopera.com/marcomarongiu/blog/YouTubeMonkeys.png). Pastebėk, kad nesimėto koks nors "MySQL query failed connection lost omg omg" (aišku, ir PHP jie nenaudoja, turi proto... :D). Tik šiuo atveju jau duodama užkoduota turbūt pilna klaidos informacija (ne vien ID).
Antraštė: Ats: [ TVS ] Praktikos tikslais
Parašė: Kalnų karalius 2014-07-15 22:51:37 pm
Pastebėjau ir daugiau nepatogumų iš vartotojo pusės, redagavimų laukuose esančios reikšmės susdedamos į placeholder o ne į value. Negera praktika.