Elikkä tateilin tälläistä koodia aamulla, mutta, kun laitan sen palvelimelle, se ei toimi (eikä kyllä mun omalla koneellakaan). Voisko joku vähän korjailla tota? Tiedän että koodi on vähän alkeellinen, mutta haluan mahdollisimman yksin kertaisen, ja kun käyttäjä kirjautuu se menee hänen omalle osoitetulle sivulle.
<html> <head> <title>Sivusto</title> </head> <boby> <form method="post " > <INPUT TYPE="text" NAME="username" VALUE="" MAXLENGHT="30" SIZE="20"> <input type="password" name="password" size="20"> <input type="submit " value="Kirjaudu"> </form> <?php if (username=="nimi1" && password=="tunnus2") { header("location: ../sivu1.php"); if (username=="nimi2" && password=="tunnus2") { header("location: ../sivu2.php"); ?> <?php elseif ($_POST ["username"]== "") print "<b>Kirjoita käyttäjänimi</b>"; else print "<font color=\"#c00505\"><b>Väärä käyttäjänimi</b></font> ?> <?php elseif ($_POST ["password"]== "") print "<b>Kirjoita salasana tekstiruutuun</b>"; else print "<font color=\"#c00505\"><b>Väärä salis</b></font> ?> </body> </html>
Koodissasi on suuri määrä erittäin alkeellisia virheitä. Aloita laittamalla virheilmoitukset näkyville ja jatka sitten PHP:n alkeista. Ihan ensiksi koodiin pitää lisätä puuttuvat sulkumerkit, lainausmerkit ja puolipisteet, ja sitten voi miettiä, onko itse koodissa mitään järkeä.
1. riviltä puuttuu Doctype
7. rivillä on ylimääräisiä välejä
8. rivillä tagit ja niiden attribuutit tulisi kirjoittaa pienellä
10. rivillä ylimääräinen välilyönti
13. ja 14. riveiltä puuttuu muuttujista $-merkit. Niitä ei myöskään ole alustettu mitenkään. Molemmilta riveiltä puuttuu myös if-lohkon sulkeva aaltosulje.
18. rivillä et voi aloittaa vertailua elseif:llä, järjestys on if, else if, else.
21. riviltä puuttuu lainausmerkki sekä puolipiste.
25. rivillä sama juttu, et voi aloittaa vertailua else if:llä.
28. riviltä puuttuu lainausmerkki ja puolipiste
Tageja ja attribuutteja ei "tulisi" kirjoittaa pienellä vaan ne pitää kirjoittaa pienellä, jos käytetään XHTML:ää. Kuvittelisin tämän pätevän myös XHTML5:ssä, vaikka se antaakin joitain oudohkoja erityisvapauksia.
Jos kirjautumisen jälkeen tehdään ainoastaan redirectaus (uudelleenohjaus), ei ole syytä olla kirjautumista lainkaan. Sivun URL:in voi tallentaa sinne selaimen kirjanmerkkeihin tai lyhentää bit.ly-palvelussa helposti muistettavaksi.
Jos haluat oikeasti tehdä kirjautumisen, tutustu PHP:n alkeisiin (Metabolix laittoikin jo linkin) ja tietokantaan.
Tein sinulle kuitenkin koodin, joka ei tarvitse tietokantaa ja on lisäksi suhtkoht simppeli:
<?php session_start(); if(isset($_GET["logout"])){ session_destroy(); header("Refresh:0;url=?"); }else{ if(!$_POST["tunnus"]==""){ // Käyttäjä 1 if($_POST["tunnus"]=="tunnus1" && $_POST["salasana"]=="salis1"){ $_SESSION["nimi"]==$_POST["tunnus"]; header("Refresh:0;url=?"); } // Käyttäjä 2 elseif($_POST["tunnus"]=="tunnus2" && $_POST["salasana"]=="salis2"){ $_SESSION["nimi"]==$_POST["tunnus"]; header("Refresh:0;url=?"); } // jne. // Väärä tunnus else{ die("Väärä tunnus tai salasana!<br /><a href=\"\">Yritä uudelleen</a>"); } } } if($_SESSION["nimi"]==""){ print " <h1>Kirjaudu sisään</h1> <form action=\"\" method=\"post\"> Käyttäjätunnus<br /> <input type=\"text\" name=\"tunnus\" /><br /><br /> Salasana<br /> <input type=\"text\" name=\"salasana\" /><br /><br /> <input type=\"submit\" name=\"Sisään\" /> </form> "; }else{ print " <h1>Projekti X</h1> <b>Hei, ".$_SESSION["nimi"]." · <a href=\"?logout\"></a></b> "; include("/kayttajasivut/".hash("whirlpool","##!PROJECT*X!##".$_SESSION["nimi"])); // Korvaa ##!PROJECT*X!## jollakin oikein kryptisellä merkkiyhdistelmällä, jota et kerro kenellekään muulle! } ?>
Näin tämän koodin väsäämiseen jonkun verran aikaa, joten toivon mukaan toimii. Takuita en ota. Kyseessä on tosiaankin kivikautinen kirjautumissysteemi. En ole jaksanut laittaa doctypeja tai tehdä koodista muuten validia.
Petjan koodista ei kannata ottaa mallia, siinä on ehkä jopa enemmän virheitä ja ihan yhtä huono suunnitelma kuin alkuperäisessä. Edelleen puhutaan ihan alkeista: vertailut ja sijoitukset pielessä, if- ja else-rakenteet typerästi, Refresh-otsikko jne.
Eihän tässä nyt tietääkseni tavoiteltu mitään maailman siisteintä koodia; kyseessä on vaan ihan yksinkertainen esimerkki, jota voi oman halun mukaan soveltaa käyttötarpeidensa mukaisesti. Silloin tosin jo käyttäisi tietokantaa, mutta... anyway. Jos käyttäjä ei tarvitse muuta kuin yksinkertaisen login-skriptin sivuillensa, ei minun tarvitse alkaa tekemään jotain oliopurkkaviritelmää. Tein koodin ihan jokerina mitään testailematta, joten jos se on ongelma.
Metabolix kirjoitti:
siinä on ehkä jopa enemmän virheitä
En ole testannut koodia, mutta ei kyllä silmämääräisesti PHP heitä virhettä.
Metabolix kirjoitti:
ihan yhtä huono suunnitelma kuin alkuperäisessä
Itse asiassa jos totta puhutaan, minä en suunnitellut mitään -- minä tein.
Metabolix kirjoitti:
vertailut ja sijoitukset pielessä, if- ja else-rakenteet typerästi, Refresh-otsikko
Herra on hyvä ja näyttää oman versionsa, jossa on kaikki vertailut ja sijoitukset oikein, if- ja else-rakenteet siististi ja järkevästi, eikä käytä Refresh-otsikkoa, mutta on kuitenkin tasoltaan varsin riittävä koodin haluajalle. Aikaa 10 min.
Petja kirjoitti:
maailman siisteintä koodia; kyseessä on vaan ihan yksinkertainen esimerkki
En näe miksi esimerkki ja siisti koodi sulkisivat toisensa pois.
Petja kirjoitti:
Itse asiassa jos totta puhutaan, minä en suunnitellut mitään -- minä tein.
Voiko silloin oikeastaan edes puhua esimerkistä, jos se on epäesimerkillinen?
Voisi melkein sanoa, että koodi ilman suunnittelua kannattaa mieluummin jättää kokonaan tekemättä.
Petja kirjoitti:
Herra on hyvä ja näyttää oman versionsa, jossa on kaikki vertailut ja sijoitukset oikein
No onko omasta mielestäsi seuraavassa koodirivissäsi sitten jotain järkeä?
Petja kirjoitti:
$_SESSION["nimi"]==$_POST["tunnus"];
Grez kirjoitti:
En näe miksi esimerkki ja siisti koodi sulkisivat toisensa pois.
Eivät ne suljekaan, mutta tässä nyt ei edelleenkään tavoiteltu mitään huippukoodia = ei tehdä huippukoodia.
Grez kirjoitti:
Voisi melkein sanoa, että koodi ilman suunnittelua kannattaa mieluummin jättää kokonaan tekemättä.
Minä olen saanut tehtyä elämässäni tähän mennessä vaikka mitä ilman suunnittelua ja kaikki on ihan hyvin onnistunut! Esimerkkejä en nyt ala antamaan.
Koodin voi toteuttaa monella eri tavalla, mutta kyllä
Grez kirjoitti:
No onko omasta mielestäsi seuraavassa koodirivissäsi sitten jotain järkeä?
Petja kirjoitti:
$_SESSION["nimi"]==$_POST["tunnus"];
on ihan järkevä. Kun käytössä ei ole tietokantaa, jotenkin tulee varmistaa käyttäjä. Olisihan tämä voitu tehdä näinkin:
mutta en nyt vaan tehnyt niin
EDIT: poistettu. Ehti tulla jo sen verran juttua väliin, että kommentti oli turha.
Petja kirjoitti:
nyt ei edelleenkään tavoiteltu mitään huippukoodia = ei tehdä huippukoodia.
Mielestäni koskaan ei ole mitään syytä kirjoittaa huonoa koodia. Teetkö moniakin asioita tarkoituksella huonosti? Huippukoodi on eri asia kuin hyvä, normaali tai esimerkillinen koodi. Ei kukaan ole vaatinutkaan huippukoodia, melko normaalikin olisi riittänyt.
Petja kirjoitti:
Minä olen saanut tehtyä elämässäni tähän mennessä vaikka mitä ilman suunnittelua ja kaikki on ihan hyvin onnistunut!
Puhuinkin nyt ohjelmoinnista, en esim. baarireissuista.
Jos tarkoitit että ohjelmaprojektit on onnistuneet, niin olet varmasti tehnyt suunnittelua, ehkä et sitten ole sitä huomannut.
Petja kirjoitti:
kyllä on ihan järkevä
Siis teet vertailun, mutta et käytä sen tulosta mihinkään? Ainoa mitä tuo rivi nähdäkseni tekee, on heittää noticen jos $_SESSION -taulukossa ei ole avainta 'nimi' ja/tai $_POST -taulukossa ei ole avainta 'tunnus'. Jos tuo (satunnaiset noticet) todellakin oli tarkoituksesi, niin suunnittelun puute tosiaan näkyy.
Jos totta puhutaan, niin veikkaan että siinä pitäisi olla sijoitus = eikä vertailu ==, mutta otit aiheellisesta arvostelusta sen verran nokkiisi, ettet vieläkään huomannut sitä.
Tässä oli minun koodini, viestin aloittaja saa parantaa sitä jolloin oppii PHP:tä itsekin.
Jatkossa minut tavoittaa StackOverflowista ja mahdollisesti, mutta hyvin epätodennäköisesti Mureakuhasta. Ne satunnaiset käynnitkin Ohjelmointiputkassa ovat osaltani ohi.
Tunnukseni Ohjelmointiputkasta saa poistaa!
Grezhän huomautti ihan järkevästi, että tossa on jotain pielessä.
Petja kirjoitti:
Niin unohtui melkein sanoa, herra on hyvä ja näyttää oman versionsa,
Muussa tilanteessa toteuttaisin sivun jotenkin ihan muuten, mutta nyt yritän toteuttaa sen niin, että vertailu edellisiin on helppoa.
<?php // Tunnukset, salasanat ja sivut. $sivut = array( "tunnus1" => array("salasana1", "sivu1.php"), "tunnus2" => array("salasana2", "sivu2.php"), ); // Kirjautuminen. function login() { global $sivut; if (!isset($_POST["username"], $_POST["password"])) { return null; } $tunnus = $_POST["username"]; if (!isset($sivut[$tunnus])) { die("Tunnusta ei löydy!"); } if ($sivut[$tunnus][0] != $_POST["password"]) { die("Salasana on väärin!"); } return $tunnus; } // Kirjautumislomake. function lomake() { ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Sivusto</title> </head> <body> <form method="post" action="?"> <input type="text" name="username" required /> <input type="password" name="password" required /> <button type="submit">Kirjaudu</button> </form> </body> </html> <?php die(); } // Juhulin versio toiminnasta: ohjaus "salaiselle" sivulle. function Juhuli() { global $sivut; if (($tunnus = login()) !== null) { header("Location: {$sivut[$tunnus][1]}"); } lomake(); } // Petjan versio toiminnasta: salaisen sivun haku includella. function Petja() { global $sivut; session_start(); if (isset($_GET["logout"])) { unset($_SESSION["tunnus"]); header("Location: ./"); die("Kirjauduttiin ulos."); } if (($tunnus = login()) !== null) { $_SESSION["tunnus"] = $tunnus; header("Location: ./"); die("Kirjautuminen onnistui."); } if (isset($_SESSION["tunnus"])) { require($sivut[$_SESSION["tunnus"]][1]); die(); } lomake(); } // Ajetaan jompikumpi versio. Juhuli();
Koodissa on eräitä merkittäviä parannuksia aiempiin nähden:
On toki myös puutteita, mutta ne ovat vähäisiä ja tässä tilanteessa mielestäni perusteltuja:
Petja kirjoitti:
Miten muka if- ja else-rakenteet typerästi?
Ehtorakenteiden jäsentelyssä on vikana, että sivun käsittely jatkuu ensimmäisen if-else-rakenteen jälkeenkin, jolloin sivu tulostetaan turhaan, kun käyttäjä ohjataan saman tien pois. Lisäksi koodissa on turhaan noin monta sisäkkäistä rakennetta, kun ne kaikki voisi laittaa yhteen ketjuun tai – kun kerran suorituksen on useimmissa lohkoissa tarkoitus päättyä – erillisinä if-lauseina, joiden lopussa on aina die.
Petja kirjoitti:
Ja mikä Refresh-otsikossa on väärin?
Rivi sinänsä on oikein kirjoitettu, mutta Refresh-otsikkoa ei pidä käyttää tuollaiseen tai yleensä muuhunkaan. Location on ohjauksia varten.
Petja kirjoitti:
Eihän tässä nyt tavoiteltu mitään "maailman siisteintä koodia" vaan ihan yksinkertainen esimerkki, jota voi oman halun mukaan soveltaa.
Koodisi riveistä 15 % on selvästi väärin (idealtaan tai toiminnaltaan) ja lopuistakin suuri osa huonoja. Tuollaisen esimerkin lähettäminen on hyödytöntä ja jopa vahingollista, jos joku kopioi kaikki nuo virheesi. Jos haluat auttaa, auta edes kunnolla eli tarkista, että koodisi toimii.
Petja kirjoitti:
En ole testannut koodia, mutta ei kyllä silmämääräisesti PHP heitä virhettä.
Sitten kannattaisi testata tai opetella PHP:tä paljon paremmin. Kun ohjelmointitaitosi on vielä noin huteralla pohjalla, ei kannata yrittää vetää esimerkkikoodeja hatusta, vaan kaikkien kannalta edullista olisi, että suunnittelisit ja testaisit ne kunnolla. Muista laittaa varoitukset ja huomautuksetkin näkyville PHP:n asetuksista. Sitä paitsi eräät viat koodissasi eivät aiheuta virheilmoituksia vaan yksinkertaisesti väärän lopputuloksen.
Petja kirjoitti:
Jos käyttäjä ei tarvitse muuta kuin yksinkertaisen login-skriptin sivuillensa, ei minun tarvitse alkaa tekemään jotain oliopurkkaviritelmää.
Hyvä koodi ei edellytä olioita eikä varsinkaan purkkaviritelmää. Hyvän koodin alkeita ovat mm. virheetön toiminta ja siisti ulkoasu.
Petja kirjoitti:
Tässä oli minun koodini, viestin aloittaja saa parantaa sitä jolloin oppii PHP:tä itsekin.
Jos oikeasti tuolla asenteella mennään, niin eihän tänne tarvitse koodia lähettää enää ollenkaan. Onhan aloittajalla jo aloitusviestissään koodi, jota hän saa parantaa, jolloin oppii PHP:tä itsekin.
Mikset itse paranna koodiasi ja opi PHP:tä? Selvästi tarvitset harjoitusta lähes yhtä paljon kuin aloittaja.
Petja kirjoitti:
Tunnukseni Ohjelmointiputkasta saa poistaa!
Dramaattista. Jos kuitenkin mietit hetken, tajuat ehkä, että tunnuksen poistaminen aiheuttaa ylimääräistä vaivaa ja ikäviä sivuvaikutuksia (mm. puuttuvia tai nimettömiä viestejä) verrattuna siihen, että tunnuksen annetaan olla ja lopetat vain itse sen käyttämisen.
kirjoitan pienen jatkon tähän keskusteluketjuun vielä. en ota mitään kantaa esimerkkien koodeihin tai niiden puutteisiin tai hyvyyteen. yksi asia kuitenkin on johon haluaisin sanoa mielipiteeni: putka on erinomaisen hieno sivusto, josta saa paljon apuja ja tukea koodaukseen. jos johonkin asiaan toivoisin kiinnitettävän kuitenkin huomiota, niin se on kielenkäyttö keskustelussa. joskus tulee vastaan sellaista tekstiä, jonka joku saattaa tuntea epämiellyttäväksi tai jopa loukkaavaksi.
eli siistitään kielenkäyttöä niin saadaan putkasta vieläkin suositumpi keskustelupaikka (sehän on myös foormumin etu)! ystävällinen vastaus kantaa pitemmälle ja epäystävällinen olisi parasta olla lähettämättä eteenpäin.
tv: nimimerkki itsekin joskus vähän loukkaantunut vastauksen sävystä
omg, Putka tulee kaatumaan sen omaan ylimielisyyteen.
En tiedä olivatko kommenttini epäystävällisiä, ainakaan niitä ei erityisesti ollut tarkoitettu sellaisiksi.
Monesti varmaankin arvostelu ja eri mieltä oleminen koetaan hyökkäykseksi ja sitä kautta epäystävällisyydeksi. Toki viestiin voisi lisäillä pehmennyksiä, mutta tiiviys ja sitä kautta luettavuus kärsisi. Myöskin vastakkaisten näkemysten ja perusteltujen mielipiteiden esittämisen koen tarpeelliseksi, koska ilman niitä ei ole kehitystä eikä keskustelua.
Foorumikeskustelussa ongelmallista on se, että ei näe ennen viestiin tullutta vastausta miten toinen osapuoli ottaa asian. Normaalisti keskustellessahan jo lauseen puolessavälissä voi kuulijan reaktioista huomata, että viestiä ei ehkä vastaanoteta aiotulla tavalla ja voi päivittää sanoman suuntaa. Ja toisaalta tekstistä ei välttämättä välity missä hengessä asia sanotaan.
Toisaalta jos noudattaisin kultaista sääntöä, provosoisin ja haastaisin vielä enemmän.
Grez kirjoitti:
En tiedä olivatko kommenttini epäystävällisiä, ainakaan niitä ei erityisesti ollut tarkoitettu sellaisiksi.
Grez, Metabolix, jne. käyttävät yleensä suoraa puhetta, mikä on kaukana epäystävällisestä puheesta. Tämä ei ollut kuitenkaan ensimmäinen kerta, kun joku loukkaantuu siitä; asialle pitää tehdä joskus jotakin... autetaan me, jotka olemme joskus loukkaantuneet, korjaamaan asiaa.
Itsekin käytän yleensä suoraa puhetta, mutta vähemmän "aloittelijoita" opastaessa. "Aloittelijoilla" tarkoitan tässä tapauksessa itseäni nuorempia tai kokemattomampia +- poikkeustapaukset. Yritän käyttää suurin piirtein samaa lähestymistapaa kuin parhaat opettajani. "Aloittelijoita" opastaessa käytän nykyisin "lientä, jossa on enimmäksen vettä", mikä ärsyttää suorapuheisia (seuraava kommentti sisältää lähinnä haukut :) ). En tiedä, olenko ollenkaan oikeilla jäljillä, kun tärkein palaute jää lähes kokonaan saamatta, foorumilla kun ollaan. Aika näyttää sen...
Kielenkäytössä ei siis ole mitään vikaa, adrenaliinia ehkä vähän liikaa osassa viesteissä. Pari kertaa, kun pallo osuu nenään, oppii varautumaan siihen... itsellänikin näin :)
Jos menen filosofian puolelle, Petjan viestin lopusta, Metabolixin tyrmäyksestä ja Petjan siihen reagoimisesta voi päätellä jotain. Kenties Petja vähätteli vaivannäköään (jonkun verran aikaa = puoli päivää (eli yritti parastaan)?) mutta Metabolix ei hoksannut sitä... Tällainen teoria selittäisi minusta ongelman alun.
Viestin loppukevennys:
Grez kirjoitti:
jos noudattaisin kultaista sääntöä, provosoisin ja haastaisin vielä enemmän.
Hyvä homma, pääset harjoittamaan lempiharrastustasi parin päivän päästä ilmaantuvaan aiheeseen. Ahjotetusta koodista löytyy sitten toivon mukaan bugi tai pari vähemmän. :D
Luen putkan keskusteluja juuri siksi, että niistä oppii silloin tällöin jotain. Netistä löytyy jo ihan tarpeeksi (PHP-)foorumeita, joissa aloittelijat esittelevät surkeita koodipätkiä ja taputtavat toisiaan selkään. Putkaa ei tarvitse yrittää muuttaa sellaiseksi.
Kokeneempien koodarien kommentit ovat erittäin hyödyllisiä oppimisen kannalta. Ei niistä ole mitään syytä loukkaantua, varsinkaan kun sävy on täysin asiallinen.
Aihe on jo aika vanha, joten et voi enää vastata siihen.