[PHP] Vreemd gedrag arraykeys

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 16-09 13:49

Patriot

Fulltime #whatpulsert

Topicstarter
Hallo,

Ik zal mijn post eens beginnen met een stukje code als inleiding.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

$array = array(0 => array(true,"1"), 1 => array(true,"2"), 2 => array(true,"3"), 'rid' => 5);

foreach ($array as $Key => $Val) {
    
    if ($Key != 'rid') {
        
        echo $Key;
        
    }
    
}

?>


Ik vermoed dat het gebruik van numerieke (integer) keys en string keys door elkaar PHP een beetje over de zeik helpt. Ik verwacht zelf namelijk in dit script een output van "123".

PHP is het echter niet met me eens. PHP vind dat de key 0 (integer) gelijk is aan 'rid' (string) en geeft als output '12'. Ligt het aan het door elkaar gebruiken van numerieke en string keys, of is dit een PHP bug?

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Patriot schreef op zondag 25 november 2007 @ 23:21:
PHP:
1
$array = array(0 => array(true,"1"), 1 => array(true,"2"), 2 => array(true,"3"), 'rid' => 5);

Ik vermoed dat het gebruik van numerieke (integer) keys en string keys door elkaar PHP een beetje over de zeik helpt. Ik verwacht zelf namelijk in dit script een output van "123".

PHP is het echter niet met me eens. PHP vind dat de key 0 (integer) gelijk is aan 'rid' (string) en geeft als output '12'. Ligt het aan het door elkaar gebruiken van numerieke en string keys, of is dit een PHP bug?
"123" kun je sowieso vergeten: de 3 wordt nergens als key gebruikt. Dat 0 en 'rid' gelijk zijn, komt omdat PHP de string 'rid' naar een integer converteert. Hierbij kijkt hij naar getallen die in de string voorkomen. Omdat 'rid' geen getal bevat, wordt dit 0. Wil je dit voorkomen, kijk dan naar !==, die checkt ook het type variabele.

Acties:
  • 0 Henk 'm!

  • ibmos2warp
  • Registratie: Januari 2007
  • Laatst online: 20-11-2023

ibmos2warp

Eval is Evil

Volgens mij moet (kan je beter) is_int http://nl3.php.net/is_int gebruiken, als je wilt controleren of een variable nou een integer is...

Edit: Of zoals GlowMouse zegt: !==

[ Voor 11% gewijzigd door ibmos2warp op 25-11-2007 23:32 ]

Ik weet alles van niks
Vind Excel ongelovelijk irritant.


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 16-09 13:49

Patriot

Fulltime #whatpulsert

Topicstarter
GlowMouse schreef op zondag 25 november 2007 @ 23:28:
[...]

"123" kun je sowieso vergeten: de 3 wordt nergens als key gebruikt. Dat 0 en 'rid' gelijk zijn, komt omdat PHP de string 'rid' naar een integer converteert. Hierbij kijkt hij naar getallen die in de string voorkomen. Omdat 'rid' geen getal bevat, wordt dit 0. Wil je dit voorkomen, kijk dan naar !==, die checkt ook het type variabele.
123 was een denkfoutje, dat moet natuurlijk 012 zijn.

Wat ik echter niet snap is waar die string naar integer conversie plaats moet vinden, en belangrijker nog: waarom. Ik snap dat !== in dit geval werkt, en zo doe ik het nu ook; maar ik blijf het vreemd vinden dat dit probleem zich voor doet.

Ik snap dat PHP loosely typed is, en dat dergelijke conversies soms plaats moeten vinden, maar ik snap echt niet waarom dit in dit geval moet gebeuren. Dat is toch totaal niet logisch hier?

EDIT: Ok, ik zie wel in waarom hij het doet. Maar het is mijns inziens handiger als het anders gedaan wordt. Bijvoorbeeld een string die niet naar een integer geconverteerd kan worden (met andere woorden: waar het eerste teken iets anders is als een cijfer) zou ook niet naar een string geconverteerd moeten worden.

[ Voor 14% gewijzigd door Patriot op 25-11-2007 23:41 ]


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Patriot schreef op zondag 25 november 2007 @ 23:37:
[...]


123 was een denkfoutje, dat moet natuurlijk 012 zijn.

Wat ik echter niet snap is waar die string naar integer conversie plaats moet vinden, en belangrijker nog: waarom. Ik snap dat !== in dit geval werkt, en zo doe ik het nu ook; maar ik blijf het vreemd vinden dat dit probleem zich voor doet.

Ik snap dat PHP loosely typed is, en dat dergelijke conversies soms plaats moeten vinden, maar ik snap echt niet waarom dit in dit geval moet gebeuren. Dat is toch totaal niet logisch hier?
Wat als je als input de string '123' krijgt (bv via een form), en die met de integer 123 wilt vergelijken? Ondanks de loose typing zou je dan toch eerst een type-conversie moeten doen, dat lijkt me verwarrender.

Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 16-09 13:49

Patriot

Fulltime #whatpulsert

Topicstarter
Ja, ik snap inderdaad wel wáárom hij de integer nu probeert te converteren. Wat ik enigzins vreemd vind, is dat hij bij een 'gefaalde' conversie niet gewoon de string gebruikt.

EDIT: Hier zal uiteraard vast een goede verklaring voor zijn hoor, hoogstwaarschijnlijk wordt de string naar int conversie internet ergens door geregeld wat simpelweg de integer teruggeeft; waardoor geen onderscheid gemaakt kan worden tussen '0' en 'string'; maar het is imho een beetje vreemd (ondanks de loose typing van PHP) dat 0 == 'poep'. Dat moet imho NOOIT valideren.

[ Voor 52% gewijzigd door Patriot op 25-11-2007 23:47 ]


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Patriot schreef op zondag 25 november 2007 @ 23:43:
Ja, ik snap inderdaad wel wáárom hij de integer nu probeert te converteren. Wat ik enigzins vreemd vind, is dat hij bij een 'gefaalde' conversie niet gewoon de string gebruikt.
Waar trek je de grens? Is '123 ' nog 123? En hoe zit het dan met '123]' of '123a'? In het verleden heeft men ergens voor gekozen, en dat gedrag kun je niet zomaar wijzigen. Je kunt bij de wishlist voor PHP6 eens zoeken of ze dit wel van plan zijn.

Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 16-09 13:49

Patriot

Fulltime #whatpulsert

Topicstarter
GlowMouse schreef op zondag 25 november 2007 @ 23:48:
[...]

Waar trek je de grens? Is '123 ' nog 123? En hoe zit het dan met '123]' of '123a'? In het verleden heeft men ergens voor gekozen, en dat gedrag kun je niet zomaar wijzigen. Je kunt bij de wishlist voor PHP6 eens zoeken of ze dit wel van plan zijn.
Ik trek persoonlijk de grens bij een falende conversie die dan maar default naar 0 maar daardoor opeens wel valideerd. Ik snap dat het een vergelijkbare situatie is, en dat het beste gedrag uiteindelijk gewoon het strictly typed gedrag is (omdat dit nooit tot onverwachte resultaten zal leiden); maar ik vind het vreemder dat 0 == "string" dan 123 == '123'. Ik vind 123 == '123a' nog logischer dan 0 == "string".

Acties:
  • 0 Henk 'm!

  • Scott
  • Registratie: December 2004
  • Laatst online: 20-09 21:57

Scott

Ik ben, dus ik tweak

GlowMouse schreef op zondag 25 november 2007 @ 23:48:
[...]

Waar trek je de grens? Is '123 ' nog 123? En hoe zit het dan met '123]' of '123a'? In het verleden heeft men ergens voor gekozen, en dat gedrag kun je niet zomaar wijzigen. Je kunt bij de wishlist voor PHP6 eens zoeken of ze dit wel van plan zijn.
Ik zou zeggen als er géén getal in een string staat. In 'tweakers' staat geen getal, wordt naar 0 geconverteerd en zou dus gelijk zijn aan 0. Uiteindelijk komt het er dan op neer dat 'tweakers' == 0. Dat vind ik echt raar :?. Ik zou zeggen: als een string niet naar integer geconverteerd kan worden vanwege een gebrek aan getallen in die string, zou er pertinent false uit de vergelijking string == integer moeten komen.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Patriot schreef op zondag 25 november 2007 @ 23:43:
waardoor geen onderscheid gemaakt kan worden tussen '0' en 'string'; maar het is imho een beetje vreemd (ondanks de loose typing van PHP) dat 0 == 'poep'. Dat moet imho NOOIT valideren.
Maar welke int is dan wel gelijk aan 'poep'?

Want andere mensen zouden het weer raar vinden als : 123=='123'; niet meer opgaat.

En de oplossing is ook simpel : wil je een string vergelijken met een int dan moet je zelf gaan converteren. Wil je een string alleen vergelijken met een string dan moet je types controleren dmv ===.

btw, wat is gedachte achter integer keys gecombineerd met string keys??? Ikzelf zou desnoods de integer keys converteren naar hun string-variant '0' zodat alles gelijk blijft binnen 1 array...
ScottB schreef op zondag 25 november 2007 @ 23:54:
[...]


Ik zou zeggen als er géén getal in een string staat. In 'tweakers' staat geen getal, wordt naar 0 geconverteerd en zou dus gelijk zijn aan 0. Uiteindelijk komt het er dan op neer dat 'tweakers' == 0. Dat vind ik echt raar :?. Ik zou zeggen: als een string niet naar integer geconverteerd kan worden vanwege een gebrek aan getallen in die string, zou er pertinent false uit de vergelijking string == integer moeten komen.
Dan krijg je imho nog veel raarder gedrag, als ik dan een string van 8092 tekens heb, dan is het false als er geen letters inzitten en true als er wel ergens de gezochte letters inzit, ook al is dit er maar 1tje ergens aan het einde.

Maar gewoon bijna altijd === gebruiken, dan gaat het wel goed.

[ Voor 33% gewijzigd door Gomez12 op 26-11-2007 00:06 ]


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 16-09 13:49

Patriot

Fulltime #whatpulsert

Topicstarter
Gomez12 schreef op zondag 25 november 2007 @ 23:59:
btw, wat is gedachte achter integer keys gecombineerd met string keys??? Ikzelf zou desnoods de integer keys converteren naar hun string-variant '0' zodat alles gelijk blijft binnen 1 array...
Heeft te maken met tijdsnood en de manier waarop gegevens binnenkomen.
Pagina: 1