Olen opetellut php:tä alle viikon ja nyt olen yrittänyt saada vieraskirjaan vastaustoimintoa. Olen yrittänyt saada vastaustoiminnon sellaiseksi, että jos vastausta ei ole niin se näyttää lomakkeen johon vastaus kirjoitetaan. Jos vastaus on jo, niin se näyttäisi pelkän vastauksen. Mutta en ole saanut sitä toimimaan. Ajattelin kysyä täällä, onko koodissani jotain vikaa?
Tässä koodit:
vieraskirja.php
<?php include("yla.php"); ?> <h3>Vieraskirja</h3> <a href="kirjoita.php">Kirjoita viestisi.</a> <?php include("viestit.php"); ?> <?php include("ala.php"); ?>
viestit.php
<?php //luetaan viestit taulukkoon $viestit = file("viestit.txt"); //käännetään taulukko, jolloin uusimmat viestit tulevat ylimmiksi $viestit = array_reverse($viestit); //viestien määrä on suoraan taulukon rivien määrä $viestimaara = count($viestit); if($viestimaara == 0) { echo '<p>Vieraskirjassa ei ole vielä yhtään viestiä.<br />Kirjoita nyt ja ole ensimmäinen.</p>'; } //käydään jokainen viesti läpi for ($i = 0; $i < $viestimaara; $i++) { //$viestit[$i] on merkkijono, joka sisältää viestin $i tiedot //pystyviivoilla erotettuna; jaetaan viestit $tiedot-taulukkoon $tiedot = explode("|", $viestit[$i], 4); //erotellaan tiedot omiin muuttujiinsa $nimi = $tiedot[0]; $aika = $tiedot[1]; $viesti = $tiedot[2]; $vastaus = $tiedot[3]; //tulostetaan viesti echo '<p><b>Lähettäjä</b>:'; echo $nimi; echo '<br /><b>Aika</b>: ' . date("d.m.Y H:i", $aika) . '<br />'; echo $viesti; if($vastaus == NULL) { echo '<form action="vastaus.php" method="post">'; echo '<input type="hidden" name="aika" readonly="readonly" value="$aika" />'; echo '<textarea name="vastaus" cols="45" rows="6"></textarea><br />'; echo '<input type="submit" value="Vastaa" />'; echo '</form><hr />'; }else{ echo '<br />Vastaus:<br />'; echo $vastaus; echo '<hr />'; } } ?>
kirjoita.php
<?php //jos nimeä ja viestiä ei ole annettu, näytetään lomake... if (($_POST['nimi']) == NULL || ($_POST['viesti']) == NULL) { ?> <?php include("yla.php"); ?> <h3>Vieraskirja</h3> <form action="kirjoita.php" method="post"> Nimimerkki:<br /><input type="text" name="nimi" /><br /> Viesti:<br /><textarea name="viesti"rows="8" cols="50"></textarea><br /> <input type="submit" value="Kirjoita" /> </form> <?php include("ala.php"); ?> <?php //...muussa tapauksessa kirjoitetaan viesti tiedostoon } else { //avataan tiedosto append-tilassa: kirjoitetaan tiedoston loppuun $tiedosto = fopen("viestit.txt", "a"); //haetaan lomakkeen kautta tulleet muuttujat $nimi = $_POST['nimi']; $viesti = $_POST['viesti']; //poistetaan ylimääräiset kenoviivat (\) $viesti = stripslashes($viesti); //estetään HTML-tagien käyttäminen $viesti = htmlspecialchars($viesti); //muutetaan rivinvaihdot HTML-muotoon $viesti = str_replace("\n", "<br>", $viesti); //Vastaus arvoon NULL $vastaus = NULL; // $nimi = str_replace("|", "l", $nimi); $viesti = str_replace("|", "l", $viesti); //otetaan talteen aika, jolloin viesti lähetettiin $aika = time(); //muodostetaan tiedostoon tallennettava rivi $rivi = "$nimi|$aika|$viesti|$vastaus\n"; //kirjoitetaan rivi tiedostoon fwrite($tiedosto, $rivi); //suljetaan tiedosto fclose($tiedosto); //ohjataan käyttäjä vieraskirjasivulle header("Location: vieraskirja.php"); } ?>
vastaus.php
<?php $rivit = file("viestit.txt"); for ($viestit = 0; $viestit < count($rivit); $viestit++) { $tiedot = explode("|", 4); if ($tiedot[1] == $_POST["aika"]) { //erotellaan tiedot omiin muuttujiinsa $nimi = $tiedot[0]; $aika = $tiedot[1]; $viesti = $tiedot[2]; $vastaus = $_POST["vastaus"]; } } $tiedosto2 = fopen("viestit.txt", "w"); fwrite($tiedosto2, implode("", $rivit)); fclose($tiedosto2); //ohjataan käyttäjä vieraskirjasivulle header("Location: vieraskirja.php"); ?>
apinaakoijataan kirjoitti:
<?php if($vastaus == NULL) { echo '<form action="vastaus.php" method="post">'; echo '<input type="hidden" name="aika" readonly="readonly" value="$aika" />'; echo '<textarea name="vastaus" cols="45" rows="6"></textarea><br />'; echo '<input type="submit" value="Vastaa" />'; echo '</form><hr />'; } ?>
Mikäli lomake ei tulostu tarkoittaa se sitä, että $vastaus muuttujassa on jokin muu arvo kuin NULL kokeile var_dump($vastaus) se kertoo arvo ja tyypin, joka auttanee ongelmassa. Jos ongelna on jokin muu, niin kerro toki sekin (ja virheet).
Mahdetaanko NULL kirjoittaa tiedostoon, jos se laitetaan noin? Eikös NULL tarkoita tyhjää, eli periaatteessa kirjoitettava merkkijono on tyhjä.
Vika on varmaankin taas siinä, että viimeiseen sarakkeeseen jäävät rivinvaihtomerkit, jolloin teksti ei ole ""
vaan "\n"
tai jopa "\r\n"
. Jos tuo on koodin ainoa virhe, ratkaisu on lisätä file-funktion parametriksi FILE_IGNORE_NEW_LINES:
$viestit = file('viestit.txt', FILE_IGNORE_NEW_LINES);
Metabolix kirjoitti:
$viestit = file('viestit.txt', FILE_IGNORE_NEW_LINES);
Kiitos, nyt toimii tämä osa.
Mutta nyt ongelma on, ettei vastausta kirjoiteta ylös. Eli ongelma on todennäköisesti vastaus.php:ssä.
Yritin tehdä vastaustoiminnan siten, että se etsii oikean vietsin lähetysajan mukaan.
Mutta kun lähetän vastauksen, niin ei se sitä ainakaan muistiin kirjoita.
Sama ohje pätee edelleen jos kirjoitus ei onnistu, niin vertailu ei välttämättä ole oikein. Muutoinkan päivämäärän tallentaminen muotoiltuna ei ole järkevää, vaan parempi olisi pitää se ihan time() funktion antamana aikaleimana.
Tulosta silmukassa noiden muutrtujien arvoja ja katso mikä menee vikaan. Melko varmaan ongelma on helpohko ratkaista.
En mielestäni tallenna sitä muotoiltuna. Vaan se tallennetaan kirjoitus.php:ssä tuolla tavalla kuin kerroit eli $aika=time()...
Uskoisin että ongelma on tässä:
echo '<input type="hidden" name="aika" readonly="readonly" value="$aika" />';
;
Koitin tulostaa tuon arvon, niin se tulostaa vain tämän: $arvo.
Kuinka se pitäisi tuonne formiin kirjoittaa, että sieltä tulisi oikea arvo.
EDIT: Nyt sain sieltä arvon kun laitoin näin:value='. $aika .'
Mitä nuo pisteet tuossa tarkoittavat?
Ja nyt koitan saada jonkun arvon ulos tuolta vastaus.php:stä,
kun se ei anna mitään ulos...
piste on katenointioperaattori, jolla voi yhdistellä merkkijonoja toisiinsa. Se miksei tuo ensimmäinen toiminut on niinkin yksinkertainen juttu kuin, että yksinkertaisen hipsujen kanssa php ei tulkitse muuttujia. Lainausmerkkien kanssa tuo olisi tuottanut halutun lopputuloksen. Koita vielä laittaa var_dump($_POST), niin saat nuo lähetetyt kentät esille.
Tähän aiheketjuunm postaan mielipiteeni:
Ei näin:
<?php $muuttuja = 'arvo'; echo '<a href="http://www.google.fi/">Google</a>'; echo 'Muuttuja on ' . $arvo . ' ja sillä selvä!'; ?>
Kyllä näin:
<?php $muuttuja = "arvo"; echo "<a href=\"http://www.google.fi/\">Google</a>\n"; echo "Muuttuja on $arvo ja sillä selvä!"; ?>
Omaan silmääni tuo jälkimmäinen vain näyttää paremmalta...
Ja mielummin vielä nuo umlautit ihan vaan ääkkösiksi. Sekin näyttää vaan niin paljon mukavammalta. :)
Omaan silmään selkein ja kaunein olisi:
<a href="http://www.google.fi/">Google</a> Muuttuja on arvo ja sillä selvä
Eli poistin täysin turhat php-väkästykset.
Paratiisin poika kirjoitti:
Tähän aiheketjuunm postaan mielipiteeni:
Ei näin:
<?php $muuttuja = 'arvo'; echo '<a href="http://www.google.fi/">Google</a>'; echo 'Muuttuja on ' . $arvo . ' ja sillä selvä!'; ?>Kyllä näin:
Huomasitkohan mitään eroa muuttujilla $muuttuja ja echossa käytetyllä $arvo:lla?
Sinun esimerkkisihän tulostaisi: "Muuttuja on ja sillä selvä!";
en ees osaa käyttää tosta . juttua :(
Nyt sain tiedot siirtymään ja tallentamaan. Ainoa ongelma nyt on se, että kun vastaus tallennetaan, niin ainoastaan vastattu viesti jää jäljelle ja muut viestit poistuvat...
Missä vika nyt?
Tässä on tämän hetkinen vastaus.php:
<?php $viestit = file('viestit.txt', FILE_IGNORE_NEW_LINES); $viestimaara = count($viestit); //käydään jokainen viesti läpi for ($i = 0; $i < $viestimaara; $i++) { //$viestit[$i] on merkkijono, joka sisältää viestin $i tiedot //pystyviivoilla erotettuna; jaetaan viestit $tiedot-taulukkoon $tiedot = explode("|", $viestit[$i], 4); if ($tiedot[1] == $_POST["aika"]) { //erotellaan tiedot omiin muuttujiinsa $nimi = $tiedot[0]; $aika = $tiedot[1]; $viesti = $tiedot[2]; $vastaus = $_POST["vastaus"]; } } $tallennavastaus = fopen("viestit.txt", "w"); $rivi = "$nimi|$aika|$viesti|$vastaus\n"; fwrite($tallennavastaus, $rivi ); fclose($tallennavastaus); //ohjataan käyttäjä vieraskirjasivulle header("Location: vieraskirja.php"); ?>
Tyhjennät tiedoston ja kirjoitat sinne vain yhden rivin. Sinun pitäisi avata tiedosto ennen for-silmukkaa ja kirjoittaa sinne kaikki rivit, muutettu rivi uudessa muodossa ja muut rivit entisellään.
Minä avaan tiedoston lukua varten ennen for-silmukkaa, jotta voin löytää korvattavan rivin.
<?php $viestit = file('viestit.txt', FILE_IGNORE_NEW_LINES); $viestimaara = count($viestit); (Tässäkö pitäisi avata kirjoitustilaan??) //käydään jokainen viesti läpi for ($...
Enhän minä pysty silloin avaamaan sitä samaan aikaan kirjoitustilaan?
apinaakoijataan kirjoitti:
Enhän minä pysty silloin avaamaan sitä samaan aikaan kirjoitustilaan?
Funktio file avaa tiedoston lukutilaan, lukee sen sisällön ja sulkee tiedoston, joten voit avata tiedoston heti sen jälkeen kirjoitustilaan.
Kiitos paljon kaikille auttajille.
Nyt toimii :D
Lopullinen vastaus.php:
<?php $viestit = file('viestit.txt', FILE_IGNORE_NEW_LINES); $viestimaara = count($viestit); $tallennavastaus = fopen("viestit.txt", "w"); //käydään jokainen viesti läpi for ($i = 0; $i < $viestimaara; $i++) { //$viestit[$i] on merkkijono, joka sisältää viestin $i tiedot //pystyviivoilla erotettuna; jaetaan viestit $tiedot-taulukkoon $tiedot = explode("|", $viestit[$i], 4); if ($tiedot[1] == $_POST["aika"]) { //erotellaan tiedot omiin muuttujiinsa $nimi = $tiedot[0]; $aika = $tiedot[1]; $viesti = $tiedot[2]; $vastaus = $_POST["vastaus"]; $rivi = "$nimi|$aika|$viesti|$vastaus\n"; fwrite($tallennavastaus, $rivi ); } else { $nimi = $tiedot[0]; $aika = $tiedot[1]; $viesti = $tiedot[2]; $vastaus = $tiedot[3]; $rivi = "$nimi|$aika|$viesti|$vastaus\n"; fwrite($tallennavastaus, $rivi ); } } fclose($tallennavastaus); //ohjataan käyttäjä vieraskirjasivulle header("Location: vieraskirja.php"); ?>
Olen vasta-alkaja php:n parissa,
joten onko ehdotuksia,
mitä kannattaisi seuraavaksi tehdä?
Kannattaa siivota vähän koodia. Sekä if-, että else-osassa on yhteistä kaikki muu paitsi $vastaus-muuttuja, jolloin muut sijoitukset ja fwriten voi laittaa ifin ulkopuolella. Muutenkin if-osassa vertailet $tiedot[1]-muuttujaa ja silti sijoitat sen arvon samaan muuttujaan sekä if- että else-osassa, joten mieti, mitä arvoa ja muuttujaa kannattaa käsitettä ifissä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.