Olen koittanu tehdä sivusta sellasta, että koko tekstisisältö tallennetaan tietokantaan ja se haetaan sivulle GET:n avulla. Sain melko hyvin toimimaan, mutta vielä on pientä ongelmaa..
// Jos sivua ei ole valittu, haetaan etusivun sisältö... if(!isset($_GET['content'])) { $getcontent = mysql_query("SELECT * FROM content WHERE id = '1'") or die("<div id='error'>Tapahtui virhe etusivua ladatessa!</div>"); } else { // ... muussa tapauksessa haetaan sivun sisältö tietokannasta $getcontent = mysql_query("SELECT * FROM content WHERE id = '".$_GET['content']."'") or die("<div id='error'>Tapahtui virhe sivun sisältöä ladatessa!"); } // Jos haetaan olematonta sisältöä if (!$getcontent) { die("<div class='error'>Virhe! Haettua sivua ei ole olemassa.</div>"); }
Nyt siis hakemalla /index.php tai /index.php?content=1 saan etusivun sisällön paikoilleen niinkuin pitääkin, mutta esim. /index.php?content=0 ei anna haluttua virheilmoitusta vaan pelkän sivun ilman tekstisisältöä. Oon kokeillu jo kaikenlaista, mutten vain löydä tähän ratkaisua. Missä vika?
Sitten toinen kysymys perään. Käytän sivuilla tuota ajv:n kirjautumis/rekisteröitymis koodivinkkiä. Kuinkahan hakkerointivarma tuo on? Jos tarvitsisin sivuille mahdollisimman varmaa rekisteröitymis/kirjautumis mahdollisuutta, niin miten sellainen kannattaisi toteuttaa (pitääkö opiskella muutakin kuin php:tä)?
Tuo $getcontent on aina tosi (https://www.php.net/manual/en/language.types.
Virheilmoitus tulisi antaa jos kysely ei palauta yhtään riviä.
Tuossa koodissasi on myös SQL-injektio haavoittuvuus, kaikki käyttäjältä tuleva data kannattaa escapettaa ja tarkistaa ennen kuin se välitetään kyselyyn.
Helpoiten tuo hoituu suoraa PDO:lla mm. sen takia, että se osaa automaattisesti escapettaa kaikki kyselyyn liitetyt parametrit.
Edit. Esim. näin:
<?php $db = new PDO("mysql:host=tietokanta_servu;dname=tietokannan_nimi", "tunnus", "salasana"); // Luodaan PDO-olio $query = $db->prepare("SELECT * FROM content WHERE id = ?"); // Valmistellaan kysely $query->execute(array($_GET['id'])); // Suoritetaan kysely, liitetään parametrit $row = $query->fetchObject(); // Haetaan tulokset olioina echo $row->content; // Tulostetaan sisältö... Tietokannan muutkin kentät voidaan tulostaa samalla tavalla. ?>
Muuttujasta $getcontent voi tarkistaa vain, onnistuiko haku; myös nolla riviä palauttava haku on teknisesti onnistunut. Täsmälleen saman asian tarkistat jo kyselyrivin perässä olevalla or-alkuisella pätkällä. If-lauseessa pitäisi tarkistaa mysql_num_rows-funktiolla, montako riviä saatiin.
PHP:n tavallinen MySQL-rajapinta kannattaa vaihtaa PDO:hon, josta kerrotaan Ohjelmointiputkan MySQL ja PHP -oppaassa.
Kiitos vastauksista. Olin ottanut tuon
Melkolailla suoraan tuosta PHP:n manuaalista example #1. Nyt huomasinkin, että tuo esimerkkihän todellakin epäonnistuu eli palauttaa false, kun taas minulla se ei epäonnistu vaan palauttaa nolla riviä..
Pitääkin sitten alkaa opiskella tuota PDO:ta..
Tähän asiaan palatakseni..
Muutin nyt tavallisen MySQL-rajapinnan PDO:hon. Käytän sivuilla tuota ajv:n kirjautumis/rekisteröitymis -koodivinkkiä, joka käyttää tavallista MySQL-rajapintaa. Voikohan sitä muuttaa helposti PDO:ksi vai kannattaako edes?
Esimerkiksi millaisia olisivat vastaavat käskyt PDO:lle seuraavissa tapauksissa:
//muuttujat turvallisesti talteen $tunnus = get_magic_quotes_gpc() ? $_POST['tunnus'] : mysql_real_escape_string($_POST['tunnus']); $salasana = get_magic_quotes_gpc() ? $_POST['salasana'] : mysql_real_escape_string($_POST['salasana']);
//jos lisättyjä rivejä on yksi, kirjautuminen onnistui if(mysql_affected_rows($lnk) == 1){
Löytyisikö tähän viimeisimpään ongelmaani vastausta vai jäikö se vain kaikilta huomaamatta, kun kyselin sitä ketjussa johon olin jo vastauksen saanut. Olisi kai pitänyt tehdä tälle oma aihe?
PDO on sen verta kokenut seikkailija, että hanskaa ehkäisyn itte. Riittää kun pukkaat parametrit PDO::preparen
läpi (Esimerkit 1 ja 2). Seuraamuksia voit seurata PDOStatement::rowCountilla
.
PS. Rapiat nelisen tuntia on melko nihkeä aika huhuiluun, joillakin meistä saattaa olla jopa elämää Putkan ulkopuolella. Manuskaa saa ja on suotavaa selailla myös itte.
Magic quotes -asetuksen varalta voit lisäksi käyttää tätä ohjetta.
tsuriga kirjoitti:
Seuraamuksia voit seurata
PDOStatement::rowCountilla
.
Toisaalta eikö tuossa riittäisi, että tarkistetaan execute()
-metodin palauttavan true?
Riittää tosiaan joo. Myöhemmässä mysql_affected_row:n
sisältävässä ehtolauseessa em. funkkarin voikin ym. syystä tiputtaa suoraan pois.
Kiitos taas vastauksista. Seuraavaksi kokeilenkin noita neuvoja toteuttaa käytännössä.
tsuriga kirjoitti:
PS. Rapiat nelisen tuntia on melko nihkeä aika huhuiluun, joillakin meistä saattaa olla jopa elämää Putkan ulkopuolella.
Itsekin mietin, että taidan hiukan hätäillä, mutta kun teitä jotka yleensä vastailette kysymyksiin näytti olevan kirjautuneena niin oletin, ettette vain ole huomanneet tätä kysymystä. Laitoin kuitenkin uuden kysymyksen jo vastauksen saaneeseen aiheeseen, joka saattoi vaikeuttaa sen löytämistä.
Todennäköisesti yksi fiksu vaihtoehto olisi toteuttaa koko systeemi täysin oliopohjaisena. Eli luot vaikka luokat User, Session ja Auth. Tuo User-luokka voisi hoitaa kaikki asiat tietokannan users-tauluun (tai jokin vastaava, jossa on käyttäjätiedot). Sitten tuo Session-luokka tarjoaisi välineet istuntojen luomiseen ja poistamiseen ja tuo Auth-luokka voisi toteuttaa varsinaiset välineet tunnistautumista varten, kuten metodit login()
, logout()
ja isLogin()
.
En nyt itsekään ole vielä mikään olioguru, mutta sen perusteella, mitä olen OOP:stä oppinut, niin toteuttaisin tuon homman suurinpirtein tuohon suuntaan.
Aihe on jo aika vanha, joten et voi enää vastata siihen.