Nie jesteś zalogowany.
Jeśli nie posiadasz konta, zarejestruj je już teraz! Pozwoli Ci ono w pełni korzystać z naszego serwisu. Spamerom dziękujemy!

Ogłoszenie

Prosimy o pomoc dla małej Julki — przekaż 1% podatku na Fundacji Dzieciom zdazyć z Pomocą.
Więcej informacji na dug.net.pl/pomagamy/.

#1  2013-03-04 20:10:05

  HAL9000 - Użytkownik

HAL9000
Użytkownik
Zarejestrowany: 2006-04-22

Przetwarzanie formularzy

Pisze taki maly projekt na zaliczenie dla znajomego, ktory ma byc taka tablica ogloszen.
W sumie juz jest niemal skonczone (mimo ze pisanie w php z uzyciem sql, javascript i html jednoczesnie moze czasami zakrecic czlowiekiem ;-)) ale tak mi sie spodobala ta zabawa z php ze chcialem sam dla siebie sie dowiedziec jak to ma byc poprawnie zrobione.
Mianowicie chodzi o to jak poprawnie wysylac i przetwarzac formularze aby uchronic sie od glupich bledow w stylu wielokrotnego dodawania tych samych danych itp.

Tutaj teoria http://en.wikipedia.org/wiki/Post/Redirect/Get
tutaj reguly do tego wzorca z nastepnego wyniku google:
Never show pages in response to POST - nie pokazuj stron do ktorych dane sa wysylane metoda post
Always load pages using GET - zawsze laduj strony uzywajac metody get
Navigate from POST to GET using REDIRECT - przekieruj z post do get

Tak wiec ma to wygladac tak (na razie bez konkretnego kodu)

1)strona a z formularzem z metoda post i zabezpieczona np tym http://docs.jquery.com/Plugins/Validation
2)strona b, ktora niczego nie wyswietla a jedynie przetwarza (php) i przekierowuje do #3
3)strona c, ktora wyswietla podsumowanie tego co sie wydarzylo (informuje o ewentualnych bledach itp)

Teraz konkrety:
plik formtest.php

Kod:

<?php
require_once('doctype.php');
require_once('session.php');
require_once('head.php');
?>
<body>
<div id="siteContain">
    <?php
        require_once('siteheader.php');
    ?>
    <div id="content">
    <div id="leftMenu">
        leftmenu
    </div>
    <div id="mainContent">
        <form action="formtest_post.php" method="POST">
        <label for="uname">Login</label><input type="text" name="uname" id="uname" /><br />
        <label for="uemail">Email</label><input type="text" name="uemail" id="uemail" /><br />
        <button type="submit">Wyślij</button>
        </form>
    </div>
    <div class="spacer"></div>
    
    </div>
    <div id="footer"><?php require_once('footer.php'); ?></div>
</div>
</body>
</html>

plik formtest_post.php:

Kod:

<?php
if(isset($_POST['uname']) && isset($_POST['uemail']) && !empty($_POST['uname']) && !empty($_POST['uemail'])) {
    $mysqlhost = "localhost";
    $mysqluser = "root";
    $mysqlpass = "";
    $mysqldb = "test";
    $conn = mysql_connect($mysqlhost, $mysqluser, $mysqlpass);
    mysql_select_db($mysqldb) or die();
    $adduserquery = "INSERT INTO uzytkownicy(name, email) VALUES(\"{$_POST['uname']}\", \"{$_POST['uemail']}\")";
    $query_run = mysql_query("START TRANSACTION");
    $query_run = mysql_query($adduserquery);
    $query_run =mysql_query("SELECT id FROM uzytkownicy ORDER BY id DESC LIMIT 1");
    if(mysql_num_rows($query_run)) {
        $row = mysql_fetch_assoc($query_run);
        $id = $row['id'];
        mysql_free_result($query_run);
    }
    mysql_query("COMMIT");
    mysql_close($conn);
    ($id)?(header("Location: formtest_get.php?id=$id")):(header("Location: formtest_get.php?id=0"));
}
?>

plik formtest_get.php:

Kod:

<?php
require_once('doctype.php');
require_once('session.php');
require_once('head.php');
?>
<body>
<div id="siteContain">
    <?php
        require_once('siteheader.php');
    ?>
    <div id="content">
    <div id="leftMenu">
        left
    </div>
    <div id="mainContent">
        <?php
        if(isset($_GET['id']) && !empty($_GET['id'])) {
            echo $_GET['id'];
        }
        else {
            echo 0;
        }
        ?>
    </div>
    <div class="spacer"></div>
    
    </div>
    <div id="footer"><?php require_once('footer.php'); ?></div>
</div>
</body>
</html>

ps wiem ze przyklad jest glupi ale nie chcialem zaciemniac a jedynie przedstawic idee
ps2 w tych dolaczonych plikach nie ma zadnej magii zwykly kod html cala logika jest zawarta w tym co widac

1) Dobrze to zrozumialem czy tez umknelo mi cos waznego?
2) W pliku formtest_post.php $query_run = mysql_query("START TRANSACTION"); blokuje tabele aby mozna w nastepnych zapytaniach dostac sie do wlasnie dodanego rekordu sa jakies lepsze sposoby aby to zrobic?
3) Jak wygenerowac "losowy lancych" w url, ktory zaprowadzi do takiego rekordu z bazy danych cos jakby zamiennik do tego mojego ?id=$id (miedzy innymi oprogramowanie tego forum generuje cos takiego po wyslaniu posta/u?)
Pozdrawiam


For some reason I'm thinking I'm still 25 but I act like I'm 12.

Offline

 

#2  2013-03-04 22:58:28

  kamikaze - Administrator

kamikaze
Administrator
Zarejestrowany: 2004-04-16

Re: Przetwarzanie formularzy

1) Chyba ok. Nie ma w tym wielkiej filozofii.
2) Żeby co zrobić? Inaczej zablokować tabele czy dostać rekord? Nie ma potrzeby używać transakcji by pobrać rekord, a tabele można zablokować na wiele sposobów zależnie od poziomu izolacji.
3) Wygeneruj przy zapisie, zapisz w bazie i po nim wyszukuj ;] Chyba, że forum używa jakiego odwracalnego algorytmu i nie musi zapisać wygenerowanego stringa.

http://forum.dug.net.pl/viewtopic.php?pid=226181#p226181 - toż to zwykłe id posta z bazy. Nic generowanego.

Offline

 

#3  2013-03-05 09:55:15

  ponury_kostek - Użytkownik

ponury_kostek
Użytkownik
Skąd: Wałbrzych
Zarejestrowany: 2007-01-02
Serwis

Re: Przetwarzanie formularzy

1) Zabezpieczenia po stronie klienta OK, ale po stronie serwera są ważniejsze. Poczytaj o mysql_real_escape_string lub mysqli::real_escape_string i "Magic Quotes"
2) Jak już pisał kamikaze, transakcja nie jest potrzebna do tego co starasz się osiągnąć. Jeśli chcesz tylko obrać id ostatnio dodanego wiersza wystarczy użyć mysql_insert_id lub mysqli::$insert_id. Żeby sprawdzić błędy w zapytaniu użyj mysql_error lub mysqli::$error

Offline

 

Stopka forum

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson
To nie jest tylko forum, to nasza mała ojczyzna ;-)

[ Generated in 0.011 seconds, 12 queries executed ]

Informacje debugowania

Time (s) Query
0.00011 SET CHARSET latin2
0.00004 SET NAMES latin2
0.00149 SELECT u.*, g.*, o.logged FROM punbb_users AS u INNER JOIN punbb_groups AS g ON u.group_id=g.g_id LEFT JOIN punbb_online AS o ON o.ident='18.190.207.144' WHERE u.id=1
0.00091 UPDATE punbb_online SET logged=1716173474 WHERE ident='18.190.207.144'
0.00039 SELECT * FROM punbb_online WHERE logged<1716173174
0.00075 DELETE FROM punbb_online WHERE ident='85.208.96.212'
0.00063 SELECT topic_id FROM punbb_posts WHERE id=226188
0.00116 SELECT id FROM punbb_posts WHERE topic_id=23080 ORDER BY posted
0.00078 SELECT t.subject, t.closed, t.num_replies, t.sticky, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, 0 FROM punbb_topics AS t INNER JOIN punbb_forums AS f ON f.id=t.forum_id LEFT JOIN punbb_forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=3) WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id=23080 AND t.moved_to IS NULL
0.00008 SELECT search_for, replace_with FROM punbb_censoring
0.00127 SELECT u.email, u.title, u.url, u.location, u.use_avatar, u.signature, u.email_setting, u.num_posts, u.registered, u.admin_note, p.id, p.poster AS username, p.poster_id, p.poster_ip, p.poster_email, p.message, p.hide_smilies, p.posted, p.edited, p.edited_by, g.g_id, g.g_user_title, o.user_id AS is_online FROM punbb_posts AS p INNER JOIN punbb_users AS u ON u.id=p.poster_id INNER JOIN punbb_groups AS g ON g.g_id=u.group_id LEFT JOIN punbb_online AS o ON (o.user_id=u.id AND o.user_id!=1 AND o.idle=0) WHERE p.topic_id=23080 ORDER BY p.id LIMIT 0,25
0.00117 UPDATE punbb_topics SET num_views=num_views+1 WHERE id=23080
Total query time: 0.00878 s