ThinkPHP 關聯模型定義中,mapping_type 值必須使用常量而非字符串,這是導致關聯查詢失效的高頻低級錯誤。本文揭示核心差異、錯誤現象、正確寫法。
class EliteMajorModel extends RelationModel {
protected $_link = array(
'EliteStudent' => array(
// ❌ 錯誤:字符串 'HAS_MANY' - 框架無法識別
'mapping_type' => 'HAS_MANY',
// ✅ 正確:常量 HAS_MANY - 框架內部常量識別
'mapping_type' => HAS_MANY,
'class_name' => 'EliteStudent',
'foreign_key' => 'mid',
'mapping_name' => 'studentslist',
),
);
}
ThinkPHP 內部關聯類型判斷邏輯:
// ThinkPHP/Model/RelationModel.class.php 片段
switch ($linkInfo['mapping_type']) {
case HAS_MANY: // 常量比較
// 處理一對多邏輯
break;
case BELONGS_TO:
// ...
// 字符串 'HAS_MANY' 不會匹配任何 case 分支
}
HAS_MANY 定義為整數 1(或其他具體值)'HAS_MANY' 是字符串,switch 嚴格比較失敗default 分支或拋出異常,關聯失效| 關係類型 | 常量名 | 錯誤寫法 | 正確寫法 |
|---|---|---|---|
| 一對多 | HAS_MANY | 'HAS_MANY' | HAS_MANY |
| 屬於 | BELONGS_TO | 'BELONGS_TO' | BELONGS_TO |
| 一對一 | HAS_ONE | 'HAS_ONE' | HAS_ONE |
| 多對多 | MANY_TO_MANY | 'MANY_TO_MANY' | MANY_TO_MANY |
class ArticleModel extends RelationModel {
protected $_link = array(
// 一對多:文章 -> 評論
'Comment' => array(
'mapping_type' => HAS_MANY,
'class_name' => 'Comment',
'foreign_key' => 'article_id',
'mapping_name' => 'comments',
'mapping_order' => 'create_time DESC',
'mapping_limit' => 10,
),
// 多對多:文章 <-> 標簽 (通過中間表 article_tag)
'Tag' => array(
'mapping_type' => MANY_TO_MANY,
'class_name' => 'Tag',
'foreign_key' => 'article_id',
'relation_foreign_key' => 'tag_id',
'relation_table' => 'article_tag',
'mapping_name' => 'tags',
),
// 屬於:文章 -> 作者
'Author' => array(
'mapping_type' => BELONGS_TO,
'class_name' => 'User',
'foreign_key' => 'author_id',
'mapping_name' => 'author',
'parent_key' => 'id',
),
);
}
// 使用
$article = M('Article')->relation(true)->find(1);
var_dump($article['comments']); // 評論列表
var_dump($article['tags']); // 標簽列表
var_dump($article['author']); // 作者信息
$model = M('Article');
// 查看解析後的關聯信息
var_dump($model->getRelationInfo());
// 或開啟 SQL 日誌查看生成的 JOIN 查詢
HAS_MANY、BELONGS_TO 等,不要加引號use Think\Model\RelationModel 或繼承關係正確Has_Many 會報錯Think\Model\RelationModel 中定義更多關聯模型技巧:《ThinkPHP關聯模型完全指南》、《複雜關聯查詢優化實戰》