Steek je hand op als je het volgende ook stom vindt:
'50' == '50.00' is TRUE
Test:
<?php
var_dump('50' == '50.00'); // bool(true)
?>
Ik weet en snap (en love) dat PHP type ongevoelig en ontzettend vrij is, maar als beide delen strings zijn wordt toch zeker wel op de waarde gecontroleerd??? Nu worden ze als float ofzo vergeleken? Dat is raar!
Ik heb altijd gedacht dat het enige verschil tussen == en === was dat de eerste niet en de tweede wel op type controleert. Blijkbaar is dat niet!! Want beide zijn string en toch is het met == true en met === false!
Nee, ik vind dit niet raar. Met == maakt php daar blijkbaar toch getallen van (op zich wel raar) en die worden vergeleken. En die zijn gelijk. Met === wordt ook het type vergeleken en dan moet php het wel als zijnde een string behandelen en nee, die zijn dus niet gelijk.
Maar dan is het toch juist raar? Het verschil tussen == en === is dat de typen bij de tweede hetzelfde moeten zijn. De typen ZIJN al hetzelfde, dus zouden == en === toch hetzelfde moeten doen??
Ik vind het heel erg raar. Ik ga voortaan in ieder geval overal === en !== gebruiken.
Maar dan is het toch juist raar? Het verschil tussen == en === is dat de typen bij de tweede hetzelfde moeten zijn. De typen ZIJN al hetzelfde, dus zouden == en === toch hetzelfde moeten doen??
Ik vind het heel erg raar. Ik ga voortaan in ieder geval overal === en !== gebruiken.
== vergelijkt en converteert eventueel het type tijdens het vergelijken om te kijken of ze dan wel gelijk zijn. === converteert het type niet, dus als ze niet van hetzelfde type zijn, zijn ze automatisch al niet gelijk. En zijn ze wel van hetzelfde type, dan wordt er gecontroleerd op inhoud. Zo vreemd is dat toch niet?
Wat is hier raar aan?
50 is hetzelfde als 50.00? (==)
en 50 is niet identiek aan 50.00 (===)
?Onbekende gebruiker
18-12-2010 15:16
gewijzigd op 18-12-2010 15:25
Rudie dirkx op 18/12/2010 01:14:28
(…)
Ik heb altijd gedacht dat het enige verschil tussen == en === was dat de eerste niet en de tweede wel op type controleert. Blijkbaar is dat niet!! Want beide zijn string en toch is het met == true en met === false!
(…)
Ja, de eerste (==) checkt niet op type. Intern zal denk ik de eerste variabele naar integer worden omgezet. Dat betekend dus ook dat de tweede variabele omgezet moet worden. Makkelijk is om deze ook naar integer om te zetten. Dus dan krijg je twee keer 50 en dat is gelijk aan elkaar. Dat is dus precies een voorbeeld van weak typing.
Je moet dus inderdaad goed opletten wat je precies checkt met php. Ook moet je goed opletten met floats in php.
Zie ook de volgende php.net pagina’s:
[php] types.comparisons[/php]
[php] language.types.type-juggling[/php]
[php] language.types.string#language.types.string.conversion[/php]
[php] language.operators.comparison[/php]
Verder is dit misschien ook wel een interessant verhaal.
Als je een strong typing taal pakt zoals Java heb je ook wat rare dingetjes:
<?php // LET OP! Dit is GEEN php. Dit is alleen voor de kleurtjes
/**
* Deze klasse is voor het testen van types in java.
* Java is een strong typing language en gaat dus anders om met zijn variabelen.
* Elke methode en veld is static want dan kunnen we ze zo benaderen.
* In java doe je concatten niet met een . maar met +.
* @author Karl
* @version 18-12-2010
* @see http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
* @see http://download.oracle.com/javase/tutorial/java/data/index.html
*
*/
public class type_testing_java {
// Aanmaken van een aantal velden
public static int a = 5;
public static int b = 9;
public static int c = 100;
public static double d = 1.5; // Wordt standaard 0.0d zie docs
public static double e = 2.0;
public static String f = "test"; // Object type
public static double g = 100.0;
/**
* Main method. Deze wordt altijd uitgevoerd.
* Hier roepen we dus al onze test methodes aan.
* @param args
*/
public static void main(String[] args) {
// Onderstaande regels leveren output (zie codeblokje hieronder).
System.out.println(levertTweeIntsEenDouble());
System.out.println(levertTweeDoublesEenDouble());
System.out.println(levertTweeIntsEnEenDoubleEenDouble());
System.out.println(levertEenIntEnEenDoubleEenDouble());
System.out.println(levertEenDoubleEenIntEenDoubleEenDouble());
System.out.println(kunnenWeDrieIntsEenDoubleLatenLeveren());
System.out.println(weWillenEenStringTerugMetTweeIntsAlsEenIntEnMetEenString());
System.out.println(weWillenEenStringTerugMetEenStringEnTweeIntsAlsEenInt());
System.out.println(weZeidenDatWeEenStringTerugMetEenStringEnTweeIntsAlsEenIntWouden());
System.out.println(weZeidenDatWeEenStringTerugMetTweeIntsEnMetEenStringWouden());
}
/*
* Nog even een methode uitleg:
* public static double levertTweeIntsEenDouble()
* Dat betekend dat deze methode door iedereen benaderd mag worden -> public
* Er hoeft geen object van deze klasse te zijn -> static
* Het type wat de methode teruggeeft -> double
* De naam van de methode en geen parameters -> levertTweeIntsEenDouble()
*
* Deze is iets anders:
* public static String weWillenEenStringTerugMetEenStringEnTweeIntsAlsEenInt()
* Het enige verschil is de String. String is een object type (zie hierboven de links).
* Dat betekend dus dat er van String een klasse is. En dat er een object zal bestaan
* van het type String als je deze gebruikt.
* In java is het zo dat je alleen primitieve datatypes hebt (int, double, char, etc.)
* Als je wat anders wilt, zoals String, dan zit je bij een object datatype.
* String is dus een klasse die intern een string bijhoud als iets.
* Hoe hoef je niet te weten.
*/
/**
* Deze methode is om te kijken of twee ints een double levert.
* De uitkomst zou 0.55555556 moeten zijn (breuk)
* @return De uitkomts van de breuk a/b
*/
public static double levertTweeIntsEenDouble()
{
return a/b;
}
/**
* Deze methode is om te kijken of twee doubles een double levert.
* De uitkomst zou 0.75 moeten zijn
* @return De uitkomst van de breuk d/e
*/
public static double levertTweeDoublesEenDouble()
{
return d / e;
}
/**
* Deze methode is om te kijken of de volgorde van types wat uitmaakt.
* De uitkomst zou dus 55.55555555556 moeten zijn
* @see type_testing_java#levertEenDoubleEenIntEenDoubleEenDouble()
* @return De uitkomst van de formule (a/b)*g.
*/
public static double levertTweeIntsEnEenDoubleEenDouble()
{
return a/b * g;
}
/**
* Deze methode is om te kijken of een int en een double wel een double oplevert.
* De uitkomst zou dus 500.0 moeten zijn
* @return De uitkomst van het product van a*g
*/
public static double levertEenIntEnEenDoubleEenDouble()
{
return a*g;
}
/**
* Deze methode is om te kijken of de volgorde van types wat uitmaakt.
* De uitkomst zou dus 55.55555555 moeten zijn.
* @see type_testing_java#levertTweeIntsEnEenDoubleEenDouble()
* @return De uitkomst van de formule (a*g)/b
*/
public static double levertEenDoubleEenIntEenDoubleEenDouble()
{
return a*g/b;
}
/**
* Nu we bovenstaande methodes hebben uitgevoerd zullen we dit ons afvragen
* De uitkomst zou dus 55.555555556 moeten zijn.
* @see type_testing_java#levertTweeIntsEnEenDoubleEenDouble()
* @see type_testing_java#levertTweeIntsEenDouble()
* @return
*/
public static double kunnenWeDrieIntsEenDoubleLatenLeveren()
{
return (double)a/b * c;
}
/**
* Met strings is er ook wat aan de hand.
* @return (a+b) + f
*/
public static String weWillenEenStringTerugMetTweeIntsAlsEenIntEnMetEenString()
{
return a + b + f;
}
/**
* Nu we de functie {@link type_testing_java#weWillenEenStringTerugMetTweeIntsAlsEenIntEnMetEenString()}
* hebben gezien, willen we dus de integer op het eind van onze string
* @return f+(a+b) (of niet?)
*/
public static String weWillenEenStringTerugMetEenStringEnTweeIntsAlsEenInt()
{
return f + a + b;
}
/**
* Blijkbaar werkt het niet zo in java @link {@link type_testing_java#weWillenEenStringTerugMetEenStringEnTweeIntsAlsEenInt()}
* gaf ons een ander resultaat dan we wouden
* @return f+(a+b)
*/
public static String weZeidenDatWeEenStringTerugMetEenStringEnTweeIntsAlsEenIntWouden()
{
return f + (a+b);
}
/**
* Blijkbaar werkte @link {@link type_testing_java#weWillenEenStringTerugMetTweeIntsAlsEenIntEnMetEenString()} wat we wouden.
* Nu willen we dat we twee ints aan het begin moet. Hoe moet dat dan?
* @return a+b+f
*/
public static String weZeidenDatWeEenStringTerugMetTweeIntsEnMetEenStringWouden()
{
return "" + a + b + f;
}
}
// Om gezeur van bbcode parser te vermijden:
?>