環境
PHP 8.1.4RC1
CakePHP 4.3.6
想定
CakePHPではアソシエーションを用いることで以下のようなSQLに対して、次のようなオブジェクトでデータを扱える。
SQL
SELECT * FROM A JOIN B ON B.id = A.id JOIN C ON C.id = B.id
CakePHP
$a->belongsTo('b', ['className'=>'B', 'bindingKey'=>['id'], 'foreignKey'=>['id']]);
$a->b->belongsTo('c', ['className'=>'C', 'bindingKey'=>['id'], 'foreignKey'=>['id']]);
$data = $a->find()->contain(['b', 'b.c'])>all();
var_export
object(App\Model\Entity\A) id:0 {
'id' => 1,
'name' => 'Aのカラム',
...
'b' => object(App\Model\Entity\B) id:1 {
'id' => 1,
'name' => 'Bのカラム',
...
'c' => object(App\Model\Entity\C) id:1 {
'id' => 1,
'name' => 'Cのカラム',
...
}
}
}
現象
しかし、間で結合しているBはカラムを取得せずに、Cを取得しようとすると、エンティティBが取得できなかった。
SQL
SELECT a.id, c.id FROM A JOIN B ON B.id = A.id JOIN C ON C.id = B.id
CakePHP
$a->belongsTo('b', ['className'=>'B', 'bindingKey'=>['id'], 'foreignKey'=>['id']]);
$a->b->belongsTo('c', ['className'=>'C', 'bindingKey'=>['id'], 'foreignKey'=>['id']]);
$data = $a->find()->contain(['b', 'b.c'])->select(['a.id', 'c.id'])->all();
この場合、以下のように取得できるはずが、$a->b
が存在しない模様。
PHP
$a_id = $a->id;
$c_id = $a->b->c->id; // Attempt to read property "id" on null
var_export($a->b); //=> NULL
どういう文言で調べればいいかわからなかったので、select
にbの適当なカラムを設定することに。