• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

php - form - data urodzenia - pomocy!

Object Storage Arubacloud
0 głosów
1,164 wizyt
pytanie zadane 27 lutego 2017 w PHP przez MałyAleWariat Bywalec (2,830 p.)

Dzień dobry.
Zaznaczam, że jestem zielony i uczę się z kursów szefa na yt :P
Mam problem, z formularzem rejestracyjnym, a tak wygląda część o którą mi chodzi :

Data urodzenia (rok-miesiąc-dzień):<br> 
<input type="date" name="year" value="rok" /> <input type="date" name="month" value="miesiąc" /> <input type="date" name="day" value="dzień" /><br> 
<?php
if (isset($_SESSION['e_data_urodzenia']))
{ 
  echo '<div class="error">'.$_SESSION['e_data_urodzenia'].'</div>'; 
  unset($_SESSION['e_data_urodzenia']); 
} 
?>

A tak kod do sprawdzenia poprawności:

// Poprawność daty urodzenia
$day = $_POST['day'];
$month = $_POST['month'];
$year = $_POST['year'];
$data_urodzenia = ($year."-".$month."-".$day);
$data_urodzenia = $_SESSION['data_urodzenia'];
             
$data_obecna = new DateTime();
$data_podana = new DateTime($_SESSION['data_urodzenia']);
             
if (($data_obecna - "co trzeba odjąć, żeby pasowało?") > $data_podana)
{
  $wszystko_OK=false;
  $_['e_data_urodzenia']="Portal dla użytkowników 18+!";
}
             
if(!isset($_POST['day']) && ($_POST['month']) && ($_POST['year']))
{
  $wszystko_OK=false;
  $_['e_data_urodzenia']="Proszę podać poprawną datę!";
}

I pytanie nr. 1 brzmi: Co powinienem odjąć od "$obecna data", żeby grało ?

Pytanie nr. 2: Czy da się zrobić tak, żeby "value=" w "form" miało postać yyyy-mm-dd, z możliwością zmiany tylko yyyy, mm, dd, a żeby "-" zostały zablokowane na stałe?

Pytanie nr. 3: Czy kod jest zupełnie do niczego ? angry I trzeba to zrobić inaczej?

komentarz 27 lutego 2017 przez xandros Nałogowiec (29,450 p.)

> Pytanie nr. 3: Czy kod jest zupełnie do niczego ? angry I trzeba to zrobić inaczej?

Nie tak zupełnie, ale trzeba go porządnie zrefaktoryzować.

Stwórz funkcje, methode, closure do tego, a nie czystą strukture. :P

Unikaj mieszania php z htmlem. Jeżeli nie musisz, to tego nie rób.

Jak piszesz w języku angielskim to pisz w nim, a nie mieszasz "day" z "data_podana"

Dana metoda/funkcja, nie powinna mieć więcej niż 30 lini kodu. :P

Powinna wykonywać jedna rzecz i robic to porządnie.

Nie może mieć więcej niż 3 nested blocks (zagnieżdzeń ifów,while,for etc.)

Zawsze przed komitem pomyśl, czy da się coś zrobić prościej.

3 odpowiedzi

+1 głos
odpowiedź 27 lutego 2017 przez krispello Obywatel (1,440 p.)

Proponuję skorzystać z:

<input type="date">

 

komentarz 27 lutego 2017 przez MałyAleWariat Bywalec (2,830 p.)
Panie majster, ale jak Pan widzisz, to mam tak ustawione.
komentarz 27 lutego 2017 przez krispello Obywatel (1,440 p.)
:I Moje niedopatrzenie. Wystarczy Ci jedna zmienna do przechowywania wartości daty.
+1 głos
odpowiedź 27 lutego 2017 przez Assasz Nałogowiec (30,460 p.)
Nie rozumiem, masz trzy inputy typu date dla roku, miesiąca i dnia oddzielnie? Nie powinien jeden taki input zwracać pełnej daty? Co do pytań:

1. Najłatwiej stworzyć obiekty DateTime, jeden z datą wymaganą minimalnie jako parametrem, drugi z datą podaną i odjąć je od siebie funkcją diff(). Potem wyniki porównujesz.

2. Możesz to zrobić za pomocą atrybutów min i max.

Co do reszty kodu to nadpisujesz stworzoną zmienną data_urodzenia zmienną sesyjną, a dalej, w drugim ifie sprawdzasz tylko pierwszą zmienną, czy istnieje; dwie pozostałe jedynie, czy zostały przesłane metodą post.
komentarz 27 lutego 2017 przez MałyAleWariat Bywalec (2,830 p.)
Mógłbyś rozwinąć pkt. 2 ?
komentarz 27 lutego 2017 przez MałyAleWariat Bywalec (2,830 p.)
Mam trzy inputy oznaczone jako "rok - miesiąc - dzień" i tak podpisane, żeby było jasne, gdzie co wpisać, i dlatego w pkt. 2 zadałem pytanie, czy da się to jakoś przekręcić, żeby było w jednym.
+1 głos
odpowiedź 27 lutego 2017 przez xandros Nałogowiec (29,450 p.)

By nie było, że daje gotowca:

/**
     * @return string
     */
    public function getAge()
    {
        if (empty($this->birthday)) {
            return 'Nie powiem';
        }
        $age = (new DateTime($this->birthday))->diff((new DateTime()), true)->y;
        if ($age < 8) {
            return 'Za młody by mieć konto';
        }
        if ($age > 120) {
            return 'Starszy niż świat';
        }
        $age .= ' ' . ($age == 1 ? 'rok' : ($age % 10 >= 2 && $age % 10 <= 4 && ($age % 100 < 10 || $age % 100 >= 20) ? 'lata' : 'lat'));

        return $age;
    }

Jest to "stara" metoda z pewnej klasy, która  pokazuje date urodzenia w latach :P

Przerób ją sobie pod własne wymagania.

A tak w ogóle:

> $data_urodzenia = $_SESSION['data_urodzenia'];

Co wy macie z tymi sesjami? Do wywalenia.

$day = $_POST['day'];
$month = $_POST['month'];
$year = $_POST['year'];

nie rozumiem ludzi, którzy przepisują tak wartości, tylko po to, by je odczytać =/

Jeśli boisz się, że przypadkowo nadpiszesz zmienną globalną, to można zrobić tak:

$myRequestParams = $_POST;

//odwolanie do zmiennej:
echo $myRequestParams['day']; //pokazuje dzien

a jeszcze taki trik pokaże, dla ludzi używających php7.1:

 $_POST['day'] = 'a';
 $_POST['month'] = 'b';
 $_POST['year'] = 'c';

list('day' => $day, 'month' => $month, 'year' => $year) = $_POST;

var_dump($day, $month, $year);
/** 
 * pokaże: 
 * string(1) "a"
 * string(1) "b"
 * string(1) "c"
**/

 

komentarz 27 lutego 2017 przez MałyAleWariat Bywalec (2,830 p.)

Jak pisałem dopiero się uczę :) Napisałem, bo utknąłem w punkcie. Dumam, dumam i wydumać nie mogę.

> $data_urodzenia = $_SESSION['data_urodzenia'];

To zrobiłem, żeby potem odczytywać datę na innej stronie, ale masz rację, przecież to potem można wyciągnąć bezpośrednio z bazy danych.
 

Ale interesuje mnie, czy i jeżeli tak, to w jaki sposób, można wewnątrz inputa zrobić taki zapis:

yyyy-mm-dd

Tak, żeby na sztywno, (na stałe) były ustawione "-", a żeby użytkownik mógł podmienić tylko wartości yyyy, mm i dd. 

komentarz 27 lutego 2017 przez xandros Nałogowiec (29,450 p.)
tak: 3 rozne inputy odpowiednio ostylowane

lub jakis JS, ktory bedzie co wpisanie literki sprawdzał i przeformatowywał
komentarz 27 lutego 2017 przez MałyAleWariat Bywalec (2,830 p.)

JS się jeszcze nie uczyłem, więc czarna magia cheeky
Czyli ten zapis jest ok?

$data_urodzenia = ($year."-".$month."-".$day);

komentarz 27 lutego 2017 przez xandros Nałogowiec (29,450 p.)
składnią, pięknością, czy ogólnie?

ja bym napisał:

$birthday = "{$year}-{$month}-{$day}";

ale i tak datetime sam powinien sobie wyparsowac date.
komentarz 27 lutego 2017 przez Boshi VIP (100,240 p.)

@xandros

($age == 1 ? 'rok' : ($age % 10 >= 2 && $age % 10 <= 4 && ($age % 100 < 10 || $age % 100 >= 20) ? 'lata' : 'lat'));

nie dało się gorzej :P?  toż to jest w ogóle nieczytelne laugh

komentarz 27 lutego 2017 przez MałyAleWariat Bywalec (2,830 p.)
Dlatego dalej pytam :P
komentarz 27 lutego 2017 przez xandros Nałogowiec (29,450 p.)

> nie dało się gorzej :P?  toż to jest w ogóle nieczytelne 

Nie przesadzaj, wiesz ile pamięci dzieki temu zyskał :D

W sumie to nie mój kod (ja stworzylem osobną klase a Scrummaster i zrobił z tego to cos :D), ale i tak umiem to rozczytać:

Jeśli age jest równe 1, to zwórć "rok',

inaczej jeżeli modulo 10 z age  jest większe lub = 2 i modulo 10 z age jest mniejsze lub równe 4 i jezeli jedno z tych jest prawdą:

  • modulo 100 z age jest mniejsze od dziesieciu
  • modulo 100 z age jest większe lub równe 2

to zwórj 'lata' inaczej zwróć 'lat' :P

Prosty warunek dla prostego języka :D

 

Ten kwałek kodu mu raczej nie był potrzebny :D... bardziej chodziło mi o 

$age = (new DateTime($this->birthday))->diff((new DateTime()), true)->y;
        if ($age < 8) {
            return 'Za młody by mieć konto';
        }
        if ($age > 120) {
            return 'Starszy niż świat';
        }

 

komentarz 27 lutego 2017 przez Boshi VIP (100,240 p.)
Ty to umiesz rozczytać, ale daj nowemu :D

Nie no przesadzam może trochę, ale zagnieżdżanie tylu warunków i nawiasów w postaci operatora trójkowego to trochę przegięcie ;)
komentarz 28 lutego 2017 przez MałyAleWariat Bywalec (2,830 p.)

Dziękuję za podpowiedzi, temat można zamknąć laugh

Rozwiązałem to tak:

// Poprawność daty urodzenia
if(isset($_POST['submit']))
{
  $dzien = $_POST['dzien'];
  $miesiac = $_POST['miesiac'];
  $rok = $_POST['rok'];
  $data_urodzenia = ($rok."-".$miesiac."-".$dzien);
				
  $urodziny = mktime(0,0,0,$miesiac,$dzien,$rok);
  $roznica = time() - $urodziny;
				
  $wiek = floor($roznica / 31556926);
				
  echo $roznica; end();
  echo $wiek;
				
  if ($wiek <= 18)
  {
    $wszystko_OK=false;
   $_SESSION['e_wiek'] = "Nie masz ukończonych 18 lat!";
  }
}

A tabelę zrobiłem trochę inaczej:

Data urodzenia: <br>
  <select class="tabela_dat" name="rok">
    <option>Rok</option>
    <option  label="1900" value="1900">1900</option>
    <option  label="1901" value="1901">1901</option>
    <option  label="1902" value="1902">1902</option>
    <option  label="1903" value="1903">1903</option>
    <option  label="1904" value="1904">1904</option>
    <option  label="1905" value="1905">1905</option>

itd...

Ale bardzo dziękuję za podpowiedzi wink

komentarz 28 lutego 2017 przez MałyAleWariat Bywalec (2,830 p.)

Bez tego :

 echo $roznica; end();
 echo $wiek;

 ;d

Podobne pytania

0 głosów
0 odpowiedzi 140 wizyt
pytanie zadane 7 grudnia 2016 w Python przez Kuchtek Nowicjusz (140 p.)
–1 głos
1 odpowiedź 376 wizyt
pytanie zadane 1 lutego 2017 w PHP przez ThePatrykOOO Dyskutant (8,400 p.)
+1 głos
3 odpowiedzi 464 wizyt

92,568 zapytań

141,420 odpowiedzi

319,624 komentarzy

61,956 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...