Laravel Türkiye Discord Kanalı Forumda kod paylaşılırken dikkat edilmesi gerekenler!Birlikte proje geliştirmek ister misiniz?
Merhaba,

Bildiğiniz üzere Laravel üzerinde elde ettiğimiz elequent objelerini multidimension arraya çevirmek oldukça basit. Ancak bu objeleri slice etmek düşündüğümüz kadar basit değil mallesef. (object) $array; yöntemi ile yarattığımız objeler ise birer fake object olmaktalar ve aşağıdaki şekilde erişilmesi pek mümkün olamayan objeler barındırıyorlar. Neyse özet geçelim. Bu fonksiyon bir objeyi istediğiniz aralıklarda böler ve size istediğini aralıktaki elmanları barındıran bir object döndürür tekrardan. Oldukça performanslı bir yol değil ancak elequent objeleri üzerinde harika çalışıyor.

Optimize ettiğimiz müşteri yazılımlarında genellikle yazılımcı arkadaşların 3 parçaya bölmesi gereken veri için 3 ayrı sorgu kullandığı (limit vs ile) yahut looplar içinde artık çözümlenemez bir hale salça php ile yazılmış bir yazılımdan farkı kalmamış bir yazılımı teslim ettiğini görüyoruz. Bu tarz bir yazılımın en büyük sorunu, çağdaş yazılım geliştirme kurallarının 1 numarası olan "yeniden kullanılabilirlik" ilkesini yerle bir etmektedir. 3 farklı sorgu ise size sunucu, bandwith ve şişen memoryler olarak zamanla uygulamaya gelen ziyaretçi trafiğinizden çok daha hızlı bir şekilde dönüşmekte. /app/start/local.php içine aşağıdaki kodları yapıştırın:
#objectSlice() verilen obje kolleksiyonunu istenilen aralıkta böler ve obje olarak dödürür
#Neden end ve start ters?
#Kodlarken kolayca objectSlice($object,5); şeklinde çağırabilmek için [img]/assets/images/smileys/wink.png[/img] 
#Keşke python olsaydı... Python FTW!

function objectSlice($object,$end,$start=0){

 $array = $object->toArray();
 $sliced_array = array_slice($array,$start,$end);
 
 return json_decode(json_encode ($sliced_array), FALSE);

}
Daha sonra aynı dizindeki global.php dosyasını açıp en alta
require_once("local.php");
satırını ekliyoruz.
Peki nasıl kullanacağım hocu bunu? Diyebilirsiniz aşağıda örneklemeye çalıştım:
$news = News::with('tags')->with('categories')->orderBy('news_id','DESC')->take(20)->get();

//otomatik olarak en başından başlayıp 5 tane getirir: 0-4 arası.
//başka aralıklar için önce bitiş sonra başlangıç aralığı veriilmelidir : objectSlide($news,12,5);
	$sliced_object = objectSlice($news,5);

	foreach($sliced_object as $slider_news){

 echo $slider_news->news_id;
	
	foreach ($slider_news->tags as $tags) {

 echo$tags->news_tag;
	}
	}
Nerelerde işimize yarayabilir? Bir haber sitesinin ana sayfasını düşünelim. 5 haber slider içinde verilecek 5 haber farklı bir formatta sunulacak, diğer 10 haber ise include edilern sağ sutunda verilecek ve arada bir sürü kod parçası daha var loopa alma şansınız yok yahut benim gibi kodun salçaya dönmesini istemiyorsunuz. burada kullanılabilir. Sizi hem zamandan hem fazla sorgudan hem de salçaya dönmüş template dosyalarından kurtarır Not olarak ekleyeyeyim:
function arrayToObject($array) {
 $object=new stdClass();
 foreach ($array as $key => $value){
 if(is_array($value)) $value=arrayToObject($value);
 $object->{$key}=$value;
 }
 return $object;
}

function objectSliceObject($object,$end,$start=0){
 
 if (!is_object($object)) {
 return $object;
 }

 $array = $object->toArray();
 $sliced_array = array_slice($array,$start,$end);

 return arrayToObject($sliced_array);

}
Kullanımı ve sonuçları aynı:
$news = News::with('tags')->with('categories')->orderBy('news_id','DESC')->take(20)->get();

//otomatik olarak en başından başlayıp 5 tane getirir: 0-4 arası.
//başka aralıklar için önce bitiş sonra başlangıç aralığı veriilmelidir : objectSlide($news,12,5);
	$sliced_object = objectSliceObject($news,5);

	foreach($sliced_object as $slider_news){

 echo $slider_news->news_id;
	
	foreach ($slider_news->tags as $tags) {

 echo$tags->news_tag;
	}
	}

Yukarıdaki gibi bir yöntem mantıki açıdan çok daha performanslı çalışcaktır. Ancak benim şahsi denemelerimde 1. yöntemin daha hızlı bir sonuç verdiğini gördüm. Bu nedenle, kesinlikle en doğru yöntem budur diye bir iddia ortaya atmıyorum. Hatta daha doğru olduğunu düşündüğünüz yöntemleri paylaşmanızı 4 göz, 2 gözlük çerçevesiyle bekliyorum

Hadi iyi traşlar!
$news = News::with('tags')->with('categories')->orderBy('news_id','DESC')->take(20)->get();
gibi bir atama ile bir Eloquent koleksiyonu döndüğünü biliyoruz. Laravel üçte, çoklu sonuçlar sağlamakta kullanılan bir sorgu metodundan bir model olguları dizisi döndürülürdü. Buna karşın, Laravel dörtte bunun yerine bir model olguları koleksiyonu döndürülmektedir. Eloquent koleksiyonu Illuminate\Support\Collection sınıfını genişletir. Bu sınıf ise ArrayAccess, ArrayableInterface, Countable, IteratorAggregate, JsonableInterface arayüzlerini implemente eder. Dolayısıyla bir Eloquent koleksiyonuna bir dizi şeklinde erişebildiğimiz gibi, koleksiyon natif bir tip değil bir sınıf olduğu için aynı zamanda nesnede kullanılabilecek metodları da vardır ve koleksiyon üzerinde bir kısmı bir diziyle ilgili olan bu fonksiyonları kullanabiliriz. Bunlardan birisi de slice fonksiyonudur. Bununla yeni bir koleksiyon oluşturmuş oluruz. Ayrı bir dilimleme fonksiyonu yazmaksızın aynı işin başarılacağını düşünüyorum. (İlkinde foreach yerine de koleksiyon sınıfının each metodu kullanılmıştır.)
$sliced = $news->slice(0, 5); //$itibaren, $uzunluk
$sliced->each(function($slider_news)
 {
 echo $slider_news->title.'<br />';
 foreach ($slider_news->tags as $tags) {
 echo $tags->news_tag;
	}
 });
+1

@sergin arkadaş çok teşekkürler. slice() methodunu dökümantasyonda göremedim maalesef.
3 yıl sonra
gelecekten necro bump

bu metod işlevini yeni laravellerde (5.1 ve üstünde olmalı) collection'lara chunk() diyerek yapabiliyorsunuz.
Arda'nın belirttiği chunk'a örnek vermek gerekirse;
@foreach(array_chunk($posts, 3) as $postSet)
 <div class="row">
 @foreach($postSet as $post)
 <h3>{{ $post->title }}</h3>
 @endforeach
 </div>
@endforeach
Onun haricinde şu da olabilir
$users = User::all()
@foreach($users->chunk(100) as $each100Users)
{{-- collection'ı 100 100 array bölüp ayrı ayrı işleyebiliyorsunuz bu sayede --}}
@foreach($each100Users as $user)
<p>{{ $user->firstname }}</p>
@endforeach
{{-- bu endforeach sonu her bir 100 adette bitecek ve sıradaki $each100Users için yeniden başlayacal --}}
@endforeach
Ama arka planda bu da array_chunk çalıştırıyor