【发布时间】:2018-04-05 14:20:13
【问题描述】:
我打算以某种语言获取新闻$newif($new_lang->lang_id == $lang_id),然后我查看与新闻相对应的图像表@foreach($data['images'] as $image),这是主要的@if($image->imageable_id == $new->id && $image->main == '1')。
问题是嵌套 foreach 时,加载非常缓慢,因为它们包含 7,000 多条新闻和大约 70,000 张图片。
如何在不将一个 foreach 嵌套在另一个中的情况下获得相同的结果?
@foreach($new->langs as $new_lang)
@if($new_lang->lang_id == $lang_id)
@foreach($data['images'] as $image)
@if($image->imageable_id == $new->id && $image->main == '1')
@php
$mini = substr($image->path, 0, strrpos( $image->path, "/"));
$name = substr($image->path, strrpos($image->path, '/') + 1);
$image_mini = $mini.'/mini-'.$name;
@endphp
<div class="crop">
<a href="{{ route('noticia', [$new->id, $new_lang->slug]) }}">{{ HTML::image(file_exists($image_mini)? $image_mini : $image->path, '', array('class' => 'img-responsive ancho_100')) }}</a>
</div>
@endif
@endforeach
@endif
@endforeach
已编辑:添加了控制器和特征
这是控制器:
use ListNoticias;
public function actualidad(Request $request)
{
$data['section_id'] = explode(',', '1,2,3');
$data['ruta'] = 'actualidad';
$data['title'] = __('header.actualidad');
$data['num'] = $request->num;
$url = $request->url();
$data = $this->listNoticias($data, $url);
return view('web.actualidad.listado', compact('data'));
}
还有特点:
trait ListNoticias
{
public function listNoticias($data, $url)
{
$now = date('Y-m-d');
$time = date('H:i:s');
(isset($data['num']))? $num = $data['num'] : $num = '15';
$data['images'] = Image::where('imageable_type', 'App\Models\Noticia')->get();
$data['sections'] = Section::all();
$data['noticias'] = Noticia::with('langs')->where('date', '<', $now)
->where('active', '1')
->whereIn('section_id', $data['section_id'])
->orWhere('date', '=', $now)
->where('time', '<=', $time)
->where('active', '1')
->whereIn('section_id', $data['section_id'])
->orderBy('date', 'desc')
->orderBy('time', 'desc')
->get();
$data['noticias-es'] = [];
$data['noticias-en'] = [];
$data['noticias-pt'] = [];
foreach($data['noticias'] as $row){
foreach($row->langs as $row_lang) {
if ($row_lang->lang_id == '1') {
$data['noticias-es'][] = $row;
} elseif ($row_lang->lang_id == '2') {
$data['noticias-en'][] = $row;
} elseif ($row_lang->lang_id == '3') {
$data['noticias-pt'][] = $row;
} else null;
}
}
// Manual paginate
/* Get current page form url e.x. &page=1
Create a new Laravel collection from the array data
Slice the collection to get the items to display in current page
Create our paginator and pass it to the view
set url path for generated links
*/
$currentPage = LengthAwarePaginator::resolveCurrentPage();
// ES
$itemCollection = collect($data['noticias-es']);
$currentPageItems = $itemCollection->slice(($currentPage * $num) - $num, $num)->all();
$data['noticias-es'] = new LengthAwarePaginator($currentPageItems , count($itemCollection), $num);
$data['noticias-es']->setPath($url);
// EN
$itemCollection = collect($data['noticias-en']);
$currentPageItems = $itemCollection->slice(($currentPage * $num) - $num, $num)->all();
$data['noticias-en'] = new LengthAwarePaginator($currentPageItems , count($itemCollection), $num);
$data['noticias-en']->setPath($url);
// PT
$itemCollection = collect($data['noticias-pt']);
$currentPageItems = $itemCollection->slice(($currentPage * $num) - $num, $num)->all();
$data['noticias-pt'] = new LengthAwarePaginator($currentPageItems , count($itemCollection), $num);
$data['noticias-pt']->setPath($url);
return $data;
}
}
已编辑 2
第一个视图是部分视图,包含在此视图中,并且还有另外两个 foreach nestead。这是因为我需要三个显示记录。我已经评论了问题不需要的其他包含:
@foreach ($data['noticias-'.$lang]->chunk(3) as $chunk)
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 pad_inf_2">
@foreach($chunk as $key => $new)
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4 pad_der_1">
<article>
//@include('web.index.partials.noticia_etiqueta')
@include('web.actualidad.partials.noticia_image_listado')
//@include('web.index.partials.noticia_date_section')
//@include('web.index.partials.noticia_title')
</article>
</div>
@endforeach
</div>
@endforeach
模型公告:
class Noticia extends Model
{
protected $fillable = ['section_id', 'active', 'date', 'time', 'author'];
public function images()
{
return $this->morphMany('App\Models\Image', 'imageable');
}
public function tags()
{
return $this->morphToMany('App\Models\Tag', 'taggable');
}
public function section()
{
return $this->belongsTo('App\Models\Section');
}
public function langs()
{
return $this->hasMany('App\Models\LangNoticia');
}
}
LangNoticia 模型:
class LangNoticia extends Model
{
protected $fillable = ['noticia_id', 'lang_id', 'title', 'lead', 'text', 'author_place', 'slug'];
public function noticia()
{
return $this->belongsTo('App\Models\Noticia');
}
}
EDITED 3:在 abr
的建议下减少了 trait 中的代码特征减少:
trait ListNoticias
{
public function listNoticias($data, $url)
{
$lang = Session::get('lang');
if($lang == 'en') $lang_id = '2';
elseif($lang == 'pt') $lang_id = '3';
else $lang_id = '1';
$now = date('Y-m-d');
$time = date('H:i:s');
(isset($data['num']))? $num = $data['num'] : $num = '15';
$data['sections'] = Section::all();
$data['images'] = Image::where('imageable_type', 'App\Models\Noticia')->where('main', true)->get();
$noticias = Noticia::with('langs')
->where('date', '<', $now)
->where('active', '1')
->whereIn('section_id', $data['section_id'])
->orWhere('date', '=', $now)
->where('time', '<=', $time)
->where('active', '1')
->whereIn('section_id', $data['section_id'])
->orderBy('date', 'desc')
->orderBy('time', 'desc')
->get();
$data['noticias-'.$lang] = [];
foreach($noticias as $row){
foreach($row->langs as $row_lang) {
if ($row_lang->lang_id == $lang_id) {
$data['noticias-'.$lang][] = $row;
}
}
}
// Paginate
/* Get current page form url e.x. &page=1
Create a new Laravel collection from the array data
Slice the collection to get the items to display in current page
Create our paginator and pass it to the view
set url path for generated links
*/
$currentPage = LengthAwarePaginator::resolveCurrentPage();
$itemCollection = collect($data['noticias-'.$lang]);
$currentPageItems = $itemCollection->slice(($currentPage * $num) - $num, $num)->all();
$data['noticias-'.$lang] = new LengthAwarePaginator($currentPageItems , count($itemCollection), $num);
$data['noticias-'.$lang]->setPath($url);
return $data;
}
}
【问题讨论】:
-
你能显示调用视图的控制器方法吗?
-
是的,我已经更新了。
-
Noticia和Image之间有关系吗? -
是的,卡米洛。我已经再次更新,因为我看到信息丢失(编辑 2)
-
一个
Noticia有几个images
标签: php laravel laravel-5 foreach