我在Repository类中编写了这个函数,以便从Doctrine接收一个简单的键值。难道没有构建Doctrine函数来执行此操作吗? (我无法找到它)。或者可以改进代码。
这是我的功能:
public function getListBy($criteria=null, $key, $value) {
$dql = "SELECT i.".$key." as k,
i.".$value." as v
FROM MbFooBundle:Input i";
if (isset($criteria) && is_array($criteria)) {
foreach($criteria as $cKey => $cValue) {
if (!isset($where))
$where = " WHERE ";
else
$where .= " AND ";
$where .= "i.".$cKey." = ".(is_numeric($cValue) ? $cValue : "'".$cValue."'");
}
$dql .= $where;
}
$query = $this->getEntityManager()
->createQuery($dql);
$result = $query->getArrayResult();
$list = array();
if (count($result)) {
foreach($result as $data) {
$list[$data['k']] = $data['v'];
}
}
return $list;
}
答案 0 :(得分:2)
我不会这样做。但是这段代码很容易被SQL Injection攻击,但它也会破坏一些standards。
这是我的思维方式 我会创建一个方法来操纵标准学说findBy
的结果/**
* Data Manipulator
*/
class DataManipulator
{
/**
* Associates any traversable input into its key and value
*
* @param mixed $input A Traversable input
* @param string $key Key to associate
* @param string $value Value to associate
* @return array Associated array
*
* @throws InvalidArgumentException When Input is not traversable
*/
public function associate($input, $key, $value)
{
if (!is_array($input) && !($input instanceof Traversable)) {
throw new InvalidArgumentException("Expected traversable");
}
$out = array();
foreach ($input as $row) {
$out[$this->getInput($row, $key)] = $this->getInput($row, $value);
}
return $out;
}
/**
* Fetches the input of a given property
*
* @param mixed $row An array or an object
* @param string $find Property to find
* @return mixed Property's value
*
* @throws UnexpectedValueException When no matching with $find where found
*/
protected function getInput($row, $find)
{
if (is_array($row) && array_key_exists($find, $row)) {
return $row[$find];
}
if (is_object($row)) {
if (isset($row->$find)) {
return $row->$find;
}
$method = sprintf("get%s", $find);
if (method_exists($row, $method)) {
return $row->$method();
}
}
throw new UnexpectedValueException("Could not find any method to resolve");
}
}
然后你可以使用它
$em = $this->getDoctrine()->getManager();
$results = $em->getRepository('AcmeFooBundle:Input')
->findBy(array('category' => 'foo'));
$manipulator = new DataManipulator;
$filtered = $manipulator->associate($results, 'key', 'value');
如果您只需要选择部分对象,则应在存储库中创建一个方法,该方法将获取您的部分输入。
此功能必须必须获取对象,而不是关联其内容。
public function findPartialBy(array $values, array $criterias = array())
{
$qb = $this->createQueryBuilder('i');
$qb->select($values);
foreach ($criterias as $key => $value) {
$qb->andWhere(sprintf("i.%s", $key), sprintf(":%s", $key))
$qb->setParameter(sprintf(":%s", $key), $value);
}
return $qb->getQuery()->getResult();
}
然后你可以使用它
$fetch = array('key', 'value');
$em = $this->getDoctrine()->getManager();
$results = $em->getRepository('AcmeFooBundle:Input')
->findPartialBy($fetch, array('category' => 'foo'));
$manipulator = new DataManipulator;
$filtered = $manipulator->associate($results, 'key', 'value');