EC-CUBE / ec-cube

EC-CUBE is the most popular e-commerce solution in Japan
https://www.ec-cube.net
Other
735 stars 646 forks source link

Routerの実装 #7

Closed shinichi-takahashi closed 9 years ago

shinichi-takahashi commented 9 years ago
$arrMaps = array(
    array(
        'method' => 'GET|POST',
        'path'   => '/',
        'dir'    => '',
        'class'  => 'index'
    ),
    array(
        'method' => 'GET|POST',
        'path'   => '/products/detail',
        'dir'    => 'products',
        'class'  => 'detail'
    ),
    array(
        'method' => 'GET|POST',
        'path'   => '/admin/',
        'dir'    => 'admin',
        'class'  => 'index'
    ),
    array(
        'method' => 'GET|POST',
        'path'   => '/admin/login',
        'dir'    => 'admin',
        'class'  => 'login'
    ),
);
nobuhiko commented 9 years ago

ここまでするなら class/pages/ -> controller に変更し、switch ($this->getMode()) を吸収してしまったほうがよくないでしょうか?

izayoi256 commented 9 years ago

ADMIN_DIRの機能を残すようであれば、

array(
    array(
        'method' => 'GET|POST',
        'admin' => true,
        'path' => '/login',
        'dir' => 'admin',
        'class' => 'login',
    )
)

のようにadminをパラメータ化して、/ADMIN_DIR/loginへのアクセス時にこのルートへパースする方がいいのではないでしょうか。

nobuhiko様のコントローラ化は私も賛成ですが、そうするとビジネスロジックをコントローラから切り離さないとコントローラファイルがかなり複雑化しそうな気がします・・。

pineray commented 9 years ago

$arrMaps を定義した後に hook を設置して、プラグインによるルーティング定義を収集して $arrMaps に追加。 さらにその後にもう一つ hook を設置して $arrMaps を渡し、コアや他のプラグインの定義を書き換えられるようにすれば、かなり便利になりますね。

pineray commented 9 years ago

$arrMaps は path をキーにした連想配列にしたほうが、いろいろ扱いやすくなると思います。

shinichi-takahashi commented 9 years ago

みなさま

コメントありがとうございます。

$arrMaps = array(
    // http://example.com/
    '/' => array(
        'method' => 'GET|POST',
        'dir'    => '',
        'class'  => 'index'
    ),
    // http://example.com/products/detail/
    '/products/detail/' => array(
        'method' => 'GET|POST',
        'dir'    => 'products',
        'class'  => 'detail'
    ),
    // http://example.com/admin/products/class/
    '/products/class/' => array(
        'method' => 'GET|POST',
        'admin' => true,
        'dir'    => 'products',
        'class'  => 'class'
    ),
);
shinichi-takahashi commented 9 years ago

@pineray

$arrMaps を定義した後に hook を設置して、プラグインによるルーティング定義を収集して $arrMaps に追加。 さらにその後にもう一つ hook を設置して $arrMaps を渡し、コアや他のプラグインの定義を書き換えられるようにすれば、かなり便利になりますね。

すみません。具体的なイメージがわかず、こちらもう少し詳しく教えていただけませんか?

shinichi-takahashi commented 9 years ago

@nobuhiko

class/pages/ -> controller に変更し、switch ($this->getMode()) を吸収してしまったほうがよくないでしょうか?

そうですねえ。 実装イメージは、CakePHPなどのFWとほぼほぼ同じですか??

pineray commented 9 years ago

@shinichi-takahashi

$arrMaps を定義した後に hook を設置して、プラグインによるルーティング定義を収集して $arrMaps に追加。 さらにその後にもう一つ hook を設置して $arrMaps を渡し、コアや他のプラグインの定義を書き換えられるようにすれば、かなり便利になりますね。

すみません。具体的なイメージがわかず、こちらもう少し詳しく教えていただけませんか?

プラグイン独自のページを表示する場合に、そのページのルーティング定義を追加する必要があると思うのですが、routes.php を書き換えるのは好ましい動作ではなく、hook で解決するのがスマートだと思います。 また、ページの処理をプラグイン独自のものに差し替えたい、という要望が必ず生じてくると思いますので、これも hook で解決できたほうが良いと思います。 追加と変更を別々の hook で実装したほうが、より柔軟にルーティング定義を扱うことができます。

pineray commented 9 years ago

@shinichi-takahashi

パスの頭の「/」は必要でしょうか? それが関係するのはおそらくフロントページだけで、そこだけ特別に処理を行えば良いように思います。 (例えば、キーを'<front>'としておき、ルーティングのクエリが無い場合はそのページを表示する、と言った具合です)

また、method や admin などは任意の項目にして、記入がない場合はデフォルトの値を適用するほうが簡便だと思います。 (例えば method が無い場合は GET|POST を適用、admin が無い場合は false を適用)

pineray commented 9 years ago

@shinichi-takahashi

連投ですみません。 パスをキーにするのであれば、そもそも admin の指定は不要ですね。

$arrMaps = array(
    // http://example.com/admin/products/class/
    'admin/products/class' => array(
        'method' => 'GET|POST',
        'dir'    => 'products',
        'class'  => 'class'
    ),
);

としておき、パスの「admin」を ADMIN_DIR に差し替えれて処理すれば良いように思います。

ttsuru commented 9 years ago

HTTP_URL / HTTPS_URL をテンプレート上で記載しないといけないため、セキュリティー上、危ない実装のサイトを多く拝見します。

そのため、Routingのマッチだけではなく、URLのGenerateにも対応するほうが良いのではないでしょうか。 たとえば、 <!--{'cart'|path}-->とすれば /cart/ が生成されるとみんなで幸せになれると思います。

また、HTTPSもRoutingの値に含めてもよいのではないでしょうか。 そうすれば、httpでアクセスしている際に <!--{'shopping_index'|path}--> がテンプレートで呼び出されれば https://example.co.jp/shopping/ を出力するなどの応用がききます。

また、Symfony ComponentのRoutingの実装が参考になるとおもいます。 http://symfony.com/doc/current/components/routing/introduction.html https://github.com/symfony/Routing

PHP5.3以上のみが動作対応なのであればそのままSymfony Componentを利用するのも手かと思いますが、いかがでしょうか。

shinichi-takahashi commented 9 years ago

@ttsuru

URLのGenerateに関して、下記イメージであってますか? templateに、生成の際に参照する値をいれてます。 +SSLフラグがTRUEならSSLを強制するイメージです。

$arrMaps = array(
    // http://example.com/admin/products/class/
    'admin/products/class' => array(
        'method' => 'GET|POST',
        'dir'    => 'products',
        'class'  => 'class',
        'ssl' => true,
        'template' => 'product_class'
    ),
);

また、記載できていなかったのですが、フレームワーク、SymfonyComponentは利用しない方向で考えています。 ですが、Router部分のSymfonyComponentが独立しているもので、ラップするのが容易なのであれば利用も検討したいです。 私の知識不足で申し訳ないのですが、実装イメージ(階層がどうなるとか、ラッパーはどんな感じになるとか)いただけると助かります。

shinichi-takahashi commented 9 years ago

@pineray hookについて、合点がいきました!ありがとうございます!

パスの頭の「/」は必要でしょうか?

こちらはどっちでもいいかな、と思っています。 任意項目については、最小構成と最大構成で提示していった方が共有しやすいかもしれませんね。

一度今までの意見を整理したいと思います。

ttsuru commented 9 years ago

@shinichi-takahashi

ご確認ありがとうございます。 お伝えしたかったイメージ通りです。

Symfony Componentsについては単独での利用も可能です。 Laravel、Silex、Drupal、phpBBあたりが利用しています。 ライセンスもMIT Licenseで使いやすいと思います。

Rotingがわかりやすく簡潔になれば、カスタマイズやテンプレートの様々な問題が解決するような気がします。 特に、Generatorがあると、テンプレートによって表記が揺れている部分が全て統一できると思います。

現在はテンプレートに依存してしまっている /products/{product_id}.html などのパスの書き換えも同時に解決は可能かと思います。

Smarty テンプレートでのイメージは以下になります。 ちなみにテンプレートエンジンも、Smartyのままでしょうか?

<!--{"product_detail"|path}-->
もしくは
<!--{path name="product_detail" product_id=1}-->
http://example.com/products/detail.php?product_id=1
Routingの設定によっては以下のようにも
http://example.com/products/detail/1.html
shinichi-takahashi commented 9 years ago

@ttsuru

Symfony Componentsについて、ありがとうございます。 ちなみにですが、なぜフレームワークを利用しない方向になっているかというと

の2段階で依存してしまうので懸念しておりました。 (実装経験がなく、工数感や使用感がわからないため、)実際に試してみて、 容易に利用できるようであれば、取り入れたいと思います!

Smartyに関しては、ちょっと話題がRoutingからズレてしまうので、 別Issueを立てようと思います。

疑問に思ったことなどあれば、ご自由にIssueたてて頂いて構いませんので、 (むしろいっぱい立ててほしいです)今後、何かお困りの点や不明点あらば 新規で立てていただくようにお願いします!

ttsuru commented 9 years ago

@shinichi-takahashi

ありがとうございます。 様々な点をケアできる内容を実装できるのであれば独自実装も良いかと思いますが、PEAR含め、ある程度の担保があるために利用されているのかと思いました。

それぞれが依存するという問題は「Dependency injection」(DI)という考え方も一つだと思います。 フレームワークに依存しないようにしていることはソースを見ていると、とても伝わってきますが、その分、最近主流の実装やからEC-CUBEが取り残されて行っているように思えます。 Symfony Componentsが最近海外のオープンソース系に採用されている理由も、DIの元でComponentごとに利用できるからだと思います。

現状のEC-CUBEではほぼメンテの止まったPEARやSmartyに依存している部分もあり、PHP5.3ではNoticeエラーも頻発すると思います。

ECの中で非常にシェアが高いソフトウェアだからこそ、ぜひ、この辺りも含めてECサイトの開発に道筋をつけていただけると幸いです。

shinichi-takahashi commented 9 years ago

@ttsuru

なるほどなるほど、ありがとうございます。 今、導入について、とても悩んでいるところなんですが、Symfony ComponentのRoutingを採用することで、 EC-CUBEのプラグインの利用や、構造が便利・簡潔になるなどの利点は増えそうですか? やはり、プラグインによる拡張性は重視したく、慎重に選択していきたいです。

shinichi-takahashi commented 9 years ago

以下ルールを提案します。

class Hoge_Ex extends Hoge()
{
}
shinichi-takahashi commented 9 years ago

Silexの採用に伴い、本件クローズいたします。