<commit_before>
WingPHPのご利用ありがとうございます。
このファイルはWingPHPの利用方法について簡単に説明したファイルです。

  index. ------------------------------
     1) How to install.
     2) Directory
     3) URL Rule 1 "Basic Rule"
     4) URL Rule 2 "index Method"
     5) URL Rule 3 "URL Arguments"
     6) Controller
     7) View
     8) Model
     9) autoload
    10) FAQ
  -------------------------------------

WingPHPは「MVCモデル」を採用した軽量のフレームワークです。
モデルにPDO, ViewにSmartyを利用することで、これまでの知識を再利用
できる学習コストの低さを求めています。


------------------------
1) How to install.
------------------------
 同梱されている INSTALL.*.txt をご覧ください。


------------------------
2) Directory
------------------------
 各ディレクトリは次のような意味を持ちます。

  controller ... コントローラー用のクラス
  model ........ モデル用のクラス
  view ......... ビュー用のHTML(Smartyテンプレート)
    layout .....  layout機能を用いる際に利用
    _common ....  共通パーツを保存する際に利用
  temp ......... Smartyのキャッシュ置場
  lib .......... アプリ内で利用するクラス
  htdocs ....... ドキュメントルート
  conf.php ..... アプリ内全体で利用する$Confの設定、
                 ルーティングの設定を行うクラスの設定


------------------------------
3) URL Rule 1 "Basic Rule"
------------------------------
 例えば以下のようなURLがあったとします。

   http://yourdomain/catalog/view/


 このURLへアクセスがあった場合、WingPHPは次のような動作をします。

    1. htdocs/catalog/view/ のファイルの存在をチェック
      1.1 ファイルがある場合 → その内容を返却し終了
      1.2 ファイルがない場合 → 2へ進む

    2. controllerを実行
      2.1 controller/catalog.phpをinclude する
      2.2 class CatalogController のインスタンスを生成、viewメソッドを実行し終了
            
            // 以下はイメージです
            include_once('controller/catalog.php');
            
            $obj = new CatalogController();
            $obj->view();

      2.3 もし上記のファイルやクラス、メソッドが存在しない場合は、
          次の「404エラー」を出力するURLへリダイレクトされます。
          http://yourdomain/error/msg/404


 つまり、URLは次のような意味を持つことになります。

       http://yourdomain/(コントローラー名)/(メソッド名)/



------------------------------
4) URL Rule 2 "index method"
-----------------------------
 メソッド名は省略することが可能です。
 次のURLの場合は
    http://yourdomain/catalog

 以下のURLと同じ意味になります。
    http://yourdomain/catalog/index

 もしindexメソッドが存在しない場合は404エラーとなります。
 また明示的にindexをつけても問題ありません。



------------------------------
5) URL Rule 3 "URL Arguments"
-----------------------------
 次のURLは、コントローラーに対しURLから引数を渡しています。

      http://yourdomain/catalog/view/12345/simple

         ↓

      include_once('controller/catalog.php'); 

      $obj = new CatalogController();
      $obj->view(array(12345, 'simple'));

 viewメソッドに注目してください。
 URLのメソッド指定部分から先の12345, "simple" が引数として渡されます。

 実際にメソッド内で利用する際には、以下のようなコードを記述します。

   public function view($argv){
     $id   = $argv[0];  //12345
     $mode = $argv[1];  //"simple"
 
   }

 値はスラッシュ(/)で区切られ、いくつでも渡すことが可能です。
   ※URLの最大長がブラウザやサーバに依存しますので、
    あまりに長大になる場合はPOSTメソッドのクエリーを
    用いてください。
  

-----------------------------
6) Controller
-----------------------------
 コントローラー作成時の注意点は3つです。

   1. すべてのControllerは、controller/base.php内にある BaseControllerクラスを継承する。
   2. ファイル名は controller/(クラス名を小文字).php 
   3. クラス名は (クラス名)Controller とする。

 これはフレームワークのお作法ですので、必ず守っていただく必要があります。

 例えば catalog という名前のコントローラーを作成する場合は
 次のようになります。

   // controller/catalog.php
   class CatalogController extends BaseController{
       public function index(){
         echo "helloworld";
       }
   }

 実際に上記のファイルを作成したら、ブラウザからアクセスしてみてください。
   http://yourdomain/catalog
   http://yourdomain/catalog/index


 ■呼ばれたくないメソッド
   ユーザーに直接呼ばれたくないメソッドは private を明示的に
   記述してください。private になっているメソッドは呼び出さ
   れません。仮に呼ばれても404になります。

    class CatalogController extends BaseController{
       // 呼び出せます
       public function callable(){
         echo "callable";
       }

       // 呼び出せない
       private function cantcall(){
         echo "can not call";
       }
   }



-----------------------------
7) View
-----------------------------
 WingPHPではViewにSmartyを採用しています。
 現在では3.1系のみの利用が可能です。
 http://www.smarty.net/docs/ja/

 Viewとして用いるHTMLは、viewディレクトリ配下に自由なファイル名で
 保存し、それをコントローラーから呼び出すことができます。
 

 例えば、
 view/catalog/index.html にSmarty記法でかかれたファイルを
 置いたとします。これを出力するためのコードは以下になります。

   class CatalogController extends BaseController{
       public function view(){
           $this->display('catalog/index.html');
       }
   }

 継承元のスーパークラス内にあるdisplayメソッドに、
 Viewのファイルのパスを与えるだけです。


 また変数をSmartyに渡す場合は、以下になります。

   class CatalogController extends BaseController{
       public function view(){
           $this->assign('name', 'value');
           $this->display('catalog/index.html');
       }
   }

 Smartyが標準で用意しているメソッド名と合わせてありますので、
 特に深く考えなくても利用できるようになっています。


 ■ layout 機能を使用する
   例えばニュースサイトやブログで、記事内容はページによって変わるが、
   メニューや基本的なデザインは一緒という場合は多々あります。

   これの実装方法は色々がありますが、すべてのテンプレートにすべての内容を書いてしまうと、
   いざデザインを変更するとなった時に大変なお祭りになります。こんな時に用いるのが
   layout機能です。

    class CatalogController extends BaseController{
       public function view(){
           $this->layout('layout/base.html');     //ここに注目
           $this->display('catalog/index.html');
       }
    }
  
   全ページで共通するHTML等を layout/base.html に記述します。
   当該ページの内容を 'catalog/index.html' に記述します。

   layout/base.html 内に {$CONTENT} と書いた部分が
   catalog/index.html に置き換わります。

   具体的には次のような動きになります。

      ○layout/base.html
        <html><head><title>layout test</title></head>
        <body>
        {$CONTENT}
        </body>
        </html>

      ○catalog/index.html
        <h1>HelloWorld</h1>
        <p>welcome to wingphp</p>

      ○最終的な出力結果($this->display()実行結果)
        <html><head><title>layout test</title></head>
        <body>
        <h1>HelloWorld</h1>
        <p>welcome to wingphp</p>
        </body>
        </html>

   注意点としては、layoutメソッドは必ずdisplayよりも前に実行する必要があること、
   またassignで渡した変数は、layout用のファイルにも影響を与えることです。



-----------------------------
8) Model
-----------------------------
 WingPHPのモデルは、ざっくり言うとPDOを経由し、MySQLとデータのやりとりを
 する機能になります。
 
 このモデルにもコントローラーと同様のお作法があります。

   1. すべてのModelは、Model/base.php 内にある BaseModelクラスを継承する。
   2. ファイル名は model/(クラス名を小文字).php 
   3. クラス名は (クラス名)Model とする。

 コードにした場合、次のようになります。

   // model/catalog.php
   class CatalogModel extends BaseModel{
     public function set(){
         ;
     }
     public function get(){
         ;
     }
   }

 モデルはコントローラーを経由して呼ばれることがほとんどですので、
 public/privateの違いはコントローラーから隠すかどうかという意味しか
 持ちません。
   ※Smartyのプラグインを用意することで、簡単にViewからも
     Modelを呼ぶことができます。


 ■ SELECT句
   モデルからSELECT句を発行するには、selectメソッドを用います。

     class CatalogModel extends BaseModel{
       public function get($id){
          return(
            $this->select('select * from catalog where id=?', array($id))
          );
       }
     }

     //ControllerからModelを利用
     class CatalogController extends BaseController{
       public function index($argv){
          $id = $argv[0];

          $model = new CatalogModel();
          $model->get($id);
       }
     }

   失敗時にはfalseが返ってきます。
   成功時には次のような2次元配列が返却されます。
   (ゼロ件だった場合は空の配列が返却されます)
 
     array(
         array('column1'=>'value', 'column2'=>'value')
       , array('column1'=>'value', 'column2'=>'value')
       , array('column1'=>'value', 'column2'=>'value')
     )


   しかし、これだとまどろっこしい場合があります。
   あらかじめ結果が1レコードだけと分かりきっている時です。例えばcountして件数だけ知りたい、
   プライマリーキーで絞り込んだ時などが考えられます。こういった時には select1 メソッドを
   使用するのが良いでしょう。

     //違いはメソッド名に "1" がつくかどうか
     $this->select1('select count(*) as cnt  from catalog where id=?', array($id))

   select1は、仮に複数レコードが結果だった場合でも最初の1レコード目のみが返却されます。
   またselectと異なり配列も1次元となります。

     array('cnt'=>123)


 ■ INSERT/UPDATE/DELETE句
   何らかのデータ更新を行う場合は、execメソッドを利用します。

     class CatalogModel extends BaseModel{
       public function create($val){
            $ret = $this->exec(
                'insert into catalog values(?,?,?)'
              , array($val['name'], $val['price'], $val['description'])
            );

            return($ret);
       }
     }

     //ControllerからModelを利用
     class CatalogController extends BaseController{
       public function index($argv){
          $model = new CatalogModel();
          $ret   = $model->create(array(
                            'name'  => $argv[0]
                          , 'price' => $argv[1]
                          , 'description' => $argv[2]
                    ));

           $this->assign('is_create', $ret);
           $this->display('catalog/create.html');
       }
     }

   成功すればtrue, 失敗すればfalseが返されます。
   上記の例ではinsertを行っていますが、同様にupdate,deleteも行えます。
   権限さえあればcreate tableなどももちろん可能です。


 ■ トランザクション
   複数のSQLを実行し、そのうちのひとつでも失敗したら処理を取り消したい(rollbackしたい)
   場合はどうすればよいでしょうか？

    // 仕様変更予定のため後日記入


 ■ キャッシュ
   WingPHPではSQLの実行結果をmemcachなどに一定時間自動的にキャッシュする機能があります。
   これのON/OFFを切り替えるだけで、コード上はまったく意識することなくDBへの負荷を減らす<commit_msg>利用方法に追記(途中)<commit_after>
WingPHPのご利用ありがとうございます。
このファイルはWingPHPの利用方法について簡単に説明したファイルです。

  index. ------------------------------
     1) How to install.
     2) Directory
     3) URL Rule 1 "Basic Rule"
     4) URL Rule 2 "index Method"
     5) URL Rule 3 "URL Arguments"
     6) Controller
     7) View
     8) Model
     9) autoload
    10) FAQ
  -------------------------------------

WingPHPは「MVCモデル」を採用した軽量のフレームワークです。
モデルにPDO, ViewにSmartyを利用することで、これまでの知識を再利用
できる学習コストの低さを求めています。


------------------------
1) How to install.
------------------------
 同梱されている INSTALL.*.txt をご覧ください。


------------------------
2) Directory
------------------------
 各ディレクトリは次のような意味を持ちます。

  controller ... コントローラー用のクラス
  model ........ モデル用のクラス
  view ......... ビュー用のHTML(Smartyテンプレート)
    layout .....  layout機能を用いる際に利用
    _common ....  共通パーツを保存する際に利用
  temp ......... Smartyのキャッシュ置場
  lib .......... アプリ内で利用するクラス
  htdocs ....... ドキュメントルート
  conf.php ..... アプリ内全体で利用する$Confの設定、
                 ルーティングの設定を行うクラスの設定


------------------------------
3) URL Rule 1 "Basic Rule"
------------------------------
 例えば以下のようなURLがあったとします。

   http://yourdomain/catalog/view/


 このURLへアクセスがあった場合、WingPHPは次のような動作をします。

    1. htdocs/catalog/view/ のファイルの存在をチェック
      1.1 ファイルがある場合 → その内容を返却し終了
      1.2 ファイルがない場合 → 2へ進む

    2. controllerを実行
      2.1 controller/catalog.phpをinclude する
      2.2 class CatalogController のインスタンスを生成、viewメソッドを実行し終了
            
            // 以下はイメージです
            include_once('controller/catalog.php');
            
            $obj = new CatalogController();
            $obj->view();

      2.3 もし上記のファイルやクラス、メソッドが存在しない場合は、
          次の「404エラー」を出力するURLへリダイレクトされます。
          http://yourdomain/error/msg/404


 つまり、URLは次のような意味を持つことになります。

       http://yourdomain/(コントローラー名)/(メソッド名)/



------------------------------
4) URL Rule 2 "index method"
-----------------------------
 メソッド名は省略することが可能です。
 次のURLの場合は
    http://yourdomain/catalog

 以下のURLと同じ意味になります。
    http://yourdomain/catalog/index

 もしindexメソッドが存在しない場合は404エラーとなります。
 また明示的にindexをつけても問題ありません。



------------------------------
5) URL Rule 3 "URL Arguments"
-----------------------------
 次のURLは、コントローラーに対しURLから引数を渡しています。

      http://yourdomain/catalog/view/12345/simple

         ↓

      include_once('controller/catalog.php'); 

      $obj = new CatalogController();
      $obj->view(array(12345, 'simple'));

 viewメソッドに注目してください。
 URLのメソッド指定部分から先の12345, "simple" が引数として渡されます。

 実際にメソッド内で利用する際には、以下のようなコードを記述します。

   public function view($argv){
     $id   = $argv[0];  //12345
     $mode = $argv[1];  //"simple"
 
   }

 値はスラッシュ(/)で区切られ、いくつでも渡すことが可能です。
   ※URLの最大長がブラウザやサーバに依存しますので、
    あまりに長大になる場合はPOSTメソッドのクエリーを
    用いてください。
  

-----------------------------
6) Controller
-----------------------------
 コントローラー作成時の注意点は3つです。

   1. すべてのControllerは、controller/base.php内にある BaseControllerクラスを継承する。
   2. ファイル名は controller/(クラス名を小文字).php 
   3. クラス名は (クラス名)Controller とする。

 これはフレームワークのお作法ですので、必ず守っていただく必要があります。

 例えば catalog という名前のコントローラーを作成する場合は
 次のようになります。

   // controller/catalog.php
   class CatalogController extends BaseController{
       public function index(){
         echo "helloworld";
       }
   }

 実際に上記のファイルを作成したら、ブラウザからアクセスしてみてください。
   http://yourdomain/catalog
   http://yourdomain/catalog/index


 ■呼ばれたくないメソッド
   ユーザーに直接呼ばれたくないメソッドは private を明示的に
   記述してください。private になっているメソッドは呼び出さ
   れません。仮に呼ばれても404になります。

    class CatalogController extends BaseController{
       // 呼び出せます
       public function callable(){
         echo "callable";
       }

       // 呼び出せない
       private function cantcall(){
         echo "can not call";
       }
   }



-----------------------------
7) View
-----------------------------
 WingPHPではViewにSmartyを採用しています。
 現在では3.1系のみの利用が可能です。
 http://www.smarty.net/docs/ja/

 Viewとして用いるHTMLは、viewディレクトリ配下に自由なファイル名で
 保存し、それをコントローラーから呼び出すことができます。
 

 例えば、
 view/catalog/index.html にSmarty記法でかかれたファイルを
 置いたとします。これを出力するためのコードは以下になります。

   class CatalogController extends BaseController{
       public function view(){
           $this->display('catalog/index.html');
       }
   }

 継承元のスーパークラス内にあるdisplayメソッドに、
 Viewのファイルのパスを与えるだけです。


 また変数をSmartyに渡す場合は、以下になります。

   class CatalogController extends BaseController{
       public function view(){
           $this->assign('name', 'value');
           $this->display('catalog/index.html');
       }
   }

 Smartyが標準で用意しているメソッド名と合わせてありますので、
 特に深く考えなくても利用できるようになっています。


 ■ layout 機能を使用する
   例えばニュースサイトやブログで、記事内容はページによって変わるが、
   メニューや基本的なデザインは一緒という場合は多々あります。

   これの実装方法は色々がありますが、すべてのテンプレートにすべての内容を書いてしまうと、
   いざデザインを変更するとなった時に大変なお祭りになります。こんな時に用いるのが
   layout機能です。

    class CatalogController extends BaseController{
       public function view(){
           $this->layout('layout/base.html');     //ここに注目
           $this->display('catalog/index.html');
       }
    }
  
   全ページで共通するHTML等を layout/base.html に記述します。
   当該ページの内容を 'catalog/index.html' に記述します。

   layout/base.html 内に {$CONTENT} と書いた部分が
   catalog/index.html に置き換わります。

   具体的には次のような動きになります。

      ○layout/base.html
        <html><head><title>layout test</title></head>
        <body>
        {$CONTENT}
        </body>
        </html>

      ○catalog/index.html
        <h1>HelloWorld</h1>
        <p>welcome to wingphp</p>

      ○最終的な出力結果($this->display()実行結果)
        <html><head><title>layout test</title></head>
        <body>
        <h1>HelloWorld</h1>
        <p>welcome to wingphp</p>
        </body>
        </html>

   注意点としては、layoutメソッドは必ずdisplayよりも前に実行する必要があること、
   またassignで渡した変数は、layout用のファイルにも影響を与えることです。



-----------------------------
8) Model
-----------------------------
 WingPHPのモデルは、ざっくり言うとPDOを経由し、MySQLとデータのやりとりを
 する機能になります。
 
 このモデルにもコントローラーと同様のお作法があります。

   1. すべてのModelは、Model/base.php 内にある BaseModelクラスを継承する。
   2. ファイル名は model/(クラス名を小文字).php 
   3. クラス名は (クラス名)Model とする。

 コードにした場合、次のようになります。

   // model/catalog.php
   class CatalogModel extends BaseModel{
     public function set(){
         ;
     }
     public function get(){
         ;
     }
   }

 モデルはコントローラーを経由して呼ばれることがほとんどですので、
 public/privateの違いはコントローラーから隠すかどうかという意味しか
 持ちません。
   ※Smartyのプラグインを用意することで、簡単にViewからも
     Modelを呼ぶことができます。


 ■ SELECT句
   モデルからSELECT句を発行するには、selectメソッドを用います。

     class CatalogModel extends BaseModel{
       public function get($id){
          return(
            $this->select('select * from catalog where id=?', array($id))
          );
       }
     }

     //ControllerからModelを利用
     class CatalogController extends BaseController{
       public function index($argv){
          $id = $argv[0];

          $model = new CatalogModel();
          $model->get($id);
       }
     }

   失敗時にはfalseが返ってきます。
   成功時には次のような2次元配列が返却されます。
   (ゼロ件だった場合は空の配列が返却されます)
 
     array(
         array('column1'=>'value', 'column2'=>'value')
       , array('column1'=>'value', 'column2'=>'value')
       , array('column1'=>'value', 'column2'=>'value')
     )


   しかし、これだとまどろっこしい場合があります。
   あらかじめ結果が1レコードだけと分かりきっている時です。例えばcountして件数だけ知りたい、
   プライマリーキーで絞り込んだ時などが考えられます。こういった時には select1 メソッドを
   使用するのが良いでしょう。

     //違いはメソッド名に "1" がつくかどうか
     $this->select1('select count(*) as cnt  from catalog where id=?', array($id))

   select1は、仮に複数レコードが結果だった場合でも最初の1レコード目のみが返却されます。
   またselectと異なり配列も1次元となります。

     array('cnt'=>123)


 ■ INSERT/UPDATE/DELETE句
   何らかのデータ更新を行う場合は、execメソッドを利用します。

     class CatalogModel extends BaseModel{
       public function create($val){
            $ret = $this->exec(
                'insert into catalog values(?,?,?)'
              , array($val['name'], $val['price'], $val['description'])
            );

            return($ret);
       }
     }

     //ControllerからModelを利用
     class CatalogController extends BaseController{
       public function index($argv){
          $model = new CatalogModel();
          $ret   = $model->create(array(
                            'name'  => $argv[0]
                          , 'price' => $argv[1]
                          , 'description' => $argv[2]
                    ));

           $this->assign('is_create', $ret);
           $this->display('catalog/create.html');
       }
     }

   成功すればtrue, 失敗すればfalseが返されます。
   上記の例ではinsertを行っていますが、同様にupdate,deleteも行えます。
   権限さえあればcreate tableなどももちろん可能です。


 ■ トランザクション
   複数のSQLを実行し、そのうちのひとつでも失敗したら処理を取り消したい(rollbackしたい)
   場合はどうすればよいでしょうか？

     class CatalogModel extends BaseModel{
       public function set(){
         $this->begin();
		 if(    $this->exec('insert into catalog(id,name)  values(?,?)', array(1234,'foobar'))
		    &&  $this->exec('insert into detail(id,price)  values(?,?)', array(1234,10500)) ){
		   
		   $this->commit();    //両方成功した場合
	     }
		 else{
		   $this->rollback();  //どちらか片方でも失敗した場合
		 }
	 }

   通常、execは処理が終了したタイミングで自動的に

 ■ キャッシュ
   WingPHPではSQLの実行結果をmemcachなどに一定時間自動的にキャッシュする機能があります。
   これのON/OFFを切り替えるだけで、コード上はまったく意識することなくDBへの負荷を減らす
{'fraction_non_alphanumeric': 0.16271813243961633, 'fraction_numerical': 0.013001271235409685, 'mean_word_length': 2.1553327256153145, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 106, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5124029', 'n_tokens_mistral': 8741, 'n_tokens_neox': 7956, 'n_words': 931}