[PHP] Leerlingnummer word gezien als octaal

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Mac_Cain13
  • Registratie: Juni 2003
  • Laatst online: 17-09 15:48
We zijn hier met een paar lui druk aan het coden aan een projectje en het gaat allemaal leuk, maar nu loop ik toch tegen een probleem aan.

Alle leerlingen hebben namelijk een leerlingnummer, deze bestaat altijd uit 6 cijfers. Dus leerling 5610 krijgt 2 leading zeros om op 6 cijfers te komen. Dit ging allemaal goed, totdat ik zo'n nummer ga echo'en. PHP denkt dat het een octaal getal is en gaat het lopen converteren naar een decimaal.

Hierdoor krijg ik allemaal niet gewenste output, alleen kan ik geen functie vinden om PHP te dwingen het getal als decimaal te zien. Wel converteer functies, maar dat is juist wat ik niet wil.

Op zich zou ik er ook geen problemen mee hebben als die leading zeros zouden verdwijnen. (MySQL schrapt ze namelijk ook standaard.) Natuurlijk kan ik zelf iets schrijven wat uitzoekt of het eerste getal een 0 is en zo ja deze schrappen, maar het lijkt mij dat dit probleem meer voorkomt.

Hoe zouden jullie dit leading zero probleem oplossen? De enige oplossing die ik nu zie is een functie schrijven die de nullen schrapt, maar dit vind ik eigenlijk een beetje rare oplossing. PHP zou ze mijn inziens gewoon zelf moeten schrappen en niet als een octaal zien.

Acties:
  • 0 Henk 'm!

  • 418O2
  • Registratie: November 2001
  • Nu online
wat is het type van de variabele waar je het aan toe kent ? Als je die type-casted naar decimaal (of gewoon int) wordt de situatie dan anders?

en wat is je output wel dan? Het leerlingnummer zonder leading zero's ?

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

'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!

  • Mac_Cain13
  • Registratie: Juni 2003
  • Laatst online: 17-09 15:48
Die functie ken ik, maar is in dit geval niet van toepassing. Deze zet het getal namelijk van octaal om naar decimaal, maar mijn getal is al decimaal. Het vervelende is namelijk dat ik een decimaal heb, maar PHP het ziet als een octaal.

Ik zal het even proberen toe te lichten met een stukje code:
PHP:
1
2
3
4
5
6
7
8
<?php
    /* Het (decimale) leerlingennummer zoals het binnenkomt, 
    maar PHP denkt door die 1e nul dat het octaal is. */
    $llnummer = 005610; 
    
    // Een echo:
    echo 'Het nummer is: '.$llnummer; // Dit geeft: Het nummer is 2952
?>


PHP voert dus door die eerste 0 automatisch octdec() uit, terwijl ik dat helemaal niet wil! De vraag is dus, hoe leer ik PHP dat eigenwijze converteren af? En vertel ik hem dat die eerste nullen gewoon nullen zijn (en evt. zelfs wel weg mogen). :P
edit:
Overgens helpt type casting niet, want dit mag alleen maar tussen types (int naar string bijv.) en niet tussen getallen stelsels (oct naar dec bijv.).

[ Voor 9% gewijzigd door Mac_Cain13 op 24-03-2005 18:13 ]


Acties:
  • 0 Henk 'm!

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28

JeRa

Authentic

Je hebt het erover dat de database ook geen rekening houdt met de leading zeroes. Waar zijn de leading zeroes voor bedoeld?

Als het puur esthetisch is, dan zou je een functie kunnen maken die de leading zeroes toevoegt zodra je ze nodig hebt, maar intern gewoon het nummer zonder nullen te verwerken. Je functie zou dan gewoon een string moeten retourneren die je kunt outputten.

ifconfig eth0 down


Acties:
  • 0 Henk 'm!

Verwijderd

Mac_Cain13 schreef op donderdag 24 maart 2005 @ 18:09:
[...]

Die functie ken ik, maar is in dit geval niet van toepassing. Deze zet het getal namelijk van octaal om naar decimaal, maar mijn getal is al decimaal. Het vervelende is namelijk dat ik een decimaal heb, maar PHP het ziet als een octaal.

Ik zal het even proberen toe te lichten met een stukje code:
PHP:
1
2
3
4
5
6
7
8
<?php
    /* Het (decimale) leerlingennummer zoals het binnenkomt, 
    maar PHP denkt door die 1e nul dat het octaal is. */
    $llnummer = 005610; 
    
    // Een echo:
    echo 'Het nummer is: '.$llnummer; // Dit geeft: Het nummer is 2952
?>


PHP voert dus door die eerste 0 automatisch octdec() uit, terwijl ik dat helemaal niet wil! De vraag is dus, hoe leer ik PHP dat eigenwijze converteren af? En vertel ik hem dat die eerste nullen gewoon nullen zijn (en evt. zelfs wel weg mogen). :P
$llnummer = 5610;

Zorgen dat "zoals het binnenkomt" het goed aangeleverd wordt. Als het als integer ergens staat is het een eitje, als het als string ergens staat is het een eitje, als het met ranzige PHP code wordt aangeleverd dan maak je het jezelf erg moeilijk. Toch?

Acties:
  • 0 Henk 'm!

  • Mac_Cain13
  • Registratie: Juni 2003
  • Laatst online: 17-09 15:48
JeRa schreef op donderdag 24 maart 2005 @ 18:11:
Je hebt het erover dat de database ook geen rekening houdt met de leading zeroes. Waar zijn de leading zeroes voor bedoeld?
Die leerlingnummers (met leading zeroes) krijg ik aangeleverd vanuit mijn informatiebron. Ze zijn dan voor mij alleen maar lastig, omdat PHP zich er in verslikt. Dus ze zouden ook gewoon weg mogen...
Als het puur esthetisch is, dan zou je een functie kunnen maken die de leading zeroes toevoegt zodra je ze nodig hebt, maar intern gewoon het nummer zonder nullen te verwerken. Je functie zou dan gewoon een string moeten retourneren die je kunt outputten.
Zo'n idee zou inderdaad kunnen, al doe ik het dan liever gewoon helemaal zonder die leading zeroes en output ik gewoon 5610. Alleen moet ik dan dus wel eerst die leading zeroes zien te schrappen.

Wat ik zo apart vind is dat PHP er geen rekening mee houd dat je ook wel eens een decimaal zou kunnen hebben met leading zeroes en dus maar zelf even aan het toveren gaat met getallen stelsels.

Acties:
  • 0 Henk 'm!

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28

JeRa

Authentic

Je kunt intval() gebruiken om getallen mét of zonder leading zeroes naar decimale getallen om te zetten.

PHP:
1
2
$waarde = intval('001234');
echo $waarde;


Hier komt als het goed is gewoon 1234 uit :)

ifconfig eth0 down


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Inderdaad, als je leading zeros niet in de database vermeld staan, kun je het beste gewoon met getallen zonder die zeros werken en gebruikmaken van bijvoorbeeld sprintf () om 't zaakje de nullen te geven zodra nodig:
PHP:
1
2
$myNumber = 1234;
$myFormattedNumber = sprintf ( '%06u', $myNumber );


Ik kan me trouwens niet zo goed voorstellen dat dit zomaar gebeurt. MySQL geeft namelijk altijd gewoon strings terug aan PHP, en zolang je geen arithmetische operaties op die strings uitvoert blijven het gewoon strings. Dan nog is het lastig om PHP te laten denken dat je met een octal te maken hebt:

PHP:
1
2
3
$someString = '0789'; // octal?
$someString += 0; // implicit type cast
echo $someString; // echoes 789


Ik ben dus wel benieuwd of je dit in een snippet kunt reproduceren

[ Voor 6% gewijzigd door drm op 24-03-2005 18:26 . Reden: typ0z0r ]

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28

JeRa

Authentic

Mac_Cain13 schreef op donderdag 24 maart 2005 @ 18:18:
Wat ik zo apart vind is dat PHP er geen rekening mee houd dat je ook wel eens een decimaal zou kunnen hebben met leading zeroes en dus maar zelf even aan het toveren gaat met getallen stelsels.
Het is een functie van PHP om getallen die beginnen met een nul automatisch in te lezen als een octaal getal. Dit is niet alleen in PHP zo, maar in veel script- en programmeertalen. In C++ heb je de welbekende prefix '0x' voor hexadecimale getallen en ook vele suffices voor types; PHP verwacht in dit geval dat je decimale getallen gewoon schrijft zoals het hoort, zonder de leading zeroes dus.

ifconfig eth0 down


Acties:
  • 0 Henk 'm!

Verwijderd

Mac_Cain13 schreef op donderdag 24 maart 2005 @ 18:18:

Wat ik zo apart vind is dat PHP er geen rekening mee houd dat je ook wel eens een decimaal zou kunnen hebben met leading zeroes en dus maar zelf even aan het toveren gaat met getallen stelsels.
De PHP vindt dat getallen die met een 0 beginnen in het octale stelsel staan geen decimale getallen zijn. Zo gek is dat toch niet? Wil je dat niet, zorg dan dat er geen nul voor staat. Is de input een string? Strip de nullen, en je kunt vrij eenvoudig een integer maken van wat overblijft.

Wil je een 6-cijferig getal weergeven, links "opgevuld" met nullen? Ook daar zijn oplossingen voor:
http://www.php.net/str_pad
http://www.php.net/printf

Acties:
  • 0 Henk 'm!

  • Mac_Cain13
  • Registratie: Juni 2003
  • Laatst online: 17-09 15:48
JeRa schreef op donderdag 24 maart 2005 @ 18:21:
Je kunt intval() gebruiken om getallen mét of zonder leading zeroes naar decimale getallen om te zetten.

[...]
Intval was inderdaad datgene wat ik zocht! Het zet mijn getallen allemaal perfect om naar nette decimalen. Dit is dé manier om van die leading zeros af te komen.
drm schreef op donderdag 24 maart 2005 @ 18:21:
Inderdaad, als je leading zeros niet in de database vermeld staan, kun je het beste gewoon met getallen zonder die zeros werken en gebruikmaken van bijvoorbeeld sprintf () om 't zaakje de nullen te geven zodra nodig:
PHP:
1
2
$myNumber = 1234;
$myFormattedNumber = sprintf ( '%06u', $myNumber );
De leading zeros terug krijgen lukt inderdaad. Met sprintf is het zelfs een makkie zo te zien, maar daar kom ik wel uit.
Ik kan me trouwens niet zo goed voorstellen dat dit zomaar gebeurt. MySQL geeft namelijk altijd gewoon strings terug aan PHP, en zolang je geen arithmetische operaties op die strings uitvoert blijven het gewoon strings. Dan nog is het lastig om PHP te laten denken dat je met een octal te maken hebt:

PHP:
1
2
3
$someString = '0789'; // octal?
$someString += 0; // implicit type cast
echo $someString; // echoes 789


Ik ben dus wel benieuwd of je dit in een snippet kunt reproduceren
Zodra de getallen uit MySQL komen rollen is er inderdaad geen probleem, maar ik moet eerst de hele boel inlezen vanuit HTML files. Niet de meest prettige manier, maar helaas heb ik geen andere mogelijkheid.

Hmm, en met dat ik dit type besef ik dat dat natuurlijk ook een string is en dat de sha1 hash die ik hiermee ging maken ook perfect klopt. :X

Ik heb nog eens even goed zitten testen en je hebt inderdaad gelijk dat dit niet zomaar voorkomt. Het probleem was dat ik net tijdens het debuggen zelf even de variable vulde als een integer en hierdoor wel last had van dat octale gedoe.

Cheatah heeft dus ook helemaal gelijk dat het alleen bij het binnenkomen even goed geregeld moet worden en dan is de rest een eitje.

Verder was het ook even lastig dat MySQL die leading zeros schrapte, maar met intval() haal ik ze nu gewoon allemaal weg. Dat is wel zo makkelijk en voor de gebruikers wel zo fijn, dat scheeld ze ook weer twee nullen typen. ;)
JeRa schreef op donderdag 24 maart 2005 @ 18:22:
[...]

Het is een functie van PHP om getallen die beginnen met een nul automatisch in te lezen als een octaal getal. Dit is niet alleen in PHP zo, maar in veel script- en programmeertalen. In C++ heb je de welbekende prefix '0x' voor hexadecimale getallen en ook vele suffices voor types; PHP verwacht in dit geval dat je decimale getallen gewoon schrijft zoals het hoort, zonder de leading zeroes dus.
Het is inderdaad niet zo raar dat er zulke functies bestaan en vooral de 0x voor hexadecimalen is handig. Het verschil vind ik alleen dat daar nog een letter in zit. De x is geen getal dus zal dit ook nooit een probleem worden met leading zeros oid. Als ze nou voor octale getallen een '0y' prefix zouden gebruiken zou je hier ook nooit rare leading zero dingen kunnen krijgen.

Al komt het in de praktijk inderdaad weinig voor dat het mis gaat. Tenzij je met je domme hoofd gaat debuggen met een int ipv een string. :P

In ieder geval, hartelijk bedankt voor de moeite enz. :>
Ik heb er weer wat van geleerd ook al was het mijn eigen fout.

Acties:
  • 0 Henk 'm!

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
Misschien dom idee maar als je het volgende probeert

PHP:
1
2
3
4
5
6
7
<?

$nr = (int) 01234;

echo $nr;

?>


Kan het zelf niet testen maar zo lijkt mij toch dat hij meteen een integer er van maakt :?

[ Voor 4% gewijzigd door 4Real op 24-03-2005 22:36 . Reden: typo ]


Acties:
  • 0 Henk 'm!

Verwijderd

4Real schreef op donderdag 24 maart 2005 @ 22:35:
Misschien dom idee maar als je het volgende probeert

PHP:
1
2
3
4
5
6
7
<?

$nr = (int) 01234;

echo $nr;

?>


Kan het zelf niet testen maar zo lijkt mij toch dat hij meteen een integer er van maakt :?
ja zonder leading 0.. enige manier om die getallen met leading nul op te slaan is door ze als string op te slaan lijkt me?

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op donderdag 24 maart 2005 @ 22:41:
[...]

ja zonder leading 0.. enige manier om die getallen met leading nul op te slaan is door ze als string op te slaan lijkt me?
Dat werkt niet. Dit werkt wel:
PHP:
1
2
3
4
5
6
7
<?

$nr = (int) '01234';

echo $nr;

?>


Edit: verkeerde poster gequote |:(

[ Voor 9% gewijzigd door Verwijderd op 24-03-2005 22:45 ]


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Een leerling"nummer" is geen getal of nummer, als leading zeroes meetellen. Een eigenschap van getallen is namelijk dat het getal 'abcdef' gelijk is aan (100000*a+10000*b+1000*c+100*d+10*e+f)
en als a=0 is dat dus gelijk aan (10000*b+1000*c+100*d+10*e+f) = 'bcdef'.

Wat jij beschrijft is een string, daar is elk karakter van belang, en strings zijn alleen gelijk als ze even lang zijn en karakter-voor-karakter gelijk.

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


Acties:
  • 0 Henk 'm!

Verwijderd

MSalters schreef op donderdag 24 maart 2005 @ 23:26:
Een leerling"nummer" is geen getal of nummer, als leading zeroes meetellen. Een eigenschap van getallen is namelijk dat het getal 'abcdef' gelijk is aan (100000*a+10000*b+1000*c+100*d+10*e+f)
en als a=0 is dat dus gelijk aan (10000*b+1000*c+100*d+10*e+f) = 'bcdef'.

Wat jij beschrijft is een string, daar is elk karakter van belang, en strings zijn alleen gelijk als ze even lang zijn en karakter-voor-karakter gelijk.
In een database is het wel gewoon een integer, als je het voor jezelf makkelijk wilt houden. Als je zorgt dat het overal integers zijn, behalve in de output (daar maak je er een zero padded string van 6 tekens van), dan gaat dat allemaal prima.

Je hebt helemaal gelijk, maar in neem aan dat je niet wilt impliceren dat dat leerlingnummer binnen de applicatie een string moet zijn?
Pagina: 1