我想创建一个自动查询构建器,它从控制器中的url获取params并将其传递给我的存储库。
现在我有一组键/过滤器,查询可以使用它来构建其where子句,它匹配url中的params的键,它可以工作。只要我只用一把钥匙。
如果我...做:
".../api/v1/companies?is_accountant=0" -->WORKS
".../api/v1/companies?is_accountant=0&name=test&street=testLane -->FAILS, returns empty
记录存在于我的数据库中,但它返回一个空对象。如果我用1键单独尝试,它会找到记录
有人能发现问题吗?
private $filters = ['id','street','name','is_accountant','nr_ext','postal_code'];
public function getCompaniesFilterd($params, $limit)
{
if (!empty($params)) {
$query = Company::query();
foreach($params as $param)
{
foreach($this->filters as $filter)
{
if(key($params) == $filter)
{
$query->where($filter,'=',$param);
}
}
}
$companies = $query->get();
dd($query);
return $companies;
}
return Company::take(10)->get();
}
输出
{
"data": []
}
查询转储
object(Illuminate\Database\Eloquent\Builder)[222]
protected 'query' =>
object(Illuminate\Database\Query\Builder)[221]
protected 'connection' =>
object(Illuminate\Database\MySqlConnection)[212]
protected 'pdo' =>
object(PDO)[181]
...
protected 'readPdo' => null
protected 'reconnector' =>
object(Closure)[220]
...
protected 'queryGrammar' =>
object(Illuminate\Database\Query\Grammars\MySqlGrammar)[211]
...
protected 'schemaGrammar' => null
protected 'postProcessor' =>
object(Illuminate\Database\Query\Processors\MySqlProcessor)[214]
...
protected 'events' =>
object(Illuminate\Events\Dispatcher)[14]
...
protected 'paginator' =>
object(Closure)[219]
...
protected 'cache' =>
object(Closure)[218]
...
protected 'fetchMode' => int 8
protected 'transactions' => int 0
protected 'queryLog' =>
array (size=1)
...
protected 'loggingQueries' => boolean true
protected 'pretending' => boolean false
protected 'database' => string 'homestead' (length=9)
protected 'tablePrefix' => string '' (length=0)
protected 'config' =>
array (size=9)
...
protected 'grammar' =>
object(Illuminate\Database\Query\Grammars\MySqlGrammar)[211]
protected 'selectComponents' =>
array (size=11)
...
protected 'tablePrefix' => string '' (length=0)
protected 'processor' =>
object(Illuminate\Database\Query\Processors\MySqlProcessor)[214]
protected 'bindings' =>
array (size=5)
'select' =>
array (size=0)
...
'join' =>
array (size=0)
...
'where' =>
array (size=3)
...
'having' =>
array (size=0)
...
'order' =>
array (size=0)
...
public 'aggregate' => null
public 'columns' =>
array (size=1)
0 => string '*' (length=1)
public 'distinct' => boolean false
public 'from' => string 'companies' (length=9)
public 'joins' => null
public 'wheres' =>
array (size=3)
0 =>
array (size=5)
...
1 =>
array (size=5)
...
2 =>
array (size=5)
...
public 'groups' => null
public 'havings' => null
public 'orders' => null
public 'limit' => null
public 'offset' => null
public 'unions' => null
public 'lock' => null
protected 'backups' =>
array (size=0)
empty
protected 'cacheKey' => null
protected 'cacheMinutes' => null
protected 'cacheTags' => null
protected 'cacheDriver' => null
protected 'operators' =>
array (size=19)
0 => string '=' (length=1)
1 => string '<' (length=1)
2 => string '>' (length=1)
3 => string '<=' (length=2)
4 => string '>=' (length=2)
5 => string '<>' (length=2)
6 => string '!=' (length=2)
7 => string 'like' (length=4)
8 => string 'not like' (length=8)
9 => string 'between' (length=7)
10 => string 'ilike' (length=5)
11 => string '&' (length=1)
12 => string '|' (length=1)
13 => string '^' (length=1)
14 => string '<<' (length=2)
15 => string '>>' (length=2)
16 => string 'rlike' (length=5)
17 => string 'regexp' (length=6)
18 => string 'not regexp' (length=10)
protected 'model' =>
object(Winbooks\Core\Models\Company)[213]
protected 'table' => string 'companies' (length=9)
protected 'fillable' =>
array (size=10)
0 => string 'name' (length=4)
1 => string 'street' (length=6)
2 => string 'nr_ext' (length=6)
3 => string 'postal_code' (length=11)
4 => string 'city' (length=4)
5 => string 'phone' (length=5)
6 => string 'fax' (length=3)
7 => string 'email' (length=5)
8 => string 'is_accountant' (length=13)
9 => string 'country_id' (length=10)
protected 'connection' => null
protected 'primaryKey' => string 'id' (length=2)
protected 'perPage' => int 15
public 'incrementing' => boolean true
public 'timestamps' => boolean true
protected 'attributes' =>
array (size=0)
empty
protected 'original' =>
array (size=0)
empty
protected 'relations' =>
array (size=0)
empty
protected 'hidden' =>
array (size=0)
empty
protected 'visible' =>
array (size=0)
empty
protected 'appends' =>
array (size=0)
empty
protected 'guarded' =>
array (size=1)
0 => string '*' (length=1)
protected 'dates' =>
array (size=0)
empty
protected 'touches' =>
array (size=0)
empty
protected 'observables' =>
array (size=0)
empty
protected 'with' =>
array (size=0)
empty
protected 'morphClass' => null
public 'exists' => boolean false
protected 'eagerLoad' =>
array (size=0)
empty
protected 'macros' =>
array (size=0)
empty
protected 'onDelete' => null
protected 'passthru' =>
array (size=12)
0 => string 'toSql' (length=5)
1 => string 'lists' (length=5)
2 => string 'insert' (length=6)
3 => string 'insertGetId' (length=11)
4 => string 'pluck' (length=5)
5 => string 'count' (length=5)
6 => string 'min' (length=3)
7 => string 'max' (length=3)
8 => string 'avg' (length=3)
9 => string 'sum' (length=3)
10 => string 'exists' (length=6)
11 => string 'getBindings' (length=11)
答案 0 :(得分:0)
我能够用你的代码重新演绎这种行为,但我不确定是什么导致它。错误似乎是过滤器值不会改变,循环可能有一些奇怪的问题。所以我想把它作为一个重写和改进你的代码的机会,因为我认为Laravel允许一种更优雅的方式来做到这一点。
private $filters = ['id','street','name','is_accountant','nr_ext','postal_code'];
public function getCompaniesFiltered($params, $limit = 10)
{
$params = array_diff_key($params, $this->filters);
if(empty($params))
{
return Company::take($limit)->get();
}
return Company::where($params)->get();
}
使用getCompaniesFiltered(Input::all());
调用它对我来说很好。
修改强> 在仔细观察循环之后,我很确定问题只是一个额外的's':
if(key($params) == $filter)
应该是
if(key($param) == $filter)
if (1 == 'name')
(或比较布尔值,字符串和一些整数)可能会导致PHP中出现一种非常奇怪的行为。
编辑2:
注意:请不要在同一主题下提出单独的问题。虽然它们是相关的,但它们仍然是不同的问题,但是你应该给予那些回答它们的人以获得两者的功劳。既然你似乎是StackOverflow的新手,那么现在就让它保持原状,但请记住以后的问题。
asewers:
“如果我使用你之前的建议它有效,但我刚注意到,如果你输入一个错误的参数仍然想搜索表格 - &gt;导致表格中找不到错误行。 “
是的,array_diff
不是最好的选择,应该是:
$params = array_intersect_key($params, array_flip($this->filters))
“我正在尝试像以前一样查询,但现在我也希望能够将params放在我的相关模型上。”
再一次,Laravel使用Eloquent的eager loading concept让这很容易。该课程可能如下所示:
private $mainFilters = ['id', 'name', 'preview','user_id', 'date', 'status'];
private $fileFilters = ['path', 'uuid'];
private $invoicesFilters = ['due_date', 'payment_status', 'type'];
public function getDocumentsFiltered($params, $limit = 10)
{
$dependencies = $this->getDependencies($params);
$documentParams = $this->filterParams($params, $this->mainFilters));
$documents = Document::with($dependencies);
if(empty($documentParams))
{
return $documents->take($limit)->get();
}
return $docuemnts->where($documentParams)->get();
}
protected function getDependencies($params)
{
$fileParams = $this->filterParams($params, $this->fileFilters));
$invoiceParams = $this->filterParams($params, $this->invoiceFilters));
return [
'file' => function($query) use ($fileParams) {
$query->where($fileParams);
},
'invoice' => function($query) use ($invoiceParams) {
$query->where($invoiceParams);
},
'user',
'folder',
];
}
protected function filterParams($input, $filter)
{
return array_intersect_key($input, array_flip($filter);
}
代码没有评论,但我认为它几乎解释了自己。
答案 1 :(得分:0)
@Quasdunk你的最后一个答案确实是更好的选择/答案。如果我使用你以前的建议它有效,但我只是注意到,如果你输入一个错误的参数仍然想搜索表 - &gt;导致找不到表中的错误行。
这是我的最终代码
private $filters = ['id', 'name', 'date', 'status'];
public function getDocumentListFilterd($params, $limit = 10)
{
if (!empty($params)) {
$query = Document::query();
foreach($params as $param => $value)
{
foreach($this->filters as $filter)
{
if($param == $filter)
{
$query->where($filter,'=',$value);
}
}
}
$documents = $query->get();
//dd($query);
return $documents;
}
return Company::take(10)->get();
}