如何在laravel sql查询中获得灵活性

I want to add a sql filter where('comment_id', '=', 1) to php code

$datas = $this->model->ADD HERE->orderBy('created_at', 'DESC')->paginate(15);

Trying to add the string to code take me hours. How to make it?


Here is my code:

CommentResource.php passing the sql filter as string parameter.

<?php
class CommentResource extends BaseResource
{    
    public function index()
    {
        $filter = "where('comment_id', '=', 1)";
        return parent::index_filter($filter);
    }

CommentResource.php

<?php
class BaseResource extends Controller
{
    protected function index_filter($filter)
    {
        $datas = $this->model->ADD HERE->orderBy('created_at', 'DESC')->paginate(15);
        return view($this->resourceView.'.index')->with('datas', $datas);
    }
}

As I understand you want to use different types of where as filters in your queries. That's why you want to make them dynamic. I would suggest the following solution for your task:

<?php
class CommentResource extends BaseResource
{    
    public function index()
    {
        $filter = [ 'operator' => 'where', 'args' => ['comment_id', '=', 1]];
        return parent::index_filter($filter);
    }

<?php
class BaseResource extends Controller
{
    protected function index_filter($filter)
    {
        $where = $filter['operator'];
        $args = $filter['args'];
        $datas = $this->model->$where(...$args)->orderBy('created_at', 'DESC')->paginate(15);
        return view($this->resourceView.'.index')->with('datas', $datas);
    }
}

However, it will work starting from Php5.6+ because of oeprator ...

I am not sure if I got your requirements correctly, but if you rewrite index_filter to accept field and value separately, then you may user a regular where() from laravel:

protected function index_filter($field,$value)
  {
    $datas = $this->model->where($field,$value)->orderBy('created_at', 'DESC')->paginate(15);
    return view($this->resourceView.'.index')->with('datas', $datas);
}

You can find the docs here. In case you really need more flexibility:

protected function index_filter($filter)
  {
    $datas = $this->model->whereRaw($filter)->orderBy('created_at', 'DESC')->paginate(15);
    return view($this->resourceView.'.index')->with('datas', $datas);
}

Have in mind though that this is really dangerous, as you expose the possibility to inject malicious code, it should be definitely properly escaped beforehand.

My latest code works right. I'll post here.

<?php
class CommentResource extends BaseResource
{    
    public function index()
    {
        $options = [
          'filters'=>[
                       [ 'operator' => 'where',
                         'args'     => [
                                         [ 'article_id', '=', $article_id ],
                                         [ 'comment_id', '=', $comment_id ],
                                         // add filter args...
                                       ],
                       ],
                       // add filter operators here...
                     ],
          'sorts' => [
                       'column'     => $sortColumn, // change sort column...
                       'order'      => $sortOrder,  // change sort order...
                     ],
                   ];
        return parent::index_filter($options);
    }

<?php
class BaseResource extends Controller
{
    protected function index_filter($options, $number=15)
    {
        $result   = $this->model;
        foreach ($options['filters'] as $filter) {
            $operator = $filter['operator'];
            $args     = $filter['args'];
            $result   = $result->$operator($args);
        }
        if ( $options['sorts'] != [] ) {
            $column   = $options['sorts']['column'];
            $order    = $options['sorts']['order'];
            $result   = $result->orderBy($column, $order);
        }
        return $result->paginate($number);
    }
}

The reason I change ...$args to $args is, when 'args' has more than on value, for example,

                 'args'     => [
                                 [ 'article_id', '=', $article_id ],
                                 [ 'comment_id', '=', $comment_id ],
                                 // add filter args...
                               ],

...$args will change 'args' to one array, but $args will remain 'args' as nest array, which is the operator 'where' want.