Laravel 5从数据库结果中形成另一个数组

时间:2022-10-25 08:19:19

I'm new to Laravel and I've been struggling too long with this now, tried to search SO and google for information but can't solve this.

我是Laravel的新手,我已经在这个问题上挣扎了太久了,我试着搜索SO和谷歌来寻找信息,但是无法解决这个问题。

I'm creating blog and need to make some kind of navigation/archive which displays year and months and how many blog posts there have been per year and invidual month. By clicking those years/months I would then display posts during that time period on different view.

我正在创建博客,需要做一些导航/存档,显示年份和月份,以及每年和每个月有多少博客文章。通过点击那些年/月,我将在那个时间段显示不同观点的帖子。

I want them to be displayed in the view like this:

我希望它们像这样显示在视图中:

2015 (10)
  January(3)
  February(3)
  March(3)
  April(1)
2014 (2)
  May(1)
  June(1)

And so on.

等等。

I got database query like this:

我得到这样的数据库查询:

    $links = \DB::table('posts')
    ->select(\DB::raw('YEAR(created_at) year, MONTH(created_at) month, MONTHNAME(created_at) month_name, COUNT(*) id'))
    ->where('active',1)
    ->groupBy('year')
    ->groupBy('month')
    ->orderBy('year', 'desc')
    ->orderBy('month', 'desc')
    ->get();

Which gives me table like this:

我的桌子是这样的:

   array:3 [
      0 => {#275
        +"year": "2015"
        +"month": "10"
        +"month_name": "October"
        +"id": "3"
      }
      1 => {#274
        +"year": "2015"
        +"month": "9"
        +"month_name": "September"
        +"id": "1"
      }
      2 => {#273
        +"year": "2014"
        +"month": "8"
        +"month_name": "August"
        +"id": "1"
      }
    ]

How can I print it on my view like I described? If I go through the array in views like this:

如何像我描述的那样在我的视图上打印它?如果我像这样在视图中遍历数组:

@foreach($links as $link)
    <h3 class="text-uppercase"><a href="{{ url('blog/'.$link->year) }}">{{ $link->year }}</a></h3>
    <p><small class="blog_date"><a href="{{ url('blog/'.$link->year.'/'.$link->month) }}">{{ $link->month_name }} ({{ $link->id }}) </a></small>
@endforeach

I tried to use foreach-loop in my Controller to create another array from DB-results where structure would be in correct form and I could just use foreach to print it on the view, but couldn't get it work.

我尝试在我的控制器中使用foreach-loop从DB-results中创建另一个数组,其中的结构应该是正确的形式,我可以使用foreach在视图上打印它,但是不能让它工作。

I know I'm near the solution, but I'm still learning. Please someone tell me which is the best way to do this.

我知道我已经接近解决方案了,但我还在学习。请告诉我哪一个是最好的方法。

2 个解决方案

#1


1  

Try this in your blade:

在你的剑刃上试试这个:

<?php $first_loop = 0; ?>
@foreach($links as $link)
    @if($first_loop == 0)
        <?php 
        $first_loop = 1;
        $current_year = $link->year;
        ?>
        <h3 class="text-uppercase"><a href="{{ url('blog/'.$link->year) }}">{{ $link->year }}</a></h3>
        <p><small class="blog_date"><a href="{{ url('blog/'.$link->year.'/'.$link->month) }}">{{ $link->month_name }} ({{ $link->id }}) </a></small></p>
    @else
        @if($current_year == $link->year)
            <p><small class="blog_date"><a href="{{ url('blog/'.$link->year.'/'.$link->month) }}">{{ $link->month_name }} ({{ $link->id }}) </a></small></p>
            <?php
            $current_year = $link->year;
            ?>
        @else
            <h3 class="text-uppercase"><a href="{{ url('blog/'.$link->year) }}">{{ $link->year }}</a></h3>
            <p><small class="blog_date"><a href="{{ url('blog/'.$link->year.'/'.$link->month) }}">{{ $link->month_name }} ({{ $link->id }}) </a></small></p>
            <?php
            $current_year = $link->year;
            ?>
        @endif
    @endif
@endforeach

#2


1  

You can do some preparation on your data before outputting it. For example:

在输出数据之前,你可以对数据做一些准备。例如:

$links = // .. your query;

$years = array_pluck($links, 'year');

$results = [];


foreach($years as $year)
{
   $posts_count = 0;
   $posts = array_where($links, function($key, $value) use ($year, $posts_count){
         if($value['year'] == $year)
         {
            $posts_count += $value['id'];
            return true;
         }

         return false;
   });

   $results[$year] = ['posts' => $posts, 'posts_count' => $posts_count];
}

You can do the above in some repository/service class, or even in the controller if you want (although not recommended)

您可以在某些存储库/服务类中执行上述操作,甚至可以在控制器中执行(尽管不建议这样做)

And then in your view you can have something like:

在你看来

@foreach($results as $year => $result)
   <a href="">{{ $year }} {{ data_get($result, 'posts_count') }}</a>
       <ul> 
            @foreach(data_get($result, 'posts') as $monthly_post)
               <li><a href="">{{ data_get($monthly_post, 'month_name') }} {{ data_get($monthly_post, 'id') }}</a></li>
            @endforeach
       </ul>
@endforeach

This code is untested, so use it as inspiration for your approach, not a copy-paste solution.

这段代码没有经过测试,所以请将它作为您的方法的灵感,而不是复制粘贴解决方案。

#1


1  

Try this in your blade:

在你的剑刃上试试这个:

<?php $first_loop = 0; ?>
@foreach($links as $link)
    @if($first_loop == 0)
        <?php 
        $first_loop = 1;
        $current_year = $link->year;
        ?>
        <h3 class="text-uppercase"><a href="{{ url('blog/'.$link->year) }}">{{ $link->year }}</a></h3>
        <p><small class="blog_date"><a href="{{ url('blog/'.$link->year.'/'.$link->month) }}">{{ $link->month_name }} ({{ $link->id }}) </a></small></p>
    @else
        @if($current_year == $link->year)
            <p><small class="blog_date"><a href="{{ url('blog/'.$link->year.'/'.$link->month) }}">{{ $link->month_name }} ({{ $link->id }}) </a></small></p>
            <?php
            $current_year = $link->year;
            ?>
        @else
            <h3 class="text-uppercase"><a href="{{ url('blog/'.$link->year) }}">{{ $link->year }}</a></h3>
            <p><small class="blog_date"><a href="{{ url('blog/'.$link->year.'/'.$link->month) }}">{{ $link->month_name }} ({{ $link->id }}) </a></small></p>
            <?php
            $current_year = $link->year;
            ?>
        @endif
    @endif
@endforeach

#2


1  

You can do some preparation on your data before outputting it. For example:

在输出数据之前,你可以对数据做一些准备。例如:

$links = // .. your query;

$years = array_pluck($links, 'year');

$results = [];


foreach($years as $year)
{
   $posts_count = 0;
   $posts = array_where($links, function($key, $value) use ($year, $posts_count){
         if($value['year'] == $year)
         {
            $posts_count += $value['id'];
            return true;
         }

         return false;
   });

   $results[$year] = ['posts' => $posts, 'posts_count' => $posts_count];
}

You can do the above in some repository/service class, or even in the controller if you want (although not recommended)

您可以在某些存储库/服务类中执行上述操作,甚至可以在控制器中执行(尽管不建议这样做)

And then in your view you can have something like:

在你看来

@foreach($results as $year => $result)
   <a href="">{{ $year }} {{ data_get($result, 'posts_count') }}</a>
       <ul> 
            @foreach(data_get($result, 'posts') as $monthly_post)
               <li><a href="">{{ data_get($monthly_post, 'month_name') }} {{ data_get($monthly_post, 'id') }}</a></li>
            @endforeach
       </ul>
@endforeach

This code is untested, so use it as inspiration for your approach, not a copy-paste solution.

这段代码没有经过测试,所以请将它作为您的方法的灵感,而不是复制粘贴解决方案。