Функция/метод, чтобы получить выборочные столбцы


Можно ли упростить getRows() или это нормально, как сейчас?

protected $container;
public function __construct(ContainerInterface $container) {
    $this->container = $container;
    $this->em = $this->getDoctrine()->getManager();
}

/*
* @param    $ntt              name of the entity to fetch
* @param    $cols             columns to fetch
* @param    $where            array of data to be matched (for example array('id'=>1))
* @param    $result_type      type of result required. (object|array)
*/
public function getRows($ntt,$cols=array(),$where=array(),$result_type=null){
    $data = 'nulllllll';
    if($ntt && $where && is_array($where)){
        $i = 1;
        $filter = '';
        foreach ($where as $key => $value) {
            if(is_array($value)){
                $filter = $filter.($filter ? ' AND ' : '')."tm.$key in (:v$i)";
            }else{
                $filter = $filter.($filter ? ' AND ' : '')."tm.$key = :v$i";
            }
            $param['v'.$i] = $value;
            $i++;
        }

        $select = 'tm';
        if($cols){
            $select = '';
            foreach ($cols as $col) {
                $select = $select.($select ? ', ' : '')."tm.$col";
            }
        }

        $ntt = 'AppBundle:'.$ntt;
        $data = $this->em->getRepository($ntt)->createQueryBuilder('tm')
        ->select($select)
        ->where($filter)
        ->setParameters($param)
        ->getQuery();
        if($result_type == 'array'){
            $data = $data->getArrayResult();
        }else{
            $data = $data->getResult();
        }
    }
    return $data;
}

Звоню:

getRows('My_user',array('lName','llname'),array('id'=>array(1,4,50)),'array')

Где My_user мое лицо, имя и lName и llname колонки я хочу принести.

Вывод:

Array
(
    [0] => Array
        (
            [lName] => Abc
            [llname] => Sha
        )

    [1] => Array
        (
            [lName] => And
            [llname] => Bainbri
        )

    [2] => Array
        (
            [lName] => Ken
            [llname] => Lee
        )

)


131
0
задан 16 марта 2018 в 12:03 Источник Поделиться
Комментарии
2 ответа

Я предлагаю свой код, чтобы быть переписан следующим образом (Пожалуйста, обратите внимание на встроенные комментарии):

<?php

// Requires PHP >= 5.4

public function getRows($ntt, $cols = array(), $where = array(), $result_type = null)
{
$data = 'nulllllll';

// Early return after checking arguments,
// instead of nesting the rest of the code inside the if{}
if (!($ntt && $where && is_array($where))) {
return $data;
}

$filters = [];
$param = [];

// The callback function here uses outer variables: `$filters` and `$param`,
// that are passed by reference `&`
array_walk($where, function($value, $key) use (&$filters, &$param) {
static $i = 0;
$i++;

$placeholder = "v{$i}";
$condition = is_array($value) ? "in (:{$placeholder})" : "= :{$placeholder}";
$filters[] = "tm.{$key} {$condition}";
$param[$placeholder] = $value;
});

// Use `implode` to concatenate the `$filters` into a string
$filter = implode(' AND ', $filters);

$select = 'tm';
if (!empty($cols) && is_array($cols)) {
$select = implode(', ', array_map(function($column) {
return "tm.{$column}";
}, $cols));
}

$repository = "AppBundle:{$ntt}";
$data = $this->em->getRepository($repository)->createQueryBuilder('tm')
->select($select)
->where($filter)
->setParameters($param)
->getQuery();

if ($result_type === 'array') {
return $data->getArrayResult();
}

return $data->getResult();
}

1
ответ дан 17 марта 2018 в 12:03 Источник Поделиться

Эту функцию твой теряется сама идея ОРМ. Собственное решение является менее гибким и менее надежны, чем оригинальные доктрины. Пусть только все типа намекая, предоставляемые вашей IDE будет недоступен.

Вместо вызова этой функции вы должны использовать

$this->em->getRepository(My_user::class)->find([1,4,50])->getArrayResult();

В случае, если вам нужно применить другой фильтр, а затем просто использовать findBy() вместо того, чтобы найти().

Вы должны понимать, что нынешняя модель использования доктрины есть сильная причина. Реализуя свои функции, вы будете вводить много потенциальных проблем, делая их трудно отлаживать. Что делает ваш код менее гибким одновременно. Не говоря уже о жесткой связи, что делает ваше приложение, чтобы опираться на такие соображения, как расслоение всегда называли AppBundle, предприятие менеджер всегда одинакова и т. д.

1
ответ дан 19 марта 2018 в 10:03 Источник Поделиться