概要
EC-CUBE 2系のSC_ClassAutoloader.phpにおいて、*_Exクラスファイルの期待パスと実際のファイル配置に相違がある問題について調査した結果をまとめる。
問題の発端
- 決済プラグインの提供する
data/class_extends/helper_extends/SC_Helper_Purchase_Ex.php が正常にロードされない環境がある
data/class/SC_ClassAutoloader.phpの145行目からの処理で、*_Exファイルが存在しない場合はエイリアスを作成している
- composerのオートローダーと、このエイリアスはどちらが優先されるか?
data/class_extends/helper_extends/SC_Helper_Purchase_Ex.phpの場合はどちらが優先されるか?
正常にロードされない環境での暫定対応
data/app_initial.php の末尾で、 require_once にて明示的にロードすることで解消可能
diff --git a/data/app_initial.php b/data/app_initial.php
index 57e4cf3b5..5e9bac2c3 100755
--- a/data/app_initial.php
+++ b/data/app_initial.php
@@ -65,3 +65,6 @@ SC_Helper_HandleError_Ex::load();
// アプリケーション初期化処理
$objInit = new SC_Initial_Ex();
$objInit->init();
+
+require_once(CLASS_EX_REALDIR . 'helper_extends/SC_Helper_Purchase_Ex.php');
+require_once(CLASS_EX_REALDIR . 'helper_extends/SC_Helper_Payment_Ex.php');
オートローダー優先順位
登録順序
- Composerオートローダー:
html/define.php:16-20で最初にロード
- EC-CUBEカスタムオートローダー:
data/app_initial.php:56-61で後から登録
優先順位の決定要因
spl_autoload_register(
function ($class) {
SC_ClassAutoloader_Ex::autoload($class, __DIR__.'/downloads/plugin/');
},
true, true // 第3引数がtrueで先頭に登録
);
結論: spl_autoload_registerの第3引数がtrueのため、EC-CUBEオートローダーがComposerオートローダーより優先される。
パス解決の仕組み
SC_Helper_Purchase_Ex の例
1. クラス名の分析
SC_Helper_Purchase_Ex → ['SC', 'Helper', 'Purchase', 'Ex']
$is_ex = true(末尾が'Ex')
$count = 4
$classpath = CLASS_EX_REALDIR (data/class_extends/)
2. パス構築(47-59行目の条件分岐)
条件:($arrClassNamePart[0] === 'SC') && $is_ex === true && $count >= 4
3. 詳細条件(54-58行目)
if ($count === 4 && $arrClassNamePart[2] != 'Index' && $arrClassNamePart[3] === 'Ex') {
$classpath .= strtolower(implode('/', array_slice($arrClassNamePartTemp, 1, -1))).'/';
}
4. 最終パス構築
$arrClassNamePartTemp = ['SC', 'Helper_extends', 'Purchase', 'Ex'](50行目で変更)
array_slice($arrClassNamePartTemp, 1, -1) → ['Helper_extends', 'Purchase']
- 最終的な期待パス:
data/class_extends/helper_extends/purchase/SC_Helper_Purchase_Ex.php
期待パスと実際パスの相違
1. SC_Helper_*_Ex 系(24ファイル)
代表例:SC_Helper_Purchase_Ex
- オートローダー期待パス:
data/class_extends/helper_extends/purchase/SC_Helper_Purchase_Ex.php
- 実際のファイルパス:
data/class_extends/helper_extends/SC_Helper_Purchase_Ex.php
影響を受けるファイル一覧:
- SC_Helper_Kiyaku_Ex.php
- SC_Helper_Purchase_Ex.php
- SC_Helper_HandleError_Ex.php
- SC_Helper_Category_Ex.php
- SC_Helper_Mailtemplate_Ex.php
- SC_Helper_PageLayout_Ex.php
- SC_Helper_News_Ex.php
- SC_Helper_Customer_Ex.php
- SC_Helper_Holiday_Ex.php
- SC_Helper_Address_Ex.php
- SC_Helper_Payment_Ex.php
- SC_Helper_FileManager_Ex.php
- SC_Helper_FPDI_Ex.php
- SC_Helper_BestProducts_Ex.php
- SC_Helper_Bloc_Ex.php
- SC_Helper_CSV_Ex.php
- SC_Helper_TaxRule_Ex.php
- SC_Helper_Mail_Ex.php
- SC_Helper_Maker_Ex.php
- SC_Helper_Delivery_Ex.php
- SC_Helper_Plugin_Ex.php
- SC_Helper_Session_Ex.php
- SC_Helper_Transform_Ex.php
- SC_Helper_Mobile_Ex.php
- SC_Helper_DB_Ex.php
2. SC_Graph_*_Ex 系(4ファイル)
代表例:SC_Graph_Bar_Ex
- オートローダー期待パス:
data/class_extends/graph_extends/bar/SC_Graph_Bar_Ex.php
- 実際のファイルパス:
data/class_extends/graph_extends/SC_Graph_Bar_Ex.php
影響を受けるファイル:
- SC_Graph_Bar_Ex.php
- SC_Graph_Line_Ex.php
- SC_Graph_Pie_Ex.php
- SC_Graph_Base_Ex.php
3. SC_Api_*_Ex 系(3ファイル)
代表例:SC_Api_Abstract_Ex
- オートローダー期待パス:
data/class_extends/api_extends/abstract/SC_Api_Abstract_Ex.php
- 実際のファイルパス:
data/class_extends/api_extends/SC_Api_Abstract_Ex.php
影響を受けるファイル:
- SC_Api_Abstract_Ex.php
- SC_Api_Operation_Ex.php
- SC_Api_Utils_Ex.php
4. SC_DB_DBFactory_*_Ex 系(2ファイル)
代表例:SC_DB_DBFactory_MYSQL_Ex
- オートローダー期待パス:
data/class_extends/db_extends/dbfactory/mysql/SC_DB_DBFactory_MYSQL_Ex.php
- 実際のファイルパス:
data/class_extends/db_extends/dbfactory/SC_DB_DBFactory_MYSQL_Ex.php
影響を受けるファイル:
- SC_DB_DBFactory_MYSQL_Ex.php
- SC_DB_DBFactory_PGSQL_Ex.php
5. SC_SessionFactory_*_Ex 系(2ファイル)
代表例:SC_SessionFactory_UseRequest_Ex
- オートローダー期待パス:
data/class_extends/sessionfactory_extends/userequest/SC_SessionFactory_UseRequest_Ex.php
- 実際のファイルパス:
data/class_extends/sessionfactory_extends/SC_SessionFactory_UseRequest_Ex.php
影響を受けるファイル:
- SC_SessionFactory_UseRequest_Ex.php
- SC_SessionFactory_UseCookie_Ex.php
6. Admin系の深い階層(多数)
代表例:LC_Page_Admin_Order_Multiple_Ex
- オートローダー期待パス:
data/class_extends/page_extends/admin/order/multiple/LC_Page_Admin_Order_Multiple_Ex.php
- 実際のファイルパス:
data/class_extends/page_extends/admin/order/LC_Page_Admin_Order_Multiple_Ex.php
7. operations下のファイル(13ファイル)
代表例:CartModify_Ex
- オートローダー期待パス:
data/class_extends/CartModify/Ex.php (PEAR形式のパス変換)
- 実際のファイルパス:
data/class_extends/api_extends/operations/CartModify_Ex.php
影響を受けるファイル:
- CartModify_Ex.php
- CartAdd_Ex.php
- AddrFromZip_Ex.php
- CartCreate_Ex.php
- ItemSearch_Ex.php
- CartGet_Ex.php
- BrowseNodeLookup_Ex.php
- GetVersion_Ex.php
- Default_Ex.php
- CartClear_Ex.php
- ItemLookup_Ex.php
ファイル存在チェックの実行箇所
主要チェック箇所
- SC_ClassAutoloader.php:147行目(エイリアス作成前)
if (!file_exists($classpath) && str_contains($class, '_Ex')) {
class_alias(preg_replace('/_Ex$/', '', $class), $class);
}
- SC_ClassAutoloader.php:152行目(メインのファイルロード)
if (file_exists($classpath)) {
include $classpath;
} else {
// include_pathでの検索処理(155-162行目)
}
実際の動作フロー
期待パスと実際パスに相違がある場合:
- 152行目の
file_exists($classpath)がfalseを返す
- 155-162行目のinclude_path検索が実行される
- Composerのclassmapオートローダーが実際のファイルパスを把握しているため、最終的にファイルがロードされる
- 147-149行目のエイリアス作成処理は実行されない(ファイルが存在するため)
ただし、環境によってはエイリアス作成処理が実行され、 *_Ex クラスが正常にロードされない場合がある模様
影響範囲
合計影響ファイル数
約70個以上のファイルで期待パスと実際パスに相違があると推定される。
正常に動作する理由
- Composerのclassmapが実際のファイル位置を正確に把握
- include_path検索によるフォールバック機能
- spl_autoload_register チェーンによる複数オートローダー連携
技術的考察
問題の根本原因
- EC-CUBEオートローダーのパス構築ロジックが実際のファイル配置規則と一致していない
- SC_ClassAutoloader.php:49行目のコメント「クラスファイルのディレクトリ命名が変。変な現状に合わせて強引な処理をしてる。」が示す通り、既知の設計問題
現在の解決策
- Composer classmapとinclude_path検索によるフォールバック機能で実質的に解決されている
- パフォーマンス上の軽微な影響はあるものの、機能的には問題なし
- 環境によってはエイリアス作成処理が優先されてしまう場合があるので、修正が望ましい
概要
EC-CUBE 2系の
SC_ClassAutoloader.phpにおいて、*_Exクラスファイルの期待パスと実際のファイル配置に相違がある問題について調査した結果をまとめる。問題の発端
data/class_extends/helper_extends/SC_Helper_Purchase_Ex.phpが正常にロードされない環境があるdata/class/SC_ClassAutoloader.phpの145行目からの処理で、*_Exファイルが存在しない場合はエイリアスを作成しているdata/class_extends/helper_extends/SC_Helper_Purchase_Ex.phpの場合はどちらが優先されるか?正常にロードされない環境での暫定対応
data/app_initial.phpの末尾で、 require_once にて明示的にロードすることで解消可能オートローダー優先順位
登録順序
html/define.php:16-20で最初にロードdata/app_initial.php:56-61で後から登録優先順位の決定要因
結論:
spl_autoload_registerの第3引数がtrueのため、EC-CUBEオートローダーがComposerオートローダーより優先される。パス解決の仕組み
SC_Helper_Purchase_Ex の例
1. クラス名の分析
SC_Helper_Purchase_Ex→['SC', 'Helper', 'Purchase', 'Ex']$is_ex = true(末尾が'Ex')$count = 4$classpath = CLASS_EX_REALDIR(data/class_extends/)2. パス構築(47-59行目の条件分岐)
条件:
($arrClassNamePart[0] === 'SC') && $is_ex === true && $count >= 43. 詳細条件(54-58行目)
4. 最終パス構築
$arrClassNamePartTemp = ['SC', 'Helper_extends', 'Purchase', 'Ex'](50行目で変更)array_slice($arrClassNamePartTemp, 1, -1)→['Helper_extends', 'Purchase']data/class_extends/helper_extends/purchase/SC_Helper_Purchase_Ex.php期待パスと実際パスの相違
1. SC_Helper_*_Ex 系(24ファイル)
代表例:SC_Helper_Purchase_Ex
data/class_extends/helper_extends/purchase/SC_Helper_Purchase_Ex.phpdata/class_extends/helper_extends/SC_Helper_Purchase_Ex.php影響を受けるファイル一覧:
2. SC_Graph_*_Ex 系(4ファイル)
代表例:SC_Graph_Bar_Ex
data/class_extends/graph_extends/bar/SC_Graph_Bar_Ex.phpdata/class_extends/graph_extends/SC_Graph_Bar_Ex.php影響を受けるファイル:
3. SC_Api_*_Ex 系(3ファイル)
代表例:SC_Api_Abstract_Ex
data/class_extends/api_extends/abstract/SC_Api_Abstract_Ex.phpdata/class_extends/api_extends/SC_Api_Abstract_Ex.php影響を受けるファイル:
4. SC_DB_DBFactory_*_Ex 系(2ファイル)
代表例:SC_DB_DBFactory_MYSQL_Ex
data/class_extends/db_extends/dbfactory/mysql/SC_DB_DBFactory_MYSQL_Ex.phpdata/class_extends/db_extends/dbfactory/SC_DB_DBFactory_MYSQL_Ex.php影響を受けるファイル:
5. SC_SessionFactory_*_Ex 系(2ファイル)
代表例:SC_SessionFactory_UseRequest_Ex
data/class_extends/sessionfactory_extends/userequest/SC_SessionFactory_UseRequest_Ex.phpdata/class_extends/sessionfactory_extends/SC_SessionFactory_UseRequest_Ex.php影響を受けるファイル:
6. Admin系の深い階層(多数)
代表例:LC_Page_Admin_Order_Multiple_Ex
data/class_extends/page_extends/admin/order/multiple/LC_Page_Admin_Order_Multiple_Ex.phpdata/class_extends/page_extends/admin/order/LC_Page_Admin_Order_Multiple_Ex.php7. operations下のファイル(13ファイル)
代表例:CartModify_Ex
data/class_extends/CartModify/Ex.php(PEAR形式のパス変換)data/class_extends/api_extends/operations/CartModify_Ex.php影響を受けるファイル:
ファイル存在チェックの実行箇所
主要チェック箇所
実際の動作フロー
期待パスと実際パスに相違がある場合:
file_exists($classpath)がfalseを返すただし、環境によってはエイリアス作成処理が実行され、
*_Exクラスが正常にロードされない場合がある模様影響範囲
合計影響ファイル数
約70個以上のファイルで期待パスと実際パスに相違があると推定される。
正常に動作する理由
技術的考察
問題の根本原因
現在の解決策