Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: PHP: Vessanseinäsimulaattori

Sivun loppuun

Pyry [30.11.2004 22:58:32]

#

Täällä putkassa tai mureakuhassa saattaa olla jo samantyyppinen koodivinkki ja vieläpä samalla nimellä, joten älkää sellaisesta epäkohdasta valittako. Lähinnä tässä demoan noita serialize() ja unserialize()-funktioita, jotka ovat ainakin omassa käytössäni osoittautuneet erittäin käteviksi.

Koodia voi testata osoitteessa http://nkey.homelinux.org/misc/wc_wall.php

<?php
/*
Vessanseinäsimulaattori v0.1
(c) Pyry Haulos 2004
http://nkey.homelinux.org/

Koodi demoaa serialize()- ja
unserialize()-funktioiden käyttöä, joista
on tarkempaa tietoa osoitteessa
https://www.php.net/manual/en/function.serialize.php
ja
https://www.php.net/manual/en/function.unserialize.php

Testattu php:n versiolla 5.0.2
Pitäisi toimia versioissa > 4.0
Voi testata osoitteessa
http://nkey.homelinux.org/misc/wc_wall.php
*/

// tietokantafilu
$dbfile = "./viestit.txt";

// ?x tyhjentää
$methodx = "clear";

// maksimi ja minimipituudet
$name_min_len = 3;
$name_max_len = 30;
$message_min_len = 5;
$message_max_len = 1000;

$max_line_len = 100; // yhden rivillisen maksimipituus
$max_newline_count = 30; // kuinka monta rivinvaihtoa saa viestissä olla

$max_messages = 100; // viestien maksimimäärä

function get_contents($filename)
{
    $read_handle = fopen($filename, "r");
    $contents = fread($read_handle, filesize($filename));
    fclose($read_handle);

    return $contents;
}

function put_contents($filename, $content)
{
    if (!$file_handle = fopen($filename, 'w'))
    {
        return false;
    }

    if (fwrite($file_handle, $content))
    {
        fclose($file_handle);
        return true;
    }
    else
    {
        fclose($file_handle);
        return false;
    }
}

// tyhjä viestitaulukko
$messages = array();

// chekataan, onko dbfile kirjoitettava
if (!is_readable($dbfile))
{
    die("Database is not readable!");
}

if (!is_writable($dbfile))
{
    die("Database is not writable!");
}

// tarkistetaan, onko salaista metodia x kutsuttu, jolloin tietokanta tyhjennetään
if (isset($_GET[$methodx]))
{
    if ( @put_contents($dbfile, serialize($messages) ))
    {
        die("Database cleared!");
    }
    else
    {
        die("Failed to clear database!");
    }
}

// loaditaan viestit tietokannasta
$serialized_messages = get_contents($dbfile);

if (($messages = unserialize($serialized_messages)) === false)
{
    die("Failed to unserialize messages!");
}

// tarkistetaan, onko uusi viesti lähetetty lisättäväksi
if (isset($_POST['name'], $_POST['message']))
{
    // sitten tehdään securityjutskat noille
    $name = stripslashes($_POST['name']);
    $name = htmlspecialchars($name);

    $message = stripslashes($_POST['message']);
    $message = htmlspecialchars($message);

    if (strlen($name) < $name_min_len)
    {
        $error = "Liian lyhyt nimi!";
    }
    else if (strlen($name) > $name_max_len)
    {
        $error = "Liian pitkä nimi!";
    }
    else if (strlen($message) < $message_min_len)
    {
        $error = "Liian lyhyt viesti!";
    }
    else if (strlen($message) > $message_max_len)
    {
        $error = "Liian pitkä viesti!";
    }
    else if (substr_count($message, "\n") > $max_newline_count)
    {
        $error = "Liian monta rivinvaihtoa viestissä!";
    }

    if (!isset($error))
    {
        // pätkitään sanat lyhyemmiksi
        $message = wordwrap($message, $max_line_len, "\n", true);

        // korvataan rivinvaihdot
        $message = nl2br($message); // nykyisin nl2br() on xhtml-yhteensopiva

        $messages[] = array('date' => date("d.m.y G:i:s"), 'name' => $name, 'message' => $message);

        if (count($messages) > $max_messages)
        {
            // poistetaan vanhimmat viestit
            $messages = array_slice($messages, (count($messages) - $max_messages), count($messages));
        }

        if (@put_contents( $dbfile, serialize($messages) ))
        {
            $success = "Viesti lisätty!";
        }
        else
        {
            $error = "Viestin lisääminen epäonnistui!";
        }

        unset($message); // poistetaan, jottei lähetetty viesti näkyisi
    }
}

// sitten printataan formi ja viestit
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

  <head>
    <title>vessanseinä v0.1</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
    <style type="text/css">
.text {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 12px;
    color: #000000;
}
.message {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 12px;
    color: #000000;
    background-color: #EEEEEE;
}
input {
    border: 1px solid #CCCCCC;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 12px;
    color: #000000;
    text-decoration: none;
    height: 16px;
    background-color: #EEEEEE;
}
textarea {
    border: 1px solid #CCCCCC;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 12px;
    color: #000000;
    text-decoration: none;
    background-color: #EEEEEE;
}
.button {
    border: 1px solid #CCCCCC;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 12px;
    color: #000000;
    text-decoration: none;
    height: 16px;
    background-color: #EEEEEE;
}
    </style>
  </head>

  <body>
    <?php

if (isset($error))
{
    echo '
    <p class="text">
      <font color="#FF0000">'.$error.'</font>
    </p>';
}
else if (isset($success))
{
    echo '
    <p class="text">
      <font color="#00FF00">'.$success.'</font>
    </p>';
}

    ?>
    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" class="text">

      <table width="400" border="0" cellpadding="2" cellspacing="2">
        <tr>

      <td width="100" class="text" valign="middle">
            nimi
      </td>
      <td width="300" class="text" valign="middle">
        <input type="text" name="name" value="<?php if (isset($name)) { echo $name; } ?>" size="50" />
      </td>

    </tr>
    <tr>

      <td width="100" class="text" valign="middle">
        viesti
      </td>
      <td width="300" class="text" valign="middle">
            <textarea name="message" rows="5" cols="48"><?php if (isset($message)) { echo $message; } ?></textarea>
      </td>

    </tr>
    <tr>

      <td width="100" />
      <td width="300" class="text" valign="middle">
        <input type="submit" name="button" value=" lis&auml;&auml; viesti " />
      </td>

    </tr>
      </table>

    </form>
    <br />
    <table width="800" border="0" cellpadding="2" cellspacing="2">

      <?php

$messages = array_reverse($messages); // uusin ensin

foreach ($messages as $message)
{
    echo '
      <tr>
        <td width="100" valign="middle" class="message">
      '.$message['date'].'
    </td>
    <td width="100" valign="middle" class="message">
      '.$message['name'].'
    </td>
    <td width="600" valign="middle" class="message">
      '.$message['message'].'
    </td>
      </tr>';
}
      ?>

    </table>
  </body>
</html>

tsuriga [01.12.2004 02:00:44]

#

Näyttäisi varsin toimivalta systeemiltä, välejäkin on mukavasti. En tiedä, onko sitten tarkoituksella, mutta $name:a ei unsetata viestin kirjoittamisen jälkeen. Hehheh otitkos/vaihdoitkos esimerkistä maagisen tyhjennysmetodin pois? Noi yhden rivin ehtolauseet _itse_ "sieventäsin" :).

T.M. [01.12.2004 15:03:06]

#

Mikä ihmeen vessan seinäsimulaattori...!?
Tuohan on selvästi vieraskirjan alku :L

Joo ja kannattaa jättää nuo PHP5 funktioiden käyttö pois näinkin pienistä esimerkeistä. Nimittäin palvelimien PHP:tä ei ole vielä läheskään kaikissa paikoissa päivitetty.

Kaksi kertaa count($messages) ->

$messages = array_slice($messages, (count($messages) - $max_messages), count($messages));

Tuskin se muuttujaan asetus on hitaampi kuin kaksi kertaa tuon funktion kutsu.

Anteeksi negatiivinen palautteeni taas kerran. (tuskin saan anteeksi)

Pyry [01.12.2004 16:21:05]

#

Nyt on korvattu ne php5 funktiot omilla, testatkaa joku vanhemmalla php:llä.

lainaus:

Anteeksi negatiivinen palautteeni taas kerran. (tuskin saan anteeksi)

Eipä mitään, pitäähän olla kriittinen, tai mitään kehitystä ei tapahdu.

Gwaur [02.12.2004 00:07:49]

#

"Vessanseinä" :P

Eipä tuossa kuvauksessa olevalla testaulla toimi ainakaan japanimerkit. Liekö vika sitten serverissä tai skriptissä tai missä. Kirjoitin "日本語か", eli "Nihongo ka?" eli "Japania?", juuri testatakseni niiden merkkien toimimista :)

Tumpi [02.12.2004 00:18:38]

#

Höh, odotin jotain tyyliin kuva, jossa erilaisilla fonteilla sekaisin kaikkia noita kirjoituksia. :P

Pyry [02.12.2004 10:29:45]

#

Jaa'a, noi japskumerkkien puuttumiset varmaankin johtuu serveristä, en näe niitä kuitenkaan niin tarpeellisiksi, että laittaisin toimimaan :)

Tumpin ehdotus on mainio, voisihan sitä vähän parannella. Lähinnä tein tuon sitä varten, että luokkakaverit ei yrittäis sotkea mun vieraskirjaa, vaan menisivät peeloilemaan tuonne.

T.M. [02.12.2004 21:36:32]

#

Huppistas... unohdin vinettää vielä siitä ettei kannata tunkea niitä viestejä yhteen taulukkoon. Parempi tapa olisi tunkea ne riveittäin tiedostoon, joka riville oma serializoitu datansa.
Riveittäin kun tunkee ne, kannasta tulee noin 6 kertaa nopeampi (testattu on). Isoilla tiedostoilla nopeusero on huomattava.

Pyry [02.12.2004 22:02:08]

#

No vastavinetystä; mitäs sitten, kun joku tunkee viestiinsä rivinvaihdon? Ne pitää tietenkin parsia pois. Eikä tuossa tapauksessa kannasta pääse tulemaan kovinkaan isoa, max. 100 viestiä. Näissä asioissa joutuu tekemään kompromisseja helppouden ja tehokkuuden kanssa :)

juha127 [11.09.2005 19:50:36]

#

Kokeilin tuota "Vessanseinääsi", mutta en saanut toimimaa sitä
mul tuli ilmoitus Parse error: parse error, unexpected '=' in /mbnet/j/juha127/phpsivu/kuvat/testi/testi.php on line 29

En itse osannut korjata virhettä, koska olen vielä aika aloitteleva php:ssä.

Metabolix [10.12.2011 02:59:17]

#

Nyt olisi kyllä syytä jo vaihtaa ne PHP5:n funktiot takaisin. Lisäksi PHP_SELFin voisi ottaa kokonaan pois, sehän on sekä turha että tunnettu tietoturvariski. Muutenkin koodi kaipaisi uutta tarkistusta (PHP:n virheilmoitukset käyttöön!) ja siistimistä etenkin HTML:n ja CSS:n puolelta.


Sivun alkuun

Vastaus

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

Tietoa sivustosta