Comment convertir une chaîne en nombre en PHP?

671

Je veux convertir ces types de valeurs, '3', '2.34', '0.234343', etc. à un certain nombre. En JavaScript, nous pouvons utiliser Number(), mais existe-t-il une méthode similaire disponible en PHP?

Input             Output
'2'               2
'2.34'            2.34
'0.3454545'       0.3454545
Sara
la source
63
Attention lecteur: il n'y a pas de vraie réponse à cette question :(
Matthieu Napoli
@MatthieuNapoli La réponse est que généralement Php le comprend pour vous - l'un des avantages d'un système de type dynamique.
Kolob Canyon
12
Avec toutes les chaînes d'incertitude et «habituellement».
person27
2
@MatthieuNapoli En quoi le casting de caractères n'est-il pas une "vraie réponse"? Vous pouvez même vérifier le type après avoir transcrit le texte si vous voulez être un bébé à ce sujet
Kolob Canyon
3
@MatthieuNapoli Je suis heureux que vous ayez clarifié votre point de vue pour signifier qu'il y a plus d'une façon de dépouiller un chat, plutôt qu'il n'y a aucun moyen de le faire. Le cast est très important dans les opérations de base de données, par exemple. Par exemple, sur une requête PDO paramétrée, l'analyseur aura parfois du mal à réaliser qu'il s'agit d'un nombre et non d'une chaîne, puis vous vous retrouvez avec un 0 dans un champ entier parce que vous n'avez pas converti la chaîne en un entier dans l'étape de paramétrage.
stubsthewizard

Réponses:

1033

Vous n'avez généralement pas besoin de le faire, car PHP contraindra le type pour vous dans la plupart des circonstances. Pour les situations où vous ne voulez convertir explicitement le type, coulé il:

$num = "3.14";
$int = (int)$num;
$float = (float)$num;
décomposer
la source
4
ici, la situation est un peu différente, je veux convertir n'importe quelle chaîne (ne contient que des nombres) en un nombre général. Comme U le sait peut-être en javaScript, nous pouvons utiliser parseInt () pour convertir string => int ou parseFloat () pour convertir string => float. mais en général javaScript utilise Number () pour convertir chaîne => nombre. Je veux une méthode similaire en php?
Sara
4
Cela m'a été utile lorsque j'ai obtenu un numéro de mois à partir d'une chaîne de date complète, que j'ai utilisée pour extraire une valeur d'un tableau de noms de papillon. La conversion automatique ne se produit pas ici car les index de chaîne sont valides, mais pas équivalents.
Cazuma Nii Cavalcanti
19
Selon le contexte, il peut ne pas être sûr de supposer qu'il .s'agit du séparateur de virgule décimale. en.wikipedia.org/wiki/…
Dave Jarvis
3
@Sara: Vous pouvez également créer une fonction pour convertir la chaîne en nombre en la convertissant d'abord en entier, puis en flottant puis en comparant si les deux valeurs (entier et flottant) sont égales. Si tel est le cas, vous devez renvoyer la valeur sous forme d'entier, sinon, sous forme de flottant. J'espère que vous aurez l'idée.
Youstay Igo
2
Il y a des moments où vous devez passer l'entier au système de fichiers, ce n'est pas une bonne idée d'attendre que PHP fasse la conversion pour vous.
AaA
173

Il y a plusieurs façons de le faire:

  1. Convertissez les chaînes en types de données primitifs numériques:

    $num = (int) "10";
    $num = (double) "10.12"; // same as (float) "10.12";
  2. Effectuer des opérations mathématiques sur les chaînes:

    $num = "10" + 1;
    $num = floor("10.1");
  3. Utilisez intval()ou floatval():

    $num = intval("10");
    $num = floatval("10.1");
  4. Utilisez settype().

fardjad
la source
9
Notez que ce (double)n'est qu'un alias pour (float).
décomposer
4
@downvoter, je ne sais pas ce qui ne va pas avec ma réponse. Notez que j'ai posté ceci avant qu'OP n'édite sa question, mais cela couvre également la question éditée ( $num = "10" + 1exemple).
fardjad
2
@ ed-ta: assez sûr qu'il retournerait une valeur min / max au lieu de 0 si vous lui passez des chaînes. C'est à dire intval("9999999999")==2147483647.
riv
6
intvalest utile car vous pouvez alors l'utiliser dans array_map('intval', $arrayOfStrings);lequel vous ne pouvez pas faire de casting.
icc97
2
au lieu de $num = "10" + 1;c'est mieux à utiliser $num = "10" * 1;car cela ne changera pas la valeur (élément neutre de multiplication), c'est essentiellement quelque chose comme toNumber(..)puisque le type final sera déterminé par ce qui est nécessaire pour convertir la chaîne "10" -> (int) 10; "10.1" -> (float) 10.1;
Holly
57

Pour éviter les problèmes, essayez intval($var). Quelques exemples:

<?php
echo intval(42);                      // 42
echo intval(4.2);                     // 4
echo intval('42');                    // 42
echo intval('+42');                   // 42
echo intval('-42');                   // -42
echo intval(042);                     // 34 (octal as starts with zero)
echo intval('042');                   // 42
echo intval(1e10);                    // 1410065408
echo intval('1e10');                  // 1
echo intval(0x1A);                    // 26 (hex as starts with 0x)
echo intval(42000000);                // 42000000
echo intval(420000000000000000000);   // 0
echo intval('420000000000000000000'); // 2147483647
echo intval(42, 8);                   // 42
echo intval('42', 8);                 // 34
echo intval(array());                 // 0
echo intval(array('foo', 'bar'));     // 1
?>
gopeca
la source
4
À mon humble avis, c'est la seule bonne réponse parce que c'est la seule qui prend en compte le radix de la chaîne numérique. Toutes les réponses (même celles suggérant une fonction définie par l'utilisateur) qui utilisent simplement un transtypage de type échoueront si la chaîne numérique a un ou plusieurs zéros de tête, et la chaîne n'est PAS conçue comme un nombre avec une base octale.
Syntax Junkie
une idée si je veux convertir "12.7896" en 12.7896?
Agnes Palit
utilisez floatval () pour convertir une chaîne en float. floatval ("12.7896") sera de retour le 12.7896
gopeca
Pourquoi n'est-ce pas la réponse acceptée? En tant qu'outsider PHP, je savais déjà que (int)$my_strcela ne fonctionnerait pas car je m'occupais spécifiquement des chaînes de caractères 01et 013que je voulais interpréter comme base 10 ... Je voulais donc un moyen de fournir explicitement la base.
Giacomo Alzetta
48

Dans n'importe quelle langue (typiquement lâche), vous pouvez toujours convertir une chaîne en un nombre en y ajoutant un zéro.

Cependant, cela n'a pas beaucoup de sens car PHP le fera automatiquement au moment de l'utilisation de cette variable, et il sera de toute façon converti en chaîne au moment de la sortie.

Notez que vous souhaiterez peut-être conserver les nombres en pointillés sous forme de chaînes, car après la conversion en flottant, il peut être modifié de manière imprévisible, en raison de la nature des nombres flottants.

Votre bon sens
la source
35
Il existe de nombreuses langues où vous ne pouvez pas convertir une chaîne en nombre en ajoutant un zéro, c'est généralement considéré comme une erreur plutôt qu'une méthode valide de conversion :).
Jan Špaček
4
honzasp a raison, par exemple dans JavaScript typeof('123'+0)donne 'string', car '123'+0donne '1230'.
Oriol
5
Remarque: en PHP, il est recommandé d'utiliser la plupart du temps des comparaisons de style ===. Donc, si vous comparez vos données, il peut être très important de savoir dans quel type elles sont stockées.
Jonathon
Notez qu'en ajoutant un zéro, vous n'êtes pas en train de «lancer» dans le vrai sens, vous convertissez essentiellement.
CSᵠ
12
@oriol en javascript, vous devez ajouter le nombre à zéro 0+'123'pour obtenir123
Timo Huovinen
24

Vous pouvez utiliser:

(int)(your value);

Ou vous pouvez utiliser:

intval(string)
noobie-php
la source
que se passe-t-il si le numéro entré est '2.3456' comment puis-je obtenir 2.3456?
Sara
6
la question concerne également les flotteurs.
taseenb
Montrez-moi 1 ligne de OP où il est dit float? avant de passer les commentaires et les votes négatifs, regardez le message d'origine.
noobie-php
2
L'exemple montre des flottants, il demande comment convertir des chaînes numériques en valeurs numériques (flottants et entiers)
taseenb
Vérifiez d'abord si le nombre est un flottant avec is_float, et si cela passe, transformez en avec (float)au lieu de (int).
Martin van Driel
24

Si vous voulez obtenir un flottant pour $value = '0.4', mais int pour $value = '4', vous pouvez écrire:

$number = ($value == (int) $value) ? (int) $value : (float) $value;

C'est un peu sale, mais ça marche.

Aleksei Akireikin
la source
3
Peut-être moins sale? strpos($val, '.') === false ? intval($val) : floatval($val);
jchook
4
@jchook Peut-être plus sale car il dépend des paramètres régionaux - par exemple '0,4' au lieu de '0,4'.
Nick Rice
Bon point. Je suppose que vous pourriez utiliser à la localeconv()['decimal_point']place de '.'. Un avantage de la strpossolution est qu'elle est presque 2x plus rapide que de lancer deux fois.
jchook
2
@jchook qui se casse sur des cas comme 2.1e2, il a un point décimal, mais le nombre résultant est un entier
Tomáš Blatný
1
Utilisez simplement l' +opérateur d'identité:, var_dump(+'0.4', +'4')vous donne un flottant et un int. php.net/manual/en/language.operators.arithmetic.php
tvanc
15

Vous pouvez toujours y ajouter zéro!

Input             Output
'2' + 0           2 (int)
'2.34' + 0        2.34 (float)
'0.3454545' + 0   0.3454545 (float)
Boykodev
la source
J'ai eu cette erreur A non well formed numeric value encountered. une idée?
Agnes Palit
15

Au lieu d'avoir à choisir de convertir le stringen intou float, vous pouvez simplement y ajouter un 0, et PHP convertira automatiquement le résultat en type numérique.

// Being sure the string is actually a number
if (is_numeric($string))
    $number = $string + 0;
else // Let the number be 0 if the string is not a number
    $number = 0;
webNeat
la source
13

En PHP, vous pouvez utiliser des intval(string) or floatval(string)fonctions pour convertir des chaînes en nombres.

Kashif Khan
la source
4
non je veux une méthode commune. ce qui signifie que si son '5' => il doit se convertir en 5 et si son '2.345' => il doit se convertir en 2.345.
Sara
13

Oui, il existe une méthode similaire en PHP, mais elle est si peu connue que vous en entendrez rarement parler. Il s'agit d'un opérateur arithmétique appelé " identité ", comme décrit ici:

Opérateurs aritmétiques

Pour convertir une chaîne numérique en nombre, procédez comme suit:

$a = +$a;
aldemarcalazans
la source
Attention: piratage détecté.
Greg
Salut greg. Avez-vous cliqué sur le lien affiché ici? Voici ce que les développeurs ont dit à propos de cet opérateur: Conversion de $ a en int ou float selon le cas. La «conversion», ici, ne peut pas être comprise comme une conversion de numéro à numéro. Pourquoi? Parce que d'un point de vue arithmétique exclusif, cet opérateur est absolument inutile! Multiplier n'importe quel nombre par "+1" (l'équivalent de la fonction d'identité) n'a absolument aucun effet sur lui. Par conséquent, je ne peux pas imaginer d'autre utilité pour cet opérateur que la conversion de type suggérée ici.
aldemarcalazans
@Greg - c'est sûrement moins un hack que la plupart des autres réponses. C'est un opérateur intégré, qui fait exactement ce qui était demandé. (Bien qu'il soit probablement préférable de vérifier d'abord is_numeric, ayez donc un endroit pour mettre du code pour gérer les chaînes qui ne peuvent pas être converties correctement.)
ToolmakerSteve
Je comprends que cela fonctionne parfaitement d'utiliser un opérateur arithmétique pour le casting, mais c'est vraiment facile à manquer. Je pense que ça vaut un avertissement.
Greg
11

Juste une petite note aux réponses qui peuvent être utiles et plus sûres dans certains cas. Vous voudrez peut-être vérifier si la chaîne contient réellement une valeur numérique valide en premier et ensuite la convertir en un type numérique (par exemple si vous devez manipuler des données provenant d'une base de données qui convertit les entiers en chaînes). Vous pouvez utiliser is_numeric()puis floatval():

$a = "whatever"; // any variable

if (is_numeric($a)) 
    var_dump(floatval($a)); // type is float
else 
    var_dump($a); // any type
taseenb
la source
9

Voici la fonction qui permet d'atteindre ce que vous recherchez. Nous vérifions d'abord si la valeur peut être comprise comme un nombre, si c'est le cas, nous la transformons en int et en float. Si int et float sont identiques (par exemple, 5 == 5.0), nous renvoyons la valeur int. Si int et float ne sont pas identiques (par exemple, 5! = 5.3), nous supposons que vous avez besoin de la précision du float et renvoyez cette valeur. Si la valeur n'est pas numérique, nous lançons un avertissement et retournons null.

function toNumber($val) {
    if (is_numeric($val)) {
        $int = (int)$val;
        $float = (float)$val;

        $val = ($int == $float) ? $int : $float;
        return $val;
    } else {
        trigger_error("Cannot cast $val to a number", E_USER_WARNING);
        return null;
    }
}
CogSciGradStudent
la source
6

J'ai trouvé qu'en JavaScript, un moyen simple de convertir une chaîne en nombre est de la multiplier par 1. Cela résout le problème de concaténation, car le symbole "+" a plusieurs utilisations en JavaScript, tandis que le symbole "*" est purement pour la multiplication mathématique.

Sur la base de ce que j'ai vu ici concernant PHP étant automatiquement disposé à interpréter une chaîne contenant des chiffres comme un nombre (et les commentaires sur l'ajout, car en PHP le "+" est purement pour l'addition mathématique), cette astuce de multiplication fonctionne très bien pour PHP, également.

Je l'ai testé et cela fonctionne ... Bien que selon la façon dont vous avez acquis la chaîne, vous souhaitiez peut-être lui appliquer la fonction trim (), avant de multiplier par 1.

vernonner3voltazim
la source
6

Voici une fonction que j'ai écrite pour me simplifier les choses:

Il renvoie également des versions abrégées de booléen, entier, double et réel.

function type($mixed, $parseNumeric = false)
{        
    if ($parseNumeric && is_numeric($mixed)) {
        //Set type to relevant numeric format
        $mixed += 0;
    }
    $t = gettype($mixed);
    switch($t) {
        case 'boolean': return 'bool'; //shorthand
        case 'integer': return 'int';  //shorthand
        case 'double': case 'real': return 'float'; //equivalent for all intents and purposes
        default: return $t;
    }
}

L'appel de type avec parseNumeric défini sur true convertira les chaînes numériques avant de vérifier le type.

Donc:

type ("5", true) renverra int

type ("3.7", true) renverra float

type ("500") renverra une chaîne

Faites juste attention car c'est une sorte de méthode de fausse vérification et votre variable réelle sera toujours une chaîne. Vous devrez convertir la variable réelle au type correct si nécessaire. J'en avais juste besoin pour vérifier si la base de données doit charger un identifiant ou un alias d'élément, n'ayant donc aucun effet inattendu car il sera de toute façon analysé en tant que chaîne au moment de l'exécution.

Éditer

Si vous souhaitez détecter si les objets sont des fonctions, ajoutez ce cas au commutateur:

case 'object': return is_callable($mixed)?'function':'object';
Dieter Gribnitz
la source
6

En plus de la réponse de Boykodev, je suggère ceci:

Input             Output
'2' * 1           2 (int)
'2.34' * 1        2.34 (float)
'0.3454545' * 1   0.3454545 (float)
drugan
la source
Après y avoir réfléchi un peu, je peux également suggérer une division par 1 :)
Boykodev
1
C'est un point! :) Au fait, votre solution est bien meilleure que toutes les notations scientifiques ci-dessus. Je vous remercie.
drugan
cette solution a résolu mon problème. Dans mon cas, $id_cron = (string)date('YmdHi'); $target_id_cron = $id_cron - 1;au lieu de $ target_id_cron = (int) $ id_cron - 1;
inMILD
1
J'ai eu cette erreur A non well formed numeric value encounteredquand je veux changer la chaîne en float $num = '12,24' * 1. Toute suggestion?
Agnes Palit
5
$a = "10";

$b = (int)$a;

Vous pouvez l'utiliser pour convertir une chaîne en entier en PHP .

Pritom
la source
2
si le nombre entré est '7.2345' je ne peux pas utiliser (int) alors je dois utiliser (float). Ce dont j'ai besoin, c'est d'une solution générale.
Sara
1
Vous pouvez toujours utiliser double ou float.
Pritom
5

Vous pouvez simplement écrire comme ceci:

<?php
    $data = ["1","2","3","4","5"];
    echo json_encode($data, JSON_NUMERIC_CHECK);
?>
Dominic Amal Joe F
la source
3
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire concernant pourquoi et / ou comment ce code répond à la question améliore sa valeur à long terme.
Alex Riabov
1
Es-tu sûr de ça? Cela ne convertira pas une chaîne en nombre, mais un tableau en chaîne JSON
Nico Haase
Oui, @NicoHaase si le nombre est au format chaîne dans un tableau, il sera converti en nombre.
Dominic Amal Joe F
5

Multipliez uniquement le nombre par 1 pour que la chaîne soit convertie en type nombre.

//String value
$string = "5.1"
if(is_numeric($string)){
  $numeric_string = $string*1;
}
rolodef
la source
Assez juste, mais cette méthode (et des astuces similaires) sont déjà répertoriées dans les 24 autres réponses à cette question - je ne vois pas la valeur de la poster à nouveau.
DavidW
4

Vous pouvez utiliser:

((int) $var)   ( but in big number it return 2147483647 :-) )

Mais la meilleure solution est d'utiliser:

if (is_numeric($var))
    $var = (isset($var)) ? $var : 0;
else
    $var = 0;

Ou

if (is_numeric($var))
    $var = (trim($var) == '') ? 0 : $var;
else
    $var = 0;
Mehdi Ajdari
la source
2

Vous pouvez modifier le type de données comme suit

$number = "1.234";

echo gettype ($number) . "\n"; //Returns string

settype($number , "float");

echo gettype ($number) . "\n"; //Returns float

Pour des raisons historiques, "double" est retourné en cas de flottement.

Documentation PHP

David Lozano
la source
2

Toutes les suggestions perdent le type numérique.

Cela me semble une meilleure pratique:

function str2num($s){
// Returns a num or FALSE
    $return_value =  !is_numeric($s) ? false :               (intval($s)==floatval($s)) ? intval($s) :floatval($s);
    print "\nret=$return_value type=".gettype($return_value)."\n";
}
Rocco Galasso
la source
1

PHP le fera pour vous dans certaines limites

<?php
   $str = "3.148";
   $num = $str;

   printf("%f\n", $num);
?>
Adrian Cornish
la source
Je ne veux pas l'éteindre. Je veux le convertir et l'enregistrer dans une variable.
Sara
1
Cela l'a converti automatiquement en un flotteur. La conversion de type lâche de PHP le fait pour vous. Bien qu'il ne puisse pas faire ce que vous attendez, les autres réponses avec conversion explicite peuvent mieux fonctionner pour vous.
Adrian Cornish
$ str peut contenir '5' ou '5.258' en utilisant printf ("% f \ n", $ str) '5' sera mis à 5,000000 (je le veux comme 5) pour 5.280000 (je le veux comme 5.28) qu'il contient plusieurs décimales.
Sara
1

Il y a un moyen:

$value = json_decode(json_encode($value, JSON_NUMERIC_CHECK|JSON_PRESERVE_ZERO_FRACTION|JSON_UNESCAPED_SLASHES), true);

L' utilisation is_*ne fonctionnera pas, car le variableest un: string.

En utilisant la combinaison de json_encode()puis json_decode()il est converti en sa forme "vraie". Si c'est un vrai, stringcela donnerait un mauvais résultat.

$num = "Me";
$int = (int)$num;
$float = (float)$num;

var_dump($num, $int, $float);

Sortira: string(2) "Me" int(0) float(0)

Anuga
la source
0

J'ai eu la question "disons que vous écriviez la fonction intégrée pour convertir un entier en une chaîne en PHP, comment écririez-vous cette fonction" dans une interview de programmation. Voici une solution.

$nums = ["0","1","2","3","4","5","6","7","8","9"];
$int = 15939; 
$string = ""; 
while ($int) { 
    $string .= $nums[$int % 10]; 
    $int = (int)($int / 10); 
} 
$result = strrev($string);
Brendan
la source
0

J'ai lu les réponses et je n'ai vu personne mentionner la plus grande mise en garde dans la conversion des nombres PHP.

La réponse la plus votée suggère de faire ce qui suit:

$str = "3.14"
$intstr = (int)$str // now it's a number equal to 3

C'est brillant. PHP fait du casting direct. Et si nous faisions ce qui suit?

$str = "3.14is_trash"
$intstr = (int)$str

PHP considère-t-il que ces conversions sont valides?

Apparemment oui .

PHP lit la chaîne jusqu'à ce qu'il trouve le premier caractère non numérique du type requis. Cela signifie que pour les entiers, les caractères numériques sont [0-9]. En conséquence, il lit 3, puisqu'il est dans la plage de caractères [0-9], il continue la lecture. Lit .et s'arrête là car il n'est pas dans la plage [0-9].

La même chose se produirait si vous deviez lancer pour flotter ou doubler. PHP lirait 3, puis ., puis 1, puis 4s'arrêterait icar ce n'est pas un caractère numérique flottant valide.

Par conséquent, "million" >= 1000000évalue à faux, mais "1000000million" >= 1000000évalue à true.

Voir également:

https://www.php.net/manual/en/language.operators.comparison.php comment les conversions sont effectuées lors de la comparaison

https://www.php.net/manual/en/language.types.string.php#language.types.string.conversion comment les chaînes sont converties en nombres respectifs

Dragas
la source
0

Si vous ne savez pas à l'avance si vous avez un flottant ou un entier,
et si la chaîne peut contenir des caractères spéciaux (comme l'espace, €, etc.),
et si elle peut contenir plus d'un point ou une virgule,
vous pouvez utiliser ceci une fonction:

// This function strip spaces and other characters from a string and return a number.
// It works for integer and float.
// It expect decimal delimiter to be either a '.' or ','
// Note: everything after an eventual 2nd decimal delimiter will be removed.
function stringToNumber($string) {
    // return 0 if the string contains no number at all or is not a string:
    if (!is_string($string) || !preg_match('/\d/', $string)) {
        return 0;
    } 

    // Replace all ',' with '.':
    $workingString = str_replace(',', '.', $string);

    // Keep only number and '.':
    $workingString = preg_replace("/[^0-9.]+/", "", $workingString);

    // Split the integer part and the decimal part,
    // (and eventually a third part if there are more 
    //     than 1 decimal delimiter in the string):
    $explodedString = explode('.', $workingString, 3);

    if ($explodedString[0] === '') {
        // No number was present before the first decimal delimiter, 
        // so we assume it was meant to be a 0:
        $explodedString[0] = '0';
    } 

    if (sizeof($explodedString) === 1) {
        // No decimal delimiter was present in the string,
        // create a string representing an integer:
        $workingString = $explodedString[0];
    } else {
        // A decimal delimiter was present,
        // create a string representing a float:
        $workingString = $explodedString[0] . '.' .  $explodedString[1];
    }

    // Create a number from this now non-ambiguous string:
    $number = $workingString * 1;

    return $number;
}
user1657853
la source
-8

Une approche différente:

  1. Poussez le tout dans un tableau / tableau associatif.
  2. json_encode($your_array, JSON_NUMERIC_CHECK); éventuellement le décoder
  3. ?
  4. Profit!
Peter Mortensen
la source
7
Stack Overflow concerne les réponses aux questions, pas les blagues. Je suis sûr qu'il y a un endroit pour ça, mais cet endroit n'est pas ça.