我要这个
$this->$model_name->findByProgram_id($id)
要执行这样的事情
$this->$model_name->findBy.$field_id($id)
其中$field_id = 'program_id
和$id
是实际的字段值。这是动态调用函数所必需的。是否有可能或者我应该使用硬编码的字段名称进行处理。
希望这是有道理的!!!提前感谢客栈
我要这个
$this->$model_name->findByProgram_id($id)
要执行这样的事情
$this->$model_name->findBy.$field_id($id)
其中$field_id = 'program_id
和$id
是实际的字段值。这是动态调用函数所必需的。是否有可能或者我应该使用硬编码的字段名称进行处理。
希望这是有道理的!!!提前感谢客栈
尽管 findByXXX 魔术方法有时很方便,但它们并不总是检索数据的最有效方法。
我绝不会告诉您完全避免使用它们,但是在使用它们时需要考虑一些事项;
魔术方法依赖于__call()
PHP 调用的魔术方法(如果存在)。我不打算在这里开始另一场辩论,因为有几个已经存在。魔术方法确实有目的,可以在许多情况下使用。
请注意;
findById()
中不存在)find(xxx)
功能CakePHP 模型可能定义了很多“关系”。尽管简单地调用Model->find('all')
会为您提供所需的所有数据,但在大多数情况下,它会为您提供比您需要的更多的数据。Model->find('all')
CakePHP 中的这个查询相当于 SQL 中的这个查询;
SELECT * FROM tableA JOIN tableB JOIN tableC.....
换句话说; 它将获取tableA、tableB和tableC的所有相关字段和记录。
在大多数情况下,您不需要所有这些数据,这样的查询效率低下,占用大量内存,并导致您的网站性能不佳。
CakePHP 有一个recursive
选项,允许您指定检索数据的深度,例如,通过设置recursive = -1
,CakePHP 将只从“主”表中检索数据,而不是从相关表中检索数据;
SELECT * FROM tableA;
但是,如果您想从 tableA 和 tableC 中检索数据而不是从 tableB 中检索数据,那么您在使用时就不走运了recursive
如果您想获得更好的控制,请使用Containable behavior
. 例如,此行为允许您准确指定应包含在结果中的关系;
$this->ModelA->find('all', array(
'fields' => array(
'ModelA.id',
'ModelA.name',
'ModelC.name',
),
'contain' => array(
'ModelC',
)
));
只要您没有contain
在选项中指定键find
, ContainableBehavior 就不会做任何事情,因此默认情况下通过将其添加到$actsAs
AppModel 的数组中来添加此行为是保存的
无论您是否使用 ContainableBehavior,具体化始终是一种好习惯。始终检查 CakePHP 执行的 SQL 查询以检查它们是否有意义。始终检查这些查询返回的数据;检查它们是否不包含您不会使用的数据。
-1
在您的 AppModel ( public $recursive = -1;
)中默认将递归设置为。如果您确实需要它,请仅将递归设置为 1 或 2。如果是这样,请在每个查询的基础上执行此操作。'ModelA.name'
如果关系中的多个表包含具有相同名称的字段(例如使用而不是 just 'name'
),最好在字段前加上模型别名以防止错误尝试将所有与数据相关的逻辑/代码移出控制器并将其移至模型。
回到你原来的问题;例如,创建您自己的“方便”方法,允许您按任何字段搜索模型;启用搜索您的用户模型并仅检索 id、名称和部门名称
User extends AppModel
{
public $actsAs = array('Containable');
public function searchByField($field, $value)
{
return $this->find('all',
array(
'fields' => array(
'User.id',
'User.name',
'Department.name',
),
'conditions' => array(
// this will dynamically search by $field
$field => $value,
),
'contain' => array(
'Department',
)
)
);
}
}
这可能看起来像很多代码,但是,如果您对 CakePHP 有更多的经验,这样的方法可以在不到 5 分钟的时间内编写出来。从积极的一面; 它们将使您完全控制将要检索的内容,并且可以轻松修改以满足您的需求。
在您的控制器中,代码量只有一行;像这样使用它;
// Search by email
$data = $this->User->searchByField('User.email', 'foo@example.com');
// Search by name
$data = $this->User->searchByField('User.name', 'admin');
您可以通过使用 Cakephp 中的变形器类来做到这一点,这是一个概念,因此可能需要充实但是......
$methodName = 'findBy' . Inflector:camelize($field_id);
$this->$model_name->$methodName($id);