Maison  >  Article  >  développement back-end  >  Explication détaillée des opérations que les développeurs PHP commettent presque toujours des erreurs

Explication détaillée des opérations que les développeurs PHP commettent presque toujours des erreurs

黄舟
黄舟original
2018-05-29 10:27:561597parcourir

1. Préface

Récemment, j'ai rencontré des problèmes mineurs et inoffensifs dus au fait que PHP effectuait des opérations mathématiques.

Un remblai de mille kilomètres s'est effondré dans un nid de fourmis. L'ajout d'une conversion de type résout le problème si facilement, mais je ne pense pas que nous puissions simplement laisser tomber.

Utilisez notamment PHP pour faire des calculs financiers ou écrire des calculs d'interface et un docking en langage fortLes étudiants devraient y prêter plus d'attention.

Ce n'est pas grave, les détails déterminent le succès ou l'échec. Après une étude approfondie, il existe en effet de nombreuses façons de le faire, et j'ai aussi appris une leçon.

Savez-vous vraiment que php est un langage faiblement typé ?

Il y a quelque temps, j'ai mené des recherches sur le noyau PHP et j'avais une compréhension détaillée de la structure de stockage sous-jacente des variables PHP. Cependant, je n'ai pas compris le processus de fonctionnement des différents types de variables PHP. valeurs et le processus de transformation des types de variables.

En fait, c'est un problème avec notre PHP intelligent [conversion automatique de type]. C'est aussi la puissance de PHP en tant que langage faiblement typé , étudiez-le simplement complètement et faites un résumé.

(Il y a 5 exemples ci-dessous, tous sont des opérations très simples, mais vous ne pourrez peut-être pas en dire la raison)

2. Analyse des processus

Cas 1

Examinons d'abord les problèmes que j'ai rencontrés (simplifiés), qui est le déclencheur pour moi d'écrire ce blog.

  $a = '1.11';
  $b = '0.11';
  var_dump($a);//string(4) "1.11" 
  var_dump($b);//string(4) "0.11" 
  $re = $a - $b;
  var_dump($re);//float(1)

Remarque : Deux changements ont eu lieu.
1. Soustrayez les chaînes et transformez-les en types à virgule flottante
2. Les minutes sont toutes à deux décimales et le résultat n'est pas décimal [C'est également là que le bug se produit, car l'application nécessite deux décimales pour display】
De même, lors de la soustraction de chaînes sans nombres décimaux, le résultat est int

 $a = '11';
  $b = '1';
  var_dump($a);//string(4) "11" 
  var_dump($b);//string(4) "1" 
  $re = $a - $b;
  var_dump($re);//int(10)

Conclusion :
1. Opération en bas de PHP Pendant le processus, la conversion de type est automatiquement effectuée, les décimales sont converties en float et les entiers sont convertis en int.
2. Si vous devez limiter le nombre de décimales pour les nombres, pensez à y faire face. number_format();

a déjà commencé, parlons de cette conversion de type.

Exemple 2
Question : Ce qui suit est-il vrai ou faux ?

    var_dump(0123 == 123);  
    var_dump('0123' == 123);  
    var_dump('0123' === 123);

Quelle est la réponse ? ?
false;true;false
Analyse :
Je crois qu'il est facile pour tout le monde de deviner que le troisième est faux, car === est un jugement fort et ajoute une comparaison de types
Il y en a deux choses auxquelles il faut prêter attention ici. D'une part, la couche inférieure de PHP considérera les nombres entiers commençant par 0 comme étant octaux ; d'autre part, lors de la conversion de sting en int, le 0 initial sera supprimé
var_dump(0123 == 123); // faux, PHP le convertira par défaut. 0123 est traité comme octal, mais en réalité converti en décimal est 83. Évidemment, ce n'est pas égal.
var_dump('0123' == 123); // true ici php sera très intéressant pour convertir '0123' en nombre et supprimer le 0 précédent par défaut, qui est 123==123
var_dump(' 0123 ' === 123); // false De toute évidence, la question ci-dessus indique que les types de nombre et de chaîne sont incohérents.
Conclusion :
1. Les nombres entiers commençant par 0 seront traités par PHP comme octaux
2. Conclusion 1 du collègue exemple 1, les chaînes effectueront automatiquement une conversion de type pendant le fonctionnement, et le 0 initial sera supprimé


Exemple 3
Quel est le résultat de $x ci-dessous :

      $x = NULL;
      if ('0xFF' == 255) {
          $x = (int)'0xFF';
      }
      $x = ?

    答案是什么呢??
      $x=0而不是255
    注意点:
      首先'oxFF' == 255我们好判断,会进行转换将16进制数字转换成10进制数字,0xff = 255。PHP使用is_numeric_string 判断字符串是否包含十六进制数字然后进行转换。
      但是$x = (int)'0xFF';是否也会变成255呢?显然不是,将一个字符串进行强制类型转换实际上用的是convert_to_long,它实际上是将字符串从左向右进行转换,遇到非数字字符则停止。因此0xFF到x就停止了。所以$x=0
    结论:
      1.0开头的整形数字PHP会当作十六进制来处理
      2. string->int的过程,是将字符串从左向右进行转换,遇到非数字字符则停止。

事例四
  经过下面的运算 $x的值应该是多少?

  $x = 3 + "15%" + "$25"

  答案是什么呢?? 18
  注意点:其实就是前边的所提到的点。3+15+0=18(0时因为从左往右取数字嘛,遇到非数字停止,没有当然为0)
事例五(无关类型转换,但也很有意思)

 $a = true && false;
  var_dump($a);
  $a = true and false;
  var_dump($a);

  答案是什么呢??
    false;true

  为什么呢?是对运算符优先级的一个理解,哈哈,提醒到这里自己去查查吧~

事例六

  $arr = array(0,1,2,3);
  foreach ($arr as $key => $value) {}
  var_dump(current($arr));//最后指针停留在数组结尾,取不到值了输出false

  $arr = array(0,1,2,3);
  foreach ($arr as $key => $value) { 
  //$arr其实是进行了一次传值,用的是$arr_copy 
        $arr[$key] = $value;//进行了改值,则发生分离现象
  }
  var_dump(current($arr));//输出1

输出false 与 1;(PHP5.6环境下,php7已经做了修改);

那这个又是为什么呢?【和PHP内核有关,变量分离改变】

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn