2

私はかなり大きく成長した CakePHP で書かれた発信専用プロジェクトに取り組んでいます。このアーキテクチャは、多数のプラグインも使用します。プロジェクトの最初から、このアプリケーションのインスタンスは 1 つしかありませんでした。ただし、クライアントは、アプリケーションが機能する別の領域を見つけました。同じコードベースを使用しますが、別のデータベースを使用します。問題は、コードベースは実際には約 90% で適用できるということです。つまり、ほとんどの場合、コードベースは機能しますが、必要なわずかな変更がいくつかあります。いくつかの小さな機能強化の後、これらの変更がこの新しいインスタンスに対して継続されることは明らかです。しかし同時に、両方のインスタンスに適用される変更があります。アプリケーション全体で一連の条件を作成し、どのインスタンスが実際に実行されているかを確認するための非常にクリーンなソリューションではありません。

だから私の考えは:

  • プロジェクトを 1 つのリポジトリに保持し、1 つのコードベースのすべてのインスタンスに適用可能な変更と修正を行う
  • 必要な場合にのみ、特定のインスタンスに対してのみ、プロジェクトのデフォルト クラスをオーバーロードするクラスを含む、ある種の「mod」を作成します。
  • より明確にするために、これらの新しいクラスを含むアプリディレクトリに並列ファイル構造を持たせるのが最善です(もちろん、必要なもののみ)
  • 非常に重要なことは、ケーキのコアにまったく触れないことです。いつでも問題なくアップグレードできるようにしたいです

例:

app/controllers/invoices_controller.php:
InvoicesController extends AppController {
  public function generateInvoice() {}
}

newbusinness/controllers/invoices_controller.php:
NewbusinessInvoicesController extends InvoicesController {
  public function generateInvoice() {}
}

私たちが行くときに重要なことは次のとおりです。

www.mynewbusinnes.com/Invoices/generateInvoice

NewbusinessInvoicesController->generateInvoice()そのような子コントローラーとメソッドが存在するため、システムは自動的に を呼び出します。それ以外の場合は、デフォルトのコントローラーとメソッドを呼び出します。

低レベルのローディング クラスで、CakePHP 用にそのようなモードを作成することは可能ですか? 「実験的」とマークされている限り、runkit_method_redefine()たとえばメソッドを使用したり置き換えたりしたくありません。提案やアイデアはありますか?App::import()runkit_method_redefine()

4

2 に答える 2

2

低レベルのローディング クラスで、CakePHP 用にそのようなモードを作成することは可能ですか? runkit_method_redefine() が「実験的」とマークされている限り、runkit_method_redefine() を使用して、たとえば App::import() メソッドを置き換えたくありません。提案やアイデアはありますか?

すべてのリクエストは、最初に を通過しapp/webroot/index.phpます。このファイルはコアの一部ではなく、自分で変更できます。できることは、インクルード パスを変更して、独自に作成したフォルダをリストすることCAKE_CORE_INCLUDE_PATHです。ここでは/absolute/path/to/custom、インクルード パスとして設定します。

if (function_exists('ini_set') && ini_set('include_path', ROOT . DS . 'custom' . PATH_SEPARATOR . CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'))) {

このセクションに続いて、CakePHP のコア ブートストラップ ファイルがロードされ ( /cake/bootstrap.php)、多くのコア クラスがロードされ始めます。

require CORE_PATH . 'cake' . DS . 'basics.php';
$TIME_START = getMicrotime();
require CORE_PATH . 'cake' . DS . 'config' . DS . 'paths.php';
require LIBS . 'object.php';
require LIBS . 'inflector.php';
require LIBS . 'configure.php';
require LIBS . 'set.php';
require LIBS . 'cache.php';
Configure::getInstance();
require CAKE . 'dispatcher.php';

独自のインクルード パスを挿入したら、それらをそのパスにコピーして置き換えることができます。

ROOT
|- app/
|- cake/
  |- libs/
    |- configure.php // this would usually be loaded
|- custom/
  |- cake/
    |- libs/
      |- configure.php // now this is loaded

(注:configure.phpファイルにはConfigureAppクラスの両方が含まれています。)

つまり、 の 1 行を変更するだけでapp/webroot/index.php、直接編集せずに CakePHP のコアの任意の部分を置き換えることができます。

これで必要な変更を加えることができるかもしれませApp::importんが、これは実際にはどこにも文書化されていないため、マイレージは異なる場合があります.

于 2012-01-17T17:11:06.527 に答える
1

だから私の考えは:

  • プロジェクトを 1 つのリポジトリに保持し、1 つのコードベースのすべてのインスタンスに適用可能な変更と修正を行う
  • 必要な場合にのみ、特定のインスタンスに対してのみ、プロジェクトのデフォルト クラスをオーバーロードするクラスを含む、ある種の「mod」を作成します。
  • より明確にするために、これらの新しいクラス(もちろん必要なもののみ)を含むアプリディレクトリに並列ファイル構造を持たせることが最善です-非常に重要なことは、ケーキのコアにまったく触れないことです。いつでも問題なくアップグレードできる

これについては以前の回答で触れましたが、追加のクラス パスは、探している CakePHP の機能のように思えます。「mod」アプリの次のようなものは、 CakePHP にディレクトリbootstap.phpからもファイルをロードするように指示する必要があります。core

App::build(array(
    'plugins'     => array(ROOT . DS . 'core' . DS . 'plugins' . DS),
    'models'      => array(ROOT . DS . 'core' . DS . 'models' . DS),
    'views'       => array(ROOT . DS . 'core' . DS . 'views' . DS),
    'controllers' => array(ROOT . DS . 'core' . DS . 'controllers' . DS),
    'datasources' => array(ROOT . DS . 'core' . DS . 'models' . DS . 'datasources' . DS),
    'behaviors'   => array(ROOT . DS . 'core' . DS . 'models' . DS . 'behaviors' . DS),
    'components'  => array(ROOT . DS . 'core' . DS . 'controllers' . DS . 'components' . DS),
    'helpers'     => array(ROOT . DS . 'core' . DS . 'views' . DS . 'helpers' . DS),
    'vendors'     => array(ROOT . DS . 'core' . DS . 'vendors' . DS),
    'shells'      => array(ROOT . DS . 'core' . DS . 'vendors' . DS . 'shells' . DS),
    'locales'     => array(ROOT . DS . 'core' . DS . 'locale' . DS),
));

上記は、 と の代わりに、次のような新しいフォルダー構造を想定してい/appます/cake

- ROOT
|- app1 // look here first,
|- app2
|- core // then here,
|- cake // then lastly here.
于 2012-01-17T15:17:17.590 に答える