[PHP] true =! 1

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • g4wx3
  • Registratie: April 2007
  • Laatst online: 11-09 09:49
hoe kan ik voorkomen dat php de boolean true omzet naar 1?
dit is een waarde die ik daarna in een database (MySQL) wil opslaan, en daarna hergebruiken in javascript.
Ook al werkt het overal hetzelfde, 1 gebruik ik als er meerdere waardes mogelijk zijn (2, 3, 4) en true gebruik ik als er slecht 2 mogelijkheden zijn.

true is een bolean, 1 is een numerike waarde, dus ik wil niet dat php dat omzet

http://www.softfocus.be/


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Je bent zeker een string af aan het drukken? Als je een boolean afdrukt, dan wordt het pas een 1. Je zal dus, wanneer $boolvar === true (ja, 3 = tekens) een andere string af moeten drukken die in je database "true" representeert. MySQL kent alleen voor zover ik weet geen true of false, alleen 1 en 0...

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

  • Marcj
  • Registratie: November 2000
  • Laatst online: 15:16
In PHP is een boolean gewoon een 1-bits waarde, welke dus 0 of 1 is. Dit kan ook gewoon in MySQL opgeslagen worden als een TINYINT bijvoorbeeld. Als je echt wil dat er "true" uit komt kun je het misschien ook opslaan als een ENUM("true", "false").

Dus dat omzetten kun je niet echt verhinderen, maar er is vast wel omheen te werken. Waar ligt het probleem nu precies?

Acties:
  • 0 Henk 'm!

  • kokx
  • Registratie: Augustus 2006
  • Laatst online: 13-09 20:30

kokx

WIN

Als ik een boolean afdruk, doe ik dat zo:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
function echoBool($bool, $echo = true)
{
    $bool = ($bool) ? 'true' : 'false';
    if ($echo) {
        echo $bool;
    }
    return $bool;
}
// dit gebruik je zo:
$bool = true;

echoBool($bool);
// dit zal 'true' naar de browser sturen

$boolString = echoBool($bool, false);
// de variabele $boolString kun je nu naar de database versturen


Dit kun je heel goed gebruiken in combinatie met ENUM('true','false).

[ Voor 40% gewijzigd door kokx op 10-07-2007 13:54 . Reden: meer uitleg gebruik functie ]


Acties:
  • 0 Henk 'm!

Verwijderd

Een ENUM("true", "false") levert gewoon een string af. Voor zover ik weet bestaat er geen boolean kolomtype voor MyISAM, de oplossing is dus gebruik maken van een TINYINT en er 0 of 1 in te zetten. Bij het opslaan cast je de boolean naar een integer en bij het ophalen terug naar een boolean. Ik zie de moeilijkheid hier niet...

Acties:
  • 0 Henk 'm!

Verwijderd

kokx schreef op dinsdag 10 juli 2007 @ 13:51:
Als ik een boolean afdruk, doe ik dat zo:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
function echoBool($bool, $echo = true)
{
    $bool = ($bool) ? 'true' : 'false';
    if ($echo) {
        echo $bool;
    }
    return $bool;
}
// dit gebruik je zo:
$bool = true;

echoBool($bool);
// dit zal 'true' naar de browser sturen

$boolString = echoBool($bool, false);
// de variabele $boolString kun je nu naar de database versturen


Dit kun je heel goed gebruiken in combinatie met ENUM('true','false).
Het is naar mijn mening erg vies om letterlijk de tekst true of false in de database op te slaan, deze bevat dan onnodig veel overhead. MySQL kent het type bool (gewoon 1 bit) die hiervoor veel geschikter is.

Acties:
  • 0 Henk 'm!

  • Marcj
  • Registratie: November 2000
  • Laatst online: 15:16
Verwijderd schreef op dinsdag 10 juli 2007 @ 14:32:
[...]


Het is naar mijn mening erg vies om letterlijk de tekst true of false in de database op te slaan, deze bevat dan onnodig veel overhead. MySQL kent het type bool (gewoon 1 bit) die hiervoor veel geschikter is.
Ik ben met je eens dat tekst opslaan wel lelijk is, maar het MySQL type BOOL is gewoon een synoniem voor the type TINYINT en is dus gewoon een 0 of 1. Persoonlijk geef ik dan de voorkeur aan het gebruik van een ENUM.

Acties:
  • 0 Henk 'm!

  • g4wx3
  • Registratie: April 2007
  • Laatst online: 11-09 09:49
Bedankt voor jullie wijze toelichtingen.

http://www.softfocus.be/


Acties:
  • 0 Henk 'm!

Verwijderd

Marcj schreef op dinsdag 10 juli 2007 @ 14:37:
[...]

Ik ben met je eens dat tekst opslaan wel lelijk is, maar het MySQL type BOOL is gewoon een synoniem voor the type TINYINT en is dus gewoon een 0 of 1. Persoonlijk geef ik dan de voorkeur aan het gebruik van een ENUM.
Zou je dat kunnen onderbouwen? In mijn ogen hoort een bool ook niet meer te zijn dan een 0 of een 1. Dat is juist de hele functie van een bool. Om ipv 1 bit het als complete string op te slaan geeft nogal wat overhead. 'False' heeft 5 letters, dat is 5 * 8 bits = 40 bits, oftewel 4000% overhead. Of ga ik nu ergens de mist in?

Acties:
  • 0 Henk 'm!

  • Marcj
  • Registratie: November 2000
  • Laatst online: 15:16
Een enum wordt intern natuurlijk niet opgeslagen als tekst, maar gewoon als nummer. De tekst die tot dat nummer behoort staat gewoon in de layout van de tabel. Maar bij de output krijg je daardoor wel netjes 'true' en 'false' te zien. Tenminste, zo hoort een enum te werken. Ik ken natuurlijk de implementatie van MySQL niet, maar ik ga er van uit dat deze gewoon als een nummer wordt ge-encodeerd. In het ergste geval wordt hij als INT opgeslagen intern, dus 4 bytes ipv 1...

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Verwijderd schreef op dinsdag 10 juli 2007 @ 15:02:
[...]


Zou je dat kunnen onderbouwen? In mijn ogen hoort een bool ook niet meer te zijn dan een 0 of een 1. Dat is juist de hele functie van een bool. Om ipv 1 bit het als complete string op te slaan geeft nogal wat overhead. 'False' heeft 5 letters, dat is 5 * 8 bits = 40 bits, oftewel 4000% overhead. Of ga ik nu ergens de mist in?
Een enum is intern gewoon als een integer opgeslagen. De enige overhead die je hebt zit dus in de headers van de tabel waarin staat dat de key 0 staat voor "false" en de key 1 voor "true". Wat dat betreft kost het je dus niet veel, in ruil voor een iets beter leesbaar stukje code. :)

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

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Voor de volledigheid: Een mysql enum veld is 16 bits. En dus kunnen max 65535 elementen in de enum definitie. :)

{signature}


Acties:
  • 0 Henk 'm!

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50

BikkelZ

CMD+Z

Volgens mij ben ik wel eens zwaar de mist in gegaan met die ENUM-grappen. Iets in de zin van true != 'true' of 1 != '1'. De TINYINT methode is heel erg clean vergeleken met alle andere opties buiten een echte boolean die dus niet bestaat. Een boolean is uiteindelijk niets anders dan een bit, die aan of uit staat - 1 of 0.

iOS developer


Acties:
  • 0 Henk 'm!

  • Marcj
  • Registratie: November 2000
  • Laatst online: 15:16
Nu ik mijn post teruglees: je hebt toch niet ENUM('true', 'false') gedaan? Want dan komt 'true' onder 0 te staan en 'false' onder 1 (toch?). Dat haalt natuurlijk alles wel een beetje onderuit. Maar als dit lastig is kun je ook bij je TINYINT blijven :)

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Voutloos schreef op dinsdag 10 juli 2007 @ 15:26:
Voor de volledigheid: Een mysql enum veld is 16 bits. En dus kunnen max 65535 elementen in de enum definitie. :)
8 bits in dit geval, omdat je niet meer dan 255 verschillende mogelijkheden hebt.

Acties:
  • 0 Henk 'm!

  • pjonk
  • Registratie: November 2000
  • Laatst online: 20-09 21:53
Het nadeel van een TINYINT veld is dat je database het niet afdwingt om slechts de 2 waarden 0 en 1 te kunnen opslaan, maar zoals GlowMouse kun je gewoon 255 waarden kwijt.
Een ENUM is voor dit probleem een oplossing, omdat je hiermee afdwingt om slechts 2 verschillende waarden te kunnen opslaan. Een ENUM kun je dan ook zien als een constraint.
In MS-SQL heb je een BIT datatype waarbij je alleen de waarde 0 en 1 kunt opslaan, helaas kent MySQL dit niet.

It’s nice to be important but it’s more important to be nice


Acties:
  • 0 Henk 'm!

  • dingstje
  • Registratie: Augustus 2002
  • Laatst online: 02-01-2024
Marcj schreef op dinsdag 10 juli 2007 @ 15:44:
Nu ik mijn post teruglees: je hebt toch niet ENUM('true', 'false') gedaan? Want dan komt 'true' onder 0 te staan en 'false' onder 1 (toch?). Dat haalt natuurlijk alles wel een beetje onderuit. Maar als dit lastig is kun je ook bij je TINYINT blijven :)
Dat hoort niet uit te maken. Als je een ENUM('true', 'false') definieert moet je gewoon 'true' en 'false' in je database zetten en niet prutsen met de index van die ENUM. MySQL kan dat evengoed opslaan als 54321 en 878946. Als je toch 1 en 0 wil gebruiken moet je ENUM('0', '1') (of omgekeerd, maakt niet uit) gebruiken.

If you can't beat them, try harder


Acties:
  • 0 Henk 'm!

Verwijderd

Door een ENUM te gebruiken zal je dus letterlijk "true" of "false" terug krijgen (strings dus), dan moet je nogmaals dit gaan converteren naar een boolean met een aangepaste functie (casten levert in beide gevallen true op).

Ik zie dus geen enkele reden of voordeel om het op zo'n manier te doen. Waarom moeilijk als het makkelijk kan?

Acties:
  • 0 Henk 'm!

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50

BikkelZ

CMD+Z

pjonk schreef op dinsdag 10 juli 2007 @ 16:51:
Het nadeel van een TINYINT veld is dat je database het niet afdwingt om slechts de 2 waarden 0 en 1 te kunnen opslaan, maar zoals GlowMouse kun je gewoon 255 waarden kwijt.
Een ENUM is voor dit probleem een oplossing, omdat je hiermee afdwingt om slechts 2 verschillende waarden te kunnen opslaan. Een ENUM kun je dan ook zien als een constraint.
In MS-SQL heb je een BIT datatype waarbij je alleen de waarde 0 en 1 kunt opslaan, helaas kent MySQL dit niet.
Zolang je een TINYINT (of liever onder het alias BOOLEAN) alleen booleans voert is er niks aan de hand. Sterker nog, als je een waarde groter dan 1 voert aan een echt BIT of BOOLEAN veld dan heb je nog steeds de kans dat het opgeslagen wordt als 1, dus je gaat alleen op een andere manier de boot in als je iets anders dan een echte boolean voert aan een kolom die je voor booleans gebruikt.

Een TINYINT staat technisch gezien pal naast een (echte) BOOLEAN, terwijl een ENUM een totaal andere manier van gegevens opslaan is.

[ Voor 6% gewijzigd door BikkelZ op 11-07-2007 15:18 ]

iOS developer


Acties:
  • 0 Henk 'm!

  • Gwaihir
  • Registratie: December 2002
  • Niet online
pjonk schreef op dinsdag 10 juli 2007 @ 16:51:
Het nadeel van een TINYINT veld is dat je database het niet afdwingt om slechts de 2 waarden 0 en 1 te kunnen opslaan, maar zoals GlowMouse kun je gewoon 255 waarden kwijt.
Maar wel met een duidelijk vastgelegde betekenis. Het MySQL manual zegt:
BOOL, BOOLEAN

These types are synonyms for TINYINT(1). A value of zero is considered false. Non-zero values are considered true
En met die typeconversie kun je zowel in MySQL als PHP overweg :)
Een ENUM is voor dit probleem een oplossing, omdat je hiermee afdwingt om slechts 2 verschillende waarden te kunnen opslaan. Een ENUM kun je dan ook zien als een constraint.
Alleen als MySQL in strict SQL mode draait (ergens in 5.0.x beschikbaar gekomen). Anders heb je via de error waarde onbedoeld "true, false, alle overige". Verder is voor deze error waarde altijd de index 0 gereserveerd. Dus wie z'n enum numeriek wil benaderen komt bedrogen uit, want "false, true" zal op 1 en 2 zitten. (Zie manual)

Om beide kun je in non-strict mode heen door de 0 / error als false te gebruiken, maar da's m.i. meer hacken dan programmeren..
In MS-SQL heb je een BIT datatype waarbij je alleen de waarde 0 en 1 kunt opslaan, helaas kent MySQL dit niet.
Sinds 5.0.3 (MyISAM, meer iets later) heeft MySQL ook een echt BIT(1) veldtype. Dat is wel echt één bit lang, dus als je echt zo 'afdwingend' wilt zijn lijkt me dat voorlopig het beste. Ik hoop dat MySQL hierop voortbouwt om de belofte van een echt BOOL veldtype in te lossen.

[ Voor 3% gewijzigd door Gwaihir op 13-07-2007 19:45 ]


Acties:
  • 0 Henk 'm!

  • funkwurm
  • Registratie: December 2005
  • Laatst online: 22-02-2021
Gwaihir schreef op vrijdag 13 juli 2007 @ 19:44:
[...]
En met die typeconversie kun je zowel in MySQL als PHP overweg :)
[...]
Maar het ging de topicstarter om javascript en die gaat daar (bij mijn weten) niet op dezelfde manier mee om.

Ik zeg als tinyint(1) in je database en bij het parsen naar de client javascript heel simpel:
PHP:
1
2
$i2b=array('false', 'true'); // staat voor Int-to-Bool, in case you're wondering
echo('document.write(\''.$i2b[$waardeUitDatabase].'\');');

Recht toe recht aan, geen if-jes of andere conditiontesting.

Acties:
  • 0 Henk 'm!

  • Icelus
  • Registratie: Januari 2004
  • Niet online
funkwurm schreef op zaterdag 14 juli 2007 @ 04:36:
[...]

Maar het ging de topicstarter om javascript en die gaat daar (bij mijn weten) niet op dezelfde manier mee om.

Ik zeg als tinyint(1) in je database en bij het parsen naar de client javascript heel simpel:
PHP:
1
2
$i2b=array('false', 'true'); // staat voor Int-to-Bool, in case you're wondering
echo('document.write(\''.$i2b[$waardeUitDatabase].'\');');

Recht toe recht aan, geen if-jes of andere conditiontesting.
Of je laat Javascript zelf de conversie doen:
PHP:
1
2
$x = 1;
echo 'document.write( Boolean('.$x.') )';

Developer Accused Of Unreadable Code Refuses To Comment

Pagina: 1