2013-08-21 15 views
5

Domyślnie mysqli zwraca wszystkie wartości jako łańcuchy, opcja MYSQLI_OPT_INT_AND_FLOAT_NATIVE pozwala na konwersję wartości int i float na odpowiednie typy. Chociaż nie wpływa to na pola dziesiętne.Pola dziesiętne MySQL zwracane jako łańcuchy w PHP

Czy istnieje sposób automatycznego przesyłania wszystkich pól dziesiętnych do typu float php bez ręcznego wywoływania $value = (float) $row->some_decimal_field?

Odpowiedz

1

Bardzo w to wątpię. Ułamki dziesiętne używają matematyki z punktami stałymi i nie ma w PHP typu danych, który mógłby to zapewnić. Floats są bliskie, ale w rzeczywistości są zaokrąglone, co oznacza, że ​​przypisanie wartości 2 float może spowodować 1.99999999999999999. Więc nawet jeśli MySQL oferuje sposób na umieszczenie przecinka dziesiętnego w float PHP, ryzykujesz utratę danych przez odlewanie z dziesiętnego na zmiennoprzecinkowe.

Aby obsłużyć to czysto, potrzebujesz czegoś takiego jak GMP, ale jak można się domyślić, MySQL nie może zapewnić tego automatycznie. Będziesz musiał to zrobić ręcznie w PHP.

0

Tutaj jest coś, co można zrobić z PHP, aby rozwiązać ten problem:

function string_to_float($foo){ 
    if($foo*1==$foo && !empty($foo)){ 
     return $foo*1; 
    } else { 
     return $foo; 
    } 
} 

string_to_float($row->some_decimal_field); 

Prawdziwe pytanie brzmi, Dlaczego trzeba konwertować typ łańcucha dziesiętnych? Jeśli próbujesz użyć go w matematyce, php automatycznie wykona konwersję za Ciebie. Jako ciąg dziesiętny jest równoważny float o tej samej wartości. Oto prosty test:

$foo = "1.2"; 
$bar = 1.2; 


if($foo===$bar){ 
    $equivalent = "is"; 
} else { 
    $equivalent = "is not"; 
} 

print '"1.2" '.$equivalent.' equal to 1.2 in type and value<br />'; 

if($foo==$bar){ 
    $equivalent = "is"; 
} else { 
    $equivalent = "is not"; 
} 

print '"1.2" '.$equivalent.' equal to 1.2 in value<br />'; 

$foo = "1.2"*1; 
$bar = 1.2; 

if($foo===$bar){ 
    $equivalent = "is"; 
} else { 
    $equivalent = "is not"; 
} 

print '"1.2"*1 '.$equivalent.' equal to 1.2 in type and value<br />'; 

który powróci:

"1.2" is not equal to 1.2 in type and value 
"1.2" is equal to 1.2 in value 
"1.2"*1 is equal to 1.2 in type and value 
+0

Byłbyś odlewy stały typ danych wskazują na zmiennoprzecinkowej typu danych, jeśli nie żadnej matematyki na ciąg przy użyciu normalnych operatorów. Otrzymasz dziwne wyniki lub dziwne przybliżenia liczb, jeśli nie używasz GMP, jak wspomniano powyżej. –

+0

Dobrze, może to nie jest właściwa odpowiedź, ale jest to odpowiedź, która może pomóc innym, którzy chcą zrobić to samo. – amaster