Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Mój pierwszy skrypt
Forum PHP.pl > Forum > Przedszkole
robert-s
No dobra, dzisiaj zacząłem nauke PHP i udało mi się po całym dniu wypocić jeden skrypt. Mógłby ktoś mnie zmiażdżyć i wytknąć wszystkie błędy, żebym nie popełniał ich na przyszłość? Generalnie robi to co chcę, czyli odczytuje, wysyła i zapisuje komentarze do pliku csv, jednak może coś da się zrobić w zgrabniejszy sposób? Mam jedną stronę na CMS nieobsługującym komentarzy i chcę skrypt wstawić na jedną podstronę tylko, żeby user mógł sobie wyrazić opinię.

  1. <?php
  2.  
  3. $wczytaj = fopen("komentarze.csv", "r");
  4. while ($tablica = fgetcsv($wczytaj, 1000, ","))
  5. {
  6. echo "<div id='data'>$tablica[0]</div>";
  7. echo "<div id='imie'>$tablica[1] pisze:</div>";
  8. echo "<div id='tresc'>$tablica[2]</div>";
  9. }
  10. fclose ($wczytaj);
  11. ?>
  12.  
  13. <form id="commentform" method="post" action="wyslij.php">
  14.  
  15. <div>
  16. <label for="podpis">Podpis</label>
  17. <input id="podpis" type="text" name="podpis">
  18. </div>
  19.  
  20. <div>
  21. <label for="komentarz">Komentarz</label>
  22. <textarea id="komentarz" type="text" name="komentarz"></textarea>
  23. </div>
  24.  
  25. <div>
  26. <input id="przycisk" type="submit" value="Opublikuj komentarz" name="przycisk">
  27. </div>
  28.  
  29. </form>


  1. <?php
  2.  
  3. $podpis = $_POST['podpis'];
  4. $komentarz = $_POST['komentarz'];
  5.  
  6. echo "$podpis";
  7. echo "$komentarz";
  8. echo date('j.m.Y');
  9.  
  10. $czas = date('j.m.Y');
  11.  
  12. $list = array($czas, $podpis, $komentarz);
  13.  
  14. $wczytaj = fopen('komentarze.csv', 'a');
  15.  
  16. fputcsv($wczytaj, $list);
  17.  
  18. fclose($wczytaj);
  19. ?>


Teraz planuję jeszcze dorobić małe zabezpieczenie w postaci pytania i zliczanie znaków. Gdy będzie mniej niż ileś, komentarz się nie zapisze. Aha. I powrót na poprzednią stronę po wysłaniu. Dałoby radę dać jakąś podpowiedż jakie funkcje mi w tym pomogą?
ethann
Cytat
zliczanie znaków

strlen

Cytat
powrót na poprzednią stronę

header
np.
  1. header("Location: /index.php"); // przejście na określoną stronę
  2. header("Location: ".$_SERVER['HTTP_REFERER']); // przejście na stronę z której został użytkownik przekierowany


Proponuję także zabezpieczyć się przed XSS oraz w jakiś sposób zabezpieczyć kod przed niechcianymi znakami. W tym przypadku będą to przecinki, czyli znaki oddzielające.
zabezpieczyć się przed XSS:
przykładowo skorzystać z funkcji htmlspecialchars.

zabezpieczyć kod przed niechcianymi znakami:
proponuję zamienić przecinki [,] na html'owy ich odpowiednik [,]. W tym celu możesz skorzystać z funkcji preg_replace.
np.
  1. preg_replace("@,@", "& #44;", $komentarz); // bez spacji między &, a #.


delimiter w funkcji fgetcsv, jest defaultowo przecinkiem, więc ten argument jest zbędny.
  1. fgetcsv($wczytaj, 1000, ",") -> fgetcsv($wczytaj, 1000)



#edit
Dodałem spację między &, a # ze względu na parser w komentarzu - automatycznie zamieniał na przecinek.

Odnośnie samego skryptu sprawdzającego proponuję także upewnić się, że dane w ogóle zostały podane! Zakładając, że znasz warunki pokażę fragment kodu.
  1. if(isset($_POST['podpis'], $_POST['komentarz'])) {
  2. $podpis = $_POST['podpis'];
  3. $komentarz = $_POST['komentarz'];
  4. [...]
  5. }
  6. else echo 'Komentarz nie został wysłany.';

Zabezpieczy to bezpośrednie wejście na stronę wyslij.php bez wysłania formularza (bez warunku, odwiedzenie owej strony zakończy się dodaniem pustego wpisu).
robert-s
Dzięki wielkie. Już uzupełniam skrypt.
Crozin
1. Kod wstawiaj w BBCode PHP: [ php ] ... [ / php ], nie cytaty.
2. Jeżeli jako drugi argument fgetcsv ustawiony na 1000, to wypadałoby albo upewnić się przy dodawaniu nowego wpisu, że jego łączna długość w pliku nie przekroczy tych 1000 znaków, albo ustawić ten argument za zero by funkcja zawsze odczytywała cały wiersz.
3. Nigdy nie używaj jakiś magicznych, nic nie znaczących stałych w kodzie (patrz: $tablica[0], $tablica[1], $tablica[2]). W pętli wyświetlającej dane, od razu przypisz sobie poszczególne elementy tablicy do normalnych zmiennych (list).

CSV to fatalny format do przechowywania komentarzy. Znacznie lepszym rozwiązaniem byłoby wykorzystanie np. XML-a, który nie będzie miał problemów, gdy ktoś wrzuci w treść komentarza przecinek (znak separatora) albo nową linię.
robert-s
Kod trochę pozmieniałem już. Odnośnie zabezpieczenia przed atakami XSS. Czy jest różnica między miejscem użycia funkcji htmlspecialchars.

Przy odczytywaniu z pliku CSV w celu wyświetlenia komentarzy na stronie:
  1. echo '<div id="tresc">' . htmlspecialchars($tkomenty[2], ENT_QUOTES, 'UTF-8') . '</div>';


Przy użyciu $_POST w drugim pliku (wyslij.php):
  1. $podpis = htmlspecialchars($_POST['komentarz'], ENT_QUOTES, 'UTF-8');


Testowałem oba i wynik dla usera jest ostatecznie taki sam, czyli np. jesli spróbuje wstawić pogrubienie to wyświetli się < b> treść < /b >. Z wszczepienia javascript też nici chyba. Troche inaczej zapisuje w pliku CSV. W pierwszym przypadku < b > w drugim & l t ; b & g t ;

Wolałbym używać opcji pierwszej, bo dla drugiej funkcja strlen daje wyższe wartosci. Jednak czy to jest bezpieczne? Może mi ktoś wszczepić kod PHP i wywołać jakieś niemiłe rzeczy?
Crozin
Powinieneś używać tylko i wyłącznie pierwszego wariantu. Znaki <>&"' są niebezpieczne dopiero w dokumencie HTML.
amii
Dodam jeszcze taką ciekawostkę kiedy używasz:
  1. echo "$podpis";
  2. echo "$komentarz";

masz niewielki narzut spowodowany tym, że parser odczytuje kod z cudzysłowów i szuka znaków specjalnych i zmiennych w środku. Lepiej w takim przypadku dać bez cudzysłowów.

Dla czystych zmiennych tekstowych lepsze są apostrofy. Cudzysłów jest dobry (wygodniejszy) kiedy w środku masz zmienne lub znaki specjalne i tekst.
  1. echo "Jakiś tam sobie tekst w zmiennej $zmienna a tu jeszcze znak specjalny \n";
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.