[PHP] Controleren of variabele een integer is

Pagina: 1
Acties:
  • 269 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Ik haal uit mijn querystring een variabele waarvan ik zeker moet weten dat dit een integer is. Dat probeerde ik eerst met is_int($_GET['q']). Toen bleek dat geen enkele waarde van q er voor zorgde dat is_int true retourneerde, ben ik op GoT gaan zoeken.

Ik leerde dat alles wat PHP uit de querystring haalt als text/string behaldelt wordt. Met andere woorden - je moet eerst q omzetten naar een integer: settype($_GET['q'], 'integer') (of 'int' vanaf PHP 4.2). Nu is het nadeel dat bv. 54sads omgezet wordt naar 54. Met andere woorden - ik heb nog steeds geen antwoord op mijn vraag of q een integer waarde heeft of niet.

In een oude draad merkte iemand op, dat als je zeker wil weten of q een integer is, je deze met 1 moet vermenigvuldigen: is_int(1 * $_GET['q']), maar ook dit werkt niet.

Nu is mijn vraag - hoe kan ik nu simpel nagaan of de waarde van q slechts uit getallen (dus 0 t/m 9) bestaat??

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • LinuX-TUX
  • Registratie: December 2003
  • Laatst online: 17-09 13:27
is_int?

[ Voor 6% gewijzigd door LinuX-TUX op 20-08-2004 17:05 . Reden: d0m ]


Acties:
  • 0 Henk 'm!

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 07-11-2023

kvdveer

Z.O.Z.

kort:
is_numeric($variabele)
of: [url=http:://www.php.net/preg_match]preg_match[/]('/(-?[1-9][0-9]*)|0/',$variabele);

lang:
is_int controleert of het datatype een int is. Als je een string met getallen geeft zegt is_int dus "false", want het datatype van een string is string. je kunt met een regular expression controleren of een string een integer bevat, of met is_numeric controleren of het een getalsmatige waarde is. Is_numeric retourneert ook true voor getallen met komma's.

[ Voor 82% gewijzigd door kvdveer op 20-08-2004 17:08 ]

Localhost, sweet localhost


Acties:
  • 0 Henk 'm!

  • Xeo
  • Registratie: November 2002
  • Laatst online: 21:30

Xeo

Blaat... al gefixt

[ Voor 92% gewijzigd door Xeo op 20-08-2004 17:06 ]


Acties:
  • 0 Henk 'm!

  • Minos111
  • Registratie: Augustus 2002
  • Laatst online: 05-03-2012
Waarom haal je niet gewoon intval() over q heen? Dan kun je vervolgens checken of q 0 is, en zo ja, dan is het geen integer:

PHP:
1
2
3
4
5
6
7
$q = intval($_GET['q']);

if($q) {
  print "Integer!";
} else {
  print "No integer!";
}

[ Voor 9% gewijzigd door Minos111 op 20-08-2004 17:06 ]


Acties:
  • 0 Henk 'm!

  • simon
  • Registratie: Maart 2002
  • Laatst online: 00:18
met intval($var) krijg je alleen de integere waardes eruit..
Minos111 schreef op 20 augustus 2004 @ 17:06:
Waarom haal je niet gewoon intval() over q heen? Dan kun je vervolgens checken of q 0 is, en zo ja, dan iss het geen integer:

PHP:
1
2
3
4
5
6
7
$q = intval($_GET['q']);

if($q) {
  print "Integer!";
} else {
  print "No integer!";
}
Imho een ranzige constructie...

[ Voor 77% gewijzigd door simon op 20-08-2004 17:06 ]

|>


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Reveller schreef op 20 augustus 2004 @ 17:01:
Ik haal uit mijn querystring een variabele waarvan ik zeker moet weten dat dit een integer is. Dat probeerde ik eerst met is_int($_GET['q']). Toen bleek dat geen enkele waarde van q er voor zorgde dat is_int true retourneerde, ben ik op GoT gaan zoeken.

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

http://nl.php.net/manual/en/function.is-numeric.php ?

preg_match ('/^\d+$/',$blaah);

Lees verder ook de usercomments bij de link.

.edit: ok dit gaat veel verder dan spuit 11..... :+

[ Voor 21% gewijzigd door RedRose op 20-08-2004 17:09 ]

Sundown Circus


Acties:
  • 0 Henk 'm!

  • dingstje
  • Registratie: Augustus 2002
  • Laatst online: 02-01-2024
De is_numeric() oplossing is de beste. Daarvoor is het gemaakt. Regular Expressions zijn nogal zwaar, en zeker voor hetgeen je het zou gebruiken. Als het uiteindelijk toch een int moet worden:
PHP:
1
2
3
if (is_numeric ( $_GET['q'] ) ) {
    $_GET['q'] = (int)$_GET['q'];
}

[ Voor 9% gewijzigd door dingstje op 20-08-2004 17:11 ]

If you can't beat them, try harder


Acties:
  • 0 Henk 'm!

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 07-11-2023

kvdveer

Z.O.Z.

dingstje schreef op 20 augustus 2004 @ 17:10:
De is_numeric() oplossing is de beste. Daarvoor is het gemaakt. Regular Expressions zijn nogal zwaar, en zeker voor hetgeen je het zou gebruiken. Als het uiteindelijk toch een int moet worden:
PHP:
1
2
3
if (is_numeric ( $_GET['q'] ) ) {
    $_GET['q'] = (int)$_GET['q'];
}
Terugschrijven naar de $_GET array vind ik nou ook niet echt charmant of zo...

Localhost, sweet localhost


Acties:
  • 0 Henk 'm!

Verwijderd

kvdveer schreef op 20 augustus 2004 @ 17:11:
[...]


Terugschrijven naar de $_GET array vind ik nou ook niet echt charmant of zo...
Waarom, daar heb ik persoonlijk geen problemen mee...het is tenslotte gewoon een array zoals elke andere.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Simon schreef op 20 augustus 2004 @ 17:06:
met intval($var) krijg je alleen de integere waardes eruit..

Imho een ranzige constructie...
En waarom ranzig? Denk je nou echt dat is_integer echt wat anders doet dan checken of de intval van een var gelijk is aan de waarde van de var zelf? :?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 07-11-2023

kvdveer

Z.O.Z.

Verwijderd schreef op 20 augustus 2004 @ 17:30:
[...]

Waarom, daar heb ik persoonlijk geen problemen mee...het is tenslotte gewoon een array zoals elke andere.
Dat is nou juist het probleem: het is niet een array zoals alle anderen. Het is een superglobale array. Dat houdt in dat wijzigingen die je in een veilige scope maakt (binnen een functie bijvoorbeeld) zaken in je volledige applicatie kunnen beinvloeden. Bij een applicatie die uit max 10 kb includes bestaat kun je dat nog wel overzien, maar zodra je enkele honderden kb's aan code hebt staan (echte code, geen grote strings met HTML) dan kun je daarover geen overzicht houden.
In zo'n situatie wil je dus je globalen in tact laten... Waarom ze bij ZEND niet besloten hebben om de superglobale read-only te maken snap ik ook niet...

Localhost, sweet localhost


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Minos111 schreef op 20 augustus 2004 @ 17:06:
Waarom haal je niet gewoon intval() over q heen? Dan kun je vervolgens checken of q 0 is, en zo ja, dan is het geen integer:
en toen was de waarde van q '0', en volgens jou is dat geen integer :P

Acties:
  • 0 Henk 'm!

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 07-11-2023

kvdveer

Z.O.Z.

NMe84 schreef op 20 augustus 2004 @ 17:37:
[...]

En waarom ranzig? Denk je nou echt dat is_integer echt wat anders doet dan checken of de intval van een var gelijk is aan de waarde van de var zelf? :?
Pardon? Waar haal je deze wijsheid vandaan? Heb je toevallig recent de source ervan gelezen?
is_integer doet echt wel iets intelligenters dan de int naar een string converteren en vergelijken met het origineel...
Hold on, ik zoek het even voor je op.

php/ext/type.c
opm: is_int en is_integer zijn aliassen voor is_long
Z_TYPE_PP(arg) is een c-macro die de type-vlag uit de variabele-struct vist...
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
static void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type)
{
    pval **arg;

    if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only one argument expected");
        RETURN_FALSE;
    }

    if (Z_TYPE_PP(arg) == type) {
        if (type == IS_OBJECT) {
            zend_class_entry *ce;
            ce = Z_OBJCE_PP(arg);
            if (!strcmp(ce->name, INCOMPLETE_CLASS)) {
                RETURN_FALSE;
            }
        }
        if (type == IS_RESOURCE) {
            char *type_name;
            type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);
            if (!type_name) {
                RETURN_FALSE;
            }
        }
        RETURN_TRUE;
    } else {
        RETURN_FALSE;
    }
}

[SNIP]


PHP_FUNCTION(is_long) { 
php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_LONG); 
}

[ Voor 52% gewijzigd door kvdveer op 20-08-2004 18:01 ]

Localhost, sweet localhost


Acties:
  • 0 Henk 'm!

  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

* Rataplan does not detect the problem :?

is_numeric is niet te gebruiken, want die detecteert niet alleen ints maar ook floats. Is_int is_niet_te_gebruiken, want die controleert niet de waarde maar het type, en $_GET bevat een string, schreef je zelf al. Als regular expressions te zwaar zijn (ze doen *wel* exact wat je wilt, en niet wat PHP ervan vindt) stel je je vraag: blijft de waarde van $_GET['yada'] hetzelfde als ik PHP er op z'n eigen tolerante manier een int van laat maken?

PHP:
1
if((intval($_GET['yada']) == $_GET['yada'])
Leading zeroes, plussen en minnen toegestaan. Klaar. Niet?
edit:

Hm. Bovenstaande vindt een lege string geldige invoer wegens gelijk aan 0 |:(
PHP:
1
if(((string)abs(intval($_GET['yada']))) === $_GET['yada'])
Hier is geen overbodige info toegestaan, lege string ook niet. Verwijder "abs" voor goedkeuring van negatieve ints.

En als dat niet genoeg is zit je denk ik aan een regexp vast.

[ Voor 51% gewijzigd door Rataplan op 20-08-2004 19:29 . Reden: negatief, positief :z ]


Journalism is printing what someone else does not want printed; everything else is public relations.


Acties:
  • 0 Henk 'm!

  • raps
  • Registratie: April 2003
  • Laatst online: 06-09 19:51
edit:

Hier stond iets doms.

[ Voor 79% gewijzigd door raps op 20-08-2004 19:28 ]


Acties:
  • 0 Henk 'm!

Verwijderd

ik doe het zo:
PHP:
1
2
3
$var = "1";
if (is_numeric($var) && is_int((int)$var))
  echo "is int";

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Verwijderd schreef op 20 augustus 2004 @ 21:01:
ik doe het zo:
PHP:
1
2
3
$var = "1";
if (is_numeric($var) && is_int((int)$var))
  echo "is int";
ok, en dit dan:

PHP:
1
2
3
$var = "1.1";
if (is_numeric($var) && is_int((int)$var))
  echo "is int";


dus 1.1 is volgens jou ook een int ;)

wat jij hier fout doet is dat je het $var cast naar een int, en vervolgens kijk je of het datatype int is, wat dus altijd het geval is, mits $var maar numeric is.

[ Voor 26% gewijzigd door Erkens op 20-08-2004 21:06 ]


Acties:
  • 0 Henk 'm!

Verwijderd

hmmm....
nou je het zo zegt, idd. Toch ff verder zoeken.
Voor mij heef het verder geen grote invloed, ik stuur toch alleen integers mee.

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Verwijderd schreef op 20 augustus 2004 @ 21:12:
hmmm....
nou je het zo zegt, idd. Toch ff verder zoeken.
Voor mij heef het verder geen grote invloed, ik stuur toch alleen integers mee.
jij misschien wel, maar andere die gebruik maken van je applicatie wellicht niet, input checking dus ;)

Acties:
  • 0 Henk 'm!

Verwijderd

Je kunt ook nog ctype_digit gebruiken. Dat is lekker snel, en meestal wordt dat wel ondersteund.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

kvdveer schreef op 20 augustus 2004 @ 17:42:
Pardon? Waar haal je deze wijsheid vandaan? Heb je toevallig recent de source ervan gelezen?
is_integer doet echt wel iets intelligenters dan de int naar een string converteren en vergelijken met het origineel...
Hold on, ik zoek het even voor je op.

php/ext/type.c
Kijk, daar heb je misschien gelijk in...maareh, die functies zijn dus niet toe te passen op de GET array volgens mij, omdat alle waardes daarin voor de zekerheid strings zijn. :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • raps
  • Registratie: April 2003
  • Laatst online: 06-09 19:51
Verwijderd schreef op 20 augustus 2004 @ 21:01:
ik doe het zo:
PHP:
1
2
3
$var = "1";
if (is_numeric($var) && is_int((int)$var))
  echo "is int";
Is het dan niet zo dat:
PHP:
1
2
3
4
5
$var = "ik ben een string";

if (is_int( (int)$var) )
  echo 'true';
else echo 'false';

Ook 'true' weer geeft?


ennuh:
PHP:
1
2
3
4
$var = "1.1"; // of $var = "1";
if (is_numeric($var))
  echo 'true';
else echo 'false';

geeft volgens mij false weer.

(ongetest allemaal)

[ Voor 28% gewijzigd door raps op 21-08-2004 00:53 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Volgens mij kan het alleen met een primitieve functie van PHP (d.w.z. een functie die niet uit te drukken is in PHP), aangezien PHP redelijk ongetypeerd is. :/

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

raps schreef op 21 augustus 2004 @ 00:51:
[...]

Is het dan niet zo dat:
<knip>
kijk eens naar mijn post :X

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op 21 augustus 2004 @ 12:38:
Volgens mij kan het alleen met een primitieve functie van PHP (d.w.z. een functie die niet uit te drukken is in PHP), aangezien PHP redelijk ongetypeerd is. :/
Wat wil je eigenlijk zeggen? Dat is me niet helemaal duidelijk. Ik zal mijn antwoord trouwens nog een keer herhalen, deze keer met wat toelichting.

Alle variabelen die je haalt uit $_GET, $_POST en $_COOKIE zijn altijd strings of (meerdimensionale) arrays gevuld met strings. Een functie als ctype_digit returnt true als een string niets anders dan getallen bevat.

Overigens wil ik even toevoegen dat je ook op een andere (reeds genoemde) manier variabelen kunt controleren. Controleren in de betekenis van beheersen.
Variabelen expliciet casten als integer zorgt ook dat je er veilig mee verder kunt als de enige voorwaarde is dat het resultaat een integer moet zijn. Ikzelf heb bijvoorbeeld geen enkel probleem met de volgende voorbeelden:
PHP:
1
2
3
4
5
6
7
8
$q = 'SELECT * FROM tabel WHERE kolom = ' . (int) $_GET [ 'nr' ];

$q = sprintf (
   'SELECT * FROM tabel WHERE kolom = %u LIMIT %u, %u',
   $_GET [ 'nr' ],
   $_GET [ 'offset' ],
   $_GET [ 'limit' ]
);

offtopic:
Het enige verschil met de werkelijkheid is dat ik eigenlijk liever geen $_GET gebruik, maar een 'wrapper' functie die altijd een waarde returnt en geen notice op kan leveren.

[ Voor 4% gewijzigd door Verwijderd op 21-08-2004 18:06 ]

Pagina: 1