Giriş yapmadınız.

Duyuru

TÜRKÇE KİTAP DUYURUSU:
Laravel 5 : Laravel 5.1 Güzelliği (Türkçe)
Vue.js 2 : Vue.js 2 Majesteleri (Türkçe)

#1 20.10.2013 14:39:16

drlinux
Moderatör
Yer: İstanbul
Kayıtlı: 28.12.2012
Mesajlar: 98
Website

Php Object Slice fonksiyonu

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 ;) 
#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 wink 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 wink

Hadi iyi traşlar!


Man is a slow, sloppy and brilliant thinker; the machine is fast, accurate and stupid. ~ William M. Kelly

Çevrimdışı

#2 20.10.2013 17:49:51

sergin
Üye
Kayıtlı: 17.07.2013
Mesajlar: 130
Website

Yanıt: Php Object Slice fonksiyonu

$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;
	}
 });

Son düzenleyen sergin (20.10.2013 19:08:44)

Çevrimdışı

#3 20.10.2013 21:32:00

drlinux
Moderatör
Yer: İstanbul
Kayıtlı: 28.12.2012
Mesajlar: 98
Website

Yanıt: Php Object Slice fonksiyonu

+1

@sergin arkadaş çok teşekkürler. slice() methodunu dökümantasyonda göremedim maalesef.


Man is a slow, sloppy and brilliant thinker; the machine is fast, accurate and stupid. ~ William M. Kelly

Çevrimdışı

#4 18.06.2016 12:26:14

Arda
Üye
Yer: İstanbul
Kayıtlı: 08.03.2013
Mesajlar: 178
Website

Yanıt: Php Object Slice fonksiyonu

gelecekten necro bump big_smile

bu metod işlevini yeni laravellerde (5.1 ve üstünde olmalı) collection'lara chunk() diyerek yapabiliyorsunuz.


PacktPub'dan çıkan kitaplarım: Laravel Application Development Blueprints, Laravel Design Patterns & Best Practices.
Türkçe çıkan kitabım: Raspberry Pi

Çevrimdışı

#5 19.06.2016 02:47:33

sineld
Yönetici
Yer: Bursa
Kayıtlı: 26.12.2012
Mesajlar: 1,400
Website

Yanıt: Php Object Slice fonksiyonu

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

Çevrimdışı

#6 19.06.2016 13:01:53

Arda
Üye
Yer: İstanbul
Kayıtlı: 08.03.2013
Mesajlar: 178
Website

Yanıt: Php Object Slice fonksiyonu

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 smile


PacktPub'dan çıkan kitaplarım: Laravel Application Development Blueprints, Laravel Design Patterns & Best Practices.
Türkçe çıkan kitabım: Raspberry Pi

Çevrimdışı

Forum alt kısmı