SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

PHP Rulesでスパゲッティコードをすっきりと

ルールとデータをプログラムコードから分離

ダウンロード サンプルソース (2.9 KB)

データベースからルールを作成し、評価する

 この場合に対するRuleContextファイルを作成するには(すでに宣言したとおり、前のセクションで使用したのと同じRuleファイルSuitableForScholarShip.rulを使用します)、まず、PHP Rulesのインストール時に作成したMySQLデータベース「rules」に2つのテーブルを作成します。図5には、このセクションで使用するテーブルaveragestudentが示されています。図6と図7は、これら2つのテーブルに対して定義された列を示します。

図5 rulesデータベース: rulesデータベースのテーブルと構造
図5 rulesデータベース: rulesデータベースのテーブルと構造
図6 averageテーブル: averageテーブルには、学生IDとその学生の平均成績が含まれる
図6 averageテーブル: averageテーブルには、学生IDとその学生の平均成績が含まれる
図7 studentテーブル: studentテーブルには、変数のリストと、それらに対する各学生の値が含まれる
図7 studentテーブル: studentテーブルには、変数のリストと、それらに対する各学生の値が含まれる

 rulesデータベースとその構造を作成したら、次にRuleContextファイルを作成します。このファイルの形式は、先ほどの例よりも少し複雑になっています。

Rule_Element_Type|Rule_Element_Name|
   SQL_Statement|Expected_Return_Data_Type_from_SQL_Query

 データベースの例におけるRuleファイルは、テキストファイルの例のものと同一ですが、RuleContextは異なります。ここでのRuleContextは、以下のとおりです。

  • 学生の年間平均成績は8.0(※編集注
  • 学生は全国コンテストに出場したが、優勝はしていない
  • 学生は高校に在籍している
  • 学生の両親は、学生が奨学金を申請することに同意している

 この場合、Ruleファイル(SuitableForScholarShip.rul)によると、この学生は奨学金を受給することができません。つまり、命題結果はFALSEとなります。

 原文には「学生の年間平均成績は9.5」となっていましたが、FALSEの命題結果を得るためには年間平均成績が9.5未満である必要があるため、RuleContext内の1文を「学生の年間平均成績は8.0」に変更しました。

 明確に定められたルールと、図6と図7に示されたテーブル構造から、SQL文は非常に直観的なものとなります。この場合のRuleContextファイルは、以下のようになります。

# Format of this file is:
# Rule_Element_Type|Rule_Element_Name|
   SQL_Statement|
   Expected_Return_Data_Type_from_SQL_Query
a|studentAnnualAverage|
   SELECT a.average FROM rules.average a 
   WHERE a.variable_name = 'studentAnualAverage';|double
s|studentIsParticipatingToContest|
   SELECT if(((SELECT s.variable_name 
   FROM rules.student s 
   WHERE s.id = ? ) = 1), 1, 0);|boolean
s|studentIsGettingFirstPrize|
   SELECT if(((
     SELECT s.variable_name 
     FROM rules.student s 
     WHERE s.id = ? ) = 1), 1, 0);|boolean
s|studentIsInHighschool|
   SELECT if(((
      SELECT s.variable_name 
      FROM rules.student s 
      WHERE s.id = ? ) = 1), 1, 0);|boolean
s|studentParentsAreAgree|
   SELECT if(((
      SELECT s.variable_name 
         FROM rules.student s 
         WHERE s.id = ? ) = 1), 1, 0);|boolean  

 適切な引数とともに関数loadSqlを呼び出すスクリプトstudent.phpは、以下のようになります。

<?php
class Student extends Controller {
   private $appPhysicalPath = null;
      function __construct() {
      parent::Controller();
      $this->load->model( 'rule/RuleLoader', 'loader' );
      // FCPATH is defined in the /index.php file.
      $this->appPhysicalPath = str_replace( 'index.php', '', str_replace( '\\', 
           '/',FCPATH ) );
      // See whether we can do the same thing with this helper:
      // $this->load->helper( 'file' );
   }
   public function loadSql( $id ) {
      $this->load->model( 'rule/strategy/SqlFileLoaderStrategy', 'strategy' );
      $this->loader->setStrategy( $this->strategy );
      $data[ 'rule' ]= $this->loader->loadRule( $this->appPhysicalPath . 
            'data/SuitableForScholarShip.rul' );
      $data[ 'ruleContext' ] = $this->loader->loadRuleContext( $this-> 
            appPhysicalPath . 'data/SuitableForScholarShip.sql.con', $id );
      $data[ 'result' ]      = $data[ 'rule' ]-> 
            evaluate( $data[ 'ruleContext' ] );
      $data[ 'ruleText' ] = read_file( 'data/SuitableForScholarShip.rul' );
      $data[ 'ruleContextText' ] = 
            read_file( 'data/SuitableForScholarShip.sql.con' );
      $this->load->view( 'ruleview', $data );
   }      
}
?>

 結果を参照するには、ローカルのURLであるhttp://localhost/rules/index.php/rules/student/loadsql/1を表示します。結果は図8のようになるはずです。

図8 データベースからのRuleContextの評価: rulesデータベースに格納されたデータに対し、ルールを評価した場合の出力
図8 データベースからのRuleContextの評価: rulesデータベースに格納されたデータに対し、ルールを評価した場合の出力

 以上、PHP Rulesをインストールし、テキストファイルとデータベースの両方に格納されたRuleContextデータを実行する方法を示しました。独自のルールを作成し、それらをPHPプログラムから呼び出す方法も示しました。PHP Rulesは、変更する可能性のあるルール集合に対し、テストしなければならないテストケースが多数あるという場合に非常に適しています。ルールとデータをプログラムコードから分離することにより、ルールがどのようなものになるかが事前にはっきりとわからない場合にも、ルールの評価を行うことができます。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Octavia Andreea Anghel(Octavia Andreea Anghel)

経験豊富なPHP開発者。現在は、国内外のソフトウェア開発コンテストに参加するプログラミングチームの主任トレーナーを務める。国レベルの教育プロジェクト開発のコンサルティングも担当している。共著書に『XML technologies?XML in Java』があり、XML部分の執筆を担当。PHPやXML...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4382 2009/09/22 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー