Bedragen bij elkaar optellen via variabelen

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Nanno Koerts

Nanno Koerts

16/03/2022 15:46:15
Quote Anchor link
Beste mensen,

Ik snap het even niet meer...

Ik wil mijn variabelen bij elkaar optellen in het script om daarna het totaal weg te schrijven in de database. De gegevens komen dus vanaf een formulier en die data wil ik dan in het script al graag optellen en dan pas in de MySql database weg te schrijven.

Ik weet dat php met een punt scheiding werkt bij decimalen wat ik later weer omzet naar een komma in de layout.
Nu is het optellen van hele getallen niet zo heel moeilijk, maar ik begrijp even niet waarom dat met een decimaal erbij ineens wel moeilijk gaat, want tot mijn verbazing schrijft de php server het getal weg met een komma in mijn tabel. Wat doe ik dus fout en zie ik over het hoofd?

Moet ik nou float of varchar gebruiken als type in de database?

Om fouten te voorkomen met wegschrijven vanaf het formulier heb ik ervoor gekozen om de euro en centen apart te vermelden en die voeg ik in het script dan bij elkaar met de punt als scheidingsteken.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
$Prijs_bruto = $_POST['Prijs_euro'] . '.' .  $_POST['Prijs_cent'];
$Prijs_toeslag = $_POST['Toeslag_euro'] . '.' .  $_POST['Toeslag_cent'];


Nu bedacht ik dat het dus heel simpel op te tellen is met deze code:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$Prijs_netto = $Prijs_bruto + $Prijs_toeslag;


Maar als ik dit weg schrijf wordt er een komma geplaatst in de tabel. Why?

Ik weet niet of ik hier de SUM ook kan gebruiken omdat die in alles wat ik lees, enkel in de SELECT wordt toegepast en dat is nou juist het aparte, ik heb het nog niet in de database staan.

Wie o wie kan en wil me hiermee helpen?

Groet,

Nanno
 
PHP hulp

PHP hulp

27/06/2022 17:53:03
 
Adoptive Solution

Adoptive Solution

16/03/2022 16:30:05
Quote Anchor link
Je kan het zo doen.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$Prijs_netto = floatval($Prijs_bruto) + floatval( $Prijs_toeslag);


Of een variatie daarop.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

16/03/2022 17:00:38
Quote Anchor link
>> Moet ik nou float of varchar gebruiken als type in de database?

Een varchar zou ik niet doen.

Een float is mogelijk maar een decimal kan ook. Het verschil is dat je bij een decimal het aantal cijfers voor en achter de komma zelf kan opgeven. Bijvoorbeeld DECIMAL(10,2). Daarnaast wordt onze valuta ook nog wel eens in centen opgeslagen. 1 euro wordt dan opgeslagen als 100 eurocent. Bij het type integer kun je dan getallen opslaan tussen de -21 en +21 miljoen. Je moet zelf (met php) euro's naar eurocenten omrekenen.

>> Om fouten te voorkomen met wegschrijven vanaf het formulier heb ik ervoor gekozen om de euro en centen apart te vermelden en die voeg ik in het script dan bij elkaar met de punt als scheidingsteken.

Dit zou je niet moeten doen. Is onnodig werk en werkt juist fouten in de hand.
Gewijzigd op 16/03/2022 17:02:40 door Frank Nietbelangrijk
 
Nanno Koerts

Nanno Koerts

16/03/2022 17:02:04
Quote Anchor link
Hij blijft dan de komma plaatsen bij type VARCHAR en bij FLOAT laat hij de decimalen vervallen. Dit is toch raar??
 
Frank Nietbelangrijk

Frank Nietbelangrijk

16/03/2022 17:05:33
Quote Anchor link
Bij varchar plaats ie alles wat jij zegt alsof het een lap tekst is. Je levert dan zelf de komma aan.
Bij Float herkent hij de door jou aangeleverde komma niet en laat deze en de cijfers er achter dan ook vervallen.


Toevoeging op 16/03/2022 17:10:57:

Zowel bij een float als een decimaal mag je geen komma gebruiken.

Komt je waarde uit een formulier dan is deze "vervuild" omdat mensen altijd van alles proberen. Je moet deze waarde dan zelf controleren, eventueel aanpassen en accepteren of weigeren. Indien je applicatie de opgegeven waarde weigert zul je een nette foutmelding aan de gebruiker moeten tonen.
 
Nanno Koerts

Nanno Koerts

16/03/2022 18:38:06
Quote Anchor link
Dank voor je reactie.

Maar als je goed kijkt in mijn code gebruik ik een punt.
Dus in de database zie ik bij Prijs_bruto 10.00 en bij Prijs_toeslag 1.50
Maar het optellen doet de server dus zelf met een komma in de tabel Prijs_netto. Dus wat doe ik dan fout in mijn code en instellingen?

Frank Nietbelangrijk op 16/03/2022 17:05:33:
Bij varchar plaats ie alles wat jij zegt alsof het een lap tekst is. Je levert dan zelf de komma aan.
Bij Float herkent hij de door jou aangeleverde komma niet en laat deze en de cijfers er achter dan ook vervallen.


Toevoeging op 16/03/2022 17:10:57:

Zowel bij een float als een decimaal mag je geen komma gebruiken.

Komt je waarde uit een formulier dan is deze "vervuild" omdat mensen altijd van alles proberen. Je moet deze waarde dan zelf controleren, eventueel aanpassen en accepteren of weigeren. Indien je applicatie de opgegeven waarde weigert zul je een nette foutmelding aan de gebruiker moeten tonen.




Toevoeging op 16/03/2022 18:41:10:

Adoptive Solution op 16/03/2022 16:30:05:
Je kan het zo doen.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$Prijs_netto = floatval($Prijs_bruto) + floatval( $Prijs_toeslag);


Of een variatie daarop.


Hij laat hierbij de punt vervallen in de tabel. Geen centen te zien dus. 10.00 + 1.50 = 11
Andere optie of variatie?

Toevoeging op 16/03/2022 18:47:26:

Frank Nietbelangrijk op 16/03/2022 17:00:38:
>> Moet ik nou float of varchar gebruiken als type in de database?

Een varchar zou ik niet doen.

Een float is mogelijk maar een decimal kan ook. Het verschil is dat je bij een decimal het aantal cijfers voor en achter de komma zelf kan opgeven. Bijvoorbeeld DECIMAL(10,2). Daarnaast wordt onze valuta ook nog wel eens in centen opgeslagen. 1 euro wordt dan opgeslagen als 100 eurocent. Bij het type integer kun je dan getallen opslaan tussen de -21 en +21 miljoen. Je moet zelf (met php) euro's naar eurocenten omrekenen.

>> Om fouten te voorkomen met wegschrijven vanaf het formulier heb ik ervoor gekozen om de euro en centen apart te vermelden en die voeg ik in het script dan bij elkaar met de punt als scheidingsteken.

Dit zou je niet moeten doen. Is onnodig werk en werkt juist fouten in de hand.


Ik snap hem nu... Ik had 10,0 bij Decimal staan. Nu met 10,2 telt hij de waardes perfect op!
Thanks!!!!

Toevoeging op 16/03/2022 18:54:31:

@Frank

>> Om fouten te voorkomen met wegschrijven vanaf het formulier heb ik ervoor gekozen om de euro en centen apart te vermelden en die voeg ik in het script dan bij elkaar met de punt als scheidingsteken.

Dit zou je niet moeten doen. Is onnodig werk en werkt juist fouten in de hand. <<

De gebruiker is slechtziend en als deze dan in het veld een komma plaatst i.p.v. een punt, dan heb ik pas een probleem. En dit gebeurde regelmatig helaas. Vandaar dat ik het nu zo gescheiden doe. Nu werkt het perfect.
 
Ivo P

Ivo P

16/03/2022 22:06:31
Quote Anchor link
afgezien van validatie van wat er in de post-velden zit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
 $Prijs_bruto
= $_POST['Prijs_euro'] . '.' .  $_POST['Prijs_cent'];
?>


hier bouw je een string die er uit ziet als een decimaal getal.

Maar ik vind het logischer als je dat doet als

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
 $Prijs_bruto
= $_POST['Prijs_euro'] +  $_POST['Prijs_cent'] / 100;
?>



Maar zoals eerder al opgemerkt: het is wel verstandig om te controleren of die velden wel puur uit cijfers bestaan.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

16/03/2022 22:10:01
Quote Anchor link
>> De gebruiker is slechtziend en als deze dan in het veld een komma plaatst i.p.v. een punt, dan heb ik pas een probleem. En dit gebeurde regelmatig helaas. Vandaar dat ik het nu zo gescheiden doe. Nu werkt het perfect.

Ik dacht dat je het apart op ging slaan in de database. Heb ik niet goed gelezen :-)
 
Nanno Koerts

Nanno Koerts

16/03/2022 22:57:16
Quote Anchor link
Sinds ik de website heb gebouwd in 2008 gebruikte ik simpel een veld waarin handmatig het bedrag incl decimaal werd ingevoerd.
Aangezien ik de website aan het vernieuwen ben en ik fouten tegenkwam bij de invoer door de gebruiker, heb ik er nu voor gekozen dat ze nooit meer een fout karakter in kunnen voeren voor het optimaal gebruik van het systeem.
Nu is er enkel een kolom toeslag bijgekomen en die wil ik dus direct optellen en later deze apart optellen voor de boekhouder.
Mijn gehele website rekent al met decimalen en dat werkt al jaren prima. Ik liep enkel vast in het optellen met mijn script. Maar dat heb ik nu dus wel geleerd dankzij de reacties.

Ivo P op 16/03/2022 22:06:31:
afgezien van validatie van wat er in de post-velden zit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
 $Prijs_bruto
= $_POST['Prijs_euro'] . '.' .  $_POST['Prijs_cent'];
?>


hier bouw je een string die er uit ziet als een decimaal getal.

Maar ik vind het logischer als je dat doet als

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
 $Prijs_bruto
= $_POST['Prijs_euro'] +  $_POST['Prijs_cent'] / 100;
?>



Maar zoals eerder al opgemerkt: het is wel verstandig om te controleren of die velden wel puur uit cijfers bestaan.




Toevoeging op 17/03/2022 17:28:48:

Raar maar waar....

De optelling met de punt geeft in een echo het resultaat met een komma. Vandaar dat hij het niet weet te verwerken in de database.
Dit gaat even buiten mijn logica.

$Prijs_bruto = $_POST['Prijs_euro'] . '.' . $_POST['Prijs_cent']; = waarde 10.00
$Prijs_toeslag = $_POST['Toeslag_euro'] . '.' . $_POST['Toeslag_cent']; = waarde 2.50

$Prijs_netto = $Prijs_bruto + $Prijs_toeslag; = resultaat 12,5

Hoe kan dit nou?????
 
Adoptive Solution

Adoptive Solution

17/03/2022 19:10:05
Quote Anchor link
Probeer dit eens.

Ook zonder number format krijg ik een punt.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php

$_POST
['Prijs_euro'] = 10;
$_POST['Prijs_cent'] = 0;

$_POST['Toeslag_euro'] = 2;
$_POST['Toeslag_cent'] = 50;

$Prijs_bruto   = $_POST['Prijs_euro']   + $_POST['Prijs_cent'] / 100;
$Prijs_toeslag = $_POST['Toeslag_euro'] + $_POST['Toeslag_cent'] / 100;

$Prijs_netto = number_format( $Prijs_bruto + $Prijs_toeslag, 2, '.', '');

echo $_POST['Prijs_euro']   . '<br />';
echo $_POST['Prijs_cent']   . '<br />';
echo $_POST['Toeslag_euro'] . '<br />';
echo $_POST['Toeslag_cent'] . '<br />';

echo '========<br />';

echo $Prijs_bruto   . '<br />';
echo $Prijs_toeslag . '<br />';
echo $Prijs_netto   . '<br />';

?>
Gewijzigd op 17/03/2022 19:10:38 door Adoptive Solution
 
Nanno Koerts

Nanno Koerts

17/03/2022 19:29:20
Quote Anchor link
@adoptive

Ik had inmiddels het number format al gebruikt.
Maar waarom maakt de php server een komma van een punt??
Die logica snap ik gewoon niet.

Als ik nu alles eerst moet gaan delen, dan kan ik de rest van mijn systeem aan gaan passen omdat de waardes in mijn database dan niet kloppen. Het gebruik van number formaat lost nu mijn probleem wel op, maar begrijpen doe ik het niet.

Adoptive Solution op 17/03/2022 19:10:05:
Probeer dit eens.

Ook zonder number format krijg ik een punt.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php

$_POST
['Prijs_euro'] = 10;
$_POST['Prijs_cent'] = 0;

$_POST['Toeslag_euro'] = 2;
$_POST['Toeslag_cent'] = 50;

$Prijs_bruto   = $_POST['Prijs_euro']   + $_POST['Prijs_cent'] / 100;
$Prijs_toeslag = $_POST['Toeslag_euro'] + $_POST['Toeslag_cent'] / 100;

$Prijs_netto = number_format( $Prijs_bruto + $Prijs_toeslag, 2, '.', '');

echo $_POST['Prijs_euro']   . '<br />';
echo $_POST['Prijs_cent']   . '<br />';
echo $_POST['Toeslag_euro'] . '<br />';
echo $_POST['Toeslag_cent'] . '<br />';

echo '========<br />';

echo $Prijs_bruto   . '<br />';
echo $Prijs_toeslag . '<br />';
echo $Prijs_netto   . '<br />';

?>




Toevoeging op 17/03/2022 19:42:05:

@adoptive

Jouw code zonder number format geeft bij een decimaal getal een komma bij, in dit geval, de toeslag.
Kan het zijn dat dit met php versie 7 te maken heeft?
 
Adoptive Solution

Adoptive Solution

17/03/2022 19:54:04
Quote Anchor link
Je kan ook de losse getallen naar de database sturen en het daar laten formatteren.
Hier bijvoorbeeld met een UPDATE.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$query = "UPDATE table SET  Prijs_netto = FORMAT( " . $Prijs_bruto . " + " .  $Prijs_toeslag . ", 2)";
 
Nanno Koerts

Nanno Koerts

17/03/2022 20:30:56
Quote Anchor link
Thanks, aan deze hulp heb ik wat. Dit kende ik niet als mogelijkheid en ga die zeker in acht nemen in het proces.
Geldt dit dan hetzelfde als voor INSERT?

Adoptive Solution op 17/03/2022 19:54:04:
Je kan ook de losse getallen naar de database sturen en het daar laten formatteren.
Hier bijvoorbeeld met een UPDATE.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$query = "UPDATE table SET  Prijs_netto = FORMAT( " . $Prijs_bruto . " + " .  $Prijs_toeslag . ", 2)";
 
Ivo P

Ivo P

17/03/2022 20:50:35
Quote Anchor link
FORMAT is een functie die bedoeld is in combinatie met een SELECT-query.

Met deze functie kun je een veld formateren in bijvoorbeeld "eur 1.999,45"
Dat is vooral leuk als je de query niet in combi met PHP gebruikt. Bijvoorbeeld om een en ander direct naar een mail te copy-pasten.

Dat je nu format slechts gebruikt om hem op 2 decimalen af te ronden:
a) doe dat dan met ROUND() of FLOOR() cq. CEIL()
b) als je de kolom in je tabel definieert als een DECIMAL 10,2 bereik je hetzelfde.

En als je dan 10 + 2 met FORMAT tot 12.00 maakt en opslaat: met je SELECT query krijg je daarna gewoon 12 terug.
 
Adoptive Solution

Adoptive Solution

17/03/2022 22:04:18
Quote Anchor link
Klopt dat die format zo niet werkt.
Dan verzin ik wat anders.

Een Stored Function die je voedt met euros en centen.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
DELIMITER ;;

CREATE FUNCTION `sfSetPrijs`(`prijs_euro` int, `prijs_cent` int, `toeslag_euro` int, `toeslag_cent` int) RETURNS decimal(10,2)
BEGIN
SET @Prijs = prijs_euro + prijs_cent / 100;
SET @Toeslag = toeslag_euro + toeslag_cent / 100;
SET @Prijs_netto = 0;
SELECT FORMAT( @Prijs + @Toeslag, 2 ) INTO @Prijs_netto;
RETURN @Prijs_netto;
END;;

DELIMITER ;


Met PHP doe je dan deze query :

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

$Prijs_euro
= $_POST['Prijs_euro'];
$Prijs_cent = $_POST['Prijs_cent'];

$Toeslag_euro = $_POST['Toeslag_euro'];
$Toeslag_cent = $_POST['Toeslag_cent'];

$query = "UPDATE
    table
SET
    Prijs_netto =  sfSetPrijs("
.
    $Prijs_euro . ", " .
    $Prijs_cent . "," .
    $Toeslag_euro . ", " .
    $Toeslag_cent .
")
WHERE
    id = 2345;"
;

?>


Werkt ook met een INSERT.
 
Ad Fundum

Ad Fundum

18/03/2022 03:16:20
Quote Anchor link
Prachtig voorbeeld van SQL-injectie.

Ik vraag me sterk af of je wel een financieel programma moet willen maken zonder basiskennis van hoe computers met getallen omgaan? Als je dat programma serieus wilt inzetten kan je daar dure fouten mee maken. Zelfs Wikipedia heeft een artikel over zwevendekommagetallen als foutbron.

Computers verwerken zwevendekommagetallen volgens de IEEE 754 specificatie. PHP heeft de taal C als basis, en er bestaat niet zoiets als dat PHP iets kan met komma's in getallen. Die vermeende komma is ALTIJD een punt. Zo werken floats in PHP nu eenmaal.

Floats bestaan dus niet alleen in PHP, maar ook in de database, en ze zijn totaal ongeschikt voor het opslaan van, of rekenen met geld.

Je moet werken met exacte gegevenstypen zoals DECIMAL, en als je database ingesteld staat om getallen weer te geven met een komma in plaats van een punt, dan staat je database onhandig ingesteld en moet je dat eerst veranderen.

En wanneer je naar een gebruiker toe iets wilt met getallen, dan is het overwegen van het HTML-element 'input' het overwegen waard. Je kunt een <input> -tag maken met de attributen type="number", eventueel met step="0.01" voor de centen, min="" en max="" om te zorgen dat er geen negatieve bedragen worden ingevuld, en dat het niet hoger kan zijn dan je DECIMAL(10,2) in je database.
Gewijzigd op 18/03/2022 03:18:20 door Ad Fundum
 
Nanno Koerts

Nanno Koerts

18/03/2022 15:57:36
Quote Anchor link
Dank voor je reactie.

Ik heb geen invloed op de instellingen van de php server omdat ik deze niet zelf host.
De reden dat ik het nu juist allemaal aanpas is juist om fouten te voorkomen. Voorheen had ik enkel 1 veld waar het bedrag incl decimalen werd ingevuld en daar ging het nog wel eens fout. i.p.v. de punt werd de komma geplaatst.
En dan ben ik stom verbaasd dat een server de getallen 10.00 + 2.50 omzet naar 12,5. En als je hier een antwoord op kan geven, ben je mijn held.

Ik heb zeker mijn velden nu beveiligd met welke waardes er mogen worden ingevoerd, daar ligt het ook niet aan, wel aan de berekening door de server.
De getallen worden nu ook opgeslagen als DECIMAL in de database maar ben gewoon verbaasd dat dit pas werkt als ik het getal eerst weer een FORMAT moet geven voordat ik hem op de juiste wijze kan wegschrijven in de database.

Ik ben geen programmeur, ik ben een vormgever met beperkte kennis van PHP en deze website draait al vanaf 2008 en heeft nu drastisch verbeteringen nodig. Scripting was enorm verouderd en was nog gebaseerd op versie 4.
Het gaat hier om een systeem om kaarten voor een theater te reserveren, dus geen complex financieel gedoe. Er wordt ergens een waarde neergezet vanuit de database, er wordt een optelling gedaan en uiteindelijk een berekening van het aantal kaarten en het bedrag. Niet meer en niet minder.

Ad Fundum op 18/03/2022 03:16:20:
Prachtig voorbeeld van SQL-injectie.

Ik vraag me sterk af of je wel een financieel programma moet willen maken zonder basiskennis van hoe computers met getallen omgaan? Als je dat programma serieus wilt inzetten kan je daar dure fouten mee maken. Zelfs Wikipedia heeft een artikel over zwevendekommagetallen als foutbron.

Computers verwerken zwevendekommagetallen volgens de IEEE 754 specificatie. PHP heeft de taal C als basis, en er bestaat niet zoiets als dat PHP iets kan met komma's in getallen. Die vermeende komma is ALTIJD een punt. Zo werken floats in PHP nu eenmaal.

Floats bestaan dus niet alleen in PHP, maar ook in de database, en ze zijn totaal ongeschikt voor het opslaan van, of rekenen met geld.

Je moet werken met exacte gegevenstypen zoals DECIMAL, en als je database ingesteld staat om getallen weer te geven met een komma in plaats van een punt, dan staat je database onhandig ingesteld en moet je dat eerst veranderen.

En wanneer je naar een gebruiker toe iets wilt met getallen, dan is het overwegen van het HTML-element 'input' het overwegen waard. Je kunt een <input> -tag maken met de attributen type="number", eventueel met step="0.01" voor de centen, min="" en max="" om te zorgen dat er geen negatieve bedragen worden ingevuld, en dat het niet hoger kan zijn dan je DECIMAL(10,2) in je database.
 
- Ariën  -
Beheerder

- Ariën -

18/03/2022 16:01:09
Quote Anchor link
Nanno Koerts op 18/03/2022 15:57:36:
Dank voor je reactie.

Ik heb geen invloed op de instellingen van de php server omdat ik deze niet zelf host.


Opsich is er een hoop invloed uit te oefenen op standaard instellingen via flags in htaccess of php.ini settings. Op welke instellingen doel je op?
 
Ad Fundum

Ad Fundum

18/03/2022 21:53:51
Quote Anchor link
Nanno Koerts op 16/03/2022 15:46:15:
De gegevens komen dus vanaf een formulier en die data wil ik dan in het script al graag optellen en dan pas in de MySql database weg te schrijven.


Daar heb je het, je gebruikers voeren de cijfers in zoals zij het gewend zijn. Kan je opvangen door een str_replace(',', '.', $cijfer); en met de FORMAT()-functie in MySQL om de komma weer terug te krijgen. Let wel dat je niet in de script gaat rekenen met floats, maar met strings met bijvoorbeeld bcadd(). Of je laat het optellen aan de database, daar heb je hem voor.
 
Jan te Pas

Jan te Pas

22/03/2022 20:42:55
Quote Anchor link
Je zou de komma kunnen opvangen bij de input Regex, en dna met punt opslaan in de database. Bij het weergeven kun je het omgekeerde doen. Dus komma tonen als je een decimale punt hebt. Hierdoor sla je allen op een manier op in de database. En pas je presentatie alleen aan.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.