[php]Geboortedatum tijdens registratie

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Jboy1991
  • Registratie: September 2012
  • Laatst online: 20:24
Goedendag,

Ik zit met een situatie waarbij ik mogelijk een beetje hulp bij nodig heb. Ik laat tijdens het registreren de user zijn geboortedatum invullen. Dit heb ik nodig omdat de leden alleen boven een bepaalde leeftijd mogen zijn (12 jaar of ouder).

Nu ben ik al een dag bezig met googlen na een goed werkende oplossing maar krijg zoveel verschillende "oplossingen" te zien dat ikzelf niet weet wat nu goed is.

Zo kwam ik oplosssingen tegen die via preg_match werken maar ook via strtotime. Maar las daarbij ook weer reacties al dat het oldschool is zo te programmeren en dat het nu via datetime/datedif gaat.

Maar daar loop ik dus op vast. Hoe kan ik via een goede manier controleren of de datum die opgegeven is een echte datum is?

Ik deed het op deze manier:
code:
1
2
3
4
    if(DateTime::createFromFormat("d-m-Y", $bday)
{

}


Echter krijg ik hierbij dus al een error als je random iets invult.

Caught exception: DateTime::__construct(): Failed to parse time string (05-33-1991) at position 0 (0): Unexpected character

Iemand die mij hierbij even kan ""bijleren"" ?

Alvast bedankt

Acties:
  • 0 Henk 'm!

  • Ramon
  • Registratie: Juli 2000
  • Laatst online: 20:43
Je wil toch ook juist een error als iemand een niet bestaande datum invult, dus dat is goed lijkt me. Het enige wat jij moet doen is die error netjes afvangen en teruggeven aan de gebruiker op een gebruikersvriendelijke manier.

Check mijn V&A ads: https://tweakers.net/aanbod/user/9258/


Acties:
  • 0 Henk 'm!

  • Jboy1991
  • Registratie: September 2012
  • Laatst online: 20:24
Ramon schreef op vrijdag 2 februari 2018 @ 19:31:
Je wil toch ook juist een error als iemand een niet bestaande datum invult, dus dat is goed lijkt me. Het enige wat jij moet doen is die error netjes afvangen en teruggeven aan de gebruiker op een gebruikersvriendelijke manier.
Ja dat klop, Denk dat ik een try catch moet gebruiken ipv een if :o. Had verwacht dat een false als return kreeg als het mis ging

och dit is wel erg slecht. Oplossing is inderdaad een try catch.,

Maar is strtitime etc helemaal eruit?

[ Voor 10% gewijzigd door Jboy1991 op 02-02-2018 19:37 ]


Acties:
  • 0 Henk 'm!

  • Razr
  • Registratie: September 2005
  • Niet online
Eerste antwoord nagekeken op SO (link)? Dan krijg ik gewoon netjes false terug met de input die jij geeft in de OP. Misschien dat er toch iets fout is met je input oid?

Acties:
  • 0 Henk 'm!

  • ikvanwinsum
  • Registratie: Februari 2011
  • Laatst online: 16-09 20:38

ikvanwinsum

/dev/null

Je bent wel een haakje vergeten...

Dit werkt bij mij iig wel:
PHP:
1
2
3
4
5
6
7
<?php
        //Enter your code here, enjoy!
 $bday = "01-01-2010";
if($d = DateTime::createFromFormat("d-m-Y", $bday))
{
var_dump ($d);
}


Resultaat:
code:
1
2
3
4
5
6
7
8
object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2010-01-01 10:48:48.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(10) "US/Pacific"
}

U zegt: ‘Alles is toegestaan.’ Zeker, maar niet alles is goed. Alles is toegestaan, maar niet alles is opbouwend.


Acties:
  • 0 Henk 'm!

  • Jboy1991
  • Registratie: September 2012
  • Laatst online: 20:24
ikvanwinsum schreef op vrijdag 2 februari 2018 @ 19:49:
Je bent wel een haakje vergeten...

Dit werkt bij mij iig wel:
PHP:
1
2
3
4
5
6
7
<?php
        //Enter your code here, enjoy!
 $bday = "01-01-2010";
if($d = DateTime::createFromFormat("d-m-Y", $bday))
{
var_dump ($d);
}


Resultaat:
code:
1
2
3
4
5
6
7
8
object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2010-01-01 10:48:48.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(10) "US/Pacific"
}
Het ging er juist om dat ik die error kreeg doordat ik bewust een foutieve datum invoerde om mn foutafhandeling te checken.

Maar dmv een trycatch is het nu netjes opgelost (had er eerder aan moeten denken).

Maar vond het apart dat tijdens mijn zoektocht naar de oplossing zoveel verschillende manieren zijn om het te checken. Je hebt zelfs nog checkdate() (http://php.net/manual/en/function.checkdate.php)

Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Lees ook even de documentatie van de DateTime superclass. Om een en ander verder te versimpelen kun je bijvoorbeeld ook gebruik gaan maken van Carbon.
Razr schreef op vrijdag 2 februari 2018 @ 19:46:
Eerste antwoord nagekeken op SO (link)? Dan krijg ik gewoon netjes false terug met de input die jij geeft in de OP. Misschien dat er toch iets fout is met je input oid?
Nooit blindelings uit gaan van antwoorden op Stack Overflow. Geregeld komen daar ook vreemde antwoorden voorbij. Copy-pasten van Stack Overflow is voor mij in elk geval uit den boze.
ikvanwinsum schreef op vrijdag 2 februari 2018 @ 19:49:
Je bent wel een haakje vergeten...

Dit werkt bij mij iig wel:
PHP:
1
2
3
4
5
6
7
<?php
        //Enter your code here, enjoy!
 $bday = "01-01-2010";
if($d = DateTime::createFromFormat("d-m-Y", $bday))
{
var_dump ($d);
}
Je weet dat dit altijd evalueert naar true,omdat jouw code een variabele zet in het if-statement? :)

[ Voor 75% gewijzigd door CH4OS op 02-02-2018 20:02 ]


Acties:
  • +1 Henk 'm!

  • Razr
  • Registratie: September 2005
  • Niet online
CH4OS schreef op vrijdag 2 februari 2018 @ 19:58:
Lees ook even de documentatie van de DateTime superclass. Om een en ander verder te versimpelen kun je bijvoorbeeld ook gebruik gaan maken van Carbon.
[...]
Nooit blindelings uit gaan van antwoorden op Stack Overflow. Geregeld komen daar ook vreemde antwoorden voorbij. Copy-pasten van Stack Overflow is voor mij in elk geval uit den boze.
Daarom zeg ik ook nagekeken en niet gekopieerd. Waarom zou je niet kijken wat zo'n antwoord qua logica heeft/doet en dit vergelijken met je eigen code en daar eventueel lering uit trekken?

Acties:
  • +1 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Razr schreef op vrijdag 2 februari 2018 @ 20:01:
Daarom zeg ik ook nagekeken en niet gekopieerd. Waarom zou je niet kijken wat zo'n antwoord qua logica heeft/doet en dit vergelijken met je eigen code en daar eventueel lering uit trekken?
Ik bedoel inderdaad om naar de logica te kijken en met name de uitleg waarom de eigen code niet goed werkt. ;)

Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
Jboy1991 schreef op vrijdag 2 februari 2018 @ 19:28:
Zo kwam ik oplosssingen tegen die via preg_match werken maar ook via strtotime. Maar las daarbij ook weer reacties al dat het oldschool is zo te programmeren en dat het nu via datetime/datedif gaat.
Klopt, en nog ben je in dit topic half goed bezig.

Kijk maar eens naar <input type="date" required=""/>
En die gebruikt in de $_POST/$_GET 'Y-m-d' wat de ISO 8601 internationale standaard is
En waarom men die standaarden gebruikt kan ik in een hele lange post haarfijn uitleggen... (maar dat doen DuckDuckGo en Google ook al)

Maak je niet druk, dat doet de compressor maar


Acties:
  • 0 Henk 'm!

  • ikvanwinsum
  • Registratie: Februari 2011
  • Laatst online: 16-09 20:38

ikvanwinsum

/dev/null

CH4OS schreef op vrijdag 2 februari 2018 @ 19:58:
[...]
Je weet dat dit altijd evalueert naar true,omdat jouw code een variabele zet in het if-statement? :)
Nee?
Pak ik het volgende stukje code:
PHP:
1
2
3
4
5
6
$bday="hierwatonzin";
if($d = DateTime::createFromFormat("d-m-Y", $bday)) {
    var_dump ($d);
} else {
    echo 'oh nee toch niet';
}

Dan evalueert bij mij de if-statement toch echt naar false...

U zegt: ‘Alles is toegestaan.’ Zeker, maar niet alles is goed. Alles is toegestaan, maar niet alles is opbouwend.


Acties:
  • +1 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
DJMaze schreef op vrijdag 2 februari 2018 @ 21:15:
[...]

Klopt, en nog ben je in dit hele topic fout bezig.

Kijk maar eens naar <input type="date" required=""/>
En die gebruikt in de $_POST/$_GET 'Y-m-d' wat de ISO 8601 internationale standaard is
En waarom men die standaarden gebruikt kan ik in een hele lange post haarfijn uitleggen... (maar dat doen DuckDuckGo en Google ook al)
Ik vind iemand betichten van fout bezig te zijn en dan zelf met een lapmiddel van likmevestje aankomen anders ook geen schoonheidprijs verdienen hoor ;)

En date input lost helemaal niets op. Het is een leuk exta'tje aan de UI kant maar dat zal niemand er van weerhouden om appelflap of ' or 1 = 1 te posten o.i.d. Never trust user input. Je zult dus nog steeds een functie moeten gebruiken om de input naar iets wat een datum (datetime, timestamp, whatever) voorstelt om te zetten. En bij voorkeur gebruik je daar geen exceptions voor; die zijn namelijk voor, zoals de naam al aangeeft, uitzonderlijke gevallen. Voor userinput die vanalles-en-nogwat kan zijn is 't niet bepaald uitzonderlijk dat de input niet is wat je verwacht of zoals je het graag gezien zou hebben. Er zijn zat functies die een input nemen en dat omzetten wanneer mogelijk. Als het niet anders kan dan gebruik je de exceptions maar als het goed is is er altijd wel een functie beschikbaar waar dat niet het geval is.

De eerder genoemde regex is hooguit handig om te controleren of de input in 't verwachtte formaat is; maar zo'n controle is vrij overbodig als je de juiste functies gebruikt om de input (string) om te zetten naar 't gewenste formaat (datetime, timestamp/int, whatever) want die geven dan toch al aan of de input bruikbaar was of niet.

Overigens is heel dat Y-M-D / ISO verhaal hier helemaal niet relevant; als je een Nederlandse site hebt (of (gebruikers)voorkeur in het geval van een meertalige site bijvoorbeeld) is het vrij normaal om je gebruikers een D-M-Y voor te schotelen en bij een Amerikaanse site M-D-Y. Dat je het intern naar Y-M-D converteert, of Y-M-D verwacht als input, is vers 2. En zelfs dat is maar zelden nodig; dat deed je vroeger als je een querystring aan 't bouwen was maar als je gewoon netjes parameterized queries gebruikt is 't daar ook niet meer relevant; dan geef je gewoon je DateTime mee als argument (of je timestamp...) en laat je 't je DB en de "driver" lekker uitzoeken.

[ Voor 11% gewijzigd door RobIII op 03-02-2018 11:03 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • +4 Henk 'm!

  • Illusion
  • Registratie: November 2000
  • Laatst online: 18:51

Illusion

(the art of)

Als gebruiker vind ik het uit privacy-oogpunt nogal wat dat je mijn geboortedatum wil hebben...
Waarom krijg ik niet gewoon een vinkje: “ja op dit moment ben ik ouder dan 12” ?
Het is niet alsof een kind van 10 niet in staat is om over zijn eigen geboortedatum te liegen.

Hoe beveilig je die persoonsgegevens? Als je al niet eens in staat bent om ze te evalueren..

[ Voor 14% gewijzigd door Illusion op 03-02-2018 11:08 ]

Soms ben ik er wel, en soms ook weer niet.


Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
RobIII schreef op zaterdag 3 februari 2018 @ 10:54:
Ik vind iemand betichten van fout bezig te zijn en dan zelf met een lapmiddel van likmevestje aankomen anders ook geen schoonheidprijs verdienen hoor ;)
Hahaha je hebt gelijk, was iets te grof gezegd. Heb het aangepast.
RobIII schreef op zaterdag 3 februari 2018 @ 10:54:
Overigens is heel dat Y-M-D / ISO verhaal hier helemaal niet relevant; als je een Nederlandse site hebt (of (gebruikers)voorkeur in het geval van een meertalige site bijvoorbeeld) is het vrij normaal om je gebruikers een D-M-Y voor te schotelen en bij een Amerikaanse site M-D-Y.
Ja en nee, vanwege het internationale karakter van het web weet je niet hoe iemand D-M-Y of M-D-Y of M/D/Y of.... invult.
Want 10-08-2000 kan natuurlijk 10 Augustus of 8 Oktober zijn :)

Kies dan inderdaad gewoon voor een vinkje "Ja, ik ben ouder dan 12". En als de datum wel belangrijk is. gebruik drie input velden <dag> <maand> <jaar>.

Zelfde probleem (en de punt/komma in decimale getallen) is leuk in bijvoorbeeld Excel als je een CSV opent :)

De simpele Y-m-d regex is trouwens
PHP:
1
2
3
if (preg_match('#^([0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01]))#', $value, $match)) {
    return new \DateTime($match[1]);
}

Deze houdt geen rekening met 30 februari en 31 april :+

[ Voor 12% gewijzigd door DJMaze op 03-02-2018 11:59 ]

Maak je niet druk, dat doet de compressor maar


Acties:
  • 0 Henk 'm!

  • Jboy1991
  • Registratie: September 2012
  • Laatst online: 20:24
Illusion schreef op zaterdag 3 februari 2018 @ 11:06:
Als gebruiker vind ik het uit privacy-oogpunt nogal wat dat je mijn geboortedatum wil hebben...
Waarom krijg ik niet gewoon een vinkje: “ja op dit moment ben ik ouder dan 12” ?
Het is niet alsof een kind van 10 niet in staat is om over zijn eigen geboortedatum te liegen.

Hoe beveilig je die persoonsgegevens? Als je al niet eens in staat bent om ze te evalueren..
Als een gebruiker dat persoonlijk bezwarend vindt, heeft de gebruiker altijd nog de keuze zich niet te registreren.

Dat ik om leeftijd vraag heeft er vooral mee te maken voor bepaalde subforas die leeftijd afhankelijk zijn en om statistieken bij te houden in welk leeftijd categorie de meesten leden vallen.

de persoonsgegevens worden bewaard in een sql tabel op de server. En om sqlinjecties te voorkomen gebruik ik PDO

Maar zo kan je over alles beginnen natuurlijk, een email en IP zijn ook al prive-gegevens.

Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

ikvanwinsum schreef op zaterdag 3 februari 2018 @ 10:42:
[...]


Nee?
Pak ik het volgende stukje code:
PHP:
1
2
3
4
5
6
$bday="hierwatonzin";
if($d = DateTime::createFromFormat("d-m-Y", $bday)) {
    var_dump ($d);
} else {
    echo 'oh nee toch niet';
}

Dan evalueert bij mij de if-statement toch echt naar false...
Omdat datetime false returned als het fout gaat. Gebruik een functie die geen boolean returned als het fout gaat (die heeft php ook genoeg) en het werkt niet meer, dan heeft $d altijd een waarde. Netjes is het iig niet, imo. En dat is een reden om Stack Overflow nooit blindelings te volgen.

[ Voor 10% gewijzigd door CH4OS op 03-02-2018 12:17 ]


Acties:
  • +1 Henk 'm!

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Jboy1991 schreef op zaterdag 3 februari 2018 @ 12:04:
Als een gebruiker dat persoonlijk bezwarend vindt, heeft de gebruiker altijd nog de keuze zich niet te registreren.
Als particulier kom je misschien om de https://nl.wikipedia.org/...ening_gegevensbescherming heen. Echter zie daar het principe:
gegevensbeperking: enkel de noodzakelijke gegevens die voor het beoogde doel noodzakelijk zijn, mogen worden verzameld
Als het doel is alleen een bepaalde leeftijd toe te laten, heb ik moeten leren dat een geboortedatum voor dit doel niet noodzakelijk is, omdat het met een "ouder dan X: ja/nee" ook gaat.

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
Jboy1991 schreef op zaterdag 3 februari 2018 @ 12:04:
Als een gebruiker dat persoonlijk bezwarend vindt, heeft de gebruiker altijd nog de keuze zich niet te registreren.
Of hij vult zoals gewoonlijk een valse geboortedatum in :)
Tja, hoe kijken jongeren anders porno :o

Maak je niet druk, dat doet de compressor maar


Acties:
  • 0 Henk 'm!

  • Jboy1991
  • Registratie: September 2012
  • Laatst online: 20:24
DJMaze schreef op zaterdag 3 februari 2018 @ 20:20:
[...]

Of hij vult zoals gewoonlijk een valse geboortedatum in :)
Tja, hoe kijken jongeren anders porno :o
haha gelukkig betreft het geen porno. Maar goed punt eigenlijk.

Is het trouwens volgens de wet alsnog bezwarend als je het als optie doet (niet verplicht)?

Acties:
  • 0 Henk 'm!

  • ikvanwinsum
  • Registratie: Februari 2011
  • Laatst online: 16-09 20:38

ikvanwinsum

/dev/null

CH4OS schreef op zaterdag 3 februari 2018 @ 12:15:
[...]
Omdat datetime false returned als het fout gaat. Gebruik een functie die geen boolean returned als het fout gaat (die heeft php ook genoeg) en het werkt niet meer, dan heeft $d altijd een waarde. Netjes is het iig niet, imo. En dat is een reden om Stack Overflow nooit blindelings te volgen.
Waarom zou het niet netjes zijn? Voor het if-statement wordt $d gecast naar een boolean. Van DateTime::createFromFormat weten we dat het false returned als het fout gaat, en anders een DateTime object. Staat gewoon in de reference.

Volgens php.net evalueert het volgende naar false:
When converting to boolean, the following values are considered FALSE:

the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
De rest evalueert altijd naar true. Met andere woorden: je weet gewoon wat er gaat gebeuren. Mocht je een functie hebben die zowel 0 als false returned, kan je natuurlijk altijd nog het volgende doen:
PHP:
1
echo (($var = myFunction()) === false) ? 'returned false' : 'returned iets anders';

U zegt: ‘Alles is toegestaan.’ Zeker, maar niet alles is goed. Alles is toegestaan, maar niet alles is opbouwend.


Acties:
  • 0 Henk 'm!

  • pottink
  • Registratie: Augustus 2010
  • Laatst online: 12-09 13:57
Ik zou zeker met de DateTime library gaan werken. Indien valid heb je een DateTime object met heel veel handige helpers en functies die je kan gaan gebruiken om wat met je datum te gaan doen.
Maak misschien ook zeker gebruik van een placeholder in je input veld om je gewenste formaat aan te duiden.

PHP:
1
2
3
4
5
6
7
8
9
<?php

use \DateTime;

$date = '21/01/1950';

if (false === DateTime::createFromFormat('d/m/Y', $date)) {
  // ongeldig
}

Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Infinitive schreef op zaterdag 3 februari 2018 @ 18:12:
[...]
Als het doel is alleen een bepaalde leeftijd toe te laten, heb ik moeten leren dat een geboortedatum voor dit doel niet noodzakelijk is, omdat het met een "ouder dan X: ja/nee" ook gaat.
Pro-tip: hoe je data verzamelt hoeft niet hetzelfde te zijn als je methode van data-opslag. Om maar een extreem voorbeeld te noemen: je kunt een complete date-picker gebruiken om de gebruiker zijn geboortedatum te vragen, en alsnog alleen "ouder dan 12" op te slaan.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1