Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Tworzenie się klasy na nowo przy przesłaniu formularza - jak to obejść
Forum PHP.pl > Forum > Przedszkole
hyhyhy
Witam, piszę sobie formularz rejestracyjny w PHP z wyszczególnianiem niewypełnionych pól. Kod może trochę nieoptymalny, ale działałby, gdyby klasa nie tworzyła się za każdym razem po przesłaniu formularza. Jest to jakoś do obejścia, czy raczej powinienem sobie dać spokój, bo w PHP się tego nie stworzy? Dodam, że mam inny pisany kiedyś z nudów kod, który działa, ale zajmuje mi 4x tyle miejsca i sam się w nim gubię smile.gif

A działanie tego kodu jest takie, że jak nacisnę "rejestruj", wszystkie pola dostaję na niebiesko z hasłem "proszę uzupełnić". I nigdy nie udaje mi się go wysłać. Z pewnością działałby, gdybym odwoływał się bezpośrednio do zmiennych z $_POST, ale wolę tego unikać, bo czytałem jakiś artykuł o atakach XSS gdzie coś było, że tworzy to lukę dla takiego ataku.

  1. <?php
  2.  
  3.  
  4. class rej{
  5. var $wyslano;
  6. var $ile = 9; //ilość pól formularza-1 - potrzebne do pętli
  7. var $form = array();
  8. var $opisy = array();
  9.  
  10.  
  11. public function __construct($form_table, $wyslano) {
  12. for ($i=0;$i<$this->ile;$i++){
  13. $this->form[$i] = mysql_real_escape_string(htmlspecialchars(trim($form_table)));
  14. }
  15. $this->wyslano = mysql_real_escape_string(htmlspecialchars($wyslano));
  16. }
  17.  
  18.  
  19.  
  20.  
  21. private function input($value, $name, $style, $opis){
  22. echo '<input type="text" maxlength="100" name="'.$name.'" value="'.$value.'" style="'.$style.'" /> '.$opis;
  23. }
  24.  
  25.  
  26. private function przypiszOpisy(){
  27. $this->opisy[0] = 'Login';
  28. $this->opisy[1] = 'Hasło';
  29. $this->opisy[2] = 'Powtórz hasło';
  30. $this->opisy[3] = 'E-mail';
  31. $this->opisy[4] = 'Imię';
  32. $this->opisy[5] = 'Nazwisko';
  33. $this->opisy[6] = 'Ulica i nr domu/mieszkania';
  34. $this->opisy[7] = 'Kod pocztowy';
  35. $this->opisy[8] = 'Miasto';
  36. $this->opisy[9] = 'Telefon kontaktowy';
  37. }
  38.  
  39.  
  40. public function formularz(){
  41. $this->przypiszOpisy();
  42. echo '<table>';
  43. echo '<form action="'.$_SERVER["REQUEST_URI"].'" method=POST>';
  44.  
  45. for ($i=0;$i<$this->ile;$i++){
  46. if (!empty($this->wyslano) && empty($this->form[$i])){ //pusty
  47. echo '<tr><td>';
  48. $this->input($this->form[$i], 'form["'.$i.'"]', 'background-color: lightsteelblue;', $this->opis[$i].' - proszę uzupełnić');
  49. echo '</td></tr>';
  50. }else{
  51. echo '<tr><td>';
  52. $this->input($this->form[$i], 'form["'.$i.'"]', '', $this->opis[$i]);
  53. echo '</td></tr>';
  54. }
  55. }
  56.  
  57. echo '<input type=hidden name=wyslano value=tak />';
  58. echo '<tr><td><input type=submit value=Zarejestruj /></td></tr>';
  59. echo '</form>';
  60. echo '</table>';
  61. }
  62.  
  63. public function czyWypelniono(){
  64. if (!empty($this->form[0]) && !empty($this->form[1]) && !empty($this->form[2]) && !empty($this->form[3]) &&
  65. !empty($this->form[4]) && !empty($this->form[5]) && !empty($this->form[6]) && !empty($this->form[7]) &&
  66. !empty($this->form[8]) && !empty($this->form[9])){
  67. return true;
  68. }else{
  69. return false;
  70. }
  71. }
  72.  
  73.  
  74. }//end class rej
  75.  
  76. $r = new rej($_POST["form"],$_POST["wyslano"]);
  77. if ($r->czyWypelniono()){
  78. echo '<h1>ZAPIS, WYPELNOINO</h1>';
  79. }else{
  80. $r->formularz();
  81. }
  82.  
  83.  
  84.  
  85. ?>
  86.  
IceManSpy
A po co robisz formularz jako osobną klasę, którą i tak nigdy do niczego już nie wykorzystasz? Zrób normalnie HTMl + PHP bez takich zabaw.
lobopol
Nazwanie tego tworu klasą to duże niedopowiedzenie brakuje tu po prostu mnóstwa rzeczy (np. brak sprawdzania czy formularz został wysłany, przecież to ciebie powinno zasypać warningami/noticeami). Dodatko poczytaj sobie o xss i jak działa, a nie
Kod
bo coś przeczytałem gdzieś, ale nie pamiętam co, ale wiem, że coś robiło

Zacznę więc od początku:
  1. $r = new rej($_POST["form"],$_POST["wyslano"]);

Jeżeli używasz posta powinieneś najpierw sprawdzić czy zmienne zostały ustawione (czyli wysłany formularz funkcja isset);
  1. var $wyslano;
  2. var $ile = 9; //ilość pól formularza-1 - potrzebne do pętli
  3. var $form = array();
  4. var $opisy = array();

od php 5 nie powinno się używać var tylko public/protected/private
  1. public function __construct($form_table, $wyslano) {
  2. for ($i=0;$i<$this->ile;$i++){
  3. $this->form[$i] = mysql_real_escape_string(htmlspecialchars(trim($form_table)));
  4. }
  5. $this->wyslano = mysql_real_escape_string(htmlspecialchars($wyslano));
  6. }

Wytłumacz mi czemu w tym miejscu ustawiasz htmlspecialchars i mysql_real_escape, jeżeli masz zapisać w bazie to dopiero tam dawaj mysql_real_escape, a htmlspecialchars dawaj tylko przy wyświetlaniu (ba obie funkcje używasz na tablicy).
Ten for jaki masz działa tak czy jest ustawiona tablica czy nie przypisz całą tablicę $_POST['form'] do zmiennej $this->form[$i], czyli każdy element tablicy $this->form ma teraz całą tablicę $_POST['form']
Nie jestem pewien co htmlspecialchars/mysql_escape zrobi jak mu się poda tablicę zamiast stringa chyba false albo pusty string, ale nie chcę mi się sprawdzać.

  1. $this->wyslano = mysql_real_escape_string(htmlspecialchars($wyslano));

No tu mnie zagiąłeś, powiedz mi czemu to ma służyć? wyświetlasz/zapisujesz to gdzieś?

  1. if ($r->czyWypelniono()){
  2.  
  3. public function czyWypelniono(){
  4. if (!empty($this->form[0]) && !empty($this->form[1]) && !empty($this->form[2]) && !empty($this->form[3]) &&
  5. !empty($this->form[4]) && !empty($this->form[5]) && !empty($this->form[6]) && !empty($this->form[7]) &&
  6. !empty($this->form[8]) && !empty($this->form[9])){
  7. return true;
  8. }else{
  9. return false;
  10. }
  11. }

W tym momencie jeżeli coś było przesłane (cokolwiek) to zwróci true. Zamiast całej te sieczki można było zrobić
  1. for($i = 0;$i<=$this->ile;$i++){
  2. if(empty($this->form[$i])){
  3. return false;
  4. }
  5. return true;
  6. }


Formularz ma masę błędów składniowych typu
  1. public function formularz(){
  2. $this->przypiszOpisy();
  3. echo '<table>';
  4. echo '<form action="'.$_SERVER["REQUEST_URI"].'" method=POST>'; //a gdzie "" przy post? '<form action="'.$_SERVER["REQUEST_URI"].'" method="post">
  5.  
  6. for ($i=0;$i<$this->ile;$i++){
  7. if (!empty($this->wyslano) && empty($this->form[$i])){ //pusty // jeżeli htmlspecialchars bądź mysql_real_escape przy dostaniu tablicy zwraca false/pusty string to zawsze się to wykona po przesłaniu formularza
  8. echo '<tr><td>';
  9. $this->input($this->form[$i], 'form["'.$i.'"]', 'background-color: lightsteelblue;', $this->opis[$i].' - proszę uzupełnić'); // nadawaj klasy inputom, a nie ręczne style!
  10. echo '</td></tr>';
  11. }else{~//to będzie tylko jeżeli form nie został wysłany
  12. echo '<tr><td>';
  13. $this->input($this->form[$i], 'form["'.$i.'"]', '', $this->opis[$i]);
  14. echo '</td></tr>';
  15. }
  16. }
  17.  
  18. echo '<input type=hidden name=wyslano value=tak />'; //a cudzysłowie to kto pokasował?
  19. echo '<tr><td><input type=submit value=Zarejestruj /></td></tr>';//jak wyżej
  20. echo '</form>';
  21. echo '</table>';
  22. }


Czyli co masz zrobić:
-poczytaj o klasach
-naucz się html
hyhyhy
Okej, rozumiem, że całość do przepisania smile.gif

Cytat
a htmlspecialchars dawaj tylko przy wyświetlaniu

Widocznie "słabo" poczytałem, tekst był po angielsku, więc może źle zrozumiałem, że każde odwołanie do "surowej" zmiennej z POST/GET stwarza lukę do xss. To mi ułatwia sprawę w takim razie.

Ogólnie dzięki za zainteresowanie, przerobię go jak należy i powinno działać.
lobopol
xss jest groźny tylko i wyłącznie przy wyświetlaniu czegoś na stronie, dlatego przy wyświetlaniu danych od użytkowników warto dać htmlspecialchars aby nie mogli odpalać js/html. Zawsze jest lepiej mieć czystą wersję w bazie (szczególnie jeżeli to może być edytowane unikamy wtedy bawienia się z hmlentitydecodem). Więc jeszcze raz dawaj specialcharsa tylko przy wyświetlaniu ba stronie, a przy zapisie do bazy dawaj mysl_real_escape. I zawsze sprawdzaj przy formularzach czy wymagane pola zostały ustawione
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.