PHP Laravel, как сгруппировать данные даты в месяцы и добавить заголовок

Я создаю небольшое приложение Laravel, в котором я хочу отображать определенные выпуски, сгруппированные по месяцам. Что-то вроде этого:

January
11.1 - blabla
       more blablabla the same day

15.1 - blablabla

February
05.2 - blabla

etc...

Итак, в своем контроллере я просто делаю это:

public function index() {

  $releases = Release::orderBy('release_date', 'asc')->get();

  return view('pages.index')->with('releases', $releases);
}

И в моем файле просмотра лезвия я просматриваю данные:

@foreach ($releases as $release)
     <div>
        <p>
            <span>{{ \Carbon\Carbon::parse($release->release_date)->format('d. M')}}</span>&nbsp;
            <span>{{$release->artist}} - {{$release->album_title}} </span>
        </p>
    </div>
@endforeach

Это дает мне правильные данные, например, список записей БД, но, как упоминалось ранее, я хочу сгруппировать их по месяцам и дополнительно добавить заголовок для каждого месяца. Как я могу этого добиться?

Я использую Laravel 5.5, если это важно ...

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
622
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

UNION ALL - лучший способ сгруппировать данные заголовка и даты по месяцам.

Вы можете использовать метод Collection :: groupBy () следующим образом:

$releases->groupBy(function(Release $release) {
     return $release->release_date->format('F');
});

Теперь $ релизы - это Коллекция с названием месяца в качестве ключа и Коллекция (массив релизов) в качестве значения, подобного этому:

[
    "January" => Collection{Release, Release, Release},
    "February" => Collection{Release, Release, Release},
    ...
]

Не забывай годы;)

Если вы используете метод -> get () -> groupBy ('release_date'), он возвращает объекты по дате.

Например;

public function index() {

  $releases = Release::orderBy('release_date', 'asc')->get()->groupBy('release_date');

  return view('pages.index')->with('releases', $releases);
}

Думаю решу твою проблему.

Ответ принят как подходящий
public function index() {

    $releases = Release::orderBy('release_date', 'asc')
            ->get()->groupBy('release_date.month');

    return view('pages.index')->with('releases_groups', $releases);
}

@foreach ($releases_groups as $month => $releases_group)
    // just place group info here...
    @foreach ($releases_group as $release)
    <div>
        <p>
          <span>{{ \Carbon\Carbon::parse($release->release_date)->format('d. M')}}</span>&nbsp;
          <span>{{$release->artist}} - {{$release->album_title}} </span>
        </p>
    </div>
  @endforeach
@endforeach

Попробуй это.

Ключ groupBy('release_date.month')

rubys 09.01.2019 13:49

хм, я получаю Column not found, когда пробую это: - /

ST80 09.01.2019 13:51

Починил, поставил ->groupBy('release_date.month') после get(), и все будет хорошо.

rubys 09.01.2019 13:52

ах, я вижу, но хм ... Я не могу понять название месяца из этого ...: s

ST80 09.01.2019 13:58

Да, я редактировал код, ключ коллекции - month, и это целое число от 1~12, но я не знаю, подходит ли вам этот формат.

rubys 09.01.2019 14:07

Все доступные форматы: month, localeMonth, shortLocaleMonth, englishMonth, shortEnglishMonth, вы можете попробовать и посмотреть, какой вы хотите

rubys 09.01.2019 14:12

Итак, как мне тогда получить информацию о группе?

ST80 09.01.2019 14:21
@foreach ($releases_groups as $month => $releases_group), $month пока единственная информация о группе, хм, этого мало?
rubys 09.01.2019 14:25

ах, плохо, я только что это увидел :-) Так что теперь мне просто нужно сравнить целочисленное значение и вернуть правильную строку, например 1 = январь, 2 = февраль и т. д.?

ST80 09.01.2019 14:29

Вам не нужно этого делать, вместо этого используйте другой формат, например, ->groupBy('release_date.englishMonth'), $month будет «Январь», «Февраль» и т. д. Все доступные форматы месяцев были перечислены ранее.

rubys 09.01.2019 14:54

Посмотрев на другие ответы, вы должны знать одну важную вещь: groupBy используется для группировки полученных вами результатов. Это означает, что если вы используете paginate вместо get, тот же месяц реальной жизни может быть неправильно сгруппирован.

rubys 09.01.2019 15:02

Я предлагаю заставить ваш контроллер выполнять больше работы:

public function index() {

  // Here we get a distinct list of dates in your format
  $releaseDates = Release::Selectraw('date_format(date(release_date),"%d.%m") as Date')->distinct()->get();

  // For each date we now get the elements for each date and put them as an array entry in to the date under a 'data' section
  foreach($releaseDates as $releaseDate){
     $releaseDate['data'] = Release::whereraw('date_format(date(release_date),"%d.%m") = '.$releaseDate->Date)->get();
  }

  // Pass the data to the view as before but with new name
  return view('pages.index')->with('releaseDates', $releaseDates );
}

Тогда, на ваш взгляд:

// For each release date first
@foreach ($releaseDates as $releaseDate)
     <div>
        <p>
            //Print out the date as requested
            <span>{{ \Carbon\Carbon::parse($releaseDate->Date)->format('d. M')}}</span>&nbsp;
            // Now loop through each record nested as an array inside the date
            @foreach($releaseDate['data'] as $data)
                 <span>{{$data->artist}} - {{$data->album_title}} </span>
                 <br>
            @endforeach
        </p>
    </div>
@endforeach

Теперь у каждой записи одна и та же дата :-)

ST80 09.01.2019 14:02

@ ST80 Я добавил несколько комментариев, обратите внимание на второй цикл foreach в вашем представлении лезвия, который необходим для извлечения записей под каждой датой.

Petay87 09.01.2019 14:04

А что насчет этого (в вашем контроллере)?

$groupedReleases = null;

foreach ($releases as $release) {
    $date = $release->release_date->format('your desired format');
    $groupedReleases[$date][] = $release;
}

return $groupedReleases;

Сделать это можно так:

Таблица: релизы

id    |    released_at    |    bla_details    |    month_header_id

Таблица: month_headers

id    |    month(specific length int)    |    year(specific length int)    |    header

Модель: Release.php

public function month_header() 
{
    return $this->belongsTo('App\Models\Month');
}

Модель: MonthHeader.php

public function releases() 
{
    return $this->hasMany('App\Models\Release');
}

Помощник: getMonthName ($ integer)

Контроллер: TempController.php

public function temp()
{
    $response['month_headers'] = MonthHeader::all();
    return view('tempView', $response);
}

Просмотр лезвия: tempView.blade.php

@foreach($month_headers as $header)
    {{getMonthName($header->month)." (".$header->header.")"}}
    <ul>
        @foreach($month_headers->releases() as $release)
            <li>{{date('d.m', strtotime($release->released_at))." - ".$release->bla_details}}</li>
        @endforeach
    </ul>
@endforeach

Просмотр вывода

Январь (заголовок января)

  • 11.1 - блабла
  • 15.1 - блаблабла

Февраль (заголовок февраля)

  • 05.2 - блабла
  • 06.2 - блабла

и т.д...

Пояснение добавлено.

Saleemi 10.01.2019 08:59

Тоже очень красивое решение! :-)

ST80 10.01.2019 09:18

See the below select function with raw query where i added "Month Name" and "month number" for your reference.Please check the output.Hope this will help you

$releases = Release::select(DB::raw('some_field, MONTHNAME(release_date) as month_name, MONTHNAME(release_date) as month'))
                          ->orderBy('release_date', 'asc')->get();

You may use GroupBy if you are sure that there is not more than one release on same date.

    $releaseArray=[];
    if (!empty($releases)) {
        foreach($releases as $release){
            $releaseArray[$release->month][] = $release;
        }
    }

    print_r($releaseArray);

Теперь вы можете передать $ releaseArray в представление и выполнить итерацию для выпусков, сгруппированных по месяцам.

Другие вопросы по теме