Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Sisällön haku tietokannasta GET:llä

Sivun loppuun

AkeMake [10.11.2010 17:08:05]

#

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ä)?

seppe [10.11.2010 17:15:01]

#

Tuo $getcontent on aina tosi (https://www.php.net/manual/en/language.types.boolean.php) ja tuo sinun virheilmoituksesi tulee vain kun se on epätosi.

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.

Triton [10.11.2010 17:21:59]

#

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.


?>

Metabolix [10.11.2010 17:25:31]

#

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.

AkeMake [10.11.2010 17:47:56]

#

Kiitos vastauksista. Olin ottanut tuon

if (!$getcontent) {
    die("<div class='error'>Virhe! Haettua sivua ei ole olemassa.</div>");
}

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..

AkeMake [11.11.2010 16:59:12]

#

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){

AkeMake [11.11.2010 21:07:43]

#

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?

tsuriga [11.11.2010 21:36:15]

#

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.

Metabolix [11.11.2010 21:56:20]

#

Magic quotes -asetuksen varalta voit lisäksi käyttää tätä ohjetta.

Triton [11.11.2010 21:58:20]

#

tsuriga kirjoitti:

Seuraamuksia voit seurata PDOStatement::rowCountilla.

Toisaalta eikö tuossa riittäisi, että tarkistetaan execute()-metodin palauttavan true?

tsuriga [11.11.2010 22:09:41]

#

Riittää tosiaan joo. Myöhemmässä mysql_affected_row:n sisältävässä ehtolauseessa em. funkkarin voikin ym. syystä tiputtaa suoraan pois.

AkeMake [12.11.2010 00:00:15]

#

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ä.

Triton [12.11.2010 01:12:13]

#

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.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta