我想要这个
$this->$model_name->findByProgram_id($id)
执行类似这样的事情
$this->$model_name->findBy.$field_id($id)
其中$field_id = 'program_id
和$id
是实际字段值。
这是动态调用函数所必需的。是否可以或我应该用硬编码的字段名称进行处理。
希望这会有意义! 谢谢客栈提前
答案 0 :(得分:3)
尽管findByXXX魔术方法有时很方便,但它们并不总是检索数据的最有效方法。
通过 no not 我会告诉你完全避免使用它们,但使用它们时需要考虑几件事情;
魔术方法依赖于一种神奇的__call()
方法,该方法由PHP调用(如果存在)。我不打算在这里开始另一场辩论,因为已有几场辩论exist。魔术方法确实有用,可以在很多情况下使用。
请注意;
findById()
不存在于您的源代码中)find(xxx)
提供的所有功能 CakePHP模型可能定义了很多“关系”。虽然只需拨打Model->find('all')
即可为您提供所需的所有数据,但在大多数情况下,它会为您提供超出您的需求。 CakePHP中的Model->find('all')
等同于SQL中的此查询;
SELECT * FROM tableA JOIN tableB JOIN tableC.....
换句话说;它将获取tableA,tableB和tableC的所有相关字段和记录。
在大多数情况下,您不需要所有数据,这样的查询效率低下,使用大量内存,导致您的网站效果不佳。
CakePHP有一个recursive
选项,可让您指定深检索数据的方式,例如通过设置recursive = -1
,CakePHP将只检索'main'表中的数据,而不是相关的表;
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将不会执行任何操作,因此默认情况下将其添加到{{ 1}} AppModel的数组
无论您是否正在使用ContainableBehavior,具体是总是良好做法。 始终检查CakePHP执行的SQL查询,以检查它们是否有意义。 始终检查这些查询返回的数据 ;检查它们是否包含您不会使用的数据。
$actsAs
)中将递归设置为-1
。如果确实需要,只将递归设置为1或2。如果是这样,请在每个查询的基础上执行此操作。public $recursive = -1;
而不仅仅是'ModelA.name'
),则优先使用模型别名为字段添加前缀,以防止出错。尝试将所有与数据相关的逻辑/代码移出控制器并将其移至模型中。
回到原来的问题;创建自己的“便利”方法,允许您通过任何字段搜索模型,例如;启用搜索用户模型并仅检索ID,名称和部门名称
'name'
这可能看起来像很多代码,但是,如果你对CakePHP更有经验,那么这样的方法将在不到5分钟的时间内完成。从积极的一面;它们将为您提供完整的控制权,并且可以轻松修改以满足您的需求。
在你的控制器中,代码量只有一行;像这样使用它;
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',
)
)
);
}
}
答案 1 :(得分:1)
你可以通过使用Cakephp中的inflector类来实现,这是一个概念所以可能需要充实但是......
$methodName = 'findBy' . Inflector:camelize($field_id);
$this->$model_name->$methodName($id);