Compétences PHP : comment éviter intelligemment certains mauvais codes dans les programmes PHP

无忌哥哥
Libérer: 2023-04-03 06:54:01
original
1546 Les gens l'ont consulté

Cet article explique avec vous comment trouver un mauvais code dans un exemple de code PHP et comment résoudre le problème. Les amis intéressés peuvent s'y référer.

Je fais du développement PHP depuis près d'un an. Au cours de cette année, j'ai appris beaucoup de techniques dans l'environnement de production et j'ai appris beaucoup de choses. Durant cette période, j'ai également lu d'excellents codes sources et. informations sur Code book, j'ai quelques réflexions sur l'écriture de code et j'ai vu beaucoup de bons et de mauvais codes écrits par d'autres. Permettez-moi de parler ici de mes propres idées et améliorations.

Ce blog exprime mes propres sentiments. Lors de l'écriture du code, je me fixe des règles, qui peuvent rendre le code clair et lisible et éviter les pièges. Bien que ces règles simples ne semblent pas aussi intéressantes que les modèles de conception, avec une attention régulière, elles peuvent rendre votre code plus propre.

1. N'utilisez pas de variables non déclarées en dehors de l'objet

Ce problème peut ne pas être facile à comprendre lorsqu'il est exprimé. Ce problème est déterminé par les caractéristiques du langage PHP lui-même. Étant donné que PHP est un langage de script dynamique faiblement typé, dans de nombreux cas, ce langage est soumis à des conditions très souples permettant aux développeurs d'écrire du code. Mais souvent, ces commodités peuvent aussi se transformer en pièges, vous devez donc prêter une attention particulière lorsque vous utilisez certaines méthodes d’écriture pratiques dans des langages dynamiques.

Déclarons d'abord une classe. Appelons cette classe la classe utilisateur. L'arrière-plan de cette classe User est défini pour être fourni avec le framework et ne peut pas être modifié. pas facile à trouver. En fait, pour le cas, veuillez vous référer à la classe Request du framework laravel. Le code est le suivant :

class User {
  public $username;
  public $password;
  
  public $otherInfo = [];
  
  
  public function readUserInfo() {
    return [
      'username' => $this->username,
      'password' => $this->password,
    ];
  }
  
  public function addAtri($info) {
    array_push($this->otherInfo, $info);
  }
}
Copier après la connexion

. Un tel code semble tout à fait satisfaisant, mais nous devons ensuite faire cette opération de classe :

$user = new User();
$user->userRealName = "hello world";
Copier après la connexion

Un tel code peut être exécuté entièrement en PHP et sera ne signale pas d'erreur, mais un tel code affectera certaines choses plus tard comme des interférences. Nous supposons maintenant que le code ci-dessus est un intercepteur dans le projet Web PHP, ou qu'il peut être appelé middleware. Ensuite, nous utiliserons l'instance de cette classe dans le contrôleur et utiliserons la variable ajoutée dans le middleware, comme suit : <🎜. >

 class WebOperate {
   public function doOprate(User $user) {
     $user->userRealName = "hello world";
     next($user);
   }
 }
Copier après la connexion

Le scénario défini ici est que WebOperate est un middleware, et tous les contrôleurs utiliseront ce middleware pour atteindre le contrôleur, après avoir traité la fonction du contrôleur correspondante, Ensuite, le contrôleur injectera l'instance de middleware que le contrôleur devra utiliser, et le développeur de middleware ne se soucie pas beaucoup de son existence :

 class IndexController {
   public function index(User $user) {
     return $user->userRealName;
   }
 }
Copier après la connexion

Et tel le code peut fonctionner parfaitement. Ensuite, le développeur souhaite implémenter une autre classe User et ajouter d'autres fonctions à cette classe User. Comme mentionné précédemment, cette classe est profondément ancrée dans le framework et difficile à trouver, et ne permet pas de modification, car autre. les fonctions utilisent cette classe, nous ne pouvons donc qu'hériter et ajouter des méthodes. Selon l'expérience de développement, les développeurs penseront que la variable userRealName existe dans la classe User, voici donc la méthode d'écriture :

Tout d'abord, la classe Teacher dérivée en fonction de cet utilisateur :

 class Teacher extends User {
   public function sayHello() {
     return "hello world";
   }
 }
Copier après la connexion

De cette façon, notre professeur peut nous dire bonjour, mais pour le moment, nous voulons toujours connaître le vrai nom du professeur dans notre contrôleur, que devons-nous faire ? Sur la base de l'expérience, nous pouvons changer la classe injectée en Professeur et renvoyer le vrai nom :

 class IndexController {
   public function index(Teacher $user) {
     return $user->userRealName;
   }
 }
Copier après la connexion

Alors voici le problème. En fait, il y a. non Il n'existe pas de classe de ce type, donc cette variable n'a aucune valeur, mais selon l'expérience, le middleware s'est vu attribuer une valeur une fois, nous devrions donc pouvoir l'utiliser directement, mais une telle valeur n'existe pas. Regardez le code source et constatez qu'il n'y a aucune valeur dans la classe User héritée. Cette variable existe, alors pourquoi cette variable peut-elle être utilisée auparavant Parce que dans le middleware, la force de l'utilisateur est payée.

On ne peut donc pas utiliser de variables non déclarées directement dans une classe.

Nous devrions écrire comme ceci :

class WebOperate {
  public function doOprate(User $user) {
    $user->addAtri([
      &#39;userRealName&#39; => &#39;hello world&#39;,
    ]);
    next($user);
  }
}
Copier après la connexion

Pour un middleware comme celui-ci, les classes héritées peuvent également utiliser la même méthode lors de l'appel, Très simple et moins sujet au mauvais goût.

2. Classe ou tableau

En fait, ce problème dérive également d'un autre problème, qui est le problème de la valeur de retour de la fonction.

Tout d'abord, je précise que je pense personnellement qu'il n'est pas bon qu'une fonction renvoie plusieurs types de valeurs. Bien que cela soit très courant dans les langages dynamiques, de nombreuses méthodes natives de PHP l'ont également. , mais dans L'utilisation de cette méthode en production entraînera une incertitude dans les retours de fonctions. Nous devons faire de nombreux jugements pour prouver nos conclusions. Cependant, s'il n'y a qu'un seul type de valeur de retour, nous pouvons juger directement la valeur de retour.

ressemble au code suivant :

public function addNewUser() {
    $res = $this->addData();
    if ($res) {
      return true;
    } else {
      return [
        &#39;error&#39; => 1,
        &#39;errormsg&#39; => "没有添加成功"
      ];
    }
  }
Copier après la connexion

Un tel code sera souvent jugé une fois de plus par l'appelant, comme suit :

public function index() {
    $res = $this->addNewUser();
    if (is_array($res) && isset($res[&#39;error&#39;])) {
      return isset($res[&#39;errormsg&#39;]) ? $res[&#39;errormsg&#39;] : "未知错误";
    }
    return "成功";
  }
Copier après la connexion

Un code comme celui-ci apparaîtra presque à chaque fois que cette fonction est appelée. Non seulement le code est inesthétique, mais il est également très volumineux.

Un code comme celui-ci doit être amélioré. Tout d'abord, limitez la valeur de retour de la fonction. Par exemple, nous laissons cette fonction renvoyer uniquement des nombres de type booléen :

public function addNewUser() {
  $res = $this->addData();
  if ($res) {
    return true;
  } else {
    return false;
  }
}
Copier après la connexion

但是,显然,很多时候,我们要的不是简单的真价值,所以,我们会选择返回更多信息,这个时候,我们可以有三种处理方式。

1)返回int类型的数,然后通过这个int类型的数去判断处理结果,我们可以添加上映射关系:

class Operate{
  public $operateRes = [
    0 => &#39;成功&#39;,
    1 => &#39;添加失败&#39;,
    2 => &#39;未知错误&#39;,
  ];
  
  
  public function addNewUser() {
    $res = $this->addData();
    if ($res) {
      return 0;
    } else if ($res > 1) {
      return 1;
    }
    return 2;
  }
  
}
Copier après la connexion

这样方法的调用者就可以很简单的使用方法并给出提示了:

$opera = new Operate();
$res = $opera->addNewUser();
return $opera->operateRes[$res];
Copier après la connexion

给出统一的返回值类型的时候就完全不需要判断返回值类型而且可以设置一个规范返回提示。

2)我们也可以使用数组

3)数组给人不缺定性,因为很多时候,数组里可以认为的少写一些元素,如果少写了,程序直接报错,很不好。

所以第三种方式就是建议将固定格式的返回,写成一个类,做返回的时候,使用这个类:

class Operate{
  public function addNewUser() {
    $res = $this->addData();
    $result = new Result();
    if ($res) {
      $result->errno = 0;
      $result->errmsg = "成功";
    } else if ($res > 1) {
      $result->errno = 1;
      $result->errmsg = "失败";
    }
    $result->errno = 2;
    $result->errmsg = "未知错误";
    return $result;
  }
  
}

class Result {
  public $errno;
  public $errmsg;
}
Copier après la connexion

这样的返回,保证了所有变量的存在,同样可以减少一次判断。

所以,综合以上,在我们返回结果的时候,尽量使用同种类型的变量,尽量减少使用数组返回。

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal