我刚开始使用CakePHP,遇到了一些问题。
我有一个搜索函数,用于搜索mysql数据库中的两个表(Artist和Artist姓氏),如下所示:
class ArtistsController extends AppController {
public function search ($search) {
if ($search){
$artists = $this->Artist->find('all', array('conditions' => array("surname like '%$search%' AND Artist.id = ArtistSurname.artist_id OR firstname like '%$search%' AND Artist.id = ArtistSurname.artist_id"), 'limit' => 400, 'fields' => array('Artist.firstname', 'ArtistSurname.surname', 'Artist.dbirth', 'Artist.id')));
if (!$artists){
throw new NotFoundException(__('No search result.'));
}
$result = array();
foreach ($artists as $artist) {
$fetchedArtist = array('value' => $artist['ArtistSurname']['surname'] . " " . $artist['Artist']['firstname'], 'year' => $artist['Artist']['dbirth'], 'id' => $artist['Artist']['id']);
array_push($result, $fetchedArtist);
}
header("Content-Type: application/json");
echo json_encode($result);
$this->autoRender = false;
}
}
查询之后,我将结果放入一个新的可读数组中,用于自动完成(typeahead.js)和
以json的形式回应。只要查询找到一个名字,但如果查询只找到姓氏,这就没问题。奇怪的是,只有在找到名字时,我才从GET请求中接收application/json,否则我将在text/html中得到正确的结果。这是为什么?
最佳答案
您使用一个单独的表来存储姓氏,并通过将INNER JOIN
指定为条件的一部分(两次)来构造一个Artist.id = ArtistSurname.artist_id
。
另外,您定义条件的方式是错误的;您应该对每个条件/字段使用“array”表示法,这样CakePHP将正确地为您转义值;
$artists = $this->Artist->find('all', array(
'conditions' => array(
'OR' => array(
'ArtistSurname.surname LIKE' => '%' . $search . '%',
'Artist.firstname LIKE' => '%' . $search . '%',
)
),
joins => array(
array(
'table' => 'artist_surnames',
'alias' => 'ArtistSurname',
'type' => 'LEFT',
'conditions' => array(
'Artist.id = ArtistSurname.artist_id',
)
),
),
'limit' => 400,
'fields' => array(
'Artist.firstname',
'ArtistSurname.surname',
'Artist.dbirth',
'Artist.id'
)
));
我将艺术家姓氏艺术家关系转换为“LEFT”连接,因此如果未找到“姓氏”,也将返回结果。
通常,您不必在查询中手动指定这些关系,而是在模型关系(Artist姓氏->归属->艺术家)中指定它们:
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#associations-linking-models-together
但是,我试图尽可能接近您的原始功能。
你为什么用一个单独的模特来称呼艺术家的姓氏?我想不出有什么理由把事情弄得这么复杂?
关于php - CakePHP带有JSON的搜索功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15706831/