2016-12-06 9 views
0

多くのswitch文を使用する代わりに使用できますか?クラス内にたくさんのswitch文を使用する代わりに使用できますか?

私は別のページで動作するクラスを持っていますが、同じことをします。 しかし、各ページには読み込むデータが異なります。 これは私がやっている方法です(色は単なる例に過ぎず、実際に私のアプリケーションにはありません)。 コンストラクタのページをチェックして、$ this-> page変数に入れます。それから私はこのような機能を持っています。

private function loadTable(){ 
    switch($this->page){ 
     case "green": 
      $check = $this->loadGreen(); 
      return $check; 
     break; 
     case "blue": 
      $check = $this->loadBlue(); 
      return $check; 
     break; 
     case "orange": 
      $check = $this->loadOrange(); 
      return $check; 
     break; 
    } 
} 

しかし、私はこのような何かをし、別の機能かもしれません:あなたは、私がswitch文の多くで終わるつもりです機能の多くと非常に素早く見ることができます

public function searchRecord(){ 
    $name = trim(strip_tags($_POST['term'])); 
    switch($this->page){ 
     case "green": 
      $query = "SELECT `green_ID`,Reason FROM `green`"; 
     break; 
     case "blue": 
      $query = "SELECT `blue_ID`,Reason FROM `blue`"; 
     break; 
     case "orange": 
      $query = "SELECT `orange_ID`,`colour`,`hat` FROM `orange`"; 
     break; 
     default: 
      return ""; 
    } 
    //rest of code removed for sanity 
} 

を、これは3ページ分です。何百枚もあれば

私はすべてのケースをすべてのページに持ち、変数を設定して私が現在いるページを言うようにすると考えましたが、その変数を確認するためにスイッチが必要なので機能しません。

私は関数を呼び出すことができ、その関数が私が現在いるページによって異なることをしたいと思っていますが、私の現在のシステムは、可能ならば減らしたいswitch文をたくさん用意しています。

これを行うには良い方法がありますか? public function searchRecordGreen() をし、PHPで動作するはずです searchRecord$color() を経由して、それを呼び出す:

答えて

1

正しく実装OOPは、この問題の解決策です。それはsubtypingと呼ばれ、それは一種の多型です。

あなたはすべてのページタイプの機能を1つのクラスに詰め込んだので、たくさんのswitchステートメントで終わったのです。ページの種類の違いを特定し、機能ごとに1つの空の汎用関数を作成してください。次に、現在のページクラスを拡張し、各子クラスに1つのタイプのページに固有の機能を実装します。このような

何か:

abstract class Page 
{ 
    abstract public function loadTable(); 
    abstract protected function getSearchQuery($term); 

    public function searchRecord($term); 
    { 
     $query = $this->getSearchQuery($term); 
     // rest of search code 
    } 
} 

class GreenPage extends Page 
{ 
    public function loadTable() 
    { 
     // move the code of function Page::loadGreen() here 
    } 

    protected function getSearchQuery($term) 
    { 
     return "SELECT `green_ID`,Reason FROM `green`"; 
    } 
} 

class BluePage extends Page 
{ 
    public function loadTable() 
    { 
     // move the code of function Page::loadBlue() here 
    } 

    protected function getSearchQuery($term) 
    { 
     return "SELECT `blue_ID`,Reason FROM `blue`"; 
    } 
} 

次に、あなたはおそらくファクトリオブジェクトを作成する必要があります。

class PageFactory 
{ 
    public function createPage($name) 
    { 
     switch ($name) 
     { 
     case 'green': 
      return new GreenPage(); 
     case 'blue': 
      return new BluePage(); 
     case 'red': 
      return new RedPage(); 
     default: 
      // this either should never happen or you have a type of page as default 
     } 
    } 
} 


$factory = new PageFactory(); 
$page = $factory->createPage($name); 
$page->loadTable(); 
$page->searchRecord(trim($_POST['term'])); 
+0

これは良い計画のようですそれがどのように機能するかを完全に理解する。したがって、各ページは異なる拡張クラスを使用し、PageFactoryはそれをページに応じて各クラスにリダイレクトしますが、抽象クラスページが何をしているのかはわかりません。多くのものが共通の機能を共有しています。共通の機能はページに入れられますか?これは、C++でクラスを拡張する方法と似ています。私はこれをテストするためのテストプロジェクトを立ち上げると思います。 –

+0

私は抽象クラスについて読んでいます。私が理解するように、抽象クラスは別のクラスによって継承されたクラスです。どのクラスが拡張クラスだと思ったのですか?私は学ぶべきことがたくさんあると思われますが、これが最良の答えだと私は確信しています。 –

+0

抽象クラスは一般的な概念をモデル化します。あなたの例では、 'Page'クラスはジェネリックページをモデル化します。すべてのページに共通の操作が含まれています。それは抽象的である必要はありません。たとえば、サイトの任意のページで有効な抽象関数の実装を提供できる場合(抽象宣言ではなく)これらの関数を実装し、 'abstract'キーワードをクラス宣言から削除できます。次に、 'Page'クラスをデフォルトとして使用して、異なる動作を持つページに特定の' BluePage'または 'GreenPage'を使用することができます。 – axiac

0

あなたはおそらく色に応じてクラス名書くことができます。

は、より具体的にするには:あなたがしたい名前を持つ関数を作成し、exessiveスイッチを保存するために、関数名として$this->pageを使用することができ

<?php 
class Foo 
{ 
    function Variable() 
    { 
     $name = 'Bar'; 
     $this->$name();  // This calls the Bar() method 
    } 

    function Bar() 
    { 
     echo "This is Bar"; 
    } 
} 

$foo = new Foo(); 
$funcname = "Variable"; 
$foo->$funcname(); // This calls $foo->Variable() 

?> 

Php.netは例があります文

あなたはちょうどこのようにそれを作成することにより、スイッチを使用せずにクエリを構築することができ
+0

色は一例に過ぎなかったが、私は私のクラス名を呼ばれた場合でもsearchRecordGreen私はまだへのスイッチを使用する必要があります:あなたはそれを渡すいくつかの特性に基づいて、それはPageオブジェクトの正確な型を作成する方法を知っていますそれを呼び出すと、これらのスイッチを備えた多くの機能が終了しました.3ページしかありません。私の実際のコードに色はありません。 –

0

$query = "SELECT `".$this->page."_ID`,Reason FROM `".$this->page."`"; 
+1

$ this-> pageがユーザー入力から派生していると仮定すると、この答えは可能な** SQLインジェクションの全く新しい領域を開きます** –

+0

これは分かりますが、クエリの中にはアイテム数が異なるものがあります。これを示すために私の例を更新します。 –

+0

あなたができることは、例1のように、さまざまな関数を呼び出すことです。しかし、私は個人的には、異なるパラメータで同じ関数を呼び出すのが好きです。それはもっと多くのスイッチを持っていることを意味している場合はそれもそうです。たぶん誰か他の方が良い解決策を持っているかもしれません。 – Cashbee

0

クエリを配列に格納して参照する方法はありますか?

public function searchRecord() { 
    $q = [ 
      'blue' => 'SELECT `blue_ID`, Reason FROM `blue`', 
      'orange' => 'SELECT `orange_ID`, `colour`, `hat` FROM `orange`' 
      //.... 
     ]; 
    if(array_key_exists($this->page, $q)) { 
     $query = $q[$this->page]; 

     //insert here the code you removed for sanity 
    } else { 
     //nothing found 
     return ""; 
    } 
} 

このようにして、各ページに1つのクエリをそれぞれ1行だけ定義することができます。
そのクエリ配列を別の場所に定義すると、コードを編集して1つのページを追加または編集する必要はありません。

編集:異なる機能のための別の方法

まず、あなたが奉仕したいページごとに一つの関数が含まれているプロバイダクラス定義:

class pageProvider { 
    public static function red() {} 
    public static function green() {} 
    //.... 
} 

をし、その後、あなたは明示的にあなたの呼び出しをマップしますそのクラスに:

直接入力コードを使用してcoul dはローミングを自由にするとセキュリティホールにつながりますが、定義されたクラスの公開されている静的メソッドへの呼び出しを明示的に制限しているため、攻撃者が突発して何か悪いことを行うことはできません。

も参照してください。

+0

これは有望ですが、そこに問題があるのは私が心配しなければならないクエリ文字列だけではありません。異なるテーブルには異なるフィールド名があるので、mysqliを使用しているので、それらも保存する必要があります。しかし、私はあなたのコードを私のアプリケーションのどこか他の場所で使うことができると思っています –

+0

@ThomasWilliams - あなたの呼び出しをクラスにマップするためにリフレクションメソッドを使うことができます。例えば '$ this-> page ==" red "'、あなたのコードは 'providerClass :: red();'を呼び出します –

+0

これの例を見たいと思います。以前の反射方法については聞いていません。私はあなたの意味を理解していますが、実装する方法は理解していません。 –

0

は、あなたがこのような何かをしませんでした:

private function loadTable(){ 

    /* define what pages are acceptable*/ 
    $acceptablePages = array('green','red','blue'); 

    /* check if this->page is of an acceptable value*/ 
    if(in_array($this->page,$acceptablePages)) { 

     /* if it is acceptable then load a function with the page passed as a parameter*/ 
     return $this->loadColour($this->page); 
    } 

    return false; 

} 
+0

問題は私がloadTableを取得するとき私はまだ赤い緑または青が送信されたかどうかを確認するためにswitch文が必要です。ここでswitch文を置き換えてloadTableに移動します –

関連する問題