ホームページ > バックエンド開発 > PHPチュートリアル > PHP スキル: PHP プログラム内の一部の悪いコードを賢く回避する方法

PHP スキル: PHP プログラム内の一部の悪いコードを賢く回避する方法

无忌哥哥
リリース: 2023-04-03 06:54:01
オリジナル
1583 人が閲覧しました

この記事では、PHP サンプル コードから悪いコードを見つけて修正する方法について説明します。興味のある友人は参照してください。

私は PHP 開発を約 1 年間行ってきました。この 1 年間、本番環境で多くのテクニックを学び、多くのことを学びました。また、この期間にいくつかの優れたソース コードを読み、コードブックに関する情報については、コードの作成についていくつか考えがあり、他の人が書いた良いコードも悪いコードもたくさん見てきましたが、ここでは私自身の洞察と改善点について話しましょう。

このブログは私自身の感情を表現したものであり、コードを書くときに、コードを明確で読みやすく、落とし穴を避けることができるように、自分自身のルールを設定しています。これらの単純なルールはデザイン パターンほど魅力的には見えないかもしれませんが、定期的に注意を払うことでコードをよりきれいに見せることができます。

1. オブジェクトの外部で宣言されていない変数を使用しないでください

この問題は、表現すると理解しにくいかもしれません。この問題は、PHP 言語自体の特性によって決まります。 PHP は型指定が弱い動的スクリプト言語であるため、多くの場合、この言語には開発者がコードを作成するための条件が非常に緩く与えられています。ただし、これらの便利さが落とし穴になることもよくあるため、動的言語で便利な記述方法を使用する場合は特に注意する必要があります。

まずクラスを宣言しましょう。このクラスをユーザー クラスと呼びましょう。このユーザー クラスのバックグラウンド設定は、フレームワークに付属しており、変更が許可されていないことです。フレームワークの奥深くに隠されており、見つけるのは簡単ではありませんが、実際には、laravel フレームワークの Request クラスを参照してください。コードは次のとおりです。非常に満足できるように思えますが、次に、このクラスを操作する必要があります。

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);
  }
}
ログイン後にコピー

このようなコードは PHP で完全に実行でき、エラーは報告されません。しかし、そのようなコードはその後のいくつかのことに干渉します。ここでは、上記のコードが PHP Web プロジェクトのインターセプター、またはミドルウェアと呼ばれるものであると仮定します。次に、次のように、このクラスのインスタンスをコントローラーで使用し、ミドルウェアに追加された変数を使用します。

#

$user = new User();
$user->userRealName = "hello world";
ログイン後にコピー

ここで設定したシナリオは、WebOperate がミドルウェアであり、すべてのコントローラーがこのミドルウェアを通過した後にコントローラーに到達することです。その後、対応するコントローラー関数が処理されます。次に、コントローラーはコントローラーが使用するミドルウェア インスタンスを挿入しますが、ミドルウェア開発者はその存在をあまり気にしません。完全に実行できます。次に、開発者は、別の User クラスを実装し、この User クラスに他の機能を追加したいと考えています。前述したように、このクラスはフレームワークの奥深くにあります。また、見つけるのが難しく、変更は許可されていません。他の関数はこのクラスを使用するため、メソッドを継承して追加することしかできません。開発経験によると、開発者は userRealName 変数が User クラスに存在すると考えるため、次の記述方法になります:

最初は、この User に基づいて派生した Teacher クラスです:

 class WebOperate {
   public function doOprate(User $user) {
     $user->userRealName = "hello world";
     next($user);
   }
 }
ログイン後にコピー

このようにして、教師は挨拶をすることができますが、この時点ではまだコントローラーで教師の本名を知りたいのですが、どうすればよいでしょうか?経験に基づいて、挿入されたクラスを Teacher に変更し、実際の名前を返すことができます:

 class IndexController {
   public function index(User $user) {
     return $user->userRealName;
   }
 }
ログイン後にコピー

そこで疑問が生じます。実際、そのようなことはありません。 User クラスにあるため、この変数には値がありませんが、経験によれば、ミドルウェアにはすでに値が一度割り当てられているため、それを直接使用できるはずですが、そのような値はありません。ソースコードを見ると、継承した User クラスにこの変数が存在しないことがわかりましたが、ではなぜ以前にこの変数が使用できるのでしょうか? ミドルウェアではユーザーの力が支払われるためです。

したがって、宣言されていない変数をクラス内で直接使用することはできません。

我々は次のように書くべきです:

 class Teacher extends User {
   public function sayHello() {
     return "hello world";
   }
 }
ログイン後にコピー

このようなミドルウェアは、継承されたクラスを呼び出すときに同じメソッドを使用することもできます。これは非常に簡単です。悪い味を作り出すのは非常に困難です。

2. クラスまたは配列

実は、この問題は、関数の戻り値の問題という別の問題も派生します。

まず最初に、関数が複数のタイプの値を返すのは良くないと個人的に感じていることを明確にします。これは動的言語では非常に一般的ですが、PHP の多くのネイティブ メソッドにもこれがあります, ただし、本番環境でこのメソッドを使用すると、関数の戻り値に不確実性が生じます。結論を証明するには多くの判断を下す必要がありますが、戻り値の型が 1 つだけであれば、戻り値を直接判断できます。

は次のコードのようなものです:

 class IndexController {
   public function index(Teacher $user) {
     return $user->userRealName;
   }
 }
ログイン後にコピー

このようなコードは、多くの場合、呼び出し元によって次のようにもう一度判断されます。

class WebOperate {
  public function doOprate(User $user) {
    $user->addAtri([
      'userRealName' => 'hello world',
    ]);
    next($user);
  }
}
ログイン後にコピー

この種のコードは、この関数が呼び出されるたびにほぼ毎回表示されます。コードは見苦しいだけでなく、非常に肥大化します。

このようなコードは改善する必要があります。まず、関数の戻り値を制限します。たとえば、この関数は bool 型の数値のみを返すようにします:

public function addNewUser() {
    $res = $this->addData();
    if ($res) {
      return true;
    } else {
      return [
        'error' => 1,
        'errormsg' => "没有添加成功"
      ];
    }
  }
ログイン後にコピー

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

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

class Operate{
  public $operateRes = [
    0 => '成功',
    1 => '添加失败',
    2 => '未知错误',
  ];
  
  
  public function addNewUser() {
    $res = $this->addData();
    if ($res) {
      return 0;
    } else if ($res > 1) {
      return 1;
    }
    return 2;
  }
  
}
ログイン後にコピー

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

$opera = new Operate();
$res = $opera->addNewUser();
return $opera->operateRes[$res];
ログイン後にコピー

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

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;
}
ログイン後にコピー

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

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

以上がPHP スキル: PHP プログラム内の一部の悪いコードを賢く回避する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート