2

Ubuntu12.04でのZend-Frameworkアプリケーションの単体テストに関して問題が発生しました。プロジェクト構造はデフォルトのzendアプリケーションですが、モデルは次のように定義されています。

./application
  ./models
    ./DbTable
      ./ProjectStatus.php (Application_Model_DbTable_ProjectStatus)
    ./Mappers
      ./ProjectStatus.php (Application_Model_Mapper_ProjectStatus)
    ./ProjectStatus.php   (Application_Model_ProjectStatus)

ここでの問題は、Zend固有の自動ロードにあります。ここでの命名規則は、フォルダMappersがすべてのクラスに_Mapperをロードしますが、 _Mappersはロードしないように見えます。これは、これまでのところ問題のない内部Zendの動作です。

私のWindowsマシンでは、phpunitは問題なく実行され、これらすべてのクラスを開始しようとします。

ただし、jenkinsが実行されているUbuntuマシンでは、phpunitが適切なクラスを見つけられず、次のエラーが発生します。

Fatal error: Class 'Application_Model_Mapper_ProjectStatus' not found 
in /var/lib/jenkins/jobs/PAM/workspace/tests/application/models/Mapper/ProjectStatusTest.php
on line 39

エラーは、Zend-Autoloaderがubuntuマシンからロードされないことであるように見えますが、これがどのように、またはなぜ機能するのか理解できません。これがなぜなのかという疑問が残ります。zend autoloadingのものとのすべての接点を再確認したと思いますが、これを理解することはできません。-私の観点からは関連するスニペットを貼り付けます-そしてあなたの誰かがこれについて何か洞察を持っていることを願っています。

PHPUnit用のJenkinsスニペット

 <target name="phpunit" description="Run unit tests with PHPUnit">
   <exec executable="phpunit" failonerror="true">
     <arg line="--configuration '${basedir}/tests/phpunit.xml' --coverage-clover '${basedir}/build/logs/clover.xml' --coverage-html '${basedir}/build/coverage/.' --log-junit '${basedir}/build/logs/junit.xml'" />
   </exec>
 </target>

./tests/phpunit.xml

<phpunit bootstrap="./bootstrap.php">
   ... this shouldn't be of relevance ...
</phpunit>

./tests/bootstrap.php

<?php
// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));

require_once 'Zend/Loader/Autoloader.php';    
Zend_Loader_Autoloader::getInstance();

どんな助けでもありがたいです。

4

3 に答える 3

2

実際、問題は「models/Mappers」フォルダにあると思います。これは「モデル/マッパー」(すべて小文字)である必要があり、LinuxではなくWindowsで機能する理由を説明します。

Zend_Application_Module_Autoloaderクラスからわかるように、次のようになります。

$this->addResourceTypes(array(
            'dbtable' => array(
                'namespace' => 'Model_DbTable',
                'path'      => 'models/DbTable',
            ),
            'mappers' => array(
                'namespace' => 'Model_Mapper',
                'path'      => 'models/mappers',
            ),

ただし、以前の回答によると、すべてのデフォルトリソースを自動的に追加するには、アプリケーションをブートストラップする必要があると思います。

于 2012-07-03T14:55:24.763 に答える
1

ZFマニュアルから:

モデルとデータベーステーブルを作成する

始める前に、何かを考えてみましょう。これらのクラスはどこにあり、どのように見つけるのでしょうか。作成したデフォルトのプロジェクトは、オートローダーをインスタンス化します。他のオートローダーを接続して、さまざまなクラスの場所を認識できるようにすることができます。通常、さまざまなMVCクラスを同じツリー(この場合はapplication /)の下にグループ化し、ほとんどの場合、共通のプレフィックスを使用します。

Zend_Controller_Frontには、個々のミニアプリケーションである「モジュール」の概念があります。モジュールは、zfツールがapplication /の下に設定するディレクトリ構造を模倣しており、モジュール内のすべてのクラスは、共通のプレフィックスであるモジュール名で始まると想定されています。application/はそれ自体がモジュールです。「デフォルト」または「アプリケーション」モジュールです。そのため、このディレクトリ内のリソースの自動読み込みを設定する必要があります。

Zend_Application_Module_Autoloaderは、モジュールの下のさまざまなリソースを適切なディレクトリにマップするために必要な機能を提供し、標準の命名メカニズムも提供します。クラスのインスタンスは、ブートストラップオブジェクトの初期化中にデフォルトで作成されます。アプリケーションのブートストラップは、デフォルトでモジュールプレフィックス「Application」を使用します。そのため、モデル、フォーム、およびテーブルクラスはすべて、クラスプレフィックス「Application_」で始まります。

Zend_Application_Module_Autoloaderはデフォルトでロードされるため、この回答の例のように、アプリケーションをブートストラップするだけで済みます(フロントコントローラーを実行する必要はありません)。

アプリケーションをブートストラップしたくない場合は、Zend_Application_Module_Autoloaderを自分で初期化することにより、リソースのロードを短絡させることができます。

$autoloader = new Zend_Application_Module_Autoloader();

コードからわかるように、このクラスの__constructはinitDefaultResourceTypes()を呼び出し、探しているすべての機能を備えています。

class Zend_Application_Module_Autoloader extends Zend_Loader_Autoloader_Resource
{
    /**
     * Constructor
     *
     * @param  array|Zend_Config $options
     * @return void
     */
    public function __construct($options)
    {
        parent::__construct($options);
        $this->initDefaultResourceTypes();
    }

    /**
     * Initialize default resource types for module resource classes
     *
     * @return void
     */
    public function initDefaultResourceTypes()
    {
        $basePath = $this->getBasePath();
        $this->addResourceTypes(array(
            'dbtable' => array(
                'namespace' => 'Model_DbTable',
                'path'      => 'models/DbTable',
            ),
            'mappers' => array(
                'namespace' => 'Model_Mapper',
                'path'      => 'models/mappers',
            ),
            'form'    => array(
                'namespace' => 'Form',
                'path'      => 'forms',
            ),
            'model'   => array(
                'namespace' => 'Model',
                'path'      => 'models',
            ),
            'plugin'  => array(
                'namespace' => 'Plugin',
                'path'      => 'plugins',
            ),
            'service' => array(
                'namespace' => 'Service',
                'path'      => 'services',
            ),
            'viewhelper' => array(
                'namespace' => 'View_Helper',
                'path'      => 'views/helpers',
            ),
            'viewfilter' => array(
                'namespace' => 'View_Filter',
                'path'      => 'views/filters',
            ),
        ));
        $this->setDefaultResourceType('model');
    }
}

tests / bootstrap.phpでフロントコントローラーを実行せずにアプリケーションのみをブートストラップするには:

<?php
// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));

require_once 'Zend/Loader/Autoloader.php';  

$config = array(
    APPLICATION_PATH . '/configs/application.ini'
);

// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    array('config' => $config)
);

$application->bootstrap();
于 2012-07-03T07:42:56.117 に答える
0

従来のオートローダーが機能しなかったので、Zendアプリケーションが行うことを手動で実行しようとしました。bootstrap.phpこれが最終的にうまくいったものです

<?php    
// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));

require_once 'Zend/Loader/Autoloader.php';
require_once 'Zend/Loader/Autoloader/Resource.php';
$resources = new Zend_Loader_Autoloader_Resource(array(
  'namespace' => 'Application',
  'basePath'  => APPLICATION_PATH
));

$resources->addResourceType('form','forms','Form');
$resources->addResourceType('model','models','Model');
$resources->addResourceType('dbtable','models/DbTable','Model_DbTable');
$resources->addResourceType('mapper','models/Mappers','Model_Mapper');

論理は通常、Zendが自分で理解する必要があるものです。実際、これはWindowsで実行されているローカル開発マシンで行われます。しかし、ubuntuでは具体的にする必要があります。

それがなぜであるかを知ることは興味深いでしょう。誰かが私に理由を説明することができれば、私はおそらくあなたに正しい答えを与えることになるでしょう;)

于 2012-07-03T08:02:32.400 に答える