8

私は、パブリック マーケティング エリア、プライベート メンバー エリア、管理サイト、およびマーケティング キャンペーン管理サイトを持つ既存のプロジェクト内で Zend Framework の実装に取り​​組んでいます。現在、これらは不十分に編成されており、マーケティング エリアとメンバー エリアのコントローラー スクリプトはすべてサイトのルートの下にあり、管理者用の別のフォルダーとマーケティング キャンペーン サイト用の別のフォルダーがあります。

Zend Framework を実装するにあたり、コントローラーとビューをモジュールに分割できるようにしたいと思います (メンバー エリア用、パブリック マーケティング エリア用、管理サイト用、マーケティング キャンペーン管理サイト用)。ただし、3 つのコンポーネントはすべて同じデータベースと同じビジネス オブジェクトで動作するため、各モジュールを同じモデルにポイントできるようにする必要があります。

ただし、ドキュメントでこれを行う方法に関する情報を見つけることができませんでした。これを行う方法に関するリンクまたはそれを達成する方法に関するいくつかの簡単な指示を手伝ってくれる人はいますか?

4

5 に答える 5

9

私がしていることは、モジュール階層の外側の「ライブラリ」ディレクトリに共通クラスを保持することです。次にINCLUDE_PATH、それぞれのモジュールの「models」ディレクトリと共通の「library」ディレクトリを使用するように my を設定します。

docroot/
    index.php
application/
    library/    <-- common classes go here
    default/
        controllers/
        models/
        views/
    members/
        controllers/
        models/
        views/
    admin/
        controllers/
        models/
        views/
. . .

私のブートストラップ スクリプトでは、「application/library/」をINCLUDE_PATH. 次に、各コントローラーのinit()関数で、そのモジュールの " models/" ディレクトリをINCLUDE_PATH.

edit:setControllerDirectory()のように 機能setModuleDirectory()し、それぞれのモデル ディレクトリを に追加しませんINCLUDE_PATH。いずれにせよ、これは自分で行う必要があります。これを行う方法の一例を次に示します。

$app = APPLICATION_HOME; // you should define this in your bootstrap
$d = DIRECTORY_SEPARATOR;
$module = $this->_request->getModuleName(); // available after routing
set_include_path(
  join(PATH_SEPARATOR,
    array(
      "$app{$d}library",
      "$app{$d}$module{$d}models",
      get_include_path()
    )
  )
);

ブートストラップでパスに" " を追加することはできlibraryますが、ブートストラップで正しいモジュールの " " ディレクトリを追加することはできませんmodels。これは、モジュールがルーティングに依存しているためです。コントローラーのメソッドでこれを行う人もいればinit()、ActionController の preDispatch フックのプラグインを作成してINCLUDE_PATH.

于 2008-11-03T18:22:00.327 に答える
3

これは、命名規則に従って行うこともできますZend_Loader。モデル ファイルは、モジュール フォルダーの下のモデル フォルダーに保存します。という名前を付けてModule_Models_ModelName、そのモジュールのモデル フォルダーに ModelName.php というファイル名で保存します。アプリケーションフォルダーがインクルードパスにあることを確認し、Zend_Loader自動読み込みに使用していると仮定すると、モデルをクラス名で参照できます。

これには、モデル コードを実際のモジュールにグループ化したままにしておくという利点があります。これにより、カプセル化を促進するのに役立つ単一のフォルダー構造内に含まれるモジュールが保持されます。これは、将来、モジュールを別のプロジェクトに移植する必要がある場合にも役立ちます。

于 2008-11-16T04:14:39.013 に答える
1

あなたが説明した問題のために、このカスタム アクション ヘルパーを作成しました。

<?php

class My_Controller_Action_Helper_GetModel extends Zend_Controller_Action_Helper_Abstract
{
  /**
   * @var Zend_Loader_PluginLoader
   */
  protected $_loader;

  /**
   * Initialize plugin loader for models
   * 
   * @return void
   */
  public function __construct()
  {
    // Get all models across all modules
    $front = Zend_Controller_Front::getInstance();
    $curModule = $front->getRequest()->getModuleName();

    // Get all module names, move default and current module to
    //  back of the list so their models get precedence
    $modules = array_diff(
      array_keys($front->getDispatcher()->getControllerDirectory()),
      array('default', $curModule)
    );
    $modules[] = 'default';
    if ($curModule != 'default') {
      $modules[] = $curModule;
    }

    // Generate namespaces and paths for plugin loader
    $pluginPaths = array();
    foreach($modules as $module) {
      $pluginPaths[ucwords($module)] = $front->getModuleDirectory($module) . '/models';
    }

    // Load paths
    $this->_loader = new Zend_Loader_PluginLoader($pluginPaths);
  }

  /**
   * Load a model class and return an object instance
   * 
   * @param  string $model 
   * @return object
   */
  public function getModel($model)
  {
    $class = $this->_loader->load($model);
    return new $class;
  }

  /**
   * Proxy to getModel()
   * 
   * @param  string $model 
   * @return object
   */
  public function direct($model)
  {
    return $this->getModel($model);
  }
}

したがって、Bootstrap.php では次のようになります。

Zend_Controller_Action_HelperBroker::addPrefix('My_Controller_Action_Helper');

そして、あなたのコントローラーのいずれかで:

<?php

class IndexController extends Zend_Controller_Action 
{
  public function indexAction() 
  {
    $model = $this->_helper->getModel('SomeModel');
  }
}

これにより、すべてのモジュールで任意のコントローラーのモデルにアクセスできるようになります。

于 2009-06-02T23:19:09.667 に答える
0

私は同じ問題を抱えています。ビルの答えは私には合いません - 私は自分のモジュールを「誰が見ているか」ではなく、「彼らが何をしているか」で分ける傾向があるからです。たとえば、「フォーラム モジュール」は、管理者と公開者の両方によって管理される場合があります。admin、members、public などのフロント エンド モジュールを使用しようとしていますが、これらは「forum/validatepost」、「forum/show users personal info」などの他のモジュールを使用します。バックエンドモジュールを公開から保護する方法を誰かが明らかにできれば、それは便利です. ACL が鍵になると思いますが、「ファイル システム/.htaccess」などとは対照的に、オブジェクトによってアクセスが制御されていることに不安を覚えます。

PHPoet の質問に答えるには: (i) モジュールのコントローラー ディレクトリへのパスは、フロント コントローラーの呼び出しによって指定できます。たとえば、「12.11.2. モジュール コントローラー ディレクトリの指定」(Zend Framework Docs) を参照してください。

(ii) ビューへのパスは、ViewRenderer (コントローラー アクション ヘルパー) を使用して設定できます。別のビュー スクリプトの選択' (Zend Framework Docs)

ビューとコントローラーへのデフォルトのパスを変更する可能性をいじることで、オートローダーを解放して通常どおりに実行できます。

(オートローダの動作については調べていませんが、この種の問題を解決するためのマッパー システムを用意することは理にかなっています。)

于 2009-05-20T22:45:43.230 に答える
0

<?php
return array(
'modules' => array(
    'Application',
    'DoctrineModule',
    'DoctrineORMModule',
    'Merchant',
),
'module_listener_options' => array(
    'config_glob_paths'    => array(
        'config/autoload/{,*.}{global,local}.php',
    ),
    'module_paths' => array(
        './module',
        '../vendor',
//            'here we can load module'
        'comomonmodule'   

    ),
),
);
于 2013-10-03T05:42:29.517 に答える