1

Zend_Application_Module_Autoloaderのマニュアルには、次のように記載されています。

Zend_Applicationでモジュールブートストラップを使用する場合、Zend_Application_Module_Autoloaderのインスタンスがデフォルトでディスクリートモジュールごとに作成され、モジュールリソースを自動ロードできるようになります。

ソース: http: //framework.zend.com/manual/zh/zend.loader.autoloader-resource.html#zend.loader.autoloader-resource.module

これには、モジュールごとに空のブートストラップクラスを作成する必要があります。そうしないと、モジュールごとのリソースの自動読み込みが組み込みのオートローダーで機能しません。

今私は2つの質問があります

  • ディスクリートモジュールとは何ですか?
  • モジュールごとにブートストラップファイルを作成せずに、このリソースオートローダーをモジュールごとにデフォルトで登録する方法はありますか?各モジュールで利用できるようにしたいので、空のブートストラップクラスをたくさん作成するのは避けたいと思います。
4

5 に答える 5

7

各モジュールに空のブートストラップ クラスを追加することに抵抗があることは理解しています。ただし、再利用の場合を考えてみましょう。モジュールを個別にバンドルできる場合は、後で別のアプリケーションにドロップすることができ、オートロードは追加作業なしですぐに機能します。これは、モジュール ブートストラップの使用例の 1 つであり、現在のように動作する理由です。

(この場合の「個別」は「自己完結型」を意味し、「アプリケーション」モジュールの一部ではありません。)

この動作が気に入らない場合は、モジュールのブートストラップを自由に省略できます。モジュールのリソース オートローダーを何らかの方法で自分で追加する必要があるだけです。これは、ブートストラップ リソース メソッドを介してかなり簡単に実行できます。しかし、誰かが以前に投稿したように、テストされ文書化されたものが仕事を成し遂げるのに、なぜ車輪を再発明するのでしょうか? :)

于 2010-05-11T11:49:24.363 に答える
2

モジュールのブートストラップがオートロードを有効にする理由は、コンストラクターでオートローダーを設定する Zend_Application_Module_Bootstrap を拡張するためです。

public function __construct($application)
{
  //...
  if ($application->hasOption('resourceloader')) {
      $this->setOptions(array(
          'resourceloader' => $application->getOption('resourceloader')
      ));
  }
  $this->initResourceLoader();
  //...
}

これが実行されるのは、モジュール リソースが init 関数内の各モジュールのブートストラップを実行するためです ...

       foreach ($modules as $module => $moduleDirectory) {
        $bootstrapClass = $this->_formatModuleName($module) . '_Bootstrap';
        if (!class_exists($bootstrapClass, false)) {
            $bootstrapPath  = dirname($moduleDirectory) . '/Bootstrap.php';
            if (file_exists($bootstrapPath)) {
                $eMsgTpl = 'Bootstrap file found for module "%s" but bootstrap class "%s" not found';
                include_once $bootstrapPath;
                if (($default != $module)
                    && !class_exists($bootstrapClass, false)
                ) {
                    throw new Zend_Application_Resource_Exception(sprintf(
                        $eMsgTpl, $module, $bootstrapClass
                    ));
                } elseif ($default == $module) {
                    if (!class_exists($bootstrapClass, false)) {
                        $bootstrapClass = 'Bootstrap';
                        if (!class_exists($bootstrapClass, false)) {
                            throw new Zend_Application_Resource_Exception(sprintf(
                                $eMsgTpl, $module, $bootstrapClass
                            ));
                        }
                    }
                }
            } else {
                continue;
            }
        }

        if ($bootstrapClass == $curBootstrapClass) {
            // If the found bootstrap class matches the one calling this
            // resource, don't re-execute.
            continue;
        }

        $moduleBootstrap = new $bootstrapClass($bootstrap);
        $moduleBootstrap->bootstrap();
        $this->_bootstraps[$module] = $moduleBootstrap;
    }

簡単に言えば、空のブートストラップ ファイルを作成しない場合、適切に機能し、十分にテストされたコードの一部を独自のグローバル ブートストラップ ファイルに抽象化する必要があります。後でアプリでブートストラップする必要がある場合。

于 2010-05-10T23:41:09.937 に答える
2

モジュールを使用すると、アプリケーションを特定の問題に分けることができます。多くの場合、私の大規模なアプリケーションには、ユーザー用のデフォルト モジュールと、すべての管理機能を含む管理モジュールがあります。Zend Framework ドキュメントの「Zend Framework MVC アプリケーションの推奨プロジェクト構造 -> モジュール構造」セクションで推奨されているディレクトリ構造を使用しています。

2 番目の質問については、答えは「はい」と「いいえ」です。デフォルトの自動読み込み機能 (admin/forms ディレクトリから Admin_Form_Settings を読み込む) を利用したい場合は、各モジュールにブートストラップが必要です。詳細については、Zend Framework のモジュール ブートストラップに関する Matthew Weier O'Phinney の記事: すべきこととすべきでないことを参照してください。また、Rob Allen の投稿「Bootstrapping modules in ZF 1.8 and up」を Google で検索して確認することもできます。

2 番目の質問にはノーと答えます。各モジュールで空のブートストラップを必要としない、私が好んで使用する手法の 1 つは、すべてのアプリケーション クラスをアプリケーションの lib フォルダーに配置し、Zend Framework のディレクトリ構造を模倣することです。アプリケーションの名前が Example の場合、 /lib ディレクトリに Example という名前のフォルダーを作成します。ユーザー登録フォームは /lib/Example/Form に配置され、UserRegistration.php という名前が付けられます。私のクラスは、Example_Form_UserRegistration という名前になります。フォームを自動ロードするには、Bootstrap.php ファイルに次のものが必要です。

protected function _initAppAutoload() {

    $autoloader = Zend_Loader_Autoloader::getInstance();

    return $autoloader;
}

私のapplication.iniには行が含まれます

resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules[] = 
autoloaderNamespaces[] = "Example_"

この手法を使用すると、各モジュールに空のブートストラップを配置することなく、アプリケーションのどこにでも /lib/Example 内の任意のクラスを自動ロードできるはずです。

注: ドキュメントと Rob Allen の記事へのリンクを直接投稿しようとしましたが、私は初心者なので、リンクは 1 つしか許可されませんでした。リンクであるべきアイテムを Google に依頼して申し訳ありません。

于 2010-05-11T11:17:31.460 に答える
2

モジュール リソースのオートローダーを有効にするには、(私が知っている) 2 つの方法があります。最初のものは上記の回答でカバーされています。

application.ini にモジュール リソース行を追加します。

resources.modules[] =

次に、空のモジュール ブートストラップ ファイルを作成します。

2 つ目は、アプリケーション全体 (非モジュール) のブートストラップに次のブートストラップ メソッドを追加することです。

protected function _initModuleAutoload()
{
    $autoloader = new Zend_Application_Module_Autoloader(array(
        'namespace' => 'Foo',
        'basePath' => APPLICATION_PATH . "/modules/Foo",
    ));
    return $autoloader;
}

ただし、各モジュールのオートローダーを個別に作成する必要があります。個人的には、上記の理由から、空のブートストラップ ファイルを好みます。

注:これは、上記の@weerophinneyが言及した「ブートストラップリソースメソッド」だと思います。

于 2011-04-03T19:51:24.687 に答える
0

ブートストラップ:

$uri = explode('/',$_SERVER['REQUEST_URI']);
if($uri['1'] == 'flok'){
    $flok = new Zend_Controller_Router_Route('flok/:controller/:action/:id/*',  array('module' => 'flok', 'controller' => 'index', 'action' => 'index',  'id' =>null));
    $router->addRoute('flok', $flok);

    $resourceLoader = new Zend_Application_Module_Autoloader(array(
        'basePath'  => APPLICATION_PATH . "/flok/flok",
        'namespace' => 'Flok',
    ));

    //Init
    $frontController->registerPlugin(new Flok_Plugin_Init(),'flok');
    //Auth
    $frontController->registerPlugin(new Flok_Plugin_Auth(),'flok');

    // dynamic modules
    $ruta = APPLICATION_PATH.'/flok';
    foreach(scandir($ruta) as $mod) {
        if(!is_dir($mod) and $mod != '.DS_Store'){
            $Modululflok = new Zend_Controller_Router_Route('flok/'.$mod.'/:controller/:action/:id/*',  array('submodules' => 'flok','module' => $mod , 'controller' => 'index', 'action' => 'index',  'id' =>null));
            $router->addRoute($mod, $Modululflok);
            $resourceLoader = new Zend_Application_Module_Autoloader(array(
                'basePath'  => APPLICATION_PATH . "/flok/".$mod,
                'namespace' => ucfirst($mod),
            ));
        }
    }

    $layout = Zend_Layout::getMvcInstance();

    $layout
        ->setLayout('layout')
        ->setLayoutPath(APPLICATION_PATH . '/flok/flok/views/scripts');

    $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
    $viewRenderer->initView();
    $viewRenderer->view->addHelperPath(APPLICATION_PATH . '/flok/flok/helpers');
} else {
    $default = new Zend_Controller_Router_Route('*',  array('module' => 'default', 'controller' => 'index', 'action' => 'index'));
    $router->addRoute('default', $default);
}

コア モジュールにデータ (メニュー、ビューなど) を挿入するためのこのヘルパー:

class Zend_View_Helper_Models
{
    public function Models($tipo)
    {
        // load modules
        $ruta = APPLICATION_PATH.'/flok';
        foreach(scandir($ruta) as $mod) {
            if(!is_dir($mod) and $mod != '.DS_Store'){
                $rutaphp = $ruta.'/'.$mod.'/'.$mod.'.php';
                if(file_exists($rutaphp)){ 
                include_once($rutaphp);
                    $modul = new $mod;
                    if(isset($modul->$tipo) and $modul->$tipo === true){
                       $data = $tipo.'Data';
                       $m[] = $modul->$data;
                    } 
                }
            }
        }
        return $m;
    }

} 
于 2012-08-04T14:01:24.793 に答える