简体   繁体   English

从Doctrine获取键值列表

[英]Get key value list from Doctrine

I wrote this function inside my Repository class to receive a simple key value from Doctrine. 我在Repository类中编写了这个函数,以便从Doctrine接收一个简单的键值。 Isn't there a build in Doctrine function to do this? 是不是有Doctrine函数的内置来做这个? (I couldn't find it). (我找不到它)。 Or maybe the code can be improved. 或者可以改进代码。

Here's my function: 这是我的功能:

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;
}

I wouldn't do this. 我不会这样做。 Yet this code is vulnerable to SQL Injection but it also breaks some standards . 然而,这段代码很容易受到SQL注入攻击,但它也打破了一些标准

Here's my way of thinking. 这是我的思维方式。
I would create a method which will manipulate the results of the standard doctrine's findBy 我会创建一个方法来操纵标准学说的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");
    }
}

Then you can use it 然后你可以使用它

$em      = $this->getDoctrine()->getManager();
$results = $em->getRepository('AcmeFooBundle:Input')
               ->findBy(array('category' => 'foo'));

$manipulator = new DataManipulator;
$filtered    = $manipulator->associate($results, 'key', 'value');

You can see it working 你可以看到它的工作原理


If you need to select only partial objects, you should create a method in your repository which will fetch your partial input. 如果只需要选择部分对象,则应在存储库中创建一个获取部分输入的方法。
This function must only fetch the object, not associate its content. 此函数必须仅获取对象,而不是关联其内容。

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();
}

Then you can use it 然后你可以使用它

$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');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM