Laravel 4 Türkçe Dokümantasyon (v. 4.2) (Ücretsiz)

Laravel 4 Türkçe Dokümantasyon
(v. 4.2) (Ücretsiz)
Laravel 4 Türkiye Forumları Çeviri Ekibi
tarafından yapılan çeviriler
Sinan Eldem
Bu kitap şu adreste satılmaktadır http://leanpub.com/laravel42-tr
Bu versiyon şu tarihte yayımlandı 2014-08-04
This is a Leanpub book. Leanpub empowers authors and
publishers with the Lean Publishing process. Lean Publishing is
the act of publishing an in-progress ebook using lightweight tools
and many iterations to get reader feedback, pivot until you have
the right book and build traction once you do.
©2014 Sinan Eldem
İçindekiler
Editörün Notu . . . . . . . . . . . . . . . . . . . . . . . . .
i
Tanıtım . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Nereden Başlamalı . . . . . . . . . . . . . . . . . . . . .
Laravel Felsefesi . . . . . . . . . . . . . . . . . . . . . . .
iii
iii
iv
Laravel Hızlı Başlangıç . . . . .
Kurulum . . . . . . . . . . . .
Local Geliştirme Ortamı . . .
Rotalandırma (Routing) . . . .
Bir View Oluşturma . . . . .
Bir Migrasyon Oluşturma . .
Eloquent ORM . . . . . . . .
Veri Gösterme . . . . . . . . .
Uygulamanızın Yayımlanması
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
v
.
v
. vii
. vii
. viii
.
x
. xii
. xiii
. xiv
Sürüm Notları . . . . . . . . . . . . . . . . . . . . . . . . . xv
Laravel 4.2 . . . . . . . . . . . . . . . . . . . . . . . . . . xv
Laravel 4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Yükseltme Rehberi . . . . . . . . . . . . .
4.1’den 4.2’ye Yükseltme . . . . . . . . .
4.1.x ve Öncesinden 4.1.29’a Yükseltme .
4.1.25 ve Öncesinden 4.1.26’ye Yükseltme
4.0’dan 4.1’e Yükseltme . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
xxiii
xxiii
xxv
xxv
xxvii
İÇINDEKILER
Kurulum . . . . . . . . .
Composer Kurulumu .
Laravel Yükleme . . .
Sunucu Gereksinimleri
Yapılandırma . . . . .
Zarif URL’ler . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
1
1
2
2
3
Yapılandırma . . . . . . . . . . . . .
Giriş . . . . . . . . . . . . . . . .
Ortam Yapılandırması . . . . . .
Hassas Yapılandırmaları Korumak
Bakım Modu . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
6
8
10
Laravel Homestead . . .
Giriş . . . . . . . . . .
Dahil Edilen Yazılımlar
Yükleme & Kurulum .
Günlük Kullanım . . .
Portlar . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
12
12
12
13
16
17
İstek Yaşam Döngüsü . . . . . .
Genel Bakış . . . . . . . . . .
İstek Yaşam Döngüsü . . . . .
Start Dosyaları . . . . . . . .
Application Olayları (Events)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
18
18
18
20
22
Rotalar . . . . . . . . . . . . . . . . . .
Temel Rotalama . . . . . . . . . . . .
Rota Parametreleri . . . . . . . . . .
Rota Filtreleri . . . . . . . . . . . . .
İsimli Rotalar . . . . . . . . . . . . .
Rota Grupları . . . . . . . . . . . . .
Alt Alanadı (Subdomain) Rotalaması
Rotalarda Ön-ek . . . . . . . . . . .
Rotalara Model Bağlama . . . . . . .
404 Hatası Fırlatma . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
24
24
25
27
31
32
33
33
34
35
İÇINDEKILER
Denetçilere (Controller) Rotalama . . . . . . . . . . . . .
İstekler (Requests) ve Girdi (Input)
Temel Girdi . . . . . . . . . . . .
Çerezler (Cookies) . . . . . . . .
Önceki Girdi . . . . . . . . . . .
Dosyalar . . . . . . . . . . . . . .
İstek Bilgileri . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
37
37
38
39
40
42
Görünümler (Views) ve Cevaplar (Responses)
Temel Cevaplar . . . . . . . . . . . . . . . .
Yönlendirmeler (Redirects) . . . . . . . . . .
Görünümler (Views) . . . . . . . . . . . . .
Görünüm Kompozitörleri . . . . . . . . . . .
Özel Cevaplar . . . . . . . . . . . . . . . . .
Cevap Makroları . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
46
46
47
48
51
53
54
Denetçiler (Controllers) . . . . . . . . . . . . . . . . . . .
Temel Denetçiler . . . . . . . . . . . . . . . . . . . . . .
Denetçi Filtreleri . . . . . . . . . . . . . . . . . . . . . .
TEDA-uyumlu (Temsili Durum Aktarma uyumlu, RESTful) Denetçiler . . . . . . . . . . . . . . . . . . . .
Kaynak (Resource) Denetçileri . . . . . . . . . . . . . . .
Eksik Olan Metodların İşlenmesi . . . . . . . . . . . . . .
56
56
58
Hatalar ve Günlüğe Ekleme
Yapılandırma . . . . . . .
Hataların İşlenmesi . . . .
HTTP İstisnaları . . . . .
404 Hatalarının İşlenmesi .
Günlüğe Ekleme . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
66
66
67
68
69
69
Cepheler (Facades)
Giriş . . . . . . .
Açıklama . . . .
Pratik Kullanım .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
71
71
71
72
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
36
60
62
64
İÇINDEKILER
Cephe Oluşturma . . . . . . . . . . . . . . . . . . . . . .
Cepheleri Taklit Etme . . . . . . . . . . . . . . . . . . . .
Facade Sınıf Referansı . . . . . . . . . . . . . . . . . . .
Laravel Cashier . . . . . . . . . . . . . .
Giriş . . . . . . . . . . . . . . . . . . .
Yapılandırma . . . . . . . . . . . . . .
Bir Plana Abone Olunması . . . . . . .
Kredi Kartsız . . . . . . . . . . . . . .
Aboneliklerin Takas Edilmesi . . . . .
Abonelik Miktarı . . . . . . . . . . . .
Bir Aboneliğin İptal Edilmesi . . . . . .
Bir Aboneliğe Geri Dönülmesi . . . . .
Abonelik Durumunun Yoklanması . . .
Başarısız Ödemelerin Halledilmesi . . .
Diğer Stripe Webhook’larının İşlenmesi
Faturalar . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
79
79
79
80
82
82
83
83
84
84
86
87
87
Formlar & HTML . . . . . . . . . . . . . . .
Form Açmak . . . . . . . . . . . . . . . .
CSRF Koruması . . . . . . . . . . . . . . .
Forma Model Bağlanması . . . . . . . . .
Label Elementi . . . . . . . . . . . . . . .
Text, Textarea, Password & Hidden Alanlar
Onay Kutuları ve Seçenek Düğmeleri . . .
File Inputu . . . . . . . . . . . . . . . . . .
Aşağı Açılır Listeler . . . . . . . . . . . . .
Düğmeler . . . . . . . . . . . . . . . . . .
Özel Makrolar . . . . . . . . . . . . . . . .
URL Oluşturma . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
89
89
90
91
92
92
93
93
94
94
95
95
Frameworkün Genişletilmesi
Giriş . . . . . . . . . . . . .
Manager’lar & Factory’ler .
Genişletme Nereye Konacak
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
96
96
97
97
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
73
75
75
.
.
.
.
.
.
.
.
İÇINDEKILER
Cache . . . . . . . . .
Session . . . . . . . . .
Authentication . . . .
IoC Temelli Genişletme
Request Genişletmesi .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
98
100
102
105
106
Geçerlilik Denetimi . . . . . . .
Temel Kullanım . . . . . . . .
Hata Mesajlarıyla Çalışmak .
Hata Mesajları & Görünümler
Mevcut Geçerlilik Kuralları .
Duruma Göre Kurallar Ekleme
Özel Hata Mesajları . . . . . .
Özel Geçerlilik Kuralları . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
108
108
110
111
113
121
123
125
Güvenlik . . . . . . . . . . . . . . . . .
Yapılandırma . . . . . . . . . . . . .
Şifrelerin Saklanması . . . . . . . . .
Kullanıcı Kimliklerinin Doğrulanması
Elle Kullanıcı Girişi . . . . . . . . . .
Rotaların Korunması . . . . . . . . .
HTTP Basic Kimlik Doğrulaması . .
Şifre Hatırlatıcıları & Yenileme . . . .
Kriptolama . . . . . . . . . . . . . .
Kimlik Doğrulama Sürücüleri . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
128
128
129
129
133
134
135
136
140
141
IoC Konteyneri . . . . . . . . . . . . .
Giriş . . . . . . . . . . . . . . . . . .
Temel Kullanım . . . . . . . . . . . .
Bağlamaların Kayda Geçirileceği Yer
Otomatik Çözümleme . . . . . . . .
Pratik Kullanım . . . . . . . . . . . .
Hizmet Sağlayıcıları . . . . . . . . .
Konteyner Olayları . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
142
142
142
143
144
145
147
148
Güvenlik . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
İÇINDEKILER
Yapılandırma . . . . . . . . . . . . .
Şifrelerin Saklanması . . . . . . . . .
Kullanıcı Kimliklerinin Doğrulanması
Elle Kullanıcı Girişi . . . . . . . . . .
Rotaların Korunması . . . . . . . . .
HTTP Basic Kimlik Doğrulaması . .
Şifre Hatırlatıcıları & Yenileme . . . .
Kriptolama . . . . . . . . . . . . . .
Kimlik Doğrulama Sürücüleri . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
150
151
151
155
156
157
158
162
163
Kuyruklar . . . . . . . . . . . . . . . .
Yapılandırma . . . . . . . . . . . . .
Temel Kullanım . . . . . . . . . . . .
Kuyruğa Closure Fonksiyonu Ekleme
Kuyruk Dinleyicileri Çalıştırma . . .
Daemon Kuyruk İşçisi . . . . . . . .
Push Kuyrukları . . . . . . . . . . . .
Başarısız İşler . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
164
164
164
168
169
170
172
173
Olaylar (Events) . . . . . . . . . . . .
Temel Kullanım . . . . . . . . . . .
Joker Dinleyiciler . . . . . . . . . .
Dinleyici Olarak Sınıfları Kullanma
Olayları Sıraya Sokma . . . . . . .
Olay Abonecileri . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
175
175
177
177
178
179
Oturum . . . . . . . . . .
Yapılandırma . . . . .
Oturum Kullanımı . .
Flaş Verisi . . . . . . .
Veritabanı Oturumları
Oturum Sürücüleri . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
181
181
181
183
183
184
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Önbellekleme (Cache) . . . . . . . . . . . . . . . . . . . . . 186
Yapılandırma . . . . . . . . . . . . . . . . . . . . . . . . 186
Önbellekleme Kullanımı . . . . . . . . . . . . . . . . . . 186
İÇINDEKILER
Arttırma & Azaltma . . . . . . . . . . . . . . . . . . . . 189
Önbellek Etiketleri (Tags) . . . . . . . . . . . . . . . . . . 189
Veritabanı Önbelleği . . . . . . . . . . . . . . . . . . . . 191
Paket Geliştirme . . . . . .
Giriş . . . . . . . . . . .
Bir Paket Oluşturma . .
Paket Yapısı . . . . . . .
Hizmet Sağlayıcıları . .
Ertelenmiş Sağlayıcılar .
Paket Gelenekleri . . . .
Geliştirme İş Akışı . . .
Paket Rotaları . . . . . .
Paket Yapılandırması . .
Paket View’leri . . . . .
Paket Migrasyonları . .
Paket Varlıkları . . . . .
Paketlerin Yayımlanması
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
192
192
193
194
195
196
197
198
198
199
201
201
202
203
Posta . . . . . . . . . . . . . . . . . .
Yapılandırma . . . . . . . . . . . .
Temel Kullanım . . . . . . . . . . .
Ataşmanların Yazı İçine Gömülmesi
Postaların Sıraya Sokulması . . . .
Posta & Yerel Geliştirme . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
204
204
205
207
208
209
Sayfalama . . . . . . . . . . . . . . . .
Yapılandırma . . . . . . . . . . . . .
Kullanım . . . . . . . . . . . . . . .
Sayfalama Linklerine Ekleme Yapmak
JSON’a Dönüştürme . . . . . . . . .
Özel Sunumcular . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
211
211
211
214
215
215
Şablonlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Denetçi (Controller) Düzenleri . . . . . . . . . . . . . . . 217
Blade Şablonları . . . . . . . . . . . . . . . . . . . . . . . 218
İÇINDEKILER
Diğer Blade Kontrol Yapıları . . . . . . . . . . . . . . . . 219
Blade’in Genişletilmesi . . . . . . . . . . . . . . . . . . . 222
SSH . . . . . . . . . . . . . . .
Yapılandırma . . . . . . . .
Temel Kullanım . . . . . . .
Görevler . . . . . . . . . . .
SFTP Dosya İndirmeleri . .
SFTP Dosya Göndermeleri .
Uzak Günlüklerin İzlenmesi
Envoy Görev Çalıştırıcısı . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
224
224
224
225
226
226
227
227
Unit Testing . . . . . . . . . . . . . . . .
Giriş . . . . . . . . . . . . . . . . . . .
Testleri Tanımlamak ve Çalıştırmak . .
Test Ortamı . . . . . . . . . . . . . . .
Testlerin İçerisinden Rotaları Çağırmak
Facade’ları Taklit Etmek . . . . . . . .
Çatının Assert Metodları . . . . . . .
Yardımcı Metodlar . . . . . . . . . . .
Application’ın Tazelenmesi . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
234
234
234
235
235
237
238
241
242
Yardımcı (Helper) Fonksiyonları .
Arrayler (Diziler) . . . . . . . .
Dosya Yolları . . . . . . . . . .
Yazı İşlemleri . . . . . . . . . .
URL İşlemleri . . . . . . . . . .
Diğer . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
243
243
249
250
253
255
Yerelleştirme . . . . . . . . . . . . . .
Giriş . . . . . . . . . . . . . . . . .
Dil Dosyaları . . . . . . . . . . . .
Temel Kullanım . . . . . . . . . . .
Çoğullaştırma . . . . . . . . . . . .
Geçerlilik Denetimi Yerelleştirmesi
Paket Dil Dosyalarının Ezilmesi . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
257
257
257
258
259
260
260
İÇINDEKILER
Temel Veritabanı Kullanımı .
Yapılandırma . . . . . . . .
Okuma / Yazma Bağlantıları
Sorguları Çalıştırma . . . .
Veritabanı İşlemleri . . . . .
Bağlantılara Erişme . . . . .
Sorgu Günlükleme . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
262
262
262
263
265
266
266
Sorgu Oluşturucusu . . . . . . . .
Giriş . . . . . . . . . . . . . . .
Seçmeler . . . . . . . . . . . . .
Joinler . . . . . . . . . . . . . .
İleri Where Cümleleri . . . . . .
Kümeleme (Aggregate) İşlemleri
Ham İfadeler . . . . . . . . . .
Eklemeler . . . . . . . . . . . .
Güncellemeler . . . . . . . . . .
Silmeler . . . . . . . . . . . . .
Birleştirmeler . . . . . . . . . .
Pesimistik Kilitleme . . . . . . .
Sorguların Bellekte Saklanması
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
268
268
268
271
273
274
275
276
277
277
277
278
278
Eloquent ORM . . . . . . . .
Giriş . . . . . . . . . . . .
Temel Kullanım . . . . . .
Toplu Atama . . . . . . .
Ekleme, Güncelleme, Silme
Belirsiz Silme . . . . . . .
Zaman Damgaları . . . . .
Sorgu Kapsamları . . . . .
Küresel Kapsamlar . . . .
İlişkiler . . . . . . . . . .
İlişkilerin Sorgulanması . .
Ateşli (Eager) Yüklemeler
İlişkili Modelleri Ekleme .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
280
280
280
284
285
289
291
292
294
296
308
310
313
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
İÇINDEKILER
Ebeveyn Zaman Damgalarına Dokunma . . . . . .
Pivot Tablolarla Çalışmak . . . . . . . . . . . . . .
Koleksiyonlar . . . . . . . . . . . . . . . . . . . . .
Erişimciler & Değiştiriciler (Accessors & Mutators) .
Tarih Değiştiricileri . . . . . . . . . . . . . . . . . .
Model Olayları . . . . . . . . . . . . . . . . . . . .
Model Gözlemcileri . . . . . . . . . . . . . . . . . .
Diziye / JSON’a Çevirme . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
315
316
318
321
323
323
325
325
Şema Oluşturucusu . . . . . . . . . . . . . . . . . . . .
Giriş . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tabloların Oluşturulması ve Yok Edilmesi . . . . . . .
Sütunların Eklenmesi . . . . . . . . . . . . . . . . . .
Sütun İsimlerinin Değiştirilmesi . . . . . . . . . . . .
Sütunların Yok Edilmesi . . . . . . . . . . . . . . . .
Mevcutluk Yoklanması . . . . . . . . . . . . . . . . .
İndeks Eklenmesi . . . . . . . . . . . . . . . . . . . .
Yabancı Anahtar (Foreign Key) . . . . . . . . . . . . .
İndekslerin Yok Edilmesi . . . . . . . . . . . . . . . .
Zaman Damgaları ve Belirsiz Silmelerin Yok Edilmesi
Depolama Motorları . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
328
328
328
329
331
331
332
332
333
333
334
334
Migrasyon (Migration) ve Veri Ekme (Seeding)
Giriş . . . . . . . . . . . . . . . . . . . . . . .
Migrasyonların Oluşturulması . . . . . . . . .
Migrasyonların Çalıştırılması . . . . . . . . .
Migrasyonların Geriye Döndürülmesi . . . . .
Veritabanına Veri Ekme . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
335
335
335
336
337
337
Redis . . . . . . . . .
Giriş . . . . . . . .
Yapılandırma . . .
Kullanım . . . . .
Pipeline Kullanma
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
340
340
340
341
343
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Artisan CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
İÇINDEKILER
Giriş . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
Kullanım . . . . . . . . . . . . . . . . . . . . . . . . . . 344
Artisan’ın Geliştirilmesi . . . .
Giriş . . . . . . . . . . . . . .
Komut Oluşturulması . . . . .
Komutların Kayıt Ettirilmesi .
Diğer Komutların Çağırılması
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
346
346
346
350
351
Editörün Notu
Bu kitap, orijinal Laravel dokümantasyonunun (belgelerinin), Laravel Türkiye Forumları’nda oluşturan çeviri ekibi tarafından Türkçe’ye çevirilen kullanma kılavuzudur. Bu kitap Laravel Versiyon 4.2
içindir. Sonraki dağıtımları kapsamamaktadır.
Laravel ile tanıştıktan kısa bir süre sonra çatının Php kullanıcılarına
sağladığı kolaylıkları gördüm ve bunun Türkiye’de kullanılması
için gereken adımları attım. Öncesinde bir forum, ardından da
dokümantasyonun çevirilmesi geldi. Her şey beklediğimden daha
hızlı gerçekleşti ve bu dokümantasyon haricinde altı kitabın da
çevirisini tamamladım.
Bütün süreç boyunca yanımda olan sevgili eşim Bilge ve gözümün
ışığı kızım Tuana Şeyma’ya teşekkürler. İyi ki varsınız!
Çeviri ekibine tek tek teşekkür eder, kattıklarından dolayı minettarlığımı bildiririm. Gerek dokümantasyonun, gerekse bu kitapların
çevirisinde tüm süreç boyunca yanımda olan ve çok katkı sağlayan
değerli Sergin Arı’ya, kattıklarından dolayı minnettarım.
Çeviri sürecinde ekibimiz çok ince eleyip sık dokudu ancak yine
de hatalar yapmış olabiliriz, bu sebeple karşılaşmanız muhtemel
hataları bana aşağıdaki kanallardan bildirirseniz sevinirim. Dilerseniz Github ambarından¹ değişiklikleri kendiniz de çekme isteği
ile gönderebilirsiniz.
Sinan Eldem
E-posta: sinan@sinaneldem.com.tr
Web: www.sinaneldem.com.tr²
¹https://github.com/laravel-tr/docs
²http://www.sinaneldem.com.tr/
Editörün Notu
Twitter: twitter.com/sineld³
³http://twitter.com/sineld
ii
Tanıtım
Nereden Başlamalı
Yeni bir frameworkün öğrenilmesi zorlayıcı olabilir ama aynı zamanda heyecan vericidir. Geçişinizi kolaylaştırmak için çok temiz,
özlü bir Laravel dokümantasyonu oluşturmaya çalıştık. İşte ilk önce
neyi okuyacağınız konusunda bazı öneriler:
•
•
•
•
•
Kurulum⁴ ve Yapılandırma⁵
Rotalar⁶
İstekler (Requests) ve Girdi (Input)⁷
Görünümler (Views) ve Cevaplar (Responses)⁸
Denetçiler (Controllers)⁹
Bu belgeleri iyice okuduktan sonra, Laravelde temel istek / cevap
işleyişi üzerinde iyi bir kavrayışa sahip olacaksınız. Daha sonra,
veritabanınızın yapılandırılması¹⁰, fluent sorgu oluşturucusu¹¹ ve
Eloquent ORM¹² konularını okumak isteyebilirsiniz. Ya da, insanları
uygulamanızda oturum açmaya başlatabilmek için kimlik doğrulama ve güvenlik¹³ konularını okumak isteyebilirsiniz.
⁴/docs/installation
⁵/docs/configuration
⁶/docs/routing
⁷/docs/requests
⁸/docs/responses
⁹/docs/controllers
¹⁰/docs/database
¹¹/docs/queries
¹²/docs/eloquent
¹³/docs/security
iv
Tanıtım
Laravel Felsefesi
Laravel etkileyici ve zarif sözdizimine sahip bir web uygulama
çatısıdır (framework). Bizler geliştirmenin gerçekten tatmin edici
olması için keyifli ve üretken bir deneyim olması gerektiğine inanıyoruz. Laravel birçok web uygulamasında kullanılan yetkilendirme,
rotalama, oturum yönetimi ve ön bellekleme gibi ortak görevleri kolaylaştırarak, geliştiriciliğin zorluklarını ortadan kaldırmak amacını
gütmektedir.
Laravel, geliştiriciler için, uygulama işlevselliğinden ödün vermeden geliştirme aşamasını memnuniyet verici hale getirmeyi amaç
edinmiştir. En iyi kodu mutlu geliştiriciler yazar. Bu hedefe varmak
için, başka dillerde yazılmış Ruby on Rails, ASP.NET MVC ve Sinatra gibi çatılar da dahil olmak üzere, diğer çatılarda gördüğümüz en
iyi özellikleri birleştirmeye çalıştık.
Laravel büyük, kapsamlı uygulamalar için gereken araçları içeren
erişilebilir, aynı zamanda güçlü bir çatıdır. Mükemmel IoC konteyneri, etkileyici migrasyon sistemi ve sağlam bir yerleşik ünite
test desteği size geliştirmeyi amaçladığınız uygulama için gerekli
araçları sağlayacaktır.
Laravel Hızlı Başlangıç
Kurulum
Laravel Installer Aracılığıyla
İlk olarak, Laravel installer PHAR arşivini indirin¹⁴. Kolaylık açısından ismini laravel olarak değiştirin ve /usr/local/bin yoluna
taşıyın. Bir kere kurduktan sonra, laravel new komutu, istediğiniz
klasöre yeni bir laravel kurulumunu yapacaktır. Örneğin, laravel
new blog komutu, içinde tüm bağımlılıkları yüklenmiş yeni bir
laravel kurulumu barındıran blog klasörünü oluşturacaktır. Bu
yolla kurulum yapmak Composer ile yapmaktan çok daha hızlıdır.
Composer Aracılığıyla
Laravel framework kurulumu ve bağımlılık yönetimi için Composer¹⁵ kullanır. Şayet sizde yoksa Composer yüklemesi¹⁶ ile başlayın.
Artık terminalinizden aşağıdaki komutu vermek suretiyle Laravel
yükleyebilirsiniz:
1
2
composer create-project laravel/laravel sizin-projenizi\
n-ismi --prefer-dist
Bu komut sizin geçerli dizininiz içerisindeki yeni bir sizin-projenizin-ismi
klasörüne Laravel’in yepyeni bir kopyasını indirecek ve yükleyecektir.
¹⁴http://laravel.com/laravel.phar
¹⁵http://getcomposer.org
¹⁶http://getcomposer.org00-intro.md
vi
Laravel Hızlı Başlangıç
Eğer isterseniz, alternatif olarak Github’daki Laravel ambarının¹⁷
bir kopyasını elle indirebilirsiniz. Sonra da elle oluşturduğunuz proje dizininizin kökünde composer install komutunu çalıştırın. Bu
komut, frameworkün bağımlılıklarını indirecek ve yükleyecektir.
İzinler
Laravel yüklenmesinden sonra, app/storage dizinlerine web sunucu yazma izinleri hakları tanımanız gerekebilir. Yapılandırma konusunda daha fazla ayrıntılar için Kurulum¹⁸ dokümantasyonuna
bakınız.
Laravel’in Hizmete Sokulması
Tipik olarak, Laravel uygulamalarınızı sunmak için Apache veya
Nginx gibi bir web sunucusu kullanabilirsiniz. Eğer sizde PHP
5.4+ var ve PHP’nin yerleşik geliştirme sunucusunu kullanmak
isterseniz, serve Artisan komutunu kullanabilirsiniz:
1
php artisan serve
Dizin Yapısı
Frameworkün yüklenmesinden sonra, dizin yapısıyla aşina olmak
için projenize bir göz atın. Projenizdeki app dizini views, controllers
ve models gibi klasörler içerir. Uygulamanızın kodlarının çoğu
bu dizin içindeki bir yerlerde ikamet eder. Ayrıca, app/config
dizinini de inceleyip sizin için sunulmuş yapılandırma seçeneklerini
keşfetmek isteyebilirsiniz.
¹⁷https://github.com/laravel/laravel/archive/master.zip
¹⁸/docs/installation
Laravel Hızlı Başlangıç
vii
Local Geliştirme Ortamı
Geçmişte, makineniz üzerinde lokal bir PHP geliştirme ortamı yapılandırılması bir başağrısıydı. PHP, gerekli uzantılar ve gerekli diğer
bileşenlerin doğru sürümlerinin yüklenmesi zaman harcayıcı ve
kafa karıştırıcıdır. Bunun yerine Laravel Homestead¹⁹ kullanmayı
düşünün. Homestead Laravel ve Vagrant²⁰ için tasarlanmış basit bir
sanal makinedir. Homestead Vagrant kutusu güçlü ve sağlam PHP
uygulamaları inşa etmeniz için gerekli yazılımların hepsiyle birlikte
önceden paketlendiği için, sanallaştırılmış, izole bir geliştirme ortamını saniyeler içerisinde oluşturabilirsiniz. İşte Homestead’a dahil
edilen araçlardan bazılarından oluşan bir liste:
•
•
•
•
•
•
Nginx
PHP 5.5
MySQL
Redis
Memcached
Beanstalk
“Sanallaştırılmış” biraz karışık geliyorsa da merak etmeyin, sancısızdır. Homestead’ın bağımlılıkları olan VirtualBox ve Vagrant’ın
her ikisi de popüler tüm işletim sistemleri için grafiksel program
yükleyicileri içermektedir. Başlamak için Homestead dokümantasyonunu²¹ kontrol ediniz.
Rotalandırma (Routing)
Başlangıç olarak Laravel’de ilk Route’umuzu yazalım. Laravel’de
rota oluşturmak için en basit yol bir closure (anonim fonksiyon)
¹⁹/docs/homestead
²⁰http://vagrantup.com
²¹/docs/homestead
Laravel Hızlı Başlangıç
viii
kullanmaktır. app/routes.php dosyasını açın ve aşağıdaki kod
parçacığını sayfanın en altına yapıştırın:
1
2
3
4
Route::get('kullanicilar', function()
{
return 'Kullanıcılar!';
});
Şimdi, eğer web tarayıcınızda /kullanicilar adresine girerseniz,
ekranda Kullanıcılar! yazısını görmüş olmanız gerekir. Eğer gördüyseniz çok iyi! İlk rotanızı başarıyla oluşturdunuz.
Route’lar ayrıca controller sınıflarına da bağlanabilir. Örneğin:
1
2
Route::get('kullanicilar', 'KullaniciController@getInde\
x');
Bu Route Laravel’e şunu belirtiyor: /kullanicilar rotasına yapılan
bir istek KullaniciController sınıfındaki getIndex metodunu çağırmalıdır. Controller Routing hakkında daha fazla bilgi almak için
Controller Dökümantasyonu’na²² bir göz atın.
Bir View Oluşturma
Şimdi basit bir view dosyası oluşturup, kullanıcı bilgilerini ekrana
view üzerinden yazdıracağız. View dosyaları app/views dizini içerisinde bulunmakta olup projenizin HTML dosyalarını barındırır.
Şimdi bu dizin içerisine 2 tane dosya oluşturacağız: layout.blade.php
ve kullanicilar.blade.php. Önce layout.blade.php dosyamızı
oluşturalım:
²²/docs/controllers
Laravel Hızlı Başlangıç
1
ix
<html>
<body>
2
<h1>Laravel Hızlı Başlangıç</h1>
3
4
@yield('content')
5
</body>
6
7
</html>
Şimdiki adımda ise kullanicilar.blade.php view dosyasını oluşturalım:
1
@extends('layout')
2
3
4
5
@section('content')
Kullanıcılar!
@stop
Bu sözdizimi size ilk etapta biraz yabancı gelebilir. Bunun sebebi
Laravel’in güçlü şablonlama sisteminin (Blade) kullanılmasıdır.
Blade son derece hızlı çalışır çünkü sadece birkaç tane regex kodları kullanıp Blade sözdizimini PHP skriptlerine dönüştürür. Blade
kullanıcılarına çok büyük fonksiyonellik sağlar. Şablon kalıtımı
(Template inheritance) ve PHP’nin if ve for gibi temel kontrol
yapılarını Blade üzerinden kullanabilirsiniz. Daha fazla bilgi için
Blade Dökümantasyonu’na²³ bakınız.
Şimdi gerekli view dosyalarımızı oluşturduğumuza göre, oluşturduğumuz viewi /kullanicilar isteğine bir cevap olarak döndürelim.
Kullanıcılar! stringini döndürmek yerine, bu kez oluşturduğumuz view dosyalarını döndüreceğiz:
²³/docs/templates
Laravel Hızlı Başlangıç
1
2
3
4
x
Route::get('kullanicilar', function()
{
return View::make('kullanicilar');
});
Harika! Bir layoutu genişleten bir view oluşturdunuz. Bir sonraki
bölümümümüzde Veritabanı Katmanı (Database Layer) üzerinde
duracağız.
Bir Migrasyon Oluşturma
Bir veritabanı tablosu oluşturmak için Laravel’in migrasyon (migration) özelliğini kullanacağız. Migrationlar çok kolay bir şekilde
veritabanında değişiklikler yapmayı ve bunları takım arkadaşlarınızla paylaşmanızı sağlar.
Öncelikle bir veritabanı konfigürasyonu ayarlayalım. Tüm veritabanı konfigürasyonlarınızı app/config/database.php dosyası içerisinde değiştirebilirsiniz. Laravel öntanımlı olarak MySQL kullanmaya ayarlanmıştır, veritabanı konfigürasyonlarınızı app/config/database.php
dosyası içerisinde tanımlamanız gerekecektir. Dilerseniz driver
değerini sqlite yapıp app/database dizininde bulunan SQLite
veritabanını kullanabilirsiniz.
Sonra, bir migration oluşturmak için Artisan CLI²⁴ kullanacağız.
Projenizin ana dizinine gelerek, aşağıdaki kodu terminal üzerinde
yazın:
1
php artisan migrate:make create_users_table
Şimdi, oluşturulan migration dosyasını app/database/migrations
dizininde bulun. Bu dosya 2 metoddan oluşmaktadır: up ve down.
²⁴/docs/artisan
Laravel Hızlı Başlangıç
xi
up metodunda, tablonuzdaki değişiklikleri yapmalısınız. down me-
todunda ise yaptığınız değişiklikleri geri almalısınız.
Şuna benzeyen bir migration oluşturalım:
1
2
3
4
5
6
7
8
9
10
public function up()
{
Schema::create('users', function($table)
{
$table->increments('id');
$table->string('email')->unique();
$table->string('name');
$table->timestamps();
});
}
11
12
13
14
15
public function down()
{
Schema::drop('users');
}
Şimdi bu migrationu Artisan CLI üzerinde migrate komutu kullanarak çalıştıralım. Projenizin ana dizinine gelip aşağıdaki kodu
çalıştırın:
1
php artisan migrate
Eğer bir migrationu geri almak isterseniz migrate:rollback komutunu çalıştırmanız yeterli olacaktır. Şimdi bir veritabanı tablosu
oluşturduğumuza göre, tablomuzdan veri çekmeyi öğrenerek devam edelim!
xii
Laravel Hızlı Başlangıç
Eloquent ORM
Laravel mükemmel bir ORM aracıyla beraber gelmektedir: Eloquent. Eğer daha önce Ruby on Rails frameworkü üzerinde çalıştıysanız Eloquent size çok tanıdık gelecektir, çünkü veritabanı işlemleri
için ActiveRecord stilini kullanır.
Öncelikle, modeli tanımlayalım. Bir Eloquent modeli ilgili veritabanı tablosunu sorgulamak için kullanılabilir, aynı zamanda bu tablo
içindeki belirli bir satırı temsil eder. Merak etmenize gerek yok,
örnekleri görünce ne kadar kolay olduğunu anlayacaksınız! Model
dosyaları app/models dizininde bulunmaktadır. Şimdi o dizinde bir
User.php modeli oluşturalım:
1
class User extends Eloquent {}
Lütfen dikkat edin, herhangi bir veritabanı tablosu belirtmedik.
Eloquent’in içerisinde çeşitli gelenekler vardır, bunlardan birisi
modelin veritabanı tablosu olarak model adının çoğul halini kullanmaktır. Kullanışlı, değil mi?
Tercih ettiğiniz veritabanı yönetim aracını kullanarak, users tablosuna birkaç satır ekleyin. Ondan sonra Eloquent’i kullanarak o
tablodan bazı verileri çekip view dosyamıza göndereceğiz.
Şimdi /kullanicilar rotamızda değişiklik yapalım ve şuna benzer
bir hale getirelim:
xiii
Laravel Hızlı Başlangıç
1
2
3
4
Route::get('kullanicilar', function()
{
$users = User::all(); //Users tablosundaki tüm veriler\
i $users değişkenine atar
5
return View::make('kullanicilar')->with('users', $user\
6
7
8
s);
});
Şimdi bu scripti biraz inceleyelim. Öncelikle, User modelindeki all
metodu users tablosundaki tüm verileri çekecektir. Daha sonra bu
veriler with metodu kullanılarak view dosyasına gönderilir. with
metodu bir anahtar ve bir değer almaktadır, böylece gönderilen
veriyi view dosyası tanıyabilir.
Harika. Artık kullanıcıları view dosyamızda göstermeye hazırız!
Veri Gösterme
Şimdi view’imizde users değişkenini kullanılabilir yaptığımıza göre, onu şuna benzer bir şekilde gösterebiliriz:
1
@extends('layout')
2
3
4
5
6
7
@section('content')
@foreach($users as $user)
<p>{{ $user->name }}</p>
@endforeach
@stop
echo ifadesinin nerede olduğunu merak ediyor olabilirsiniz. Blade
kullanırken, küme parantezi arasına yazılan değişkenler aynı echo
ifadesindeki gibi ekrana bastırılır. Şimdi /kullanicilar adresine
Laravel Hızlı Başlangıç
xiv
girip veritabanınızda kayıtlı olan tüm kullanıcıların listesinin ekrana bastırıldığını görebilirsiniz.
Bu sadece bir başlangıç. Bu derste Laravel’in en temel konularını
gördünüz, ancak daha göreceğiniz birçok heyecan verici özellikler
var! Dökümantasyonu okumaya devam edin ve Laravel içerisinde
gelen birçok farklı özellik hakkında daha fazla bilgiye sahip olun.
Örneğin Eloquent²⁵ ve Blade²⁶. Belki de sizin ilginizi Queues²⁷
ve Unit Testing²⁸ çekiyordur? Ya da IoC Container²⁹ kullanarak
uygulamanızın mimarisini güçlendirmek istiyorsunuzdur? Seçim
sizin!
Uygulamanızın Yayımlanması
Laravel’in amaçlarından biri de PHP uygulama geliştirmeyi indirmekten yayımlamaya kadar keyifli bir hale getirmektir ve Laravel
Forge³⁰ Laravel uygulamalarınızı süper hızlı sunucular üzerinde
yayımlamak için basit bir yol sağlar. Forge DigitalOcean, Linode,
Rackspace ve Amazon EC2 üzerinde sunucuları yapılandırabilir ve
karşılayabilir. Tıpkı Homestead gibi, gerekli en son araçlar dahil
edilmiştir: Nginx, PHP 5.5, MySQL, Postgres, Redis, Memcached ve
başkaları. Hatta, Forge “Quick Deploy” özelliğiyle değişikliklerinizi
Github veya Bitbucket’e push ettiğiniz her seferinde kodunuzu
yayımlamış olursunuz!
Forge bunlar yanında kuyruk işçileri, SSL, Cron işleri, sub-domainler
ve daha birçok şeyi yapılandırmanıza yardım edebilir. Daha fazla
bilgi için Forge websitesini³¹ ziyaret ediniz.
²⁵/docs/eloquent
²⁶/docs/templates
²⁷/docs/queues
²⁸/docs/testing
²⁹/docs/ioc
³⁰https://forge.laravel.com
³¹https://forge.laravel.com
Sürüm Notları
Laravel 4.2
Bu sürümün tam değişiklik listesi bir 4.2 yüklemesinden php artisan
changes komutunu vererek veya Github’daki değişiklik dosyasına³²
bakarak görülebilir. Bu notlar sadece bu sürümdeki önemli geliştirmeleri ve değişiklikleri kapsamaktadır.
Not: 4.2 salınım döngüsü süresince, çeşitli Laravel 4.1
nokta salımlarına birçok küçük hata düzeltmeleri ve
geliştirmeler katılmıştır. Bu yüzden, Laravel 4.1 için
değişiklik listesini de kontrol ettiğinizden emin olun!
PHP 5.4 Gerekliliği
Laravel 4.2 PHP 5.4 veya daha üstünü gerektirir. Bu yükseltilmiş
PHP gerekliliği bize Laravel Cashier³³ benzeri araçlar için daha
anlamlı ve etkileyici interface’ler için trait’ler gibi yeni PHP özelliklerini kullanmamıza imkan verir. PHP 5.4 aynı zamanda PHP 5.3’e
göre önemli bir hız ve performans iyileştireleri de getirmektedir.
Laravel Forge
Laravel Forge, web tabanlı yeni bir uygulama olup, aralarında Linode, DigitalOcean, Rackspace ve Amazon EC2’nin yer aldığı istediğiniz bir bulut üzerinde PHP sunucuları oluşturmak ve yönetmek
için kolay bir yol sağlar. Otomatize Nginx yapılandırması, SSH key
³²https://github.com/laravel/framework/blob/4.2/src/Illuminate/Foundation/changes.
json
³³/docs/billing
xvi
Sürüm Notları
erişimi, Cron job otomasyonu, NewRelic & Papertrail aracılığıyla
sunucu takibi, “Yayımlamak için Bas (Push To Deploy)”, Laravel
kuyruk işçisi yapılandırması ve pek çok şeyi desteklemek suretiyle,
Forge sizin tüm Laravel uygulamalarınızın başlatılmasının en basit
ve en uygun fiyatlı yolunu sağlar.
Varsayılan Laravel 4.2 yüklemenizin app/config/database.php yapılandırma dosyası, yepyeni uygulamalarınızı platforma daha uygun yayımlamanıza imkan verecek şekilde artık ön tanımlı olarak
Forge kullanımı için yapılandırılmıştır.
Laravel Forge hakkında daha fazla bilgi resmi Forge web sitesinde³⁴
bulunabilir.
Laravel Homestead
Laravel Homestead sağlam ve güçlü Laravel ve PHP uygulamaları
geliştirilmesi için resmi bir Vagrant ortamıdır. Box’ların ihtiyaçlarının büyük çoğunluğu box dağıtım için paketlenmeden önce
halledilir, böyleye box’un boot edilmesi son derece hızlıdır. Homestead’da Nginx 1.6, PHP 5.5.12, MySQL, Postgres, Redis, Memcached,
Beanstalk, Node, Gulp, Grunt ve Bower yer almaktadır. Homestead
birden çok Laravel uygulamasının tek bir box’ta yönetilmesi için
basit bir Homestead.yaml yapılandırma dosyası içerir.
Varsayılan Laravel 4.2 yüklemesi şimdi artık box’un Homestead veritabanını kullanması, böylece Laravel’in ilk yükleme ve yapılandırmasının daha kolay olması için yapılandırılmış bir app/config/local/database.php
yapılandırma dosyası taşımaktadır.
Ayrıca resmi dokümantasyon Homestead³⁵ dokümantasyonunu içerecek şekilde güncellenmiştir.
³⁴https://forge.laravel.com
³⁵/docs/homestead
xvii
Sürüm Notları
Laravel Cashier
Laravel Cashier, Stripe ile abonelik faturalaması yönetilmesi için
basit, ifade edici bir kitaplıktır. Laravel 4.2’nin başlamasıyla birlikte
biz Cashier dokümantasyonunu ana Laravel dokümantasyonuna
dahil ediyoruz, ancak bu bileşenin yüklenmesi hala isteğe bağlıdır.
Cashier’in bu salınımı çok sayıda hata düzeltmeleri, birden çok para
birimi desteği ve en son Stripe API ile uyumluluk getirmektedir.
Daemon Kuyruk İşçileri
Artisan queue:work komutu “deamon modunda” bir işçi başlatmak
için şimdi bir --daemon seçeneğini destekliyor, bunun anlamı bu
işçinin framework yeniden boot edilmesi hiç olmaksızın işleri işlemeye devam edeceğidir. Bu, hafifçe daha karmaşık bir uygulama
yayımlama süreci maliyetiyle birlikte, CPU kullanımında önemli
bir azalmayla sonuçlanır.
Daemon kuyruk işçileriyle ilgili daha fazla bilgi queue documentation³⁶ dokümantasyonunda bulunabilir.
Mail API Sürücüleri
Laravel 4.2, Mail fonksiyonları için yeni Mailgun ve Mandrill API
sürecilerini getirdi. Bu birçok uygulama için, e-mailler göndermenin SMTP seçeneğinden daha hızlı ve daha güvenilir bir yöntemini
sağlar. Bu yeni sürücüler Guzzle 4 HTTP kitaplığını kullanmaktadır.
Belirsiz Silme Trait’leri
PHP 5.4 trait’ler sayesinde “soft delete”ler ve diğer “global scope”ler
için çok daha temiz bir mimari sunulmuştur. Bu yeni mimari
³⁶/docs/queues#daemon-queue-worker
xviii
Sürüm Notları
benzer global trait’lerin daha kolay inşa edilmesini ve frameworkün
kendisi içerisinde daha temiz bir “ilgilerin ayrılığı” sağlar.
Yeni SoftDeletingTrait hakkında daha fazla bilgi Eloquent³⁷ dokümantasyonunda bulunabilir.
Uygun Auth & Remindable Trait’leri
Varsayılan Laravel 4.2 yüklemesi authentication ve password reminder user interface’lerinin gerekli özellikleri içermesi için artık
basit trait’ler kullanmaktadır. Bu, Laravel’le gelen default User
model dosyasının çok daha temiz olmasını sağlamaktadır.
“Basit Sayfalandırma”
Sayfalandırma view’inizde basit “Sonraki” ve “Önceki” linkleri
kullanıyorken daha verimli sorgulara imkan vermek amacıyla Sorgu oluşturucusu ve Eloquent’e yeni bir simplePaginate metodu
eklenmiştir.
Migration Teyidi
Üretim ortamında, yıkıcı migrasyon işlemleri artık teyit isteyeceklerdir. --force seçeneği kullanılarak, komutlar herhangi bir teyit
istemeksizin çalıştırılmaya zorlanabilir.
³⁷/docs/eloquent#soft-deleting
xix
Sürüm Notları
Laravel 4.1
Değişikliklerin Tam Listesi
Bu sürümün tam değişiklik listesi bir 4.1 yüklemesinden php artisan
changes komutunu vererek veya Github’daki değişiklik dosyasına³⁸
bakarak görülebilir. Bu notlar sadece bu sürümdeki önemli geliştirmeleri ve değişiklikleri kapsamaktadır.
Yeni SSH Bileşeni
Bu sürümle birlikte tamamen yeni bir SSH bileşeni getirilmiştir. Bu
özellik sizin uzak suncuculara kolaylıkla SSH iletişimi kurmanıza
ve komut çalıştırmanıza imkan verir. Daha fazla öğrenmek için SSH
bileşeni dokümantasyonuna³⁹ bakın.
Yeni php artisan tail komutu yeni SSH bileşenini kullanmaktadır.
Daha fazla bilgi için, tail komut dokümantasyonuna⁴⁰ bakın.
Tinker’de Boris
Eğer sisteminiz destekliyorsa php artisan tinker komutu şimdi
Boris REPL⁴¹ kullanmaktadır. Bu özelliği kullanmak için readline
ve pcntl PHP uzantıları başlatılmış olmalıdır. Bu uzantılara sahip
değilseniz, 4.0’daki kabuk kullanılacaktır.
³⁸https://github.com/laravel/framework/blob/4.1/src/Illuminate/Foundation/changes.
json
³⁹/docs/ssh
⁴⁰/docs/ssh#tailing-remote-logs
⁴¹https://github.com/d11wtq/boris
xx
Sürüm Notları
Eloquent Geliştirmeleri
Eloquent’e yeni bir hasManyThrough ilişkisi eklenmiştir. Bunun
nasıl kullanılacağını öğrenmek için Eloquent dokümantasyonuna⁴²
bakın.
Modelleri ilişki sınırlandırmalarına dayalı getirmeye⁴³ imkan vermek amacıyla yeni bir whereHas metodu kullanıma girmiştir.
Veritabanı Okuma / Yazma Bağlantıları
Sorgu oluşturucu ve Eloquent de dahil olmak üzere veritabanı
katmanı boyunca artık okuma / yazma bağlantılarının otomatik
olarak ayrı ayrı ele alınması mümkün bulunmaktadır. Daha fazla
bilgi için dokümantasyonuna⁴⁴ bakın.
Kuyruk (Queue) Önceliği
Kuyruk öncelikleri şimdi queue:listen komutuna virgülle ayrılmış
bir liste geçilmesi şeklinde desteklenmektedir.
Gerçekleştirilememiş Kuyruk İşinin İşlenmesi
Kuyruk araçları şimdi queue:listen üzerinde yeni --tries anahtarı kullanılması halinde, başarısız kalmış işlerin otomatik işlenmesini
içermektedir. Başarısız kalmış işlerin işlenmesiyle ilgili daha fazla
bilgi kuyruklar dokümantasyonunda⁴⁵ bulunabilir.
⁴²/docs/eloquent#has-many-through
⁴³/docs/eloquent#querying-relations
⁴⁴/docs/database#read-write-connections
⁴⁵/docs/queues#failed-jobs
xxi
Sürüm Notları
Cache Tagları
Cache “section”larının yerini “tag”lar almıştır. Cache tagları bir
cache öğesine birden çok “tag” atamanıza ve tek bir tag’a atanmış
tüm öğeleri boşaltmanıza (flush) imkan verir. Cache taglarının
kullanılması üzerine daha fazla bilgi cache dokümantasyonunda⁴⁶
bulunabilir.
Esnek Şifre Hatırlatıcıları
Şifre hatırlatıcı motoru şifreler geçerlilik denetiminden geçirilirken,
session’a durum mesajları flaşlanırken v.b., geliştiriciye daha büyük
esneklik sağlayacak şekilde değiştirilmiştir. Gelişmiş şifre hatırlatıcı
motorunun kullanımı hakkında daha fazla bilgi için dokümantasyonuna⁴⁷ bakın.
Gelişmiş Rotalama Motoru
Laravel 4.1 tamamen yeniden yazılmış bir rotalama katmanına
sahiptir. API aynıdır; ancak, rotaların kayda geçirilmesi 4.0 ile
karşılaştırıldığında tam % 100 daha hızlıdır. Bütün motor büyük ölçüde basitleştirilmiştir ve rota ifadelerinin derlenmesinde Symfony
Routing Katmanına bağımlılık en aza indirilmiştir.
Gelişmiş Session Motoru
Bu yeni sürümde biz aynı zamanda tamamen yeni bir session motorunu da kullanıma sokuyoruz. Rotalama geliştirmelerine benzer
şekilde, yeni session katmanı da daha yalın ve daha hızlıdır. Artık
Symfony’nin (ve dolayısıyla PHP’nin) session işleme araçlarını
kullanmıyoruz ve daha basit ve sürdürülmesi daha kolay olan özel
bir çözüm kullanıyoruz.
⁴⁶/docs/cache#cache-tags
⁴⁷/docs/security#password-reminders-and-reset
xxii
Sürüm Notları
Doctrine DBAL
Eğer migrasyonlarınızda renameColumn fonksiyonunu kullanıyorsanız, composer.json dosyanıza doctrine/dbal bağımlılığını eklemeniz gerekecek. Bu paket artık ön tanımlı olarak Laravel’e dahil
edilmemektedir.
Yükseltme Rehberi
4.1’den 4.2’ye Yükseltme
PHP 5.4+
Laravel 4.2, PHP 5.4.0 veya daha üstünü gerektirir.
Kriptolama Varsayılanları
app/config/app.php yapılandırma dosyanıza yeni bir cipher seçeneği ekleyin. Bu seçeneğin değeri MCRYPT_RIJNDAEL_256 olmalıdır.
1
'cipher' => MCRYPT_RIJNDAEL_256
Bu ayar, Laravel kriptolama araçları tarafından kullanılan varsayılan cipher’i (kriptolama sistemini) kontrol etmek için kullanılabilir.
Not: Laravel 4.2’de, default cipher en güvenli cipher
olarak kabul edilen MCRYPT_RIJNDAEL_128 (AES)’dir.
Laravel <= 4.1’de kriptolanmış cookies/values’leri dekript etmek için bu cipher’i tekrar MCRYPT_RIJNDAEL_256‘e değiştirmek gereklidir
Modellerdeki Soft Silmeler Artık Trait Kullanıyor
Modellerde soft silmeler kullanıyorsanız, softDeletes propertisi
çıkartılmıştır. Artık aşağıdakine benzer şekilde SoftDeletingTrait
kullanmalısınız:
Yükseltme Rehberi
1
xxiv
use Illuminate\Database\Eloquent\SoftDeletingTrait;
2
3
4
5
class User extends Eloquent {
use SoftDeletingTrait;
}
Ayrıca, dates propertisine deleted_at sütununu elle eklemek zorundasınız:
1
2
class User extends Eloquent {
use SoftDeletingTrait;
3
protected $dates = ['deleted_at'];
4
5
}
Tüm soft silme işlemlerinin API’si aynı kalmıştır.
Not: Bu SoftDeletingTrait base modele uygulanamaz. Gerçek bir model sınıfı üzerinde kullanılmalıdır.
View / Pagination Environment Sınıflarının Adı
Değişti
Şayet Illuminate\View\Environment sınıfını veya Illuminate\Pagination\Environ
sınıfını doğrudan referans ediyorsanız, kodunuzu bunlar yerine
Illuminate\View\Factory ve Illuminate\Pagination\Factory sınıflarını referans verecek şekilde güncellemelisiniz. Bu iki sınıfın
isimleri, işlevlerini daha iyi yansıtması için değiştirilmiştir.
Pagination Sunumcusunda Ek Parametre
Eğer Illuminate\Pagination\Presenter sınıfını genişletiyorsanız,
getPageLinkWrapper abstract metodunun kalıbı rel parametresi
eklenecek şekilde değiştirilmiştir:
xxv
Yükseltme Rehberi
1
2
abstract public function getPageLinkWrapper($url, $page\
, $rel = null);
Iron.Io Queue Kriptolama
Eğer Iron.io queue sürücüsü kullanıyorsanız, bu durumda queue
yapılandırma dosyanıza yeni bir encrypt seçeneği eklemeniz gerekecektir.
1
'encrypt' => true
4.1.x ve Öncesinden 4.1.29’a Yükseltme
Laravel 4.1.29 tüm veritabanı sürücüleri için sütunların tırnak içine alınmasını iyileştirmiştir. Bu iyileştirme, modellerde fillable
özelliğini kullanmıyorken uygulamalarınızı bazı toplu atama açıklarından korur. Eğer siz toplu atamaya karşı korumak için modellerinizde fillable özelliğini kullanıyorsanız, uygulamanız korunmasız değildir. Buna karşın, eğer guarded kullanıyorsanız ve “update”
veya “save” tipindeki bir fonksiyona kullanıcının kontrolündeki bir
dizi geçiyorsanız, uygulamanız toplu atama riskinde olacağı için
hemen 4.1.29‘e yükseltmelisiniz.
Laravel 4.1.29’ye yükseltmek için, basitçe composer update komutunu verin. Bu salınımda başka düzeltmeler gereken bir değişiklik
yapılmamıştır.
4.1.25 ve Öncesinden 4.1.26’ye
Yükseltme
Laravel 4.1.26 “remember me” cookie’leri için güvenlik iyileştirmeleri getirdi. Bu güncellemeler öncesinde, eğer bir remember
xxvi
Yükseltme Rehberi
cookie kötü niyetli başka bir kullanıcı tarafından gasp edilmişse
(“hijacked”), hesabın gerçek sahibi kendi şifresini yeniledikten, çıkış
yaptıktan (logged out) v.b sonra bile ilgili cookie uzun bir zaman
süresince geçerli kalırdı.
Bu değişiklik users (veya dengi olan) veritabanı tablonuza yeni
bir remember_token sütunu eklenmesini gerektirmektedir. Bu değişiklikten sonra, uygulamanıza giriş (login) yaptıkları her seferinde
kullanıcıya yepyeni bir token atanacaktır. Bu token ayrıca kullanıcı
uygulamadan çıkış yaptığı zaman da yenilenecektir. Bu değişikliğin
etkileri şunlardır: eğer bir “remember me” cookie gasp edilirse, sadece uygulamadan çıkış yapılması bu cookie’yi geçersiz kılacaktır.
Yükseltme Adımları
Öncelikle, users tablonuza VARCHAR(100), TEXT veya dengi yeni
bir nullable remember_token sütunu ekleyin.
Daha sonra, eğer Eloquent authentication sürücüsü kullanıyorsanız,
User sınıfınızı aşağıdaki üç metodla güncelleyin:
1
2
3
4
public function getRememberToken()
{
return $this->remember_token;
}
5
6
7
8
9
public function setRememberToken($value)
{
$this->remember_token = $value;
}
10
11
12
13
14
public function getRememberTokenName()
{
return 'remember_token';
}
xxvii
Yükseltme Rehberi
Not: Bu değişiklikle mevcut tüm “remember me” oturumları geçersiz kılınacaktır, bu nedenle tüm kullanıcılar uygulamanıza yeniden authenticate olmaya (kimliği doğrulanmaya) zorlanacaklardır.
Paket Sürdürücüleri
Illuminate\Auth\UserProviderInterface interface’ine iki yeni
metod eklenmiştir. Örnek implementationlar ön tanımlı sürücülerde bulunabilir:
1
public function retrieveByToken($identifier, $token);
2
3
4
public function updateRememberToken(UserInterface $user\
, $token);
Ayrıca, Illuminate\Auth\UserInterface de “Yükseltme Adımları” kesiminde açıklanan üç yeni metodu almıştır.
4.0’dan 4.1’e Yükseltme
Composer Bağımlılığının Yükseltilmesi
Uygulamanızı Laravel 4.1’e yükseltmek için, composer.json dosyanızdaki laravel/framework sürümünü 4.1.* olarak değiştirin.
Dosyaların Değiştirilmesi
Uygulamanızdaki public/index.php dosyasını ambardaki bu yeni
kopya⁴⁸ ile değiştirin.
⁴⁸https://github.com/laravel/laravel/blob/master/public/index.php
xxviii
Yükseltme Rehberi
Uygulamanızdaki artisan dosyasını ambardaki bu yeni kopya⁴⁹ ile
değiştirin.
Yapılandırma Dosya ve Seçeneklerinin
Eklenmesi
Uygulamanızdaki app/config/app.php yapılandırma dosyanızdaki
aliases ve providers dizilerini güncelleyin. Bu dizilerin güncellenmiş değerleri bu dosyada⁵⁰ bulunabilir. Kendi özel ve paket servis
sağlayıcılarını / aliasları tekrar eklemeyi unutmayın.
Ambardaki⁵¹ yeni app/config/remote.php dosyasını ekleyin.
Uygulamanızdaki app/config/session.php dosyanıza yeni expire_on_close yapılandırma seçeneğini ekleyin. Ön tanımlı değer false
olmalıdır.
Uygulamanızdaki app/config/queue.php dosyanıza yeni failed
yapılandırma kesimini ekleyin. Bu kesimin default değerleri şöyledir:
1
2
3
'failed' => array(
'database' => 'mysql', 'table' => 'failed_jobs',
),
(İsteğe Bağlı) Uygulamanızdaki app/config/view.php dosyanızdaki pagination yapılandırma seçeneğini pagination::slider-3
olarak güncelleyin.
Controller Güncellemeleri
Eğer app/controllers/BaseController.php dosyasında en üstte
bir use cümlesi varsa, buradaki use Illuminate\Routing\Controllers\Controller;
⁴⁹https://github.com/laravel/laravel/blob/master/artisan
⁵⁰https://github.com/laravel/laravel/blob/master/app/config/app.php
⁵¹https://github.com/laravel/laravel/blob/master/app/config/remote.php
Yükseltme Rehberi
xxix
olan yeri use Illuminate\Routing\Controller; olarak güncelleyin.
Password Reminders Güncellemeleri
Şifre hatırlatıcıları daha büyük esneklik olması için elden geçirilmiştir. Artisan php artisan auth:reminders-controller komutunu çalıştırmak suretiyle yeni iskelet controlleri inceleyebilirsiniz.
Ayrıca güncellenmiş dokümantasyonu⁵² da okuyabilir ve uygulamanızı ona göre güncelleyebilirsiniz.
Uygulamanızdaki app/lang/en/reminders.php dil dosyasını güncellenen bu dosyaya⁵³ uyacak şekilde güncelleyin.
Ortam Saptama Güncellemeleri
Güvenlik sebepleri nedeniyle, uygulama ortamınızı tespit etmek
için URL domainleri artık kullanılmayabilir. Bu değerler kolaylıkla
kafeslenebilir ve saldırganların bir istek için ortamı modifiye etmesine imkan verebilir. Ortam tespitinizi makine host adları (Mac,
Linux ve Windows üzerinde hostname komutu) kullanacak şekilde
değiştirmelisiniz.
Daha Sade ve Basit Günlük Dosyaları
Laravel artık tek bir log dosyası üretir: app/storage/logs/laravel.log.
Bununla birlikte, bu davranışı yine de app/start/global.php dosyanızda yapılandırabilirsiniz.
⁵²/docs/security#password-reminders-and-reset
⁵³https://github.com/laravel/laravel/blob/master/app/lang/en/reminders.php
xxx
Yükseltme Rehberi
En Sonda Bölü Varsa Yeniden Yönlendirin
Çıkartılması
Uygulamanızın bootstrap/start.php dosyasından $app->redirectIfTrailingSlas
çağrısını çıkartın. Bu işlevsellik şimdi frameworkle gelen .htaccess
dosyası tarafından halledildiği için bu metod artık gerekli değildir.
Sonra da, sizin Apache .htaccess dosyanızın yerine, sondaki bölüleri halleden bu yenisini⁵⁴ koyun.
Güncel Rotaya Erişim
Güncel rotaya Route::getCurrentRoute() yerine şimdi Route::current()
ile erişilmektedir.
Composer Güncellemesi
Yukarıdaki değişiklikleri tamamladıktan sonra, çekirdek application dosyalarını güncellemek için composer update fonksiyonunu
çalıştırabilirsiniz! Eğer sınıf yükleme (class load) hataları alırsanız,
update komutunu şu şekilde etkinleştirilmiş --no-scripts seçeneği
ile kullanmayı deneyin: composer update --no-scripts.
Joker Olay Dinleyiciler
Joker Olay Dinleyiciler artık handler fonksiyon parametrelerinize event’i eklemez. Şayet ateşlenen olayı bulmanız gerekiyorsa,
Event::firing() kullanmalısınız.
⁵⁴https://github.com/laravel/laravel/blob/master/public/.htaccess
Kurulum
Composer Kurulumu
Laravel bağımlılıklarını yönetmek için Composer⁵⁵ kullanır. Öncelikle composer.phar dosyasını indiriniz. PHAR arşivini yerel proje
dosyanızda tutabileceğiniz gibi usr/local/bin içerisine taşıyarak
sisteminizde evrensel olarak da kullanabilirsiniz. Windows’ta Composer Windows kurulumu⁵⁶nu kullanabilirsiniz. Setup Composer’i
PATH değişkeni olarak kaydedecektir, böylece terminal üzerinde
composer yazdığınızda Composer’i direkt olarak kullanabilirsiniz.
Laravel Yükleme
Laravel Installer Aracılığıyla
İlk olarak, Laravel installer PHAR arşivini indirin⁵⁷. Kolaylık açısından ismini laravel olarak değiştirin ve /usr/local/bin yoluna
taşıyın. Bir kere kurduktan sonra, laravel new komutu, istediğiniz
klasöre yeni bir laravel kurulumunu yapacaktır. Örneğin, laravel
new blog komutu, içinde tüm bağımlılıkları yüklenmiş yeni bir
laravel kurulumu barındıran blog klasörünü oluşturacaktır. Bu
yolla kurulum yapmak Composer ile yapmaktan çok daha hızlıdır.
Composer’ın Create-Project Komutuyla
Terminalinizde Composer create-project komutunu vererek Laravel’i yükleyebilirsiniz:
⁵⁵http://getcomposer.org
⁵⁶https://getcomposer.org/Composer-Setup.exe
⁵⁷http://laravel.com/laravel.phar
2
Kurulum
1
composer create-project laravel/laravel --prefer-dist
Elle İndirerek
Composer yüklendikten sonra, Laravel framework’ün son sürümünü⁵⁸ indirip, içeriğini sunucunuzdaki bir dizine çıkarınız. Ardından, Laravel uygulamanızın ana dizininde, Laravel gereksinimlerini yüklemek için, php composer.phar install (veya composer
install) komutunu çalıştırınız. Bu işlemin başarıyla tamamlanabilmesi için sunucunuzda Git⁵⁹ yüklü olması gerekmektedir.
Laravel’i güncellemek isterseniz php composer.phar update komutunu verebilirsiniz.
Sunucu Gereksinimleri
Laravel framework’un birkaç sistem gereksinimi bulunmaktadır:
• PHP >= 5.4
• MCrypt PHP Eklentisi
PHP 5.5 için, bazı OS yayımlamaları PHP JSON eklentisinin elle yüklenmesini gerektirebilir. Ubuntu kullanırken, bu apt-get
install php5-json aracılığı ile yapılabilir.
Yapılandırma
Laravel’in çalışabilmesi için neredeyse hiç yapılandırma ayarı gerekmez. Geliştirmeye hemen başlayabilirsiniz! Ancak app/config/app.php
dosyasını ve dokümantasyonunu gözden geçirebilirsiniz. Buradaki
⁵⁸https://github.com/laravel/laravel/archive/master.zip
⁵⁹http://git-scm.com/downloads
3
Kurulum
timezone (saat dilimi) ve locale gibi değerleri uygulamanızın
ihtiyaçlarına göre düzenleyebilirsiniz.
Laravel yüklendikten sonra, local ortamınızı yapılandırmanız⁶⁰ da
gerekmektedir. Bu size local makinenizde geliştirme yaparken ayrıntılı hata mesajları alma imkanı verecektir. Ön tanımlı olarak,
üretim yapılandırma dosyanızdaki ayrıntılı hata bildirimi devre dışı
durumdadır.
Not: Bir üretim ortamında app.debug değerini asla
true ayarlamamalısınız. Bunu hiçbir zaman yapmayın.
İzinler
Laravel app/storage dizin içeriğinin web sunucu tarafından yazılabilir olmasını gerektirmektedir.
Dosya Yolları
Framework dizin yollarının birkaçı yapılandırılabilirdir. Bu dizin
yollarını değiştirebilmek için bootstrap/paths.php dosyasını gözden geçiriniz.
Zarif URL’ler
Apache
Laravel framework, URL’lerin index.php olmadan kullanımına
imkan vermek için kullanılan bir public/.htaccess dosyası ile
birlikte gelmektedir. Laravel uygulamanızın sunumu için Apache
⁶⁰/docs/configuration#environment-configuration
4
Kurulum
kullanıyorsanız mod_rewrite modülünün etkin olduğundan emin
olunuz.
Eğer Laravel ile birlikte gelen .htaccess dosyası Apache kurulumunuz ile işlev göstermezse, bunu deneyiniz:
1
2
Options +FollowSymLinks
RewriteEngine On
3
4
5
6
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
Nginx
Nginx kullanıyorsanız, ekteki ayar “zarif url”lerin çalışmasını sağlamaya yeterlidir:
1
2
3
location / {
try_files $uri $uri/ /index.php?$query_string;
}
Yapılandırma
Giriş
Laravel’in tüm yapılandırma dosyaları app/config dizini içindedir.
Tüm dosyalardaki yapılandırma seçenekleri açıklanmıştır, dosyalara göz gezdirip size sunulan seçeneklere göz atabilirsiniz.
Bazen yapılandırma değerlerine run-time (çalışma anı) esnasında
erişmeniz gerekir. Bunu Config sınıfını kullanarak yapabilirsiniz:
Bir Yapılandırma Değerine Erişmek
1
Config::get('app.timezone');
Eğer yapılandırma değeri bulunamazsa dönecek değeri ise, ikinci
bir parametreyle belirleyebilirsiniz:
1
$timezone = Config::get('app.timezone', 'UTC');
Bir Yapılandırma Değeri Ayarlamak
Lütfen dikkat edin, “nokta” şeklindeki kullanım biçimi tüm yapılandırma dosyalarına erişmenizi sağlar. Dilerseniz yapılandırma
değerlerini run-time (çalışma anı) esnasında da ayarlayabilirsiniz:
1
Config::set('database.default', 'sqlite');
Çalışma zamanında ayarlanan yapılandırma değerleri sadece güncel istek süresince ayarlanırlar ve sonraki isteklere aktarılmayacaklardır.
6
Yapılandırma
Ortam Yapılandırması
Uygulamanın çalışma ortamına göre farklı yapılandırma değerlerine sahip olmak çoğu zaman iyidir. Örneğin, kişisel bilgisayarınızda, sunucudan farklı bir önbellekleme uygulaması kullanmak
isteyebilirsiniz. Bunu ortam tabanlı yapılandırmalar oluşturarak
sağlayabilirsiniz.
Bunu yapmak çok basit! config dizini içerisinde, ortam isminizi kullandığınız (örneğin local) bir dizin daha oluşturun. Şimdi,
belirttiğiniz ortam için üzerine yazmak istediğiniz yapılandırma
dosyalarınızı ve seçeneklerinizi geçirin. Örneğin, önbellekleme yapılandırmasının üzerine yazmak için, app/config/local dizini içerisinde cache.php dosyası oluşturmanız gerekir. Oluşturduğunuz
dosyanın içerisine şunları yazın:
1
<?php
2
3
return array(
4
'driver' => 'file',
5
6
7
);
Not: ‘testing’ adını ortam ismi olarak kullanmayın. Bu
isim Unit Testing amacıyla rezerve edilmiştir.
Dikkat ederseniz, bu dosyada bütün değerleri yazmanıza gerek yok.
Sadece üzerine yazmak istediklerinizi eklemeniz yeterli. Geri kalan
değerler, öntanımlı yapılandırma değerlerinden alınacaktır.
Şimdi yapmamız gereken Laravel’e hangi ortamda çalıştığını belirtmek. Öntanımlı ortam daima production ortamıdır. Ancak ana
dizindeki bootstrap/start.php dosyası içerisine eklemeler yaparak farklı ortamlar oluşturmak mümkündür. Bu dosya içerisinde
Yapılandırma
7
$app->detectEnvironment adında bir tanım bulacaksınız. Bu me-
toda eklenen bir parametre ile Laravel’e hangi ortamda çalıştığını
belirtebilirsiniz. Hatta ihtiyacınız olursa, diğer ortam ve makine
isimlerini de dizi olarak ekleyebilirsiniz:
1
<?php
2
3
$env = $app->detectEnvironment(array(
4
'local' => array('bilgisayarınızın-ismi'),
5
6
7
));
Bu örnekte, ‘local’ ortamın ismi ve ‘bilgisayarınızın-ismi’ sunucunuzun makine ismidir. Linux ve Mac işletim sistemlerinde, terminalde hostname komutunu çalıştırarak sunucunuzun makine ismini
öğrenebilirsiniz.
Dilerseniz, detectEnvironment methoduna Closure ekleyip ortam
algılama özelliğini kendiniz de yazabilirsiniz:
1
2
3
4
$env = $app->detectEnvironment(function()
{
return $_SERVER['MY_LARAVEL_ENV'];
});
Şu anki Uygulama Ortamına Erişmek
Şu anki uygulama ortamına environment metoduyla erişebilirsiniz:
1
$environment = App::environment();
Ayrıca environment metoduna bir veya daha fazla parametre girerek, ortamın girilen parametrelerden biriyle eşleşip eşleşmediğini
kontrol edebilirsiniz:
8
Yapılandırma
1
2
3
4
if (App::environment('local'))
{
// Ortam 'local'
}
5
6
7
8
9
if (App::environment('local', 'staging'))
{
// Ortam 'local' veya 'staging'
}
Sağlayıcı Yapılandırması
Ortam yapılandırması kullanırken ana app yapılandırma dosyanıza
ortam hizmet sağlayıcıları⁶¹ eklemek isteyebilirsiniz. Denediğinizde, ortama ait sağlayıcıların, ana app yapılandırmasındaki sağlayıcıları geçersiz kıldığını fark edeceksiniz. Ortama ait sağlayıcıların,
diğerlerini geçersiz kılmak yerine onlara eklenmesini sağlamak
için ortam yapılandırma dosyalarınızda append_config yardımcı
fonksiyonunu kullanmanız gerekir:
1
2
3
'providers' => append_config(array(
'LocalOnlyServiceProvider',
))
Hassas Yapılandırmaları Korumak
“Gerçek” uygulamalarda, hassas yapılandırmaları yapılandırma dosyalarında tutmamanız önerilir. Veritabanı şifreleri, Stripe API anahtarları ve kriptolama anahtarları mümkün olduğunca yapılandırma
dosyalarının dışında tutulmalıdır. O zaman nerede tutacağız bu
bilgileri? Neyse ki, Laravel bu tip bilgilerin korunabilmesi için
⁶¹/docs/ioc#service-providers
Yapılandırma
9
“nokta” yapılandırma dosyaları adında oldukça basit bir çözüm
sağlıyor.
Öncelikle uygulamanızı ‘local’ ortamınızı tanıyacak şekilde yapılandır⁶²malısınız. Sonra projenizin kök dizininde, yani composer.json dosyanızın bulunduğu dizinde .env.local.php dosyanızı
oluşturmalısınız. Bu dosya tıpkı diğer Laravel yapılandırma dosyaları gibi anahtar-değer çiftlerine sahip bir dizi döndürmelidir.
1
<?php
2
3
return array(
4
'TEST_STRIPE_KEY' => 'super-secret-sauce',
5
6
7
);
Bu dosyadaki tüm anahtar-değer çiftleri PHP’nin $_ENV ve $_SERVER “süperküresel” değişkenlerinde erişilebilir olacaktır. Artık
yapılandırma dosyalarınızda bu değişkenlere erişebilirsiniz:
1
'key' => $_ENV['TEST_STRIPE_KEY']
.env.local.php dosyasını .gitignore dosyasına eklemeyi unutmayın. Bu, dosyanın kaynak kontrol sistemine (Git) girmesini ve
ortamınızın kişisel bilgilerine erişilmesini engeller.
Şimdi bir de projenizi yayınladığınız sunucuda .env.php dosyası oluşturup gerekli yapılandırmaları aynı formatta girin. Aynı
.env.local.php dosyası gibi, bu .env.php üretim ortamı dosyası
da hiçbir zaman kaynak kontrolde bulunmamalıdır.
Not: Her bir ortam için gerekli yapılandırma dosyasını oluşturabilirsiniz. Örneğin, development ortamında
⁶²/docs/configuration#environment-configuration
10
Yapılandırma
çalışan proje, eğer varsa .env.development.php dosyasını sisteme dahil edecektir.
Bakım Modu
Uygulamanız bakım modundayken, her istek için standart bir view gösterilir. Böylece uygulamanız güncellenirken, bir süreliğine
uygulamayı “çalışmaz hale” getirebilirsiniz. Halihazırda App::down
methoduna yapılan bir istek app/start/global.php dosyasında
bulunmaktadır. Uygulamanız bakım modunda olduğunda, kullanıcılara bu metoddan dönen yanıt gönderilecektir.
Bakım modunu açmak için down komutunu Artisan üzerinde çalıştırın:
1
php artisan down
Bakım modunu kapatmak içinse, up komutunu çalıştırabilirsiniz:
1
php artisan up
Uygulamanız bakım modundayken kullanıcılara özel bir view göstermek için app/start/global.php dosyası içerisindeki down methodunu dilediğiniz gibi değiştirebilirsiniz:
1
2
3
4
App::down(function()
{
return Response::view('bakim_sayfasi', array(), 503);
})
Eğer down metoduna girilen anonim fonksiyon (Closure) NULL değeri döndürürse, bakım modu o istek için görmezden gelinecektir.
11
Yapılandırma
Bakım Modu ve Kuyruklar
Uygulamanız bakım modunda iken, hiçbir kuyruk işlemi⁶³ uygulanmaz. Tüm işlemler, uygulama bakım modundan çıktığında normal
bir şekilde devam eder.
⁶³/docs/queues
Laravel Homestead
Giriş
Laravel sizin lokal geliştirme ortamınız da dahil olmak üzere bütün
PHP geliştirme deneyimini zevkli bir hale getirmeye çalışmaktadır.
Vagrant⁶⁴ Sanal Makinelerin yönetilmesi ve hazırlanması için basit,
zekice bir yol sağlamaktadır.
Laravel Homestead lokal makinenizde PHP, bir web sunucusu ve
diğer herhangi bir sunucu yazılımı yüklemenizi gerektirmeksizin
size harika bir geliştirme ortamı sağlayan resmi, ambalajlanmış
bir Vagrant “box”tur. İşletim sisteminizi karışmasını daha artık
dert etmeyin! Vagrant box’ları tamamen kontrol altındadır. Eğer
bir şeyler yanlış giderse, onu yok edebilir ve dakikalar içerisinde
yeniden oluşturabilirsiniz!
Homestead herhangi bir Windows, Mac ve Linux’te çalışır ve Nginx
web sunucusu, PHP 5.5, MySQL, Postgres, Redis, Memcached ve
muhteşem Laravel uygulamaları geliştirmek için gerekli diğer tüm
güzellikleri içerir.
Homestead hali hazırda Vagrant 1.6 kullanılarak inşa ve test edilmiştir.
Dahil Edilen Yazılımlar
•
•
•
•
Ubuntu 14.04
PHP 5.5
Nginx
MySQL
⁶⁴http://vagrantup.com
13
Laravel Homestead
•
•
•
•
•
•
•
Postgres
Node (Bower, Grunt ve Gulp ile)
Redis
Memcached
Beanstalkd
Laravel Envoy⁶⁵
Fabric + HipChat Uzantısı
Yükleme & Kurulum
VirtualBox & Vagrant Yüklemesi
Homestead ortamınızı başlatabilmek için, VirtualBox⁶⁶ ve Vagrant⁶⁷
yüklemelisiniz. Bu yazılım paketlerinin her ikisi de tüm popüler
işletim sistemleri için kullanımı kolay görsel yükleyiciler sağlar.
Vagrant Box Eklenmesi
VirtualBox ve Vagrant yüklendikten sonra, terminalinizde aşağıdaki komutu kullanarak Vagrant yüklemenize laravel/homestead
box’ını eklemelisiniz. Bu kutunun indirilmesi, internet bağlantı
hızınıza bağlı olarak birkaç dakika alacaktır:
1
vagrant box add laravel/homestead
Homestead Ambarını Klonlayın
Kutuyu Vagrant yüklemenize ekledikten sonra, bu ambarı klonlamalı veya indirmelisiniz. Homestead kutusu sizin tüm Laravel (ve
⁶⁵/docs/ssh#envoy-task-runner
⁶⁶https://www.virtualbox.org/wiki/Downloads
⁶⁷http://www.vagrantup.com/downloads.html
Laravel Homestead
14
PHP) projelerinizin host’u olarak hizmet edeceği için, bu ambarı
tüm Laravel projelerinizi tuttuğunuz merkezi bir Homestead dizinine klonlamayı düşünün.
1
2
git clone https://github.com/laravel/homestead.git Home\
stead
SSH Anahtarınızı Ayarlayın
Ondan sonra da, ambarda bulunan Homestead.yaml dosyasını düzenleyin. Bu dosyada, public SSH anahtarınızın, bunun yanı sıra
ana makineniz ile Homestead sanal makineniz arasında paylaşılmasını istediğiniz klasörlerin yolunu ayarlayabilirsiniz.
Bir SSH anahtarınız yok mu? Mac ve Linux’te, genel olarak aşağıdaki komutu kullanarak bir SSH anahtar çifti oluşturabilirsiniz:
1
ssh-keygen -t rsa -C "your@email.com"
Windows’ta, Git⁶⁸ yükleyebilir ve yukarıdaki komutu vermek için
Git’le birlikte bulunan Git Bash kabuğunu kullanabilirsiniz. Alternatif olarak, PuTTY⁶⁹ ve PuTTYgen⁷⁰ kullanabilirsiniz.
Bir SSH anahtarı oluşturduktan sonra, Homestead.yaml dosyanızın
authorize özelliğinde anahtarın yolunu belirtin.
Paylaşılan Klasörlerinizi Yapılandırın
Homestead.yaml dosyanızın folders özelliği Homestead ortamınız-
da paylaşmak istediğiniz klasörlerin tümünü listeler. Bu klasörler
içindeki dosyalar değiştikçe, bunlar lokal makineniz ile Homestead
ortamı arasında senkronize tutulacaktır. Ne kadar gerekiyorsa o
kadar paylaşılan klasör yapılandırabilirsiniz!
⁶⁸http://git-scm.com/
⁶⁹http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
⁷⁰http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
15
Laravel Homestead
Nginx Sitelerinizi Yapılandırın
Nginx size tanıdık değil mi? Problem değil. sites özelliği, Homestead ortamınızdaki bir klasöre kolaylıkla bir “domain” eşleştirmenize
imkan verir. Örnek bir site yapılandırması Homestead.yaml dosyasına dahil edilmiştir. Aynı şekilde, Homestead ortamınıza gerektiği
kadar çok sayıda site ekleyebilirsiniz. Homestead, üzerinde çalışmakta olduğunuz her Laravel projesi için kullanışlı, sanallaştırılmış
bir ortam olarak hizmet edebilir!
Bash Alias’ları
Homestead kutunuza Bash aliasları eklemek için, basitçe Homestead dizininin köküne aliases dosyası ekleyin.
Vagrant Box’ı Başlatın
Homestead.yaml dosyasını istediğiniz gibi düzenledikten sonra, terminalinizde Homestead dizininden vagrant up komutunu çalıştı-
rın. Vagrant sanal makineyi boot edecektir ve paylaşılan klasörlerinizi ve Nginx sitelerinizi otomatik olarak yapılandıracaktır!
Nginx siteleriniz için “domain”leri makinenizdeki hosts dosyasına
eklemeyi unutmayın! Bu hosts dosyası local domain’lerinize gelen
istekleri Homestead ortamınıza yönlendirecektir. Mac ve Linux’te,
bu dosya /etc/hosts konumundadır. Windows’ta, C:\Windows\System32\drivers\e
konumundadır. Bu dosyaya eklediğiniz satırlar aşağıdaki gibi gözükecektir:
1
127.0.0.1
homestead.app
Domain’i hosts dosyanıza ekledikten sonra, siteye tarayıcınız aracılığıyla port 8000 üzerinden erişebilirsiniz!
16
Laravel Homestead
1
http://homestead.app:8000
Veritabanlarınıza nasıl bağlanacağınızı öğrenmek için, okumaya
devam edin!
Günlük Kullanım
SSH Aracılığıyla Bağlanma
Homestead ortamınıza SSH aracılığıyla bağlanmak için, Homestead.yaml
dosyanızda belirttiğiniz SSH anahtarını kullanarak port 2222 üzerinde 127.0.0.1‘e bağlanmalısınız. Ayrıca, basitçe Homestead dizininizden vagrant ssh komutunu da çalıştırabilirsiniz.
Eğer daha fazla kolaylık istiyorsanız ∼/.bash_aliases veya ∼/.bash_profile‘inize aşağıdaki aliası eklemek yararlı olabilir:
1
alias vm='ssh vagrant@127.0.0.1 -p 2222'
Veritabanlarınıza Bağlanma
Laravel’in geliş halinde hem MySQL hem de Postgres için bir
homestead veritabanı yapılandırılmıştır. Hatta daha fazla kolaylık
için Laravel’in local “database” yapılandırma dosyası ön tanımlı
olarak bu veritabanını kullanacak şekilde ayarlanmıştır.
Navicat veya Sequel Pro aracılığıyla ana makinenizdeki MySQL
veya Postgres veritabanlarınıza bağlanmak için, 127.0.0.1 ve 33060
(MySQL) veya 54320 (Postgres) portuna bağlanmalısınız. Her iki
veritabanı için username ve password homestead / secret‘dir.
Not: Standart dışı bu portları sadece ana makinenizdeki veritabanlarına bağlanırken kullanmalısınız. Laravel, Sanal Makine içerisinde çalıştığı için, Laravel
17
Laravel Homestead
veritabanı yapılandırma dosyanızda ön tanımlı 3306 ve
5432 portlarını kullanacaksınız.
İlave Sitelerin Eklenmesi
Homestead ortamınızı hazırladıktan ve çalıştırdıktan sonra, Laravel
uygulamalarınız için başka Nginx siteleri eklemek isteyebilirsiniz.
Tek bir Homestead ortamında istediğiniz kadar çok sayıda Laravel
yüklemesi çalıştırabilirsiniz. Bunu yapmanın iki yolu vardır. İlk
olarak, basitçe bu siteleri Homestead.yaml dosyanıza ekleyebilir ve
ondan sonra da vagrant provision çalıştırabilirsiniz.
Alternatif olarak, Homestead ortamınızda bulunan serve skriptini
kullanabilirsiniz. Bu serve skriptini kullanmak için, Homestead
ortamınıza SSH ile girin ve aşağıdaki komutu çalıştırın:
1
2
serve domain.app /home/vagrant/Code/path/to/public/dire\
ctory
Not: serve komutunu çalıştırdıktan sonra, ana makinenizdeki hosts dosyanıza yeni siteyi eklemeyi unutmayın!
Portlar
Aşağıdaki portlar Homestead ortamınıza yönlendirilir:
•
•
•
•
SSH: 2222 -> 22’ye yönlendirilir
HTTP: 8000 -> 80’e yönlendirilir
MySQL: 33060 -> 3306’ya yönlendirilir
Postgres: 54320 -> 5432’ye yönlendirilir
İstek Yaşam Döngüsü
Genel Bakış
“Gerçek dünyada” bir alet kullanırken, aletin nasıl kullanıldığını bilirseniz kendinizi daha güvende hissedersiniz. Uygulama geliştirme
farklı değildir. Geliştirme aletlerinizin nasıl fonksiyon gördüklerini
bilirseniz bunları kullanırken kendinizi daha rahat ve güvende
hissedersiniz. Bu dokümanın amacı Laravel frameworkünün nasıl
“çalıştığının” iyi, yüksek düzeyli bir özetini vermektir. Tüm frameworkün daha iyi tanınmasıyla, her şey daha az “büyülü” hissedilecek ve uygulamanızı inşa ederken daha güvenli olacaksınız.
İstek yaşam döngüsünün yüksek düzeyli bir özetine ek olarak “start”
dosyalarını ve application olaylarını da anlatacağız.
Terimlerin hepsini hemencecik anlamadıysanız, inancınızı kaybetmeyin! Sadece ne olup bittiğini temel olarak kavrayama çalışın.
Dokümantasyonun diğer kesimlerini inceledikçe bilginiz giderek
büyüyecektir.
İstek Yaşam Döngüsü
Uygulamanıza gelen tüm istekler public/index.php skripti aracılığı ile yönetilir. Apache kullanırken, Laravel’le gelen .htaccess
dosyası tüm isteklerin index.php‘ye geçirilmesi işini halletmektedir. Bu noktadan itibaren, Laravel istekleri işleme ve istemciye bir
cevap döndürme sürecine başlar. Laravel bootstrap süreci hakkında
genel bir fikir elde edilmesi yararlı olacaktır, bu nedenle şimdi onu
anlatacağız!
Laravel’in bootstrap sürecini öğrenirken kavranması gereken en
önemli kavram Servis Sağlayıcılarıdır. Kendinizin app/config/app.php
İstek Yaşam Döngüsü
19
yapılandırma dosyasını açıp, buradaki providers dizisine bakarak
servis sağlayıcılarının bir listesini görebilirsiniz. Bu sağlayıcılar
Laravel için başlıca bootstrapping mekanizması olarak hizmet ederler. Fakat, servis sağlayıcıları konusuna daha fazla girmeden önce
index.php dosyasına geri dönelim. Bir istek sizin index.php dosyasına girdikten sonra, bootstrap/start.php dosyası yüklenecektir.
Bu dosya, aynı zamanda bir IoC konteyneri⁷¹ olarak hizmet eden
yeni bir Laravel Application nesnesi oluşturur.
Application nesnesi oluşturulduktan sonra, birkaç proje path’i
ayarlanacak ve ortam tespiti⁷² yapılacaktır. Ondan sonra, dahili bir
Laravel bootstrap skripti çağrılacaktır. Bu dosya Laravel kaynağının
derinliklerinde yaşar ve yapılandırma dosyalarınıza dayalı olarak
zaman dilimi (timezone), hata bildirimi ve benzeri birkaç ayarı
daha ayarlar. Fakat, oldukça önemsiz yapılandırma seçeneklerinin
ayarlanmasına ek olarak, aynı zamanda çok önemli bir şey daha yapar: uygulamanız için yapılandırılmış servis sağlayıcılarının hepsini
kayda geçirir.
Basit servis sağlayıcılarında sadece bir metod vardır: register.
Bu register metodu, Application nesnesi tarafından Application’un kendi register metodu aracılığıyla bir servis sağlayıcısı
kayda geçirildiği zaman çağrılır. Bu metod içerisinde, servis sağlayıcıları bir şeyleri IoC konteynerinde⁷³ kayda geçirirler. Esasında, her servis sağlayıcı konteynere bir veya daha fazla closure⁷⁴
(anonim fonksiyon) bağlar ki, bu closure’lar uygulamanız içinde
bağlanmış hizmetlere erişmenize imkan verirler. Yani, örnek olarak
QueueServiceProvider servis sağlayıcısı Kuyruk (Queue)⁷⁵ ile ilgili
çeşitli sınıfları çözümleyen closure’leri kayda geçirmektedir. Pek
tabii, servis sağlayıcıları sadece bir şeyleri IoC konteynerinde kayda
geçirmekte değil, her türlü bootstrapping işi için kullanılabilirler.
⁷¹/docs/ioc
⁷²/docs/configuration#environment-configuration
⁷³/docs/ioc
⁷⁴http://us3.php.net/manual/en/functions.anonymous.php
⁷⁵/docs/queues
20
İstek Yaşam Döngüsü
Bir servis sağlayıcı olay dinleyicilerini, view composer’lerini, Artisan komutlarını ve başkalarını kayda geçirebilirler.
Servis sağlayıcılarının hepsi kayda geçirildikten sonra, app/start
dosyalarınız yüklenecektir. Son olarak, app/routes.php dosyanız
yüklenecektir. routes.php dosyanız yüklendikten sonra, Request
nesnesi bir rotaya sevk edilebilmesi için “application”a gönderilir.
Özetleyecek olursak:
1. İstek public/index.php dosyasına girer.
2. bootstrap/start.php dosyası “Application”ı oluşturur ve
ortamı tespit eder.
3. Dahili framework/start.php dosyası ayarları yapılandırır ve
servis sağlayıcılarını yükler.
4. Application app/start dosyaları yüklenir.
5. Application app/routes.php dosyası yüklenir.
6. Request nesnesi Application’a gönderilir, o da Response nesnesi döndürür.
7. Response nesnesi istemciye geri gönderilir.
Artık bir Laravel uygulamasına gelen bir isteğin nasıl işlendiği
konusunda iyi bir fikre sahip olduğunuza göre, “start” dosyalarına
daha yakından bakabiliriz!
Start Dosyaları
Uygulamanızın start dosyaları app/start dizininde bulunmaktadır.
Varsayılan olarak bunlardan üçü uygulamanızın içine dahil edilmiştir. Bunlar global.php, local.php ve artisan.php‘dir. artisan.php
hakkında daha fazla bilgiye sahip olmak için Artisan komut satırı⁷⁶
dökümanlarına bakınız.
⁷⁶/docs/commands#registering-commands
İstek Yaşam Döngüsü
21
Bunlardan global.php start dosyası Günlüklerin⁷⁷ kayda geçirilmesi ve app/filters.php dosyanızın dahil edilmesi gibi ön tanımlı
birkaç temel öğe içerir. Ancak, bu dosyaya istediğiniz her şeyi
ekleyebilirsiniz. Bu dosya ortam ne olursa olsun uygulamanıza
gelen her istekte otomatik olarak dahil edilecektir. Öte yandan
local.php dosyası yalnızca uygulamanız local ortamda çalışırken
çağrılır. Ortamlar hakkında daha fazla bilgi için Yapılandırma⁷⁸
belgelerine bakınız.
local‘e ilaveten başka ortamlarınız da varsa, pek tabii bu or-
tamlar için de start dosyaları oluşturabilirsiniz. Uygulamanız o
ortamda çalıştığı zaman bunlar otomatik olarak dahil edileceklerdir. Dolayısıyla, örneğin eğer bootstrap/start.php dosyanızda yapılandırılmış olan bir development ortamına sahipseniz, bir
app/start/development.php dosyası oluşturabilirsiniz; herhangi
bir istek uygulamaya bu ortamda girdiği zaman bu dosya dahil
edilecektir.
Start Dosyalarına Koyulacak Şeyler
Start dosyaları her türlü “bootstrapping” kodun koyulacağı basit bir
yer olarak hizmet ederler. Örneğin, bir View composer’ı kayda geçirebilir, günlükleme tercihlerinizi yapılandırabilir, bazı PHP ayarlarını ve benzerlerini yapabilirsiniz. Bu tamamen size kalmış. Tabii ki,
tüm önyükleme kodunuzun start dosyalarına atılması bir karışıklık
ve dağınıklık oluşturabilir. Büyük uygulamalar için veya eğer start
dosyalarınızın karışmaya başladığını hissederseniz, bootstrapping
kodunuzun bir kısmını servis sağlayıcılarına⁷⁹ taşımayı düşünün.
⁷⁷/docs/errors
⁷⁸/docs/configuration
⁷⁹/docs/ioc#service-providers
İstek Yaşam Döngüsü
22
Application Olayları (Events)
Uygulama Olaylarının Kayda Geçirilmesi
Bunlara ek olarak before, after, close, finish ve shutdown uygulama olaylarını kayda geçirmek suretiyle istek öncesinde ve
sonrasında bazı işlemler de yapabilirsiniz:
1
2
3
4
App::before(function($request)
{
//İstek öncesi olayları
});
5
6
7
8
9
App::after(function($request, $response)
{
//İstek sonrası olayları
});
Bu olay dinleyicileri, uygulamanıza yapılan her istek öncesinde
(before) ve sonrasında (after) çalışacaktır. Bu olaylar cevapların global filtrelenmesi veya global modifikasyonu için yardımcı
olabilirler. Bunları start dosyalarınızın birinde veya bir servis
sağlayıcısında⁸⁰ kayda geçirebilirsiniz.
Bir dinleyiciyi matched eventinde de kayda geçirebilirsiniz; bu,
gelen bir istek bir rotayla eşleştirildiğinde, ancak rota daha henüz
çalıştırılmadan önce ateşlenecektir:
1
2
3
4
Route::matched(function($route, $request)
{
//
});
⁸⁰/docs/ioc#service-providers
İstek Yaşam Döngüsü
23
finish eventi bir cevap sizin uygulamanızdan istemciye geri gön-
derildikten sonra çağrılır. Burası uygulamanızın gerektirdiği bir
son dakika işlemini yapmak için iyi bir yerdir. shutdown eventi
ise tüm finish olay işleyicileri işlemlerini bitirdikten hemen sonra
çağrılır ve skript sona ermeden önce herhangi bir iş yapmak için son
fırsattır. Büyük ihtimalle, bu olaylardan birini kullanma ihtiyacınız
olmayacaktır.
Rotalar
Temel Rotalama
Uygulamanızdaki rotaların çoğu app/routes.php dosyasında tanımlanır. En temel Laravel rotası “URL deseni” ve closure (anonim
fonksiyon)‘dan oluşur.
Temel GET Rotası
1
2
3
4
Route::get('/', function()
{
return 'Merhaba Laravel!';
});
Temel POST Rotası
1
2
3
4
Route::post('bir/sey', function()
{
return 'Merhaba Laravel!';
});
Bir Rotanın Birden Çok HTTP Fiili İçin Kayda
Geçirilmesi
1
2
3
4
Route::match(array('GET', 'POST'), '/', function()
{
return 'Merhaba Laravel!';
});
Tüm HTTP Metodları (GET, POST gibi) İçin Rota Yazımı
25
Rotalar
1
2
3
4
Route::any('falan', function()
{
return 'Merhaba Laravel!';
});
Rotanın Zorunlu Olarak HTTPS Üzerinden
Kullanılmasını Sağlamak
1
2
3
4
Route::get('falan', array('https', function()
{
return 'HTTPS üzerinde olmalı!';
}));
Çoğu zaman, rotalarınız için URL’ler üretmeniz gerekecek. Bunu
URL::to metoduyla yapabilirsiniz:
1
$url = URL::to('falan');
Rota Parametreleri
1
2
3
4
Route::get('kullanici/{id}', function($id)
{
return 'Kullanıcı NO: '.$id;
});
İsteğe Bağlı Rota Parametreleri
1
2
3
4
Route::get('kullanici/{isim?}', function($isim = null)
{
return $isim;
});
Öntanımlı Değerli İsteğe Bağlı Rota Parametreleri
26
Rotalar
1
2
3
4
Route::get('kullanici/{isim?}', function($isim = 'Ali')
{
return $isim;
});
Rotalarda Düzenli İfade Kontrolü
1
2
3
4
5
Route::get('kullanici/{isim}', function($isim)
{
//
})
->where('isim', '[A-Za-z]+');
6
7
8
9
10
11
Route::get('kullanici/{id}', function($id)
{
//
})
->where('id', '[0-9]+');
Bir Where’ler Dizisi Geçilmesi
Tabii ki kuralları bir dizi hâlinde tanımlayabilirsiniz:
1
2
3
4
5
Route::get('kullanici/{id}/{isim}', function($id, $isim)
{
//
})
->where(array('id' => '[0-9]+', 'isim' => '[a-z]+'))
Global Desenler Tanımlanması
Bir rota parametresinin her zaman için verilen bir düzenli ifadeyle
sınırlandırılmasını istiyorsanız, pattern metodunu kullanabilirsiniz:
27
Rotalar
1
Route::pattern('id', '[0-9]+');
2
3
4
5
6
Route::get('kullanici/{id}', function($id)
{
// Sadece {id} sayısal ise çağrılır.
});
Bir Rota Parametre Değerine Erişmek
Bir rotanın dışında bir rota parametre değerine erişmeniz gerekirse
Route::input metodunu kullanabilirsiniz:
1
2
3
4
5
6
7
Route::filter('falan', function()
{
if (Route::input('id') == 1)
{
//
}
});
Rota Filtreleri
Rota filtreleri, sitenizin yetkilendirme gereken alanlarına erişimi
kısıtlamak için uygun bir yoldur. Laravel frameworkte aralarında bir auth filtresi, bir auth.basic filtresi, bir guestfiltresi ve
bir csrf filtresinden oluşan birkaç filtre dahil edilmiştir. Bunlar
app/filters.php dosyasında bulunmaktadır.
Rota Filtresi Tanımlama
28
Rotalar
1
2
3
4
5
6
7
Route::filter('yas', function()
{
if (Input::get('yas') < 200)
{
return Redirect::to('anasayfa');
}
});
Eğer filtreden bir yanıt (Redirect::to gibi) döndürülürse, bu cevap
cevap olarak kabul edilecek ve rota çalıştırılmayacaktır. Rotada
olabilecek after filtreleri de iptal edilecektir.
Bir Rotaya Bir Filtre Bağlanması
1
2
3
4
5
Route::get('kullanici', array('before' => 'yas', functi\
on()
{
return '200 yaş üzerisin!';
}));
Bir Controller Eylemine Bir Filtre Bağlanması
1
2
Route::get('kullanici', array('before' => 'yas', 'uses'\
=> 'UserController@showProfile'));
Rotaya Birden Çok Filtre Bağlanması
1
2
3
4
5
Route::get('kullanici', array('before' => 'auth|yas', f\
unction()
{
return '200 yaşın üzerisin ve giriş yetkin var!';
}));
Birden Çok Filtrenin Dizi Yoluyla Bağlanması
29
Rotalar
1
2
3
4
5
Route::get('kullanici', array('before' => array('auth',\
'yas'), function()
{
return '200 yaşın üzerisin ve giriş yetkin var!';
}));
Filtre Parametrelerinin Belirtilmesi
1
2
3
4
Route::filter('yas', function($route, $request, $value)
{
//
});
5
6
7
8
9
10
Route::get('kullanici', array('before' => 'yas:200', fu\
nction()
{
return 'Merhaba Laravel!';
}));
After filtreleri filtreye üçüncü parametre olarak geçilen bir $response
parametresi alırlar:
1
2
3
4
5
Route::filter('log', function($route, $request, $respon\
se)
{
//
});
Desen Temelli Filtreler
URL desenine göre de rotalara filtre ataması yapabilirsiniz.
30
Rotalar
1
2
3
4
Route::filter('admin', function()
{
//
});
5
6
Route::when('admin/*', 'admin');
Yukarıdaki örnekte, admin filtresi admin/ ile başlayan tüm rotalara
uygulanacaktır. * karakteri tüm karakterleri yakalamak için kullanılır.
Filtreleri HTTP metodlarına (GET, POST gibi) göre uygulayabilirsiniz.
1
Route::when('admin/*', 'admin', array('post'));
Filtre Sınıfları
Daha gelişmiş filtreler için Closure yerine sınıfları kullanmak isteyebilirsiniz. Filtre sınıfları uygulama IoC Konteyneri⁸¹nde çözümlendikleri için, daha fazla test edilebilirlik için bu filtrelerde
bağımlılık enjeksiyonu kullanmanız mümkün olabilecektir.
Sınıf Temelli Filtrenin Kayda Geçirilmesi
1
Route::filter('falan', 'FalanFiltresi');
Ön tanımlı olarak, FalanFiltresi sınıfındaki filter metodu çağrılacaktır:
⁸¹/docs/ioc
31
Rotalar
1
class FalanFiltresi {
2
public function filter()
{
// Filtre işlemleri...
}
3
4
5
6
7
8
}
Bu filter metodunu kullanmak istemiyorsanız, başka bir metod
belirtebilirsiniz:
1
Route::filter('falan', 'FalanFiltresi');
İsimli Rotalar
İsimli rotalar link veya yönlendirme oluştururken kolaylık sağlar.
Bir rotayı şöyle isimlendirebilirsiniz:
1
2
3
4
5
Route::get('kullanici/profil', array('as' => 'profil', \
function()
{
//
}));
Denetçi metodları için de rota isimleri belirleyebilirsiniz:
1
2
Route::get('kullanici/profil', array('as' => 'profil', \
'uses' => 'KullaniciController@profilGoster'));
Şimdi, rota isimlerini link veya yönlendirme oluştururken kullanabilirsiniz:
32
Rotalar
1
$url = URL::route('profil');
2
3
$yonlendirme = Redirect::route('profil');
Çalışan rotanın ismine currentRouteName metoduyla ulaşabilirsiniz:
1
$isim = Route::currentRouteName();
Rota Grupları
Bazen bir grup rotaya filtre atamanız gerekebilir. Her birine ayrı
filtre atamaktansa, rota gruplarını kullanabilirsiniz:
1
2
3
4
5
6
Route::group(array('before' => 'auth'), function()
{
Route::get('/', function()
{
// Yetki gerekir. ("auth" filtresi)
});
7
Route::get('user/profile', function()
{
// Yetki gerekir. ("auth" filtresi)
});
8
9
10
11
12
});
Ayrıca, grup içindeki tüm controllerlerin verilen bir aduzayında
olacağını belirtmek için group array’iniz içerisinde namespace parametresini kullanabilirsiniz:
33
Rotalar
1
2
3
4
Route::group(array('namespace' => 'Admin'), function()
{
//
});
Alt Alanadı (Subdomain) Rotalaması
Laravel rotaları joker alt alanadlarını da işleyebilirler ve joker
parmetreleri alanadına geçebilirsiniz.
Alt Alanadı Rotası Tanımlama
1
2
3
Route::group(array('domain' => '{hesapadi}.uygulamam.co\
m'), function()
{
4
Route::get('kullanici/{id}', function($hesapadi, $id)
{
//
});
5
6
7
8
9
10
});
Rotalarda Ön-ek
Bir grubun nitelikler dizisinde prefix seçeneğini kullanarak gruptaki rotalara ön-ek ekleyebilirsiniz:
34
Rotalar
1
2
Route::group(array('prefix' => 'admin'), function()
{
3
Route::get('kullanici', function()
{
//
});
4
5
6
7
8
9
});
Rotalara Model Bağlama
Model bağlama model sınıflarının rotalarda kullanılması için kolaylık sağlar. Mesela, bir kullanıcının ID’sinin aktarılması yerine,
ID ile eşleşen Kullanici modelini aktarabilirsiniz. İlk olarak, girilen
parametreler için kullanılacak modelleri Route::model metoduyla
belirleyin:
Parametrelere Model Bağlama
1
Route::model('kullanici', 'Kullanici');
Daha sonra, {kullanici} parametresini içeren bir rota belirleyin:
1
2
3
4
5
Route::get('profil/{kullanici}', function(Kullanici $ku\
llanici)
{
//
});
{kullanici} parametresi ile Kullanici modelini eşleştirdiğimizden, bir Kullanici nesnesi rotaya aktarılacaktır. Yani, profil/1
şeklindeki istek, ID’si 1 olan Kullanici nesnesini aktaracaktır.
35
Rotalar
Not: Eğer model için veritabanında eşleşme yapılamazsa, 404 hatası fırlatılır.
Eğer eşleşmeme durumunda yapılacak işlemi kendiniz belirlemek
istiyorsanız, model metoduna 3. argüman olarak bir Closure ekleyebilirsiniz:
1
2
3
4
Route::model('kullanici', 'Kullanici', function()
{
throw new NotFoundHttpException;
});
Bazen, rota parametreleri için kendi çüzümleyicinizi kullanmak
isteyebilirsiniz. Bunun için Route::bind metodu kullanılır:
1
2
3
4
Route::bind('kullanici', function($deger, $route)
{
return Kullanici::where('isim', $deger)->first();
});
404 Hatası Fırlatma
Rotadan 404 hatasını fırlatmanın iki yolu vardır. İlk olarak, App::abort
metodunu kullanabilirsiniz.
1
App::abort(404);
İkinci, Symfony\Component\HttpKernel\Exception\NotFoundHttpException
nesnesi fırlatmaktır.
404 hatalarının yakalanması ve özel yanıtla oluşturulması hakkında
daha fazla bilgiye dokümantasyonun hatalar⁸² bölümünden ulaşabilirsiniz.
⁸²/docs/errors#handling-404-errors
Rotalar
36
Denetçilere (Controller) Rotalama
Laravel sadece Closure’lara değil, aynı zamanda denetçi sınıflarına
rotalamaya da imkan verir ve hatta kaynak denetçileri⁸³ oluşturulması da mümkündür.
Daha fazla bilgi için Denetçiler⁸⁴ konusunu inceleyin.
⁸³/docs/controllers#resource-controllers
⁸⁴/docs/controllers
İstekler (Requests) ve Girdi
(Input)
Temel Girdi
Tüm kullanıcı girdisine birkaç basit metodla erişebilirsiniz. İstek
için kullanılmış olan HTTP eylemi için endişe etmenize gerek
yoktur, bütün eylemler için girdi bilgisine erişim aynıdır.
Bir Girdi Değerinin Öğrenilmesi
1
$ismi = Input::get('ismi');
Bir Girdi Değerinin (Eksik Olması Durumunda
Varsayılacak Olan Bir “Ön Değer” Belirtilerek)
Öğrenilmesi
1
$ismi = Input::get('ismi', 'Saliha');
Bir Girdi Değerinin Mevcut Olduğunun Test Edilmesi
1
2
3
4
if (Input::has('ismi'))
{
//
}
İstekteki Tüm Girdi Değerlerinin Öğrenilmesi
İstekler (Requests) ve Girdi (Input)
1
38
$girdi = Input::all();
İstek Girdisinin Sadece Bazı Değerlerinin Öğrenilmesi
1
$girdi = Input::only('kullaniciadi', 'sifre');
2
3
$girdi = Input::except('kredi_karti');
“Dizi” girdileri olan formlarda çalışırken dizilere erişim için nokta
gösterimini kullanabilirsiniz:
1
$input = Input::get('products.0.name');
Not: Bazı JavaScript kütüphaneleri, örneğin Backbone,
girdi bilgisini uygulamaya JSON olarak gönderir. Bu
girdi verisine de yine normal şekilde Input::get ile
erişebilirsiniz.
Çerezler (Cookies)
Laravel çerçevesi tarafından oluşturulan tüm çerezler, bir kimlik
doğrulama kodu ile şifrelenir ve imzalanır. Kullanıcı tarafından
değiştirilmesi halinde geçersiz kabul edilecektir.
Bir Çerez Değerinin Öğrenilmesi
1
$deger = Cookie::get('ismi');
Cevaba (Response) Yeni Bir Çerez İliştirilmesi
İstekler (Requests) ve Girdi (Input)
1
39
$yanit = Response::make('Merhaba Dünya');
2
3
4
$yanit->withCookie(Cookie::make('ismi', 'degeri', $daki\
ka));
Sonraki Cavap İçin Kuyruğa Bir Çerez İliştirilmesi
Cevap oluşturulmadan önce bir çerez oluşturmak isterseniz, Cookie::queue()
metodunu kullanın. Uygulamanızdan gelen son cevaba yeni bir
çerez iliştirilecektir.
1
Cookie::queue($name, $value, $minutes);
Süresiz Bir Çerez Oluşturulması
1
$cerez = Cookie::forever('ismi', 'degeri');
Önceki Girdi
Bazı durumlarda bir isteğin girdisini bir sonraki isteğe kadar tutmanız gerekebilir. Örneğin, doğrulama hataları için kontrol ettikten
sonra bir formu yeniden bu önceki girdi bilgisi ile doldurmak
gerekebilir.
Girdinin Oturuma(Session) Geçici Olarak
Yansıtılması (flash)
1
Input::flash();
Girdinin Sadece Bazı Değerlerinin Oturuma Geçici
Olarak Yansıtılması
40
İstekler (Requests) ve Girdi (Input)
1
2
Input::flashOnly('kullaniciadi', 'email');
irtilenler
//sadece bel\
3
4
Input::flashExcept('sifre');
//belirtilenler hariç
Girdinin geçici olarak oturuma yansıtılmasını, sık şekilde bir önceki
sayfaya tekrar-yönlendirme (redirect) ile birlikte yapacağınız için,
bu yansıtmayı (redirect)’e zincir ek yapabilirsiniz.
1
2
return Redirect::to('form')->withInput();
eğerleri ile beraber
//tüm girdi d\
3
4
5
return Redirect::to('form')->withInput(Input::except('s\
ifre'));
//belirtilenler hariç
Not: Diğer verilerin istekler arasında geçici yansıtmasını (flash), Oturum Session⁸⁵ sınıfını kullanarak
yapabilirsiniz.
Önceki Girdi Verisinin Elde Edilmesi
1
Input::old('kullaniciadi');
Dosyalar
Yollanan Bir Dosyanın Öğrenilmesi
1
$dosya = Input::file('foto');
Bir Dosya Yollanmış Olup Olmadığının Belirlenmesi
⁸⁵/docs/session
İstekler (Requests) ve Girdi (Input)
1
2
3
4
41
if (Input::hasFile('foto'))
{
//
}
Dosya file metodu tarafından döndürülen nesne, PHP SplFileInfo
sınıfının bir uzantısı olan ve dosya ile etkileşim için çeşitli metodlar
sağlayan Symfony\Component\HttpFoundation\File\UploadedFile
sınıfının bir olgusudur.
Yüklenmiş Olan Bir Dosyanın Geçerli Olup
Olmadığının Belirlenmesi
1
2
3
4
if (Input::file('foto')->isValid())
{
//
}
Yüklenmiş Olan Bir Dosyanın Taşınması
1
Input::file('foto')->move($hedefDizinPatikasi);
2
3
4
Input::file('foto')->move($hedefDizinPatikasi, $dosyaAd\
i);
Yüklenmiş Olan Bir Dosyanın Dosya Yolunun
Öğrenilmesi
1
$patika = Input::file('foto')->getRealPath();
Yüklenmiş Olan Bir Dosyanın Orijinal Adının
Öğrenilmesi
İstekler (Requests) ve Girdi (Input)
1
42
$name = Input::file('foto')->getClientOriginalName();
Yüklenmiş Olan Bir Dosyanın Uzantısının
Öğrenilmesi
1
2
$uzanti = Input::file('foto')->getClientOriginalExtensi\
on();
Yüklenmiş Olan Bir Dosyanın Boyutunun
Öğrenilmesi
1
$buyukluk = Input::file('foto')->getSize();
Yüklenmiş Olan Bir Dosyanın MIME Türünün
Öğrenilmesi
1
$mime = Input::file('foto')->getMimeType();
İstek Bilgileri
İstek Request sınıfı, uygulamanıza gelecek olan HTTP isteğini incelemeniz için birçok metod sunar ve Symfony\Component\HttpFoundation\Request
sınıfının bir uzantısıdır. Bunlardan bazıları şöyledir.
İstek URI’nın Öğrenilmesi
1
$uri = Request::path();
Retrieving The Request Method
İstekler (Requests) ve Girdi (Input)
1
43
$method = Request::method();
2
3
4
5
6
if (Request::isMethod('post'))
{
//
}
İstek Patikasının Bir Desene Uygunluğunun Test
Edilmesi
1
2
3
4
if (Request::is('admin/*'))
{
//
}
İstek URL’nin Öğrenilmesi
1
$url = Request::url();
İstek URI’nın Herhangi Bir Bölümünün Öğrenilmesi
1
$segment = Request::segment(1);
Bir İstek Başlığı(Header) Değerinin Öğrenilmesi
1
$deger = Request::header('Content-Type');
Sunucu bilgileri için $_SERVER Değerlerinin
Öğrenilmesi
1
$deger = Request::server('PATH_INFO');
İsteğin HTTPS Üzerinden Olup Olmadığının
Belirlenmesi
İstekler (Requests) ve Girdi (Input)
1
2
3
4
44
if (Request::secure())
{
//
}
İsteğin AJAX Kullanıyor Olup Olmadığının
Belirlenmesi
1
2
3
4
if (Request::ajax())
{
//
}
İsteğin JSON Content Tipine Sahip Olup Olmadığının
Belirlenmesi
1
2
3
4
if (Request::isJson())
{
//
}
İsteğin JSON İstiyor Olup Olmadığının Belirlenmesi
1
2
3
4
if (Request::wantsJson())
{
//
}
İstenen Cevap Biçiminin Kontrol Edilmesi
Request::format metodu HTTP Accept header’ine dayalı olarak,
istenen cevap formatını döndürecektir:
İstekler (Requests) ve Girdi (Input)
1
2
3
4
if (Request::format() == 'json')
{
//
}
45
Görünümler (Views) ve
Cevaplar (Responses)
Temel Cevaplar
Rotalardan String Döndürme
1
2
3
4
Route::get('/', function()
{
return 'Merhaba dünya!';
});
Özel Cevaplar Oluşturma
Bir cevap (Response) olgusu Symfony\Component\HttpFoundation\Response
sınıfından türer ve HTTP cevapları oluşturmak için çeşitli metodlar
sağlar.
1
$cevap = Response::make($contents, $statusCode);
2
3
$cevap->header('Content-Type', $deger);
4
5
return $cevap;
Eğer Response sınıfının metodlarına erişmeniz gerekiyor, ama cevap içeriği olarak bir view döndürmek istiyorsanız, kolaylık açısından Response::view metodunu kullanabilirsiniz:
Görünümler (Views) ve Cevaplar (Responses)
1
2
47
return Response::view('hello')->header('Content-Type', \
$type);
Cevaplara Çerez Bağlanması
1
$cerez = Cookie::make('isim', 'deger');
2
3
return Response::make($content)->withCookie($cerez);
Yönlendirmeler (Redirects)
Bir Yönlendirme Döndürme
1
return Redirect::to('uye/giris');
Flaş Veri Eşliğinde Bir Yönlendirme Döndürme
1
2
return Redirect::to('uye/giris')->with('mesaj', 'Giriş \
başarısız!');
Not: with metodu veriyi oturum bilgisine flaşlayacağından, bu veriyi tipik Session::get metodu ile
alabilirsiniz.
İsimli Bir Rotaya Yönlendirme Döndürme
1
return Redirect::route('giris');
Parametre Geçerek İsimli Bir Rotaya Yönlendirme
Döndürme
Görünümler (Views) ve Cevaplar (Responses)
1
48
return Redirect::route('profil', array(1));
İsimli Parametre Kullanarak İsimli Bir Rotaya
Yönlendirme Döndürme
1
return Redirect::route('profil', array('uye' => 1));
Bir Kontrolör Eylemine Yönlendirme Döndürme
1
return Redirect::action('HomeController@index');
Parametre Geçerek Bir Kontrolör Eylemine
Yönlendirme Döndürme
1
2
return Redirect::action('UserController@profil', array(\
1));
İsimli Parametre Kullanarak Bir Kontrolör Eylemine
Yönlendirme Döndürme
1
2
return Redirect::action('UserController@profil', array(\
'uye' => 1));
Görünümler (Views)
Görünümler tipik olarak uygulamanızın HTML’sini içerirler ve
kontrolörünüzün ve etki alanı mantığınızın gösterim mantığınızdan ayrık tutulmasının uygun bir yoludur. Görünümler app/views
dizininde saklanmaktadır.
Basit bir görünüm şuna benzer:
Görünümler (Views) ve Cevaplar (Responses)
1
2
49
<!-- Görünüm app/views/selamlama.php dosyasında bulunsu\
n-->
3
4
<html>
<body>
5
<h1>Merhaba <?php echo $isim; ?></h1>
6
</body>
7
8
</html>
Bu görünüm web tarayıcısına şu şekilde döndürülebilir:
1
2
3
4
5
Route::get('/', function()
{
return View::make('selamlama', array('isim' => 'Tuana \
Şeyma'));
});
View::make metodundaki ikinci parametre görünümde kullanılma-
sı gereken bir veri dizisidir.
Görünümlere Veri Geçilmesi
1
2
3
// Geleneksel yaklaşım kullanmak
$view = View::make('selamlama')->with('isim', 'Tuana Şe\
yma');
4
5
6
7
// Sihirli Metodları kullanmak
$view = View::make('selamlama')->withIsim('Tuana Şeyma'\
);
Yukarıdaki örnekte $isim değişkeni görünümden erişilebilir olacak
ve Tuana Şeyma bilgisini taşıyacaktır.
Dilerseniz, make metoduna ikinci parametre olarak veriler dizisi
geçebilirsiniz:
Görünümler (Views) ve Cevaplar (Responses)
1
50
$view = View::make('selamlama', $data);
Bir parça veriyi tüm görünümler arasında paylaşmanız da mümkündür:
1
View::share('isim', 'Tuana Şeyma');
Bir Görünüme Bir Alt Görünüm Geçirilmesi
Bazen bir görünümü başka bir görünümün içine geçirmek isteyebilirsiniz. Örneğin, app/views/evlat/view.php‘de saklanan belli
bir görünüm olsun ve biz bunu şu şekilde başka bir görünüme
geçirebiliriz:
1
2
$view = View::make('selamlama')->nest('evlat', 'evlat.v\
iew');
3
4
5
$view = View::make('selamlama')->nest('evlat', 'evlat.v\
iew', $data);
Bundan sonra bu alt görünüm ebeveyn görünümde gösterilebilir:
1
<html>
<body>
2
<h1>Merhaba!</h1>
<?php echo $evlat; ?>
3
4
</body>
5
6
</html>
Bir Görünümün Mevcut Olmadığının Belirlenmesi
Bir view’in mevcut olup olmadığını yoklamanız gerekirse, View::exists
metodunu kullanın:
Görünümler (Views) ve Cevaplar (Responses)
1
2
3
51
if (View::exists('emails.customer'))
{
//
}
Görünüm Kompozitörleri
Görünüm kompozitörleri görünüm oluşturulduğu zaman çağrılan
isimsiz fonksiyonlar veya sınıf metodlarıdır. Eğer belli bir görünüm,
uygulamanız boyunca her oluşturulduğunda bu görünüme bağlamak istediğiniz bir veri varsa, bir görünüm kompozitörü kodun
tek bir yere koyulabilmesi imkanı verebilir. Bu nedenle, görünüm
kompozitörleri “görünüm modelleri” veya “sunum yapıcı” gibi iş
görürler.
Bir Görünüm Kompozitörü Tanımlanması
1
2
3
4
View::composer('profil', function($view)
{
$view->with('navigasyon', Sayfa::all());
});
Şimdi profil görünümü her oluşturulduğunda, navigasyon verisi
bu görünüme bağlanacaktır.
Bir görünüm kompozitörüne bir defada birden çok görünüm bağlamanız da mümkündür:
Görünümler (Views) ve Cevaplar (Responses)
1
2
3
4
5
52
View::composer(array('profil','pano','bildirim'), funct\
ion($view)
{
$view->with('navigasyon', Sayfa::all());
});
Bunun yerine sınıf tabanlı bir kompozitör kullanmak isterseniz, ki
uygulama IoC Konteyneri⁸⁶ ile çözümlenebilme yararı sağlar, şöyle
yapabilirsiniz:
1
View::composer('profil', 'ProfileComposer');
Bir görünüm kompozitörü sınıfı şöyle tanımlanmalıdır:
1
class ProfileComposer {
2
public function compose($view)
{
$view->with('adet', Uye::count());
}
3
4
5
6
7
8
}
Birden Çok Composer Tanımlanması
Bir grup composer’i bir defada kayda geçirmek için composers
metodunu kullanabilirsiniz:
⁸⁶/docs/ioc
Görünümler (Views) ve Cevaplar (Responses)
1
2
3
4
5
53
View::composers(array(
'AdminComposer' => array('admin.index', 'admin.profile\
'),
'UserComposer' => 'user',
));
Not: Kompozitör sınıfının nerede saklanacağı konusunda bir gelenek olmadığına dikkat edin. composer.json
dosyanızdaki yönergeleri kullanarak otomatik yüklenebildikleri sürece, bunları istediğiniz yerde depolayabilirsiniz.
Görünüm Oluşturucular
Görünüm oluşturucuları tam olarak görünüm kompozitörleri gibi
çalışırlar; ancak bunlar görünüm oluşturulur oluşturulmaz aktifleştirilirler. Görünüm oluşturucusu kaydetmek için, basitçe creator
metodunu kullanınız:
1
2
3
4
View::creator('profil', function($view)
{
$view->with('adet', Uye::count());
});
Özel Cevaplar
Bir JSON Cevabı Oluşturma
1
2
return Response::json(array('isim' => 'Tuana Şeyma', 'i\
l' => 'Bursa'));
Bir JSONP Cevabı Oluşturma
Görünümler (Views) ve Cevaplar (Responses)
1
2
54
return Response::json(array('isim' => 'Tuana Şeyma', 'i\
l' => 'Bursa'))->setCallback(Input::get('callback'));
Bir Dosya İndirme Cevabı Oluşturma
1
return Response::download($indirilecekDosyaYolu);
2
3
4
return Response::download($indirilecekDosyaYolu, $isim,\
$basliklar);
Not: Dosya indirmelerini yöneten Symfony HttpFoundation, indirilecek olan dosyanın bir ASCII dosya ismi
olmasını gerektirir.
Cevap Makroları
Çeşitli rota ve controllerlerinizde tekrar tekrar kullanabileceğiniz
özel bir cevap tanımlamak isterseniz, Response::macro metodunu
kullanabilirsiniz:
1
2
3
4
Response::macro('caps', function($value)
{
return Response::make(strtoupper($value));
});
Bu macro fonksiyonu birinci parametre olarak bir isim ve ikinci
parametre olarak bir Closure kabul eder. Response sınıfı üzerinde
makro ismi çağrıldığı zaman makronun Closure fonksiyonu çalıştırılacaktır:
1
return Response::caps('falan');
Görünümler (Views) ve Cevaplar (Responses)
55
Makrolarınızı app/start dosyalarınızın birinde tanımlayabilirsiniz.
Alternatif olarak, makrolarınızı ayrı bir dosya içerisinde organize
edip, bu dosyayı start dosyalarınızın birisinden “include” edebilirsiniz.
Denetçiler (Controllers)
Temel Denetçiler
Bütün rotalandırma mantığını, tüm rotaları tek tek routes.php dosyasında tanımlamak yerine, bu davranışlarını Denetçiler (Controllers) sınıflarını kullanarak organize edebilirsiniz. Denetçiler, ilişkin
oldukları rotaların mantığını bir sınıfta gruplar. Aynı zamanda,
daha ileri çerçeve (framework) özelliklerini kullanma avantajına
sahiptirler, örneğin otomatik dependency injection⁸⁷ (bağımlılık
enjeksiyonu) gibi.
Denetçiler genelde app/controllers dizininde konumlandırılır ve
varsayılan olarak bu dizin composer.json dosyanızın classmap
seçeneğinde kayda geçirilmiştir.
Basit bir denetçi (controller) sınıfı örneği şöyledir:
1
class KullaniciController extends BaseController {
2
/**
* Verilen kullanıcının profilini göster.
*/
public function showProfile($id)
{
$kullanici = Kullanici::find($id);
3
4
5
6
7
8
9
10
11
12
return View::make('kullanici.profil', array('kullanic\
i' => $kullanici));
}
13
14
}
⁸⁷/docs/ioc
Denetçiler (Controllers)
57
Bütün denetçilerin BaseController sınıfından türetilmiş olması
gerekir. BaseController ın kendisi de app/controllers dizininde
bulunur ve bütün denetçiler için geçerli olacak ortak mantığın
içine yerleştirilmesinde kullanılabilir. BaseController sınıfı, framework’ün Controller sınıfının uzantısıdır. Bu durumda, oluşturmuş olduğumuz denetçi fonksiyonuna rotalandırmayı şu şekilde
yapabiliriz:
1
2
Route::get('kullanici/{id}', 'KullaniciController@showP\
rofile');
Eğer bir denetçinizi, dizin içerisinde yuvalandırarak (nest) veya
PHP aduzayları (namespaces) kullanarak organize etmek isterseniz,
bu durumda rotayı tanımlarken, tam nitelendirilmiş (yani, aduzayıyla birlikte) sınıf adını kullanınız:
1
2
Route::get('falanca', 'Namespace\FalancaController@meto\
dAdi');
Not: PHP sınıflarımızı otomatik yüklemek için Composer⁸⁸ kullandığımız için, composer onların nasıl yükleneceğini bildiği sürece controllerler dosya sistemindeki herhangi bir yerde bulunabilir. Controller dizini
uygulamanız için herhangi bir klasör yapısını zorlamaz. Controller’lara rotalama dosya sisteminden tamamen ayrık tutulmuştur.
Denetçi rotalarına isimler de verebilirsiniz:
⁸⁸http://getcomposer.org
Denetçiler (Controllers)
1
2
3
58
Route::get('falanca', array('uses' => 'FalancaControlle\
r@metodAdi',
'as' => 'rotaAdi'));
Herhangi bir denetçi eylemine ait bir URL üretmek için, URL::action
metodunu veya action helper metodunu kullanabilirsiniz:
1
$url = URL::action('FalancaController@metodAdi');
2
3
$url = action('FalancaController@metodAdi');
Çalıştırılmakta olan bir denetçi eyleminin ismine currentRouteAction
metodu ile erişebilirsiniz:
1
$action = Route::currentRouteAction();
Denetçi Filtreleri
Denetçi rotalarına, diğer rotalarda olduğuna benzer şekilde, filtreler
Filters⁸⁹ belirlenebilir:
1
2
Route::get('profile', array('before' => 'auth',
'uses' => 'KullaniciController@showProfile'));
Filtreleri, denetçinizin içerisinden de belirtebilirsiniz:
⁸⁹/docs/routing#route-filters
Denetçiler (Controllers)
1
59
class KullaniciController extends BaseController {
2
/**
* Yeni bir KullaniciController olgusu başlat.
*/
public function __construct()
{
$this->beforeFilter('auth', array('except' => 'getGir\
3
4
5
6
7
8
9
is'));
10
$this->beforeFilter('csrf', array('on' => 'post'));
11
12
$this->afterFilter('log', array('only' =>
array('falancaMetod', 'filancaMetod')));
13
14
}
15
16
17
}
Denetçi filtrelerini bir Closure kullanarak da belirtebilirsiniz:
1
class KullaniciController extends BaseController {
2
/**
* Yeni bir KullaniciController olgusu başlat.
*/
public function __construct()
{
$this->beforeFilter(function()
{
//
});
}
3
4
5
6
7
8
9
10
11
12
13
14
}
Denetçiler (Controllers)
60
Eğer filtre olarak denetçi sınıfın bir metodunu kullanmak isterseniz,
filtre isminin önüne @ koymalısınız.
1
class UserController extends BaseController {
2
/**
* Yeni bir KullaniciController olgusu başlat.
*/
public function __construct()
{
$this->beforeFilter('@filterRequests');
}
3
4
5
6
7
8
9
10
/**
* Gelen istekleri filtrele.
*/
public function filterRequests($route, $request)
{
//
}
11
12
13
14
15
16
17
18
19
}
TEDA-uyumlu (Temsili Durum Aktarma
uyumlu, RESTful) Denetçiler
Laravel size, basit TEDA (REST) isimlendirme gelenekleri kullanarak, belirleyeceğiniz tek bir rota ile, denetçilerinizin içindeki her
eylemi kullanabilme imkanını tanır. İlk olarak, Route::controller
metodu ile bu rotayı tanımlayınız:
Denetçiler (Controllers)
1
2
61
Route::controller('kullanicilar', 'KullaniciController'\
);
controller metodu iki argüman alır. Birincisi denetçinin yönetece-
ği taban URI olup, ikincisi denetçinin sınıf ismidir. Akabinde sadece,
isimlerine HTTP eyleminin ön ek olarak ekleneceği ve bunlara
cevap verecek olan metodlarınızı denetçinize ilave ediniz:
1
class KullaniciController extends BaseController {
2
public function getIndex()
{
//
}
3
4
5
6
7
public function postProfile()
{
//
}
8
9
10
11
12
public function anyLogin()
{
//
}
13
14
15
16
17
18
}
index metodları, denetçi tarafından yönetilmekte olan kök URI’a
cevap verir. Örneğimizde bu, kullanicilar dır.
Denetçinizdeki bir eylem metodunun ismi birden fazla kelimeden
oluşuyorsa, bu eylem metoduna, URI da kelime aralarına tire işareti
“-“ eklenmiş şekilde yazarak erişebilirsiniz. Örneğin, ‘KullaniciController’ denetçimizdeki aşağıdaki şekilde isimlendirilmiş olan
metod, kullanici/yonetici-profili URI’na cevap verecektir.
Denetçiler (Controllers)
1
62
public function getYoneticiProfili() {}
Kaynak (Resource) Denetçileri
Kaynak denetçileri, kaynaklar etrafında TEDA-uyumlu denetçiler
oluşturulmasını kolaylaştırır. Artisan KSA’daki (Artisan Komut Satırı Arayüzü) controller:make komutunu ve de Route::resource
metodunu kullanmak sureti ile böyle bir denetçiyi çabucak oluşturabiliriz.
Denetçiyi komut satırını kullanarak oluşturmak için şu komutu
kullanınız:
1
php artisan controller:make FotoController
Şimdi bu controller için resourceful bir rotayı kayda geçirebiliriz
(routes.php dosyasında):
1
Route::resource('foto', 'FotoController');
Bu tek bir rota deklarasyonu, foto kaynağınız üzerinde çalıştıracağınız çeşitli TEDA-uyumlu eylem metodlarına erişeceğiniz rotalar
oluşturur. Aynı zamanda, oluşturulmuş olan denetçide, bu eylemlerin her biri için metodları hazır olarak oluşturulmuş ve hangi URI’ı
ve eylemi yönettikleri yanlarına not olarak yazılmış olacaktır.
Kaynak Denetçisinin Yöneteceği Eylemler
HTTP Fiili | Patika | Eylem | Rota İsmi ———–|———————–|—
—————|————— GET | /kaynak | index | kaynak.index GET |
/kaynak/create | create (oluştur) | kaynak.create POST | /kaynak |
store (kaydet) | kaynak.store GET | /kaynak/{id} | show (göster) |
kaynak.show GET | /kaynak/{id}/edit | edit (düzenle) | kaynak.edit
Denetçiler (Controllers)
63
PUT/PATCH | /kaynak/{id} | update (güncelle)| kaynak.update DELETE | /kaynak/{id} | destroy (imha et)| kaynak.destroy
Bazen bu eylemlerin sadece bazılarına ihtiyaç duyabilirsiniz:
1
2
php artisan controller:make FotoController --only=index\
,show
//sadece belirtilenleri
3
4
5
php artisan controller:make FotoController --except=ind\
ex
//belirtilenler hariç
Ve, aynı zamanda rotasında da eylemlerin sadece bazılarını yönetmesini belirleyebilirsiniz:
1
2
Route::resource('foto', 'FotoController',
array('only' => array('index', 'show')));
3
4
5
6
Route::resource('foto', 'FotoController',
array('except' => array('create', 'store', 'update', \
'destroy')));
Varsayılan olarak tüm kaynak denetçilerinin bir rota ismi bulunur;
ancak bu isimleri üçüncü parametrede gireceğiniz dizi ile kendiniz
belirleyebilirsiniz.
1
2
Route::resource('foto', 'FotoController',
array('names' => array('create' => 'foto
Yuvalanmış Resource Controller’lerin Halledilmesi
Resource controlleri “yuvalamak” için, rota yazımında “dot” (nokta)
sözdizimi kullanın:
Denetçiler (Controllers)
1
2
64
Route::resource('photos.comments', 'PhotoCommentControl\
ler');
Bu rota “yuvalanmış” bir rota olarak kayda geçirilecek ve photos/{photoResource}/c
benzeri URI’larla erişilebilecektir:
1
class PhotoCommentController extends BaseController {
2
public function show($photoId, $commentId)
{
//
}
3
4
5
6
7
8
}
Resource Controller’lere Başka Rotalar Eklenmesi
Bir bir resource controller’e ön tanımlı resource rotaları dışında başka rotalar eklemeniz gerekli bir hale gelirse, bu rotaları
Route::resource metodunu çağırmadan önce tanımlamalısınız:
1
2
Route::get('foto/populer');
Route::resource('foto', 'FotoController');
Eksik Olan Metodların İşlenmesi
Denetçide tanımlanmamış olan metodlara gelecek olan çağrıları
işlemek için bir “hepsini yakala” metodu tanımlanabilir. Bu metodun isminin missingMethod olması gerekir ve istek için metod ve
parametre dizisi alır:
Bir Hepsini Yakala Metodunun Tanımlanması
Denetçiler (Controllers)
1
2
3
4
public function missingMethod($parameters = array())
{
//
}
65
Hatalar ve Günlüğe Ekleme
Yapılandırma
Uygulamanız için günlük işleyicisi app/start/global.php start
dosyasında⁹⁰ kayda geçirilir. Ön tanımlı olarak, bu logger tek bir
günlük dosyası kullanacak şekilde yapılandırılmıştır; bununla birlikte siz bu davranışı gereken şekilde özelleştirebilirsiniz. Laravel
popüler Monolog⁹¹ günlükleme kitaplığını kullandığığı için, Monolog’un sunduğu çeşitli işleyicilerin avantajından yararlanabilirsiniz.
Örneğin, tek bir büyük dosya yerine günlük log dosyaları kullanmak istiyorsanız, start dosyanızda aşağıdaki değişikliği yapabilirsiniz:
1
$logFile = 'laravel.log';
2
3
Log::useDailyFiles(storage_path().'/logs/'.$logFile);
Hata Ayrıntısı
Ön tanımlı olarak hata ayrıntısı uygulamanızda etkindir. Yani bir
hata oluştuğu zaman ayrıntılı bir sorun listesi ve hata iletisi gösterebileceksiniz. app/config/app.php dosyanızdaki debug seçeneğini
false ayarlayarak hata ayrıntılarını devre dışı bırakabilirsiniz.
Not: Bir üretim (production) ortamında hata ayrıntılarını devre dışı bırakmanız kuvvetle önerilir.
⁹⁰/docs/lifecycle#start-files
⁹¹https://github.com/Seldaek/monolog
Hatalar ve Günlüğe Ekleme
67
Hataların İşlenmesi
Ön tanımlı olarak, app/start/global.php dosyasında tüm istisnalar için bir hata işleyici bulunmaktadır:
1
2
3
4
App::error(function(Exception $exception)
{
Log::error($exception);
});
En temel hata işleyici budur. Ancak siz gerektiği kadar işleyici
belirleyebilirsiniz. İşleyicilere işledikleri istisnaların tipine işaret
eden isimler verilir. Örneğin, sadece RuntimeException olgularını
işleyen bir işleyici oluşturabilirsiniz:
1
2
3
4
App::error(function(RuntimeException $exception)
{
// İstisnayı işle...
});
Bir istisna işleyicisinin bir cevap döndürmesi halinde, bu cevap
tarayıcıya gönderilecek ve başka bir hata işleyici çağrılmayacaktır:
1
2
3
App::error(function(InvalidUserException $exception)
{
Log::error($exception);
4
return 'Maalesef bu hesapla ilgili yanlış bir şeyler v\
5
6
7
ar!';
});
PHP’nin önemli hatalarını (fatal error) izlemek için, App::fatal
metodunu kullanabilirsiniz:
Hatalar ve Günlüğe Ekleme
1
2
3
4
68
App::fatal(function($exception)
{
//
});
Eğer birkaç istisna işleyiciniz varsa, bunlar en genelde en spesifik
olana doğru tanımlanmalıdır. Bu yüzden, örneğin, Exception tipindeki tüm istisnaları işleyen bir işleyici Illuminate\Encryption\DecryptException
gibi özel bir istisna tipinin işleyicisinden daha önce tanımlanmalıdır.
Hata İşleyicileri Nereye Konacak
Hata işleyici kayıtları için ön tanımlı bir “konum” yoktur. Laravel bu alanda size seçme hakkı verir. Bir seçenek işleyicileri
start/global.php dosyanızda tanımlamaktır. Genelde, burası her
türlü “bootstrapping” (önce yüklenen) kodun koyulması için uygun bir yerdir. Eğer bu dosya çok kalabalık bir hale gelirse, bir
app/errors.php dosyası oluşturabilir ve bu dosyayı start/global.php
skriptinizde require yapabilirsiniz. Üçüncü bir seçenek, işleyicileri
kayda geçiren bir servis sağlayıcı⁹² oluşturmaktır. Tekrar belirtelim,
tek bir “doğru” cevap yoktur. Rahat edeceğiniz bir konum seçin.
HTTP İstisnaları
HTTP istisnaları bir istemci isteği sırasında oluşabilecek hatalar
demektir. Bu bir sayfa bulunamadı hatası (404), bir yetkisizlik hatası
(401), hatta genel 500 hatası olabilir. Böyle bir cevap döndürmek için
aşağıdaki biçimi kullanın:
⁹²/docs/ioc#service-providers
Hatalar ve Günlüğe Ekleme
1
69
App::abort(404);
İsteğe bağlı olarak, bir cevap verebilirsiniz:
1
App::abort(401, 'Yetkili değilsiniz.');
Bu istisnalar, isteğin yaşam döngüsü boyunca herhangi bir zamanda
kullanılabilir.
404 Hatalarının İşlenmesi
Uygulamanızdaki tüm “404 Not Found” hatalarını işleyerek özel
404 hata hata sayfaları döndürmenize imkan veren bir hata işleyici
kaydı yapabilirsiniz:
1
2
3
4
App::missing(function($exception)
{
return Response::view('errors.missing', array(), 404);
});
Günlüğe Ekleme
Laravel’in günlüğe ekleme imkanları güçlü Monolog⁹³ üstünde basit
bir katman sağlar. Laravel, ön tanımlı olarak uygulamanız için
tek bir günlük dosyası oluşturacak şekilde yapılandırılmıştır ve
bu dosya app/storage/logs/laravel.log içinde tutulmaktadır. Bu
günceye aşağıdakilere benzer şekilde bilgi yazabilirsiniz:
⁹³http://github.com/seldaek/monolog
Hatalar ve Günlüğe Ekleme
1
70
Log::info('İşte bu yararlı bir bilgidir.');
2
3
Log::warning('Yanlış giden bir şeyler olabilir.');
4
5
Log::error('Gerçekten yanlış giden bir şey var.');
Günlük tutucu, RFC 5424⁹⁴‘de tanımlanmış yedi günlük ekleme
düzeyi sağlamaktadır: debug, info, notice, warning, error, critical
ve alert.
Log metodlarına bağlamsal bir veri dizisi de geçilebilir:
1
2
Log::info('Günce mesajı', array('context' => 'Diğer yar\
dımcı bilgi'));
Monolog, günlüğe ekleme için kullanabileceğiniz bir takım başka
işleyicilere de sahiptir. Gerektiğinde, Laravel tarafından kullanılan
Monolog olgusuna şu şekilde ulaşabilirsiniz:
1
$monolog = Log::getMonolog();
Ayrıca, günlüğe geçirilen tüm mesajları yakalamak için bir olay
kaydı da yapabilirsiniz:
Bir günlük izleyici kaydı yapılması
1
2
3
4
Log::listen(function($level, $message, $context)
{
//
});
⁹⁴http://tools.ietf.org/html/rfc5424
Cepheler (Facades)
Giriş
Cepheler uygulamanızın IoC konteynerinde⁹⁵ bulunan sınıflar için
“statik” bir arayüz sağlar. Laravel birçok cephe ile gelmektedir ve
büyük bir ihtimalle daha ne olduklarını bilmeden onları kullanıyorsunuzdur! Laravel “facade’ları” IoC konteynerindeki altta yatan
sınıflara “static proksiler” olarak hizmet ederek, geleneksel static
metodlardan daha fazla test edilebilirlik ve esneklik sürdürürken
özlü ve anlamlı sözdizimi yararını sağlarlar.
Zaman zaman, uygulama ve paketleriniz için kendi cephelerinizi
oluşturmak isteyebilirsiniz, bu itibarla bu sınıfların kavramlarını,
geliştirilmesini ve kullanımını inceleyelim.
Not: Cepheler konusunu incelemeden önce Laravel
IoC konteyneri⁹⁶ ile çok aşina olmanız kuvvetle önerilir.
Açıklama
Bir Laravel uygulaması bağlamında bir cephe bir nesneye onun
konteynerinden erişim sağlayan bir sınıf demektir. Bu işi yapan
mekanizmalar Facade sınıfında tanımlıdır. Laravel’in cepheleri ve
sizin oluşturduğunuz kendi cepheleriniz bu temel Facade sınıfından
türeyecektir.
⁹⁵/docs/ioc
⁹⁶/docs/ioc
72
Cepheler (Facades)
Sizin cephe sınıfınız sadece tek bir metoda tatbikat getirmesi gerekiyor: getFacadeAccessor. getFacadeAccessor methodunun tanımlayacağı iş konteynerden ne çözeceğidir. Facade temel sınıfı sizin
cephelerinizden, çözülmüş nesneye yapılan çağrıları ertelemek için
__callStatic() sihirli-metodunu kullanır.
Böylece, siz Cache::get gibi bir facade çağrısı yaptığınız zaman,
Laravel IoC konteynerindeki Cache manager sınıfını çözümler ve o
sınıftaki get metodunu çağırır. Teknik açıdan ifade edilirse, Laravel
Facade’ları bir hizmet bulucu olarak Laravel IoC konteynerinin
kullanılması için pratik bir sözdizimidir.
Pratik Kullanım
Aşağıdaki örnekte, Laravel önbellekleme sistemine bir çağrı yapılmış. Bu koda göz attığınızda, Cache sınıfında statik bir metod olan
get‘in çağrılıyor olduğunu düşünebilirsiniz.
1
$deger = Cache::get('anahtar');
Ancak, eğer Illuminate\Support\Facades\Cache sınıfına bakacak
olursak, orada get adında statik bir metod olmadığını görürüz:
1
class Cache extends Facade {
2
3
4
5
6
7
8
9
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor() { return\
'cache'; }
10
11
}
73
Cepheler (Facades)
Bu Cache sınıfı temel Facade sınıfından türetilmiş ve getFacadeAccessor()
adında bir metod tanımlamış. Bu metodun işinin bir IoC bağlamasının adını döndürmek olduğunu hatırlayın.
Bir kullanıcı Cache cephesinde herhangi bir statik metoda başvurduğunda, Laravel, IoC konteynerinden cache bağlamasını çözecek
ve istenen metodu (bu örnekte get) bu nesneden çalıştıracaktır.
Yani bizim Cache::get çağrımız şu şekilde yeniden yazılabilir:
1
$value = $app->make('cache')->get('anahtar');
Cephe Oluşturma
Kendi uygulama veya paketiniz için bir cephe oluşturulması kolaydır. Sadece üç şeye ihtiyacınız vardır:
• Bir IoC bağlayıcısı.
• Bir cephe sınıfı.
• Bir cephe takma adı yapılandırması.
Bir örnek bakalım. Burada, OdemeGecidi\Odeme olarak tanımlanmış
bir sınıfımız var.
1
namespace OdemeGecidi;
2
3
class Odeme {
4
public function process()
{
//
}
5
6
7
8
9
10
}
Cepheler (Facades)
74
Bu sınıf sizin app/models dizininizde veya Composer’in nasıl otomatik yükleneceğini bildiği diğer herhangi bir dizinde konumlandırılabilir.
Bu sınıfı IoC konteynerinden çözebiliyor olmamız lazım. Öyleyse,
bir bağlama ekleyelim:
1
2
3
4
App::bind('odeme', function()
{
return new \OdemeGecidi\Odeme;
});
Bu bağlamayı kayda geçirmek için harika bir yer OdemeServiceProvider
adında yeni bir hizmet sağlayıcı⁹⁷ oluşturmak ve bu bağlamayı
register metoduna eklemek olacaktır. Daha sonra Laravel’i sizin
hizmet sağlayıcınızı app/config/app.php yapılandırma dosyasından yükleyecek şekilde yapılandırın.
Daha sonra, kendi cephe sınıfımızı oluşturabiliriz:
1
use Illuminate\Support\Facades\Facade;
2
3
class Odeme extends Facade {
4
5
6
protected static function getFacadeAccessor() { return\
'odeme'; }
7
8
}
Son olarak, eğer istiyorsak, app/config/app.php yapılandırma dosyasındaki aliases dizisine kendi cephe’miz için bir takma ad ekleyebiliriz. Artık, process metodunu Odeme sınıfının bir olgusunda
çağırabiliriz.
⁹⁷/docs/ioc#service-providers
75
Cepheler (Facades)
1
Odeme::process();
Alias (Takma Ad)’ların Otomatik Yüklenmesi
Üzerine Bir Bilgi Notu
PHP, tanımlanmamış tip dayatmalı sınıfları otomatik olarak yüklemeye çalışmayacağı için⁹⁸ app\config\app.php dosyasının aliases
dizisindeki sınıflar bazı durumlarda kullanılamamaktadır. \ServiceWrapper\ApiTime
sınıfı eğer ApiTimeoutException olarak aliaslanmış ise, namespace
\ServiceWrapper aduzayının dışındaki bir catch(ApiTimeoutException
$e) ifadesi bu istisnayı hiçbir zaman, hatta istisna çıkması durumunda bile yakalamayacaktır. Benzer bir durum, aliaslanmış
sınıflara tip dayatması olan Model’lerde de bulunmuştur. Tek geçici
çözüm, aliaslamaktan vazgeçmek ve tip dayatması yapmak istediğiniz sınıfları bunları gerektiren her dosyanın en başında use
etmektir.
Cepheleri Taklit Etme
Ünite testi cephelerin nasıl çalıştıkları konusunda önemli bir husustur. Gerçekten, cephelerin varlıkları için bile ilk neden test
edilebilirliktir. Daha fazla bilgi için, belgelerdeki Cepheleri Taklit
Etme⁹⁹ kesimine bakın.
Facade Sınıf Referansı
Aşağıda, her facade’ı ve onun altında yatan sınıfı bulacaksınız. Bu,
verilen bir facade kökü için API dokümantasyonuna hızla girme
⁹⁸https://bugs.php.net/bug.php?id=39003
⁹⁹/docs/testing#mocking-facades
Cepheler (Facades)
76
için yararlı bir araçtır. Uygun olduğunda IoC bağlama¹⁰⁰ anahtarı
da dahil edilmiştir.
Facade | Sınıf | IoC Bağlaması ————- | ————- | ————- App
| IlluminateFoundationApplication¹⁰¹ | app Artisan | IlluminateConsoleApplication¹⁰² | artisan Auth | IlluminateAuthAuthManager¹⁰³ | auth Auth (Instance) | IlluminateAuthGuard¹⁰⁴ | Blade |
IlluminateViewCompilersBladeCompiler¹⁰⁵ | blade.compiler Cache | IlluminateCacheRepository¹⁰⁶ | cache Config | IlluminateConfigRepository¹⁰⁷ | config Cookie | IlluminateCookieCookieJar¹⁰⁸ |
cookie Crypt | IlluminateEncryptionEncrypter¹⁰⁹ | encrypter DB |
IlluminateDatabaseDatabaseManager¹¹⁰ | db DB (Instance) | IlluminateDatabaseConnection¹¹¹ | Event | IlluminateEventsDispatcher¹¹²
| events File | IlluminateFilesystemFilesystem¹¹³ | files Form |
IlluminateHtmlFormBuilder¹¹⁴ | form Hash | IlluminateHashingHasherInterface¹¹⁵ | hash HTML | IlluminateHtmlHtmlBuilder¹¹⁶
| html Input | IlluminateHttpRequest¹¹⁷ | request Lang | IlluminateTranslationTranslator¹¹⁸ | translator Log | IlluminateLogW¹⁰⁰/docs/ioc
¹⁰¹http://laravel.com/api/4.2/Illuminate/Foundation/Application.html
¹⁰²http://laravel.com/api/4.2/Illuminate/Console/Application.html
¹⁰³http://laravel.com/api/4.2/Illuminate/Auth/AuthManager.html
¹⁰⁴http://laravel.com/api/4.2/Illuminate/Auth/Guard.html
¹⁰⁵http://laravel.com/api/4.2/Illuminate/View/Compilers/BladeCompiler.html
¹⁰⁶http://laravel.com/api/4.2/Illuminate/Cache/Repository.html
¹⁰⁷http://laravel.com/api/4.2/Illuminate/Config/Repository.html
¹⁰⁸http://laravel.com/api/4.2/Illuminate/Cookie/CookieJar.html
¹⁰⁹http://laravel.com/api/4.2/Illuminate/Encryption/Encrypter.html
¹¹⁰http://laravel.com/api/4.2/Illuminate/Database/DatabaseManager.html
¹¹¹http://laravel.com/api/4.2/Illuminate/Database/Connection.html
¹¹²http://laravel.com/api/4.2/Illuminate/Events/Dispatcher.html
¹¹³http://laravel.com/api/4.2/Illuminate/Filesystem/Filesystem.html
¹¹⁴http://laravel.com/api/4.2/Illuminate/Html/FormBuilder.html
¹¹⁵http://laravel.com/api/4.2/Illuminate/Hashing/HasherInterface.html
¹¹⁶http://laravel.com/api/4.2/Illuminate/Html/HtmlBuilder.html
¹¹⁷http://laravel.com/api/4.2/Illuminate/Http/Request.html
¹¹⁸http://laravel.com/api/4.2/Illuminate/Translation/Translator.html
Cepheler (Facades)
77
riter¹¹⁹ | log Mail | IlluminateMailMailer¹²⁰ | mailer Paginator |
IlluminatePaginationFactory¹²¹ | paginator Paginator (Instance) |
IlluminatePaginationPaginator¹²² | Password | IlluminateAuthRemindersPasswordBroker¹²³ | auth.reminder Queue | IlluminateQueueQueueManager¹²⁴ | queue Queue (Instance) | IlluminateQueueQueueInterface¹²⁵ | Queue (Base Class) | IlluminateQueueQueue¹²⁶
| Redirect | IlluminateRoutingRedirector¹²⁷ | redirect Redis | IlluminateRedisDatabase¹²⁸ | redis Request | IlluminateHttpRequest¹²⁹
| request Response | IlluminateSupportFacadesResponse¹³⁰ | Route
| IlluminateRoutingRouter¹³¹ | router Schema | IlluminateDatabaseSchemaBlueprint¹³² | Session | IlluminateSessionSessionManager¹³³ | session Session (Instance) | IlluminateSessionStore¹³⁴ | SSH
| IlluminateRemoteRemoteManager¹³⁵ | remote SSH (Instance) |
IlluminateRemoteConnection¹³⁶ | URL | IlluminateRoutingUrlGenerator¹³⁷ | url Validator | IlluminateValidationFactory¹³⁸ | validator
Validator (Instance) | IlluminateValidationValidator¹³⁹ | View | IlluminateViewFactory¹⁴⁰ | view View (Instance) | IlluminateViewVi¹¹⁹http://laravel.com/api/4.2/Illuminate/Log/Writer.html
¹²⁰http://laravel.com/api/4.2/Illuminate/Mail/Mailer.html
¹²¹http://laravel.com/api/4.2/Illuminate/Pagination/Factory.html
¹²²http://laravel.com/api/4.2/Illuminate/Pagination/Paginator.html
¹²³http://laravel.com/api/4.2/Illuminate/Auth/Reminders/PasswordBroker.html
¹²⁴http://laravel.com/api/4.2/Illuminate/Queue/QueueManager.html
¹²⁵http://laravel.com/api/4.2/Illuminate/Queue/QueueInterface.html
¹²⁶http://laravel.com/api/4.2/Illuminate/Queue/Queue.html
¹²⁷http://laravel.com/api/4.2/Illuminate/Routing/Redirector.html
¹²⁸http://laravel.com/api/4.2/Illuminate/Redis/Database.html
¹²⁹http://laravel.com/api/4.2/Illuminate/Http/Request.html
¹³⁰http://laravel.com/api/4.2/Illuminate/Support/Facades/Response.html
¹³¹http://laravel.com/api/4.2/Illuminate/Routing/Router.html
¹³²http://laravel.com/api/4.2/Illuminate/Database/Schema/Blueprint.html
¹³³http://laravel.com/api/4.2/Illuminate/Session/SessionManager.html
¹³⁴http://laravel.com/api/4.2/Illuminate/Session/Store.html
¹³⁵http://laravel.com/api/4.2/Illuminate/Remote/RemoteManager.html
¹³⁶http://laravel.com/api/4.2/Illuminate/Remote/Connection.html
¹³⁷http://laravel.com/api/4.2/Illuminate/Routing/UrlGenerator.html
¹³⁸http://laravel.com/api/4.2/Illuminate/Validation/Factory.html
¹³⁹http://laravel.com/api/4.2/Illuminate/Validation/Validator.html
¹⁴⁰http://laravel.com/api/4.2/Illuminate/View/Factory.html
Cepheler (Facades)
ew¹⁴¹ |
¹⁴¹http://laravel.com/api/4.2/Illuminate/View/View.html
78
Laravel Cashier
Giriş
Laravel Cashier Stripe’in¹⁴² abonelik faturalama hizmetleri için
anlamlı, akıcı bir arayüz sağlar. Sizin yazmaktan ürktüğünüz klişe
abonelik faturalama kodunun hemen tümünü halleder. Cashier,
temel abonelik yönetimine ek olarak kuponları, abonelik takasını,
abonelik “miktarlarını”, ödemesiz dönemlerin iptal edilmesini halledebilir ve hatta fatura PDF’leri üretebilir.
Yapılandırma
Composer
Öncelikle, composer.json dosyanıza Cashier paketini ekleyin:
1
"laravel/cashier": "~2.0"
Service Provider
Daha sonra, app yapılandırma dosyanızda Laravel\Cashier\CashierServiceProvid
kayda geçirin.
Migration
Cashier kullanabilmemiz için, veritabanımıza birkaç sütun eklememiz gerekiyor. Endişe etmeyin, gerekli sütunları ekleyecek bir
¹⁴²https://stripe.com
80
Laravel Cashier
migrasyon oluşturmak için cashier:table Artisan komutunu kullanabilirsiniz. Örneğin, bu alanı users tablosuna eklemek için php
artisan cashier:table users kullanın. Bu migrasyonu oluşturduktan sonra basitçe migrate komutunu çalıştırın.
Model Ayarı
Ondan sonra da model tanımlamanıza BillableTrait ve uygun tarih
değiştiricilerini ekleyin:
1
2
use Laravel\Cashier\BillableTrait;
use Laravel\Cashier\BillableInterface;
3
4
5
class User extends Eloquent implements BillableInterfac\
e {
6
use BillableTrait;
7
8
protected $dates = ['trial_ends_at', 'subscription_end\
9
10
s_at'];
11
12
}
Stripe Key
Son olarak, bootstrap dosyalarınızın birinde Stripe anahtarınızı
ayarlayın:
1
User::setStripeKey('stripe-key');
Bir Plana Abone Olunması
Bir model olgusuna sahip olduktan sonra o kullanıcıyı verilen bir
Stripe planına kolaylıkla abone edebilirsiniz:
Laravel Cashier
1
81
$user = User::find(1);
2
3
4
$user->subscription('monthly')->create($creditCardToken\
);
Bir abonelik oluştururken bir kupon uygulamak isterseniz, withCoupon
metodunu kullanabilirsiniz:
1
2
3
$user->subscription('monthly')
->withCoupon('code')
->create($creditCardToken);
Bu subscription metodu ilgili Stripe aboneliğini otomatik olarak
oluşturacaktır, bunun yanında veritabanınızı Stripe müşteri ID’si ve
ilgili diğer faturalama bilgisiyle güncelleyecektir. Eğer planınızda
Stripe’de yapılandırılmış olan bir trial (deneme) varsa, kullanıcı
kaydında deneme bitiş tarihi (trial end date) de otomatik olarak
ayarlanacaktır.
Eğer planınız Stripe’de yapılandırılmış olmayan bir deneme süresine sahipse, deneme bitiş tarihini abonelikten sonra elle ayarlamak
zorundasınız:
1
$user->trial_ends_at = Carbon::now()->addDays(14);
2
3
$user->save();
Ek Kullanıcı Ayrıntılarının Belirtilmesi
Ek müşteri ayrıntılarını geçmek isterseniz, onları create metoduna
ikinci parametre olarak geçmek suretiyle bunu yapabilirsiniz:
82
Laravel Cashier
1
2
3
4
5
$user->subscription('monthly')->create($creditCardToken\
, [
'email' => $email, 'description' => 'Our First Custome\
r'
]);
Stripe tarafından desteklenen ek alanlar hakkında daha fazlasını
öğrenmek için, Stripe’ın müşteri oluşturma dokümantasyonuna¹⁴³
bakınız.
Kredi Kartsız
Eğer uygulamanız kredi kartı olmaksızın bedava bir deneme teklif
ediyorsa, modelinizde cardUpFront özelliğini false olarak ayarlayın:
1
protected $cardUpFront = false;
Hesap oluşturulmasında, modelde deneme bitiş tarihi ayarladığınızdan emin olun:
1
$user->trial_ends_at = Carbon::now()->addDays(14);
2
3
$user->save();
Aboneliklerin Takas Edilmesi
Bir kullanıcıyı yeni bir aboneliğe takas etmek için, swap metodunu
kullanın:
¹⁴³https://stripe.com/docs/api#create_customer
83
Laravel Cashier
1
$user->subscription('premium')->swap();
Eğer kullanıcı deneme (trial) durumundaysa, deneme normal şekilde sürdürülecektir. Ayrıca abonelik için eğer bir “miktar (quantity)”
mevcutsa, miktar da sürdürülecektir.
Abonelik Miktarı
Bazen abonelikler “miktar” ile etkilenir. Örneğin, uygulamanız bir
hesap üzerinde kullanıcı başına ayda $10 ücretlendirme yapabilir.
Abonelik miktarını kolayca artırmak ve azaltmak için increment
ve decrement metodlarını kullanın:
1
$user = User::find(1);
2
3
$user->subscription()->increment();
4
5
6
// Aboneliğin mevcut miktarına beş ekle...
$user->subscription()->increment(5);
7
8
$user->subscription()->decrement();
9
10
11
// Aboneliğin mevcut miktarından beş çıkar...
$user->subscription()->decrement(5);
Bir Aboneliğin İptal Edilmesi
Bir aboneliğin iptal edilmesi parkta bir yürüyüştür:
1
$user->subscription()->cancel();
Laravel Cashier
84
Bir abonelik iptal edildiği zaman, Cashier veritabanınızdaki subscription_ends_at sütununu otomatik olarak ayarlayacaktır. Bu sütun, subscribed
metodunun ne zaman false döndürmeye başlaması gerektiğini bilmek için kullanılır. Örneğin, eğer bir müşteri 1 Martta bir aboneliği
iptal ederse ama aboneliğin sona ermesi 5 Marta kadar planlanmamışsa, subscribed metodu 5 Marta kadar true döndürmeye devam
edecektir.
Bir Aboneliğe Geri Dönülmesi
Eğer bir kullanıcı aboneliğini iptal etmiş ve bu aboneliğe kaldığı
yerden devam etmesini istiyorsanız, resume metodunu kullanın:
1
2
$user->subscription('monthly')->resume($creditCardToken\
);
Eğer kullanıcı bir aboneliği iptal eder ve daha sonra bu abonelik
tam olarak sona ermeden geri dönerse, onlara hemen fatura edilmeyecektir. Abonelikleri sadece tekrar etkinleştirilecektir ve orijinal
faturalama döngüsüne göre fatura edilecektir.
Abonelik Durumunun Yoklanması
Bir kullanıcının uygulamanıza abone olduğunu doğrulamak için,
subscribed komutunu kullanın:
1
2
3
4
if ($user->subscribed())
{
//
}
Bu subscribed metodu bir rota filtresi için harika bir adaydır:
Laravel Cashier
1
2
3
4
5
6
7
85
Route::filter('subscribed', function()
{
if (Auth::user() && ! Auth::user()->subscribed())
{
return Redirect::to('billing');
}
});
Ayrıca, onTrial metodunu kullanmak suretiyle kullanıcının hala
deneme süresinde olup olmadığını (uygunsa) da tayin edebilirsiniz:
1
2
3
4
if ($user->onTrial())
{
//
}
Kullanıcının daha önce aktif bir abone olduğunu ama aboneliğini
iptal etmiş olduğunu tayin etmek için cancelled metodunu kullanabilirsiniz:
1
2
3
4
if ($user->cancelled())
{
//
}
Ayrıca, bir kullanıcının aboneliğini iptal etmiş ama hala aboneliği
tam sona erinceye kadar “yetkisiz kullanım süresinde (grace period)” olup olmadıklarını da belirleyebilirsiniz. Örneğin, bir kullanıcı
10 Martta sona ereceği planlanmış bir aboneliği 5 Martta iptal
ederse, bu kullanıcı 10 Marta kadar “yetkisiz kullanım süresindedir”.
Subscribed metodunun bu zaman süresinde hala true döndürdüğüne dikkat ediniz.
Laravel Cashier
1
2
3
4
86
if ($user->onGracePeriod())
{
//
}
Bir kullanıcının uygulamanızdaki bir plana hiç abone olup olmadığını tayin etmek için everSubscribed metodu kullanılabilir:
1
2
3
4
if ($user->everSubscribed())
{
//
}
Bir kullanıcının verilen bir plana abone olup olmadığını ID’sine
dayalı olarak tayin etmek için onPlan metodu kullanılabilir:
1
2
3
4
if ($user->onPlan('monthly'))
{
//
}
Başarısız Ödemelerin Halledilmesi
Şayet bir müşterinin kredi kartı süresi dolarsa ne olur? Endişeye
gerek yok - Cashier sizin için müşterinin üyeliğini kolaylıkla iptal
edebileceğiniz bir Webhook controller içermektedir. Sadece bir
rotada bu controlleri belirtin:
1
2
Route::post('stripe/webhook', 'Laravel\Cashier\WebhookC\
ontroller@handleWebhook');
Hepsi bu kadar! Gerçekleşmemiş ödemeler bu controller tarafından
yakalanacak ve halledilecektir. Bu controller üç başarısız ödeme
87
Laravel Cashier
girişiminden sonra ilgili müşterinin aboneliğini iptal edecektir. Bu
örnekteki stripe/webhook URI sadece örnek içindir. Kendi Stripe
ayarlarınızda bu URI’ı yapılandırmanız gerekir.
Diğer Stripe Webhook’larının İşlenmesi
İşlemek istediğiniz başka Stripe webhook olaylarına sahipseniz,
Webhook controller’i basitçe genişletin. Metod isminiz Cashier’in
beklenen geleneğine uygun olmalıdır, burası için özel olarak, metod ismi işlemek istediğiniz Stripe webhook’un ismi ve önüne
handle getirilmiş hali olmalıdır. Örneğin, eğer invoice.payment_succeeded webhook’unu işlemek istiyorsanız controllerinize bir
handleInvoicePaymentSucceeded metodu eklemelisiniz.
1
2
class WebhookController extends Laravel\Cashier\Webhook\
Controller {
3
public function handleInvoicePaymentSucceeded($payload)
{
// Olayı işle...
}
4
5
6
7
8
9
}
Not: Webhook controller veritabanınızdaki abonelik
bilgilerini güncellemeye ek olarak Stripe API aracılığıyla aboneliği de iptal edecektir.
Faturalar
invoices metodunu kullanarak bir kullanıcının faturalarından olu-
şan bir diziyi kolaylıkla elde edebilirsiniz:
Laravel Cashier
1
88
$invoices = $user->invoices();
Müşterinin faturalarını listelerken, ilgili fatura bilgisini göstermek
için şu helper metodlarını kullanabilirsiniz:
1
{{ $invoice->id }}
2
3
{{ $invoice->dateString() }}
4
5
{{ $invoice->dollars() }}
Bir faturanın indirilebilir bir PDF’sini üretmek için downloadInvoice
metodunu kullanın. Evet, bu gerçekten bu kadar kolaydır:
1
2
3
4
return $user->downloadInvoice($invoice->id, [
'vendor' => 'Şirketiniz',
'product' => 'Ürününüz',
]);
Formlar & HTML
Form Açmak
Form Açmak
1
2
3
{{ Form::open(array('url' => 'falan/filan')) }}
//
{{ Form::close() }}
Varsayılan olarak, POST metodu kullanılır; ancak, istediğiniz bir
metodu da belirtebilirsiniz:
1
2
echo Form::open(array('url' => 'falan/filan', 'method' \
=> 'put'))
Not: HTML formları, sadece POST ve GET metotlarını
desteklediği için, PUT ve DELETE metotları formunuza
otomatik olarak bir _method gizli alanı eklenmek suretiyle taklit edilecektir.
İsimli rotalara veya controller eylemlerine işaret eden formlar da
açabilirsiniz:
1
echo Form::open(array('route' => 'route.name'))
2
3
echo Form::open(array('action' => 'Controller@method'))
Ayrıca, rota parametreleri de geçebilirsiniz:
90
Formlar & HTML
1
2
echo Form::open(array('route' => array('route.name', $u\
ser->id)))
3
4
5
echo Form::open(array('action' => array('Controller@met\
hod', $user->id)))
Formunuz dosya yüklemelerini kabul edecekse, diziye files seçeneğini ekleyin:
1
2
echo Form::open(array('url' => 'falan/filan', 'files' =\
> true))
CSRF Koruması
Bir Forma CSRF Değeri Eklemek
Laravel, uygulamanızı siteler arası istek sahtekarlıklarından korumak için kolay bir metot sunar. Öncelikle, kullanıcının oturumuna
rastgele bir değer yerleştirilir. Merak etmeyin, bu otomatik olarak
yapılır. CSRF değeri, formlarınıza gizli bir alan olarak otomatik olarak yerleştirilir. Yine de, gizli alan için HTML kodunu oluşturmak
isterseniz, token metodunu kullanabilirsiniz:
1
echo Form::token();
Bir Rotaya CSRF Filtresi Eklemek
91
Formlar & HTML
1
2
3
4
5
Route::post('profil', array('before' => 'csrf', functio\
n()
{
//
}));
Forma Model Bağlanması
Bir Model Formu Açmak
Sıklıkla, bir modelin içeriğine dayanan bir form oluşturmak isteyebilirsiniz. Bunu yapmak için, Form::model metodunu kullanın:
1
2
echo Form::model($user, array('route' => array('user.up\
date', $user->id)))
Şimdi, bir form elementi oluşturduğunuzda, mesela bir text input,
elementin ismiyle eşleşen modelin değeri, otomatik olarak alanın
değeri olarak belirlenir. Yani, örneğin, email ismine sahip bir text
alanı için, kullanıcı modelinin email niteliği değer olarak atanır.
Bununla birlikte, dahası da var! Oturum flaş verisinde inputa uyan
bir öğe mevcutsa, bu değer, model’in değerine nazaran öncelik
alacaktır. Yani, öncelik şu şekildedir:
1. Oturum Flaş Verisi (Önceki Girdi)
2. Doğrudan Atanmış Değer
3. Model Nitelik Değeri
Bu size model değerlerine bağlanan formları sadece çabukça oluşturmanıza imkan vermekle kalmaz, sunucu tarafında bir geçerlilik
hatası olduğunda tekrar kolayca doldurmanızı da sağlayacaktır!
Not: Form::model kullanıyor olduğunuzda, Form::close
ile formunuzu kapatmayı unutmayın!
92
Formlar & HTML
Label Elementi
Bir Label Elementi Üretilmesi
1
echo Form::label('email', 'E-Mail Adresi');
Ek HTML Nitelikleri Belirtme
1
2
echo Form::label('email', 'E-Mail Adresi', array('class\
' => 'awesome'));
Not: Bir label oluştururken, label ismiyle aynı isimde
oluşturduğunuz bir form elementi otomatik olarak label ile aynı isimde bir ID de alacaktır.
Text, Textarea, Password & Hidden
Alanlar
Bir Text Inputu Üretilmesi
1
echo Form::text('uyeadi');
Ön Tanımlı Bir Değer Belirtilmesi
1
echo Form::text('email', 'ornek@gmail.com');
Not: hidden ve textarea metodları text metodu ile aynı
şekilde yazılır.
Bir Password Inputu Üretilmesi
93
Formlar & HTML
1
echo Form::password('parola');
Diğer Inputlar Üretilmesi
1
2
3
echo Form::email($name, $value = null, $attributes = ar\
ray());
echo Form::file($name, $attributes = array());
Onay Kutuları ve Seçenek Düğmeleri
Bir Checkbox Veya Radio Inputu Üretilmesi
1
echo Form::checkbox('isim', 'deger');
2
3
echo Form::radio('isim', 'deger');
Seçilmiş Bir Checkbox Veya Radio Inputu Üretilmesi
1
echo Form::checkbox('isim', 'deger', true);
2
3
echo Form::radio('isim', 'deger', true);
File Inputu
Bir File Inputu Üretilmesi
1
echo Form::file('resim');
Not: Bu form files opsiyonu true ayarlanmış olarak
açılmış olmalıdır.
94
Formlar & HTML
Aşağı Açılır Listeler
Aşağı Açılır Bir Liste Üretilmesi
1
2
echo Form::select('boyut', array('B' => 'Büyük', 'K' =>\
'Küçük'));
Ön Tanımlı Seçilmiş Bir Aşağı Açılır Liste Üretilmesi
1
2
echo Form::select('size', array('B' => 'Büyük', 'K' => \
'Küçük''), 'K');
Gruplanmış Bir Liste Üretilmesi
1
2
3
4
echo Form::select('hayvan', array(
'Kediler' => array('tekir' => 'Tekir'),
'Köpekler' => array('kangal' => 'Kangal'),
));
Bir Aralık Olan Bir Aşağı Açılır Liste Üretilmesi
1
echo Form::selectRange('number', 10, 20);
Ay İsimleri Olan Bir Liste Üretilmesi
1
echo Form::selectMonth('month');
Düğmeler
Bir Submit Düğmesinin Üretilmesi
95
Formlar & HTML
1
echo Form::submit('Tıkla beni!');
Not: Bir button elemanı üretmeniz gerekiyorsa, button
metodunu kullanın. Bu aynı submit gibi yazılır.
Özel Makrolar
Bir Form Makrosunun Kayda Geçirilmesi
“Makrolar” denen kendi özel Form sınıf yardımcılarınızı tanımlamak kolaydır. Nasıl çalıştığını görün: Önce belli bir isim ve Closure
fonksiyonu ile makroyu kayda geçirin:
1
2
3
4
Form::macro('makroAlan', function()
{
return '<input type ="awesome">';
});
Şimdi adını kullanarak makronuzu çağırabilirsiniz:
Özel Bir Form Makrosunun Çağırılması
1
echo Form::makroAlan();
URL Oluşturma
URL oluşturma ile ilgili detaylı bilgi için dokümantasyonun Yardımcı (Helper) Fonksiyonları¹⁴⁴ bölümüne bakınız.
¹⁴⁴helpers#urls
Frameworkün
Genişletilmesi
Giriş
Laravel, frameworkün çekirdek bileşenlerinin davranışlarını isteğinize göre özelleştirebilmeniz, hatta tümden değiştirebilmeniz için
size birçok genişletme noktası sağlar. Örneğin, hash yapma araçları
bir HasherInterface sözleşmesi ile sağlanmış olup, kendi uygulamanızın gereksinimlerine dayalı olarak implemente edebilirsiniz.
Ayrıca, sizin kendi uygun “helper” metodlarınızı eklemenize imkan vermek üzere Request nesnesini de genişletebilirsiniz. Hatta
tamamen yeni kimlik doğrulama, cache ve session sürücüleri bile
ekleyebilirsiniz!
Laravel bileşenleri genel olarak iki şekilde genişletilir: IoC konteynerinde yeni implementasyonlar bağlayarak veya bir ekstensiyonu
“Factory” tasarım deseninin implementasyonları olan bir Manager
sınıfı ile register ederek. Bu bölümde, frameworkün genişletilmesi
için çeşitli yöntemleri keşfedeceğiz ve gerekli kodları inceleyeceğiz.
Not: Aklınızda tutun, Laravel bileşenleri tipik olarak iki yoldan biriyle genişletilir: IoC bağlamaları ve
Manager sınıfları. Manager sınıfları “factory” tasarım
deseninin bir implementasyonu olarak hizmet eder ve
cache ve session gibi sürücü temelli araçların başlatılmasından sorumludur.
Frameworkün Genişletilmesi
97
Manager’lar & Factory’ler
Laravel sürücü temelli bileşenlerin oluşturulmasını yöneten birkaç
Manager sınıfıyla gelir. Bunlar cache, session, authentication ve
queue bileşenleridir. Manager sınıfı, uygulamanın yapılandırmasına dayalı olarak belirli bir sürücü implementasyonunun oluşturulmasından sorumludur. Örneğin, CacheManager sınıfı APC,
Memcached, Native ve diğer cache sürücü implementasyonlarını
oluşturabilir.
Bu managerlerin her birisinde, managere kolaylıkla yeni sürücü çözünürlük işlevselliği enjekte edilmesi için kullanılabilen bir extend
metodu bulunmaktadır. Aşağıda, bu managerlerin her birini, onların her birine özel bir sürücü desteğinin nasıl enjekte edildiğinin
örnekleriyle birlikte göreceğiz.
Not: Laravel’le gelen CacheManager ve SessionManager
gibi çeşitli Manager sınıflarını keşfetmek için biraz
zaman ayırın. Bu sınıfların baştan sona okunması Laravel’in örtü altında nasıl çalıştığı konusunda size daha
kapsamlı bir anlayış verecektir. Tüm manager sınıfları
Illuminate\Support\Manager taban sınıfını genişletir, bu taban sınıf her manager için yararlı, ortak bazı
işlevsellik sağlar.
Genişletme Nereye Konacak
Bu dokümantasyon çeşitli Laravel bileşenlerinin nasıl genişletileceğini anlatmaktadır, ancak genişletme kodunuzu nereye koyacağınızı merak ediyor olabilirsiniz. Diğer pek çok bootstrapping
koduna benzer şekilde, bazı genişletmelerinizi start dosyalarınıza
koyabilirsiniz. Cache ve Auth genişletmeleri bu yaklaşım için iyi
adaylardır. Diğer genişletmeler, örneğin Session, bir servis sağla-
98
Frameworkün Genişletilmesi
yıcısının register metoduna yerleştirilmelidir, çünkü bunlar istek
yaşam döngüsünde çok başlarda gereklidirler.
Cache
Laravel cache aracını genişletmek için, CacheManagerdeki managera özel bir sürücü çözümleyicisi bağlamak için kullanılan ve tüm
manager sınıfları çapında ortak olan extend metodunu kullanacağız. Örneğin, “mongo” adında yeni bir cache sürücüsü register
etmek için, şöyle yapacağız:
1
2
3
4
Cache::extend('mongo', function($app)
{
// Illuminate\Cache\Repository olgusu döndür...
});
extend metoduna geçilen ilk parametre sürücünün adıdır. Bu, sizin
app/config/cache.php yapılandırma dosyanızdaki driver opsiyonuna tekabül edecektir. İkinci parametre bir Illuminate\Cache\Repository
olgusu döndürmesi gereken bir Closure’dur. Bu Closure’a Illuminate\Foundation\A
bir olgusu ve bir IoC konteyneri olan bir $app olgusu geçilecektir.
Özel cache sürücümüzü oluşturmak için, öncelikle Illuminate\Cache\StoreInterfa
sözleşmesini implemente etmemiz gerekiyor. Yani, bizim MongoDB
cache implementasyonumuz şöyle bir şey olacaktır:
99
Frameworkün Genişletilmesi
1
2
class MongoStore implements Illuminate\Cache\StoreInter\
face {
3
public
public
public
public
public
public
public
4
5
6
7
8
9
10
function
function
function
function
function
function
function
get($key) {}
put($key, $value, $minutes) {}
increment($key, $value = 1) {}
decrement($key, $value = 1) {}
forever($key, $value) {}
forget($key) {}
flush() {}
11
12
}
Sadece bir MongoDB bağlantısı kullanarak bu metodların her birini
implemente etmemiz gerekiyor. Implementasyonumuzu tamamladıktan sonra, özel sürücümüzün kaydını bitirebiliriz:
1
use Illuminate\Cache\Repository;
2
3
4
5
6
Cache::extend('mongo', function($app)
{
return new Repository(new MongoStore);
});
Yukarıdaki örnekte görebileceğiniz gibi, özel cache sürücüleri oluştururken taban Illuminate\Cache\Repository sınıfını kullanabilirsiniz. Tipik olarak kendi repository sınıfınızı oluşturma zorunluğu söz konusu değildir.
Özel cache sürücü kodunuzu nereye koyacağınızı merak ediyorsanız, onu Packagist’te bulundurmayı düşünün! Veya, uygulamanızın birincil klasörü içinde bir Extensions aduzayı oluşturabilirsiniz. Örneğin, uygulama Snappy adındaysa, cache ekstensiyonunu
app/Snappy/Extensions/MongoStore.php içine koyabilirsiniz. Bununla birlikte, Laravel’in katı bir uygulama yapısına sahip olma-
100
Frameworkün Genişletilmesi
dığını ve uygulamanızı sizin tercihlerinize göre organize etmekte
özgür olduğunuzu aklınızda tutun.
Not: Şayet kod parçalarınızı nereye koyacağınızı merak ediyorsanız, her zaman bir hizmet sağlayıcı düşünün. Daha önce tartıştığımız gibi, framework ekstensiyonlarını organize etmek için bir hizmet sağlayıcı
kullanmak kodunuzu organize etmek için harika bir
yoldur.
Session
Laravel’i özel bir session sürücüsü ile genişletmek, tıpkı cache sisteminin genişletilmesi kadar kolaydır. Aynı şekilde, özel kodumuzu
register etmek için extend metodunu kullanacağız:
1
2
3
4
Session::extend('mongo', function($app)
{
// SessionHandlerInterface'in implementasyonunu döndür
});
Session Genişletmesi Nereye Konacak
Session genişletmelerinin Cache ve Auth benzeri diğer genişletmelerden farklı biçimde kayda geçirilmesi gerekir. Sessionlar istek
yaşam döngüsünde çok erken dönemde başlatıldıkları için, bu uzantıların bir start dosyasında kayda geçirilmesi çok geç olacaktır. Bunun yerine bir servis sağlayıcısı¹⁴⁵ gerekli olacaktır. Session genişletme kodunuzu servis sağlayıcınızın register metoduna koymalısınız ve bu servis sağlayıcının adı providers yapılandırma dizisindeki default Illuminate\Session\SessionServiceProvider‘den altta konmalıdır.
¹⁴⁵/docs/ioc#service-providers
101
Frameworkün Genişletilmesi
Session Genişletmesi Yazılması
Dikkat ederseniz bizim özel session sürücümüz SessionHandlerInterfacei
implemente edecektir. Bu interface PHP 5.4+ çekirdeğine dahil edilmiştir. Eğer siz PHP 5.3 kullanıyorsanız, ileriye yönelik uyumluluğa
sahip olmanız için bu interface Laravel tarafından sizin için tanımlanmış olacaktır. Bu interface, implemente etmemiz gereken sadece
birkaç basit metod içermektedir. Bir MongoDB implementation
kalıbı şöyle bir şeydir:
1
class MongoHandler implements SessionHandlerInterface {
2
public
public
public
public
public
public
3
4
5
6
7
8
function
function
function
function
function
function
open($savePath, $sessionName) {}
close() {}
read($sessionId) {}
write($sessionId, $data) {}
destroy($sessionId) {}
gc($lifetime) {}
9
10
}
Bu metodlar cache StoreInterface kadar kolay anlaşılabilir olmadıklarından, en iyisi bu metodların her birinin yaptıklarını kısaca
keşfedelim:
• open metodu tipik olarak dosya tabanlı oturum depolama
sistemlerinde kullanılacaktır. Laravel oturumlar için PHP’nin
natif dosya depolamasını kullanan native bir session sürücüsü ile geldiğinden, bu metoda neredeyse hiçbir şey koymanız
gerekmeyecektir. Onu boş bir kalıp olarak bırakabilirsiniz.
PHP’nin bizden bu metodu implemente etmemizi istemesi,
gerçekte sadece kötü bir interface tasarımıdır (bunu ileride
tartışacağız).
• close metodu, open metoduna benzer şekilde genellikle gözardı edilebilir. Çoğu sürücü için, bu metod gerekli değildir.
Frameworkün Genişletilmesi
102
• read metodu verilen bir $sessionId ile eşlik eden oturum
verisinin string versiyonunu döndürecektir. Serileştirmeyi
Laravel sizin yerinize yapacağı için, sürücünüzde oturum verisini elde ederken veya depolarken herhangi bir serileştirme
veya başka kodlamalar yapmanıza gerek yoktur.
• write metodu $sessionId ile eşlik eden belirli bir $data
stringini MongoDB, Dynamo vb gibi kalıcı depo sistemlerine
yazacaktır.
• destroy metodu $sessionId ile eşlik eden veriyi kalıcı depodan kaldıracaktır.
• gc metodu bir UNIX timestamp türünde verilen bir $lifetime
süresinden daha eski tüm oturum verisini imha edecektir.
Memcached ve Redis gibi süresi kendiliğinden dolan sistemler için bu metod boş bırakılabilir.
SessionHandlerInterface implemente edildikten sonra, onu Ses-
sion manager ile register etmeye hazırız:
1
2
3
4
Session::extend('mongo', function($app)
{
return new MongoHandler;
});
Session sürücüsü kayda geçirildikten sonra app/config/session.php
yapılandırma dosyamızda mongo sürücüsünü kullanabiliriz.
Not: Unutmayın, özel bir session işleyici yazarsanız,
onu Packagist’te paylaşın!
Authentication
Authentication (kimlik doğrulama) da cache ve session araçlarıyla
aynı yolla genişletilebilir. Burada da yine aşina olduğumuz extend
metodunu kullanacağız:
103
Frameworkün Genişletilmesi
1
2
3
4
5
Auth::extend('riak', function($app)
{
// Illuminate\Auth\UserProviderInterface'un implementa\
syonunu döndür
});
Bu UserProviderInterface implementasyonlarının tek sorumluluğu MySQL, Riak vb gibi kalıcı bir depolama sisteminin bir UserInterface
implementasyonunu getirmektir. Bu iki interface Laravel authentication mekanizmalarının kullanıcı verisinin nerede depolandığına
veya onu temsil etmek için kullanılan sınıf tipine bakılmaksızın
fonksiyon görmeye devam etmesini sağlar.
UserProviderInterfacee bir göz atalım:
1
interface UserProviderInterface {
2
3
4
5
6
7
8
9
10
public function
public function
public function
r, $token);
public function
ls);
public function
r, array $credentials);
retrieveById($identifier);
retrieveByToken($identifier, $token);
updateRememberToken(UserInterface $use\
retrieveByCredentials(array $credentia\
validateCredentials(UserInterface $use\
11
12
}
retrieveById fonksiyonu tipik olarak kullanıcıyı temsil eden sayı-
sal bir anahtar alır (örneğin bir MySQL veritabanındaki otomatik
artan ID gibi). Metod tarafından, bu ID’e uyan UserInterface
implementasyonu getirilecek ve döndürülecektir.
retrieveByToken fonksiyonu bir kullanıcıyı onun benzersiz $identifier
i ve bir remember_token alanında saklanan “remember me” $token
Frameworkün Genişletilmesi
104
i ile elde eder. Önceki metodta olduğu gibi, bir UserInterface
implementasyonu döndürmelidir.
updateRememberToken metodu $user in remember_token alanını bu
yeni $token ile günceller. Bu yeni token ya başarılı “remember me”
login girişiminde atanan yepyeni bir token olabilir ya da kullanıcı
log out yaptığı zaman bir null olabilir.
retrieveByCredentials metodu bir uygulamaya giriş yapma girişiminde bulunulduğu zaman Auth::attempt metoduna geçilen
kimlik bilgilerinden oluşan diziyi alır. Bu metod daha sonra bu kimlik bilgilerine uyan kullanıcıyı altta yatan kalıcı depolama sisteminden “sorgulamalıdır”. Tipik olarak, bu metod $credentails['username']
üzerine bir “where” koşulu olan bir sorgu çalıştıracaktır. Bu metod
herhangi bir şifre doğrulaması veya authentication yapmaya
kalkışmamalıdır.
validateCredentials metodu kullanıcı kimliğini doğrulamak için
verilen bir $user ile $credentialsi karşılaştırır. Örneğin, bu metod
$user->getAuthPassword() stringini $credentials['password']in
bir Hash::make hali ile karşılaştırabilir.
Artık UserProviderInterface metodlarının her birini keşfettiğimize göre, bir de UserInterfacee göz atalım. Hatırlayınız, providerin
retrieveById ve retrieveByCredentials metodları bu interface’in implementasyonlarını döndürecektir:
1
interface UserInterface {
2
public function getAuthIdentifier();
public function getAuthPassword();
3
4
5
6
}
Bu interface basittir. getAuthIdentifier metodu kullanıcının “birincil anahtarını” döndürmelidir. Bir MySQL back-endinde, bu
yine otomatik artan birincil anahtar olacaktır. getAuthPassword
Frameworkün Genişletilmesi
105
kullanıcının hash’lenmiş şifresini döndürmelidir. Bu interface, sizin
kullandığınız ORM veya depolama soyutlama katmanı ne olursa
olsun, authentication sisteminin herhangi bir User sınıfı ile çalışmasına imkan verir. Ön tanımlı olarak Laravel app/models klasörü
içinde bu interface’i implemente eden bir User sınıfı bulundurur,
bu yüzden bir implementasyon örneğini görmek için bu sınıfa
başvurabilirsiniz.
Son olarak, UserProviderInterface implemente edildikten sonra,
genişletmemizi Auth facade’ı ile kayda geçirmeye hazırız:
1
2
3
4
Auth::extend('riak', function($app)
{
return new RiakUserProvider($app['riak.connection']);
});
Sürücüyü extend metodu ile register ettikten sonra, app/config/auth.php
yapılandırma dosyanızda yeni sürücüyü belirtin.
IoC Temelli Genişletme
Laravel frameworke dahil edilen hemen her hizmet sağlayıcı IoC
konteynerine nesneler bağlar. Uygulamanızın hizmet sağlayıcılarının bir listesini app/config/app.php yapılandırma dosyasında
bulabilirsiniz. Vaktiniz oldukça bu sağlayıcıların her birinin kaynak
koduna baştan sona göz gezdiriniz. Bunu yapmakla, her bir sağlayıcının frameworke neler eklediğini çok daha iyi anlayacaksınız,
bunun yanı sıra IoC konteynerine çeşitli hizmetleri bağlamak için
hangi anahtarların kullanıldığını da öğreneceksiniz.
Örneğin, HashServiceProvider IoC konteynerine bir hash anahtarı
bağlar ve bu bir Illuminate\Hashing\BcryptHasher olgusuna çözümlenir. Siz kendi uygulamanız içinde bu sınıfı genişleletebilir ve
bu IoC bağlamasını ezmek suretiyle bu sınıf yerine kendi genişletmenizi kullanabilirsiniz. Örneğin:
Frameworkün Genişletilmesi
1
2
106
class SnappyHashProvider extends Illuminate\Hashing\Has\
hServiceProvider {
3
public function boot()
{
App::bindShared('hash', function()
{
return new Snappy\Hashing\ScryptHasher;
});
4
5
6
7
8
9
10
parent::boot();
11
}
12
13
14
}
Bu sınıfın default ServiceProvider sınıfını değil HashServiceProvider
sınıfını genişlettiğine dikkat ediniz. Service providerinizi genişlettikten sonra, app/config/app.php yapılandırma dosyanızdaki
HashServiceProvider yerine sizin genişletmiş olduğunuz sağlayıcının ismini koyun.
Konteynerde bağlanan herhangi bir çekirdek sınıfın genişletilmesi
için genel yöntem budur. Esasında, her çekirdek sınıf konteynerde
bu tarzda bağlanır ve override edilebilir. Tekrar ifade edeyim,
frameworkte yer alan hizmet sağlayıcılarının baştan sona okunması
çeşitli sınıfların konteynerde nerede bağlandığı ve onu bağlamak
için hangi anahtarın kullanıldığı konusunda sizi bilgilendirecektir.
Laravelin nasıl biraraya getirildiğini daha çok öğrenmek için harika
bir yoldur.
Request Genişletmesi
Request, frameworkün çok temel bir parçası olduğu ve istek döngüsünde çok erken başlatıldığı için, Request sınıfının genişletilmesi
önceki örneklerden biraz farklı yapılır.
Frameworkün Genişletilmesi
107
İlk olarak, sınıfı normaldeki gibi genişletin:
1
<?php namespace QuickBill\Extensions;
2
3
class Request extends \Illuminate\Http\Request {
4
// Burada özel, yararlı metodlar olacak...
5
6
7
}
Sınıfı genişlettikten sonra, bootstrap/start.php dosyasını açın.
Bu dosya, uygulamanıza yapılan her istekte en başta dahil edilen
dosyalardan biridir. Dikkat ederseniz, bu dosyada yapılan ilk eylem
Laravel’in $app olgusunun oluşturulmasıdır:
1
$app = new \Illuminate\Foundation\Application;
Yeni bir application olgusu oluşturulduğu zaman, yeni bir Illuminate\Http\Request
olgusu oluşturacak ve request anahtarını kullanarak onu IoC konteynerine bağlayacaktır. Bu yüzden, “default” istek tipi olarak kullanılması gereken özel bir sınıfı belirten bir yola ihtiyacımız var,
değil mi? Ve, ne mutlu ki, application olgusundaki requestClass
metodu tam bunu yapar! Yani, bootstrap/start.php dosyamızın
en üstüne şu satırı ekleyebiliriz:
1
use Illuminate\Foundation\Application;
2
3
4
Application::requestClass('QuickBill\Extensions\Request\
');
Özel istek sınıfı belirtildikten sonra, Laravel bir Request olgusu
oluşturduğu her zaman bu sınıfı kullanacaktır, böylece sizin özel
request sınıfı olgunuzun, unit testlerde bile, her zaman kullanılabilir
olmasına imkan verecektir!
Geçerlilik Denetimi
Temel Kullanım
Laravel, Validation sınıfı aracığıyla verilerin geçerlilik denetimi ve
geçerlilik hata mesajlarının gösterilmesi için temel ve kullanışlı bir
araçla birlikte gelmektedir.
Temel Bir Geçerlilik Denetimi Örneği
1
2
3
4
$gecerlilikYoklayici = Validator::make(
array('isim' => 'Tuana Şeyma'),
array('yas' => 'required|min:5')
);
Buradaki make metoduna geçilen ilk parametre, geçerli olup olmadığına bakılacak veridir. İkinci parametre ise, bu veriye tatbik edilecek
geçerlilik kurallarıdır.
Kuralları Belirtmek İçin Dizi Kullanımı
Birden çok kural ya bir “pipe” karakteri (|) ile ayrılır, ya da ayrı dizi
elemanları olarak verilebilir.
1
2
3
4
$gecerlilikYoklayici = Validator::make(
array('isim' => 'Tuana Şeyma'),
array('yas' => array('required', 'min:5'))
);
Birçok Alana Tek Seferde Geçerlilik Denetimi Yapmak
Geçerlilik Denetimi
1
2
3
4
5
6
7
8
9
10
11
12
109
$validator = Validator::make(
array(
'name' => 'Tuana Şeyma',
'password' => 'aksakşifre',
'email' => 'tuanaseyma@eldem.com'
),
array(
'name' => 'required',
'password' => 'required|min:8',
'email' => 'required|email|unique'
)
);
Bir Validator olgusu oluşturulduktan sonra, geçerlilik denetimi
yapmak için fails veya passes metodları kullanılabilir.
1
2
3
4
if ($gecerlilikYoklayici->fails())
{
// İlgili veri geçerlik denetimini geçememiştir
}
Şayet geçerlilik denetimi başarısız olursa, geçerlik yoklayıcısından
hata mesajları alabilirsiniz:
1
$mesajlar = $gecerlilikYoklayici->messages();
Ayrıca, başarısız olan geçerlilik kurallarına bir dizi olarak da erişebilirsiniz. Bunu yapmak için failed metodunu kullanabilirsiniz:
1
$kalanlar = $gecerlilikYoklayici->failed();
Geçerlilik Denetimi
110
Dosyalar İçin Geçerlilik Denetimi
Validator sınıfı dosyaların geçerliliği konusunda size, mimes ve
benzeri kurallar sağlar. Dosyaları geçerlilikten geçirirken, tıpkı diğer verilerde olduğu gibi bunları da geçerlilik denetçisine parametre
olarak geçersiniz.
Hata Mesajlarıyla Çalışmak
Bir Validator olgusunda messages metodunu çağırdıktan sonra,
bir MessageBag olgusu alacaksınız. MessageBag sınıfında hata mesajlarıyla çalışmak için bir takım yararlı metodlar vardır.
Bir Alan İçin İlk Hata Mesajının Elde Edilmesi
1
echo $mesajlar->first('email');
Bir Alan İçin Tüm Hata Mesajlarının Elde Edilmesi
1
2
3
4
foreach ($mesajlar->get('email') as $mesaj)
{
//
}
Tüm Alanlar İçin Tüm Hata Mesajlarının Elde Edilmesi
1
2
3
4
foreach ($mesajlar->all() as $mesaj)
{
//
}
Bir Alan İçin Hata Mevcut Olup Olmadığının Tespiti
Geçerlilik Denetimi
1
2
3
4
111
if ($mesajlar->has('email'))
{
//
}
Bir Hata Mesajının Biçimlendirilmiş Olarak Alınması
1
echo $mesajlar->first('email', '<p>:message</p>');
Not: Ön tanımlı olarak, mesajlar Bootstrap’a uyumlu
bir söz dizimiyle biçimlendirilir.
Tüm Hata Mesajlarının Biçimlendirilmiş Olarak
Alınması
1
2
3
4
foreach ($mesajlar->all('<li>:message</li>') as $mesaj)
{
//
}
Hata Mesajları & Görünümler
Geçerlilik denetimi yaptıktan sonra aldığınız hata mesajlarını görünümlerinize gönderecek kolay bir yola ihtiyacınız olacak. Bu iş
Laravel tarafından pratik bir şekilde halledilmektedir. Bir örnek
olarak şu rotaları ele alalım:
Geçerlilik Denetimi
1
2
3
4
112
Route::get('kayit', function()
{
return View::make('uye.kayit');
});
5
6
7
8
Route::post('kayit', function()
{
$kurallar = array(...);
9
10
11
$gecerlilikYoklayici = Validator::make(Input::all(), $\
kurallar);
12
13
14
15
16
17
18
if ($gecerlilikYoklayici->fails())
{
return Redirect::to('kayit')->withErrors($gecerlilikY\
oklayici);
}
});
Dikkat ederseniz, geçerlilik başarısız olduğunda, Validator olgusunu withErrors metodunu kullanarak Redirect’e geçiriyoruz. Bu
metod, hata mesajlarını oturuma flaş tipinde aktaracak, yani bir
sonraki isteğe kadar kullanılabilir olacaktır.
Buna karşın, yine dikkat ederseniz GET rotamızda hata mesajlarını
görünüme açık olarak bağlamak zorunda değiliz. Bunun nedeni, Laravel’in oturum verisinde hatalar olup olmadığını her zaman yoklaması ve olduğunu tespit etmesi halinde bunları otomatik olarak
görünüme bağlamasıdır. Bu itibarla, her istekte tüm görünümleriniz için bir $errors değişkeni mevcut olacağını unutmayın,
dolayısıyla siz $errors değişkeninin her zaman tanımlanmış olduğunu iç rahatı ile varsayıp, güvenle kullanabilirsiniz. Bu $errors
değişkeni MessageBag sınıfından bir olgu olacaktır.
Bu durumda, yeniden yön verme sonrasında, otomatikman bağlanan $errors değişkenini görünümlerinizde kullanabilirsiniz:
113
Geçerlilik Denetimi
1
<?php echo $errors->first('email'); ?>
İsimli Hata Çantaları
Eğer tek bir sayfa üzerinde birden çok formunuz varsa, hata MessageBag‘lerini
isimlendirmek isteyebilirsiniz. Bu size belirli bir form için olan
hata mesajlarını elde etme imkanı verecektir. Yapacağınız tek şey
withErrors metoduna ikinci bir parametre olarak bir isim geçmektir:
1
2
return Redirect::to('register')->withErrors($validator,\
'login');
Ondan sonra $errors değişkeninden isimli MessageBag olgusuna
erişebilirsiniz:
1
<?php echo $errors->login->first('email'); ?>
Mevcut Geçerlilik Kuralları
Mevcut tüm geçerlilik kuralları ve bunların işlevleri aşağıda verilmiştir:
•
•
•
•
•
•
•
•
•
Accepted
Active URL
After (Date)
Alpha
Alpha Dash
Alpha Numeric
Array
Before (Date)
Between
Geçerlilik Denetimi
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
Boolean
Confirmed
Date
Date Format
Different
Digits
Digits Between
E-Mail
Exists (Database)
Image (File)
In
Integer
IP Address
Max
MIME Types
Min
Not In
Numeric
Regular Expression
Required
Required If
Required With
Required With All
Required Without
Required Without All
Same
Size
Timezone
Unique (Database)
URL
114
115
Geçerlilik Denetimi
accepted
Geçerlilik bakılan alan yes, on veya 1 olmalıdır. Bu, “Hizmet Şartlarının” kabul edildiğinin doğrulanmasında işe yarar.
active_url
Geçerlilik bakılan alan checkdnsrr PHP fonksiyonuna göre geçerli
bir URL olmalıdır.
after: tarih
Geçerlilik bakılan alan verilen bir tarihten sonraki bir değer olmalıdır. Tarihler PHP strtotime fonksiyonuna geçirilecektir.
alpha
Geçerlilik bakılan alan tamamen alfabe harfleri olmalıdır.
alpha_dash
Geçerlilik bakılan alan alfa-numerik karakterler yanında tire ve alt
tire de olabilir.
alpha_num
Geçerlilik bakılan alan tamamen alfa-numerik karakterler olmalıdır.
array
Geçerlili bakılan alan array tipinde olmalıdır.
116
Geçerlilik Denetimi
before: tarih
Geçerlilik bakılan alan verilen bir tarihten önceki bir değer olmalıdır. Tarihler PHP strtotime fonksiyonuna geçirilecektir.
between: min, max
Geçerlilik bakılan alan verilen min ile max arasında bir büyüklükte
olmalıdır. Stringler, sayılar ve dosyalar size kuralıyla aynı tarzda
değerlendirilir.
confirmed
Geçerlilik bakılan alana uyan eden bir falan_confirmation alanı
olmalıdır. Örneğin, geçerlilik bakılan alan parola ise, inputta karşılık gelen bir parola_confirmation alanı olmalıdır.
date
Geçerlilik bakılan alan strtotime PHP fonksiyonua göre uygun bir
tarih olmalıdır.
date_format: format
Geçerlilik bakılan alan date_parse_from_format PHP fonksiyona
göre tanımlanmış bir format‘a uygun olmalıdır.
different: alan
Verilen alan, geçerlilik bakılan alandan farklı olmalıdır.
digits: value
Geçerlilik bakılan alan numerik olmalıdır ve tam value uzunluğunda olmalıdır.
117
Geçerlilik Denetimi
digits_between:min,max
Geçerlilik bakılan alan verilen min ile max arasında bir uzunlukta
olmalıdır.
boolean
Geçerlilik bakılan alan bir boolean olarak çevrilebilmelidir. Kabul
edilen girdiler true, false, 1, 0, "1" ve "0" dır.
email
Geçerlilik bakılan alan bir e-mail adresi şeklinde biçimlendirilmiş
olmalıdır.
exists: tablo, sütun
Geçerlilik bakılan alan verilen bir veritabanı tablosunda mevcut
olmalıdır.
Exists Kuralının Basit Kullanım Şekli
1
'il' => 'exists:iller'
Özel Bir Sütun İsminin Belirtilmesi
1
'il' => 'exists:iller,kisa_hali'
Sorguya “where” cümleciği olarak eklenecek daha fazla şart da
belirtebilirsiniz:
1
'email' => 'exists:personel,email,hesap_id,1'
Bir “where” cümle parçası olarak NULL geçilmesi bir NULL veritabanı
değeri yönünden kontrol ekleyecektir:
118
Geçerlilik Denetimi
1
'email' => 'exists:staff,email,deleted_at,NULL'
image
Geçerlilik bakılan alan bir görsel (jpeg, png, bmp veya gif) olmalıdır.
in: falan, filan,…
Geçerlilik bakılan alan verilen bir değerler listesinde olmalıdır.
integer
Geçerlilik bakılan alan bir tamsayı olmalıdır.
ip
Geçerlilik bakılan alan bir IP adresi olarak biçimlendirilmiş olmalıdır.
max: deger
Geçerlilik bakılan alan bir maksimum deger‘e eşit veya ondan az
olmalıdır. Stringler, sayılar ve dosyalar size kuralıyla aynı tarzda
değerlendirilir.
mimes: falan, filan,…
Geçerlilik bakılan alan listelenen uzantılardan birine tekabül eden
bir MIME tipinde olmalıdır.
MIME Kuralının Basit Kullanım Şekli
1
'resim' => 'mimes:jpeg,bmp,png'
119
Geçerlilik Denetimi
min: deger
Geçerlilik bakılan alan bir asgari deger‘den büyük olmalıdır. Stringler, sayılar ve dosyalar size kuralıyla aynı tarzda değerlendirilir.
not_in: falan,filan,…
Geçerlilik bakılan alan verilen değerler listesinde yer almamalıdır.
numeric
Geçerlilik bakılan alan sayısal bir değer olmalıdır.
regex: desen
Geçerlilik bakılan alan verilen düzenli ifadeye uygun olmalıdır.
Not: regex deseni kullanırken, özellikle düzenli ifade bir pipe karakteri (|) içeriyorsa, kuralları belirtmek için pipe ayıracı kullanmak
yerine bir dizide belirtmek gerekli olabilir.
required
Geçerlilik bakılan alan input verisinde bulunmak zorundadır.
required_if: alan, deger
Şayet alan alanı deger‘e eşit ise, geçerlilik bakılan alan girilmek
zorundadır.
required_with: falan, filan,…
Geçerlilik bakılan alan, sadece belirtilen alanların bulunması durumunda bulunmak zorundadır.
120
Geçerlilik Denetimi
required_with_all:foo,bar,…
Geçerlilik bakılan alan, sadece belirtilen diğer alanların tümünün
mevcut olması durumunda bulunmalıdır.
required_without: falan, filan,…
Geçerlilik bakılan alan, sadece diğer belirtilen alanlar olmadığı
takdirde bulunmak zorundadır.
required_without_all:foo,bar,…
Geçerlilik bakılan alan, sadece belirtilen diğer alanların hiçbirinin
mevcut olmaması durumunda bulunmalıdır.
same: alan
Verilen alan geçerlilik bakılan alanla aynı olmalıdır.
size: deger
Geçerlilik bakılan alan verilen deger‘le aynı büyüklükte olmalıdır.
String veriler için, deger harf sayısı anlamına gelir. Numerik veriler
için, deger verilen bir tamsayı değeridir. Dosyalar için, size kilobayt
cinsinden dosya boyutuna karşılık gelir.
timezone
Geçerlilik bakılan alan timezone_identifiers_list PHP fonksiyonuna göre geçerli bir timezone tanımlayıcısı olmalıdır.
unique: tablo, sütun, haric, idSütunu
Geçerlilik bakılan alan verilen bir veritabanı tablosunda benzersiz
olmalıdır. Eğer sütun seçeneği belirtilmemişse, geçerlilik bakılan
alan aynı zamanda sütun adı olarak kabul edilecektir.
121
Geçerlilik Denetimi
Unique Kuralının Basit Kullanım Şekli
1
'email' => 'unique:uyeler'
Özel Bir Sütun Adının Belirtilmesi
1
'email' => 'unique:uyeler,email_adresi'
Verilen Bir ID İçin Unique Kuralının Göz Ardı Edilmesi
1
'email' => 'unique:uyeler,email_adresi,10'
Ek olarak Where Cümlecikleri Ekleme
Bir sorguya “where” cümlecikleri ekler gibi daha fazla şart ekleyebilirsiniz:
1
2
'email' => 'unique:users,email_address,NULL,id,account_\
id,1'
Yukarıdaki kuralda, sadece account_id‘si 1 olan satırlar unique
yoklamasına dahil edilecektir.
url
Geçerlilik bakılan alan bir URL şeklinde biçimlendirilmiş olmalıdır.
Not: Bu fonksiyon PHP’nin filter_var metodunu
kullanır.
Duruma Göre Kurallar Ekleme
Bazı durumlarda, bir alanla ilgili geçerlilik denetimini yalnızca bu
alan input dizisinde mevcut olduğu zaman çalıştırmak isteyebilirsiniz. Bunu hızla gerçekleştirmek için kural listenize sometimes
ekleyiniz:
Geçerlilik Denetimi
1
2
3
122
$v = Validator::make($data, array(
'email' => 'sometimes|required|email',
));
Yukarıdaki örnekte email alanı sadece bu alan $data dizisinde
mevcutsa geçerlilik denetiminden geçirilecektir.
Karmaşık Şartlı Geçerlilik Denetimi
Bazen belli bir alanın başka bir alan 100’den büyük bir değere sahip
olduğunda gerekli olmasını isteyebilirsiniz. Bu geçerlilik kurallarının eklenmesi sorun oluşturmak zorunda değildir. Öncelikle, asla
değişmeyecek statik kuralları nızın olduğu bir Validator olgusu
oluşturun:
1
2
3
4
$v = Validator::make($data, array(
'email' => 'required|email',
'games' => 'required|numeric',
));
Diyelim ki, game toplayıcıları için bir web uygulamamız var. Eğer
bir game toplayıcısı uygulamamıza üye olursa ve onun 100’den fazla oyunu varsa, neden bu kadar çok oyunu olduğunu açıklamasını
isteyelim. Örneğin, belki oyunları yeniden satan bir dükkanı vardır
veya sadece toplamaktan hoşlanıyor olabilir. Bu gereksinimi, duruma göre eklemek için Validator olgusunda sometimes metodunu
kullanabiliriz.
1
2
3
4
5
$v->sometimes('reason', 'required|max:500', function($i\
nput)
{
return $input->games >= 100;
});
123
Geçerlilik Denetimi
Bu sometimes metoduna geçirilen ilk parametre duruma bağlı
olarak geçerlilik denetiminden geçireceğimiz alanın adıdır. İkinci
parametre ise, eklemek istedğimiz kurallardır. Üçüncü parametre
olarak geçirilen Closure true döndürürse, ilgili kural eklenecektir.
Bu metod, karmaşık şartlı geçerlilikler inşa edilmesini çok kolaylaştırır. Bir defada birden çok alan için şartlı geçerlilik eklemeniz
de mümkündür:
1
2
3
4
5
$v->sometimes(array('reason', 'cost'), 'required', func\
tion($input)
{
return $input->games >= 100;
});
Not: Closure‘a geçirilen $input parametresi Illuminate\Support\Fluent‘ın
bir olgusu olacaktır ve input ve dosyalarınıza erişeceğiniz bir nesne olarak kullanılabilir.
Özel Hata Mesajları
Gerek duyduğunuzda, geçerlilik için ön tanımlı hata mesajları
yerine özel hata mesajları kullanabilirsiniz. Özel mesaj belirtmek
için birkaç yol var.
Validator’e Özel Mesaj Geçilmesi
124
Geçerlilik Denetimi
1
2
3
$mesajlar = array(
'required' => ':attribute alanı gereklidir.',
);
4
5
6
$gecerlilikYoklayici = Validator::make($input, $kuralla\
r, $mesajlar);
Not: Buradaki :attribute yer tutucusu geçerlilik bakılan alanın gerçek adıyla değiştirilecektir. Geçerlilik
mesajlarınızda diğer yer tutucuları da kullanabilirsiniz.
Diğer Geçerlilik Yer Tutucuları
1
2
3
4
5
6
7
8
$mesajlar = array(
'same'
=>
'size'
=>
'between' =>
dır.',
'in'
=>
: :values',
);
':attribute ve :other aynı olmalıdır.',
':attribute tam olarak :size olmalıdır.',
':attribute :min ile :max arasında olmalı\
':attribute şu tiplerden birisi olmalıdır\
Belli Bir Attribute İçin Özel Mesaj Belirlenmesi
Bazen sadece belirli bir alan için özel hata mesajları belirlemek
isteyebilirsiniz:
1
2
3
4
$mesajlar = array(
'email.required' => 'e-mail adresinizi bilmemiz gereki\
yor!',
);
Geçerlilik Denetimi
125
Özel Mesajların Dil Dosyalarında Belirtilmesi
Bazı durumlarda, özel hata mesajlarınızı doğrudan Validator‘e
geçirmek yerine bir dil dosyasında belirtmek isteyebilirsiniz. Bunu
yapmak için, mesajlarınızı app/lang/xx/validation.php dil dosyasındaki custom dizisine ekleyiniz.
1
2
3
4
5
'custom' => array(
'email' => array(
'required' => 'e-mail adresinizi bilmemiz gerekiyor!',
),
),
Özel Geçerlilik Kuralları
Özel Bir Geçerlilik Kuralını Kayda Geçirme
Laravel’de her biri yararlı çok sayıda geçerlilik kuralı bulunmaktadır; bununla birlikte siz kendiniz de bazı kurallar belirlemek
isteyebilirsiniz. Özel geçerlilik kuralı kayda geçirmenin bir yolu
Validator::extend metodunu kullanmaktır:
1
2
3
4
5
Validator::extend('falan', function($attribute, $value,\
$parameters)
{
return $value === 'falan';
});
Özel bir geçerlilik anonim fonksiyonu (Closure) üç parametre alır:
geçerlilik bakılacak $attribute‘ın adı, bu niteliğin $value‘i ve
kurala geçilecek bir $parameters dizisi.
Bu extend metoduna bir isimsiz fonksiyon yerine bir sınıf ve metod
da geçebilirsiniz:
Geçerlilik Denetimi
1
126
Validator::extend('falan', 'FalanValidator@validate');
Özel kurallarınız için aynı zamanda bir hata mesajı da tanımlamanız gerekeceğini unutmayın. Bunu, ya aynı satırda özel hata mesaj
dizisi kullanarak ya da geçerlilik dil dosyasına bir giriş eklemek
suretiyle yapabilirsiniz.
Validator Sınıfının Genişletilmesi
Validator’ü genişletmek için bir isimsiz fonksiyon çağrısı kullanmak
yerine, Validator sınıfının kendisini de genişletebilirsiniz. Bunu
yapmak için, Illuminate\Validation\Validator‘ü genişleten bir
Validator sınıfı yazın. Validation metodlarınızı, başına validate
getirerek bu sınıfa ekleyebilirsiniz:
1
<?php
2
3
4
class OzelValidator extends Illuminate\Validation\Valid\
ator {
5
6
7
8
9
10
public function validateFalan($attribute, $value, $par\
ameters)
{
return $value === 'falan';
}
11
12
}
Özel Bir Validator Çözümleyicisinin Kayda
Geçirilmesi
Daha sonra, özel Validator uzantınızı kayda geçirmeniz gerekiyor:
Geçerlilik Denetimi
1
2
3
4
5
6
127
Validator::resolver(function($translator, $data, $rules\
, $messages)
{
return new OzelValidator($translator, $data, $rules, $\
messages);
});
Özel bir geçerlilik kuralı oluştururken, bazı durumlarda, hata mesajlarıyla değiştirilecek özel yer tutucular tanımlamanız gerekebilir.
Bunu, aynen yukarıda tarif edildiği gibi özel bir Validator oluşturup,
bu validatore bir replaceXXX fonksiyonu ekleyerek gerçekleştirebilirsiniz.
1
2
3
4
5
protected function replaceFalan($message, $attribute, $\
rule, $parameters)
{
return str_replace(':falan', $parameters[0], $message);
}
Şayet Validator sınıfını genişletmeksizin özel bir mesaj “değiştirici” eklemek isterseniz, Validator::replacer metodunu kullanabilirsiniz:
1
2
3
4
5
Validator::replacer('rule', function($message, $attribu\
te, $rule, $parameters)
{
//
});
Güvenlik
Yapılandırma
Laravel, kimlik doğrulanması işlerini çok basit hale getirmeyi amaçlamaktadır. Aslında, hemen her şey hazır yapılandırılmış durumdadır. Kimlik doğrulaması yapılandırma dosyası app/config/auth.php
yerleşiminde bulunmaktadır ve kimlik doğrulama araçlarının davranışlarına nasıl ince ayarlar yapılacağı üzerine iyi belgelenmiş
çeşitli seçenekler barındırır.
Ön tanımlı olarak, Laravel app/models dizininde bir User modeli
içermektedir ve bu model ön tanımlı Eloquent kimlik doğrulama
sürücüsü ile kullanıma hazırdır. Bu modelin şemasını oluştururken
şifre alanının en az 60 karakter olmasını temin etmeniz gerektiğini
unutmayın.
Şayet sizin uygulamanız Eloquent kullanmıyorsa, Laravel sorgu
oluşturucusunu kullanan database kimlik doğrulama sürücüsünü
kullanabilirsiniz.
Not: Başlamadan önce users (veya dengi olan) tablonuzun 100 karakterlik string tipinde nullable bir remember_token sütunu taşıdığından emin olun. Bu sütun, uygulamanız tarafından sürdürülecek olan “remember
me (beni hatırla)” session’ları için bir token saklamak amacıyla kullanılacaktır. Bu, bir migrasyonda
$table->rememberToken(); kullanılarak yapılabilir.
129
Güvenlik
Şifrelerin Saklanması
Laravel’deki Hash sınıfı güvenli Bcrypt karıştırması (hashing) sağlar:
Bcrypt Kullanılarak Bir Şifrenin Karıştırılması
1
$parola = Hash::make('secret');
Bir Şifrenin Karıştırılmışa Göre Doğrulanması
1
2
3
4
if (Hash::check('secret', $karistirilmisParola))
{
// Parola doğrulanmıştır...
}
Bir Şifrenin Yeniden Karıştırılması Gerekip
Gerekmediğinin Yoklanması
1
2
3
4
if (Hash::needsRehash($karistirilmis))
{
$karistirilmis = Hash::make('secret');
}
Kullanıcı Kimliklerinin Doğrulanması
Bir kullanıcının uygulamanıza girişi için Auth::attempt metodunu
kullanabilirsiniz.
Güvenlik
1
2
3
4
5
130
if (Auth::attempt(array('email' => $email, 'password' =\
> $parola)))
{
return Redirect::intended('pano');
}
Buradaki email‘in gerekli bir seçenek değil, sadece örnek olsun diye
kullanılmış olduğunu bilin. Veritabanınızda bir “kullanıcı adı”na
(“username”e) karşılık gelen sütunu kullanmanız gerekiyor. Redirect::intended
fonksiyonu, kullanıcıları kimlik doğrulama filtresi tarafından yakalanmadan önce erişmeye çalıştıkları URL’ye yönlendirecektir.
Kullanıcının önceden girmeye çalıştığı bir url olmayan durumlarda
kullanılabilsin diye bu metoda bir dönüş URI parametresi verilebilir.
attempt metodu çağrıldığında, auth.attempt olayı¹⁴⁶ ateşlenecektir. Şayet kimlik doğrulama girişimi başarılı olur ve kullanıcı giriş
yapmış olursa, auth.login olayı da ateşlenecektir.
Bir Kullanıcının Doğrulanmış Olup Olmadığının Tayin
Edilmesi
Bir kullanıcının uygulamanıza zaten giriş yapmış olduğunu tayin
etmek için check metodunu kullanabilirsiniz:
1
2
3
4
if (Auth::check())
{
// Kullanıcı giriş yapmıştır...
}
Bir Kullanıcının Kimliğinin Doğrulanması ve
“Hatırlanması”
Şayet uygulamanıza “beni hatırla” işlevselliği vermek istiyorsanız, attempt metoduna ikinci parametre olarak true geçebilirsiniz,
¹⁴⁶/docs/events
Güvenlik
131
böylece bu kullanıcı süresiz olarak “doğrulanmış” tutulacaktır (ya
da manuel olarak çıkış işlemi yapıncaya kadar). Tabi ki, users
tablonuz “remember me” tokenini saklamakta kullanılacak olan
string remember_token sütunu içermelidir.
1
2
3
4
5
if (Auth::attempt(array('email' => $email, 'password' =\
> $parola), true))
{
// Bu kullanıcı hatırlanacak...
}
Not: attempt metodu true döndürürse, kullanıcı uygulamanıza
girmiş kabul edilir.
Kullanıcının Remember Aracılığıyla mı Doğrulanmış
Olduğunun Tayin Edilmesi
Eğer kullanıcı girişlerini “hatırlıyorsanız”, bir kullanıcının “remember me” (beni hatırla) çerezi kullanılarak doğrulanmış olup olmadığını belirlemek için viaRemember metodunu kullanabilirsiniz:
1
2
3
4
if (Auth::viaRemember())
{
//
}
Bir Kullanıcının Ek Şartlara Göre Doğrulanması
Kimlik doğrulama sorgusuna ekstra şartlar da ekleyebilirsiniz:
132
Güvenlik
1
2
3
4
5
6
if (Auth::attempt(array('email' => $email, 'password' =\
> $parola, 'aktif' => 1)))
{
// Bu kullanıcı aktiftir, üyeliği askıya alınmış de\
ğildir ve mevcuttur.
}
Not: Oturum sabitlemesine karşı koruma amacıyla,
kimlik doğrulaması sonrasında kullanıcının oturum
ID’si otomatik olarak yeniden üretilecektir.
Login Yapmış Kullanıcıya Erişme
Bir kullanıcının kimliği doğrulandıktan sonra, bu kullanıcının modeline / kaydına ulaşabilirsiniz:
1
$email = Auth::user()->email;
Kimliği doğrulanmış bir kullanıcının ID’sini elde etmek için id
metodunu kullanabilirsiniz:
1
$id = Auth::id();
Bir kullanıcıyı sadece ID’si ile uygulamanıza giriş yaptırtmak için
loginUsingId metodunu kullanın:
1
Auth::loginUsingId(1);
Login Olmaksızın Kullanıcı Bilgilerinin Geçerlilik
Denetimi
validate metodu gerçekte uygulamaya giriş yapılmaksızın bir kul-
lanıcının kimlik bilgilerinin geçerlilik denetiminden geçirilmesine
imkan verir:
133
Güvenlik
1
2
3
4
if (Auth::validate($kimlikbilgileri))
{
//
}
Bir Kullanıca Tek Bir İstek İçin Giriş Yapma
Bir kullanıcıyı uygulamanıza tek bir istek için giriş yapmak için de
once metodunu kullanabilirsiniz. Bu durumda oturum veya çerezler
kullanılmayacaktır.
1
2
3
4
if (Auth::once($kimlikbilgileri))
{
//
}
Bir Kullanıcıya Uygulamadan Çıkış Yapma
1
Auth::logout();
Elle Kullanıcı Girişi
Şayet, mevcut bir kullanıcı olgusunu uygulamanıza giriş yaptırmak
istiyorsanız, bu olguda login metodunu çağırmanız yeterlidir:
1
$uye = Uye::find(1);
2
3
Auth::login($uye);
Bu metod, bir kullanıcıyı attempt metodu kullanarak kimlik bilgileri ile giriş yaptırmaya eşdeğerdir.
134
Güvenlik
Rotaların Korunması
Belli bir rotaya sadece kimliği doğrulanmış kullanıcıların erişebilmesini sağlamak amacıyla rota filtreleri kullanılabilir. Laravel ön
tanımlı olarak auth filtresi sağlamıştır ve app/filters.php içinde
tanımlanmıştır.
Bir Rotanın Korunması
1
2
3
4
5
Route::get('profil', array('before' => 'auth', function\
()
{
// Sadece kimliği doğrulanmış üyeler girebilir...
}));
CSRF Koruması
Laravel, uygulamanızı siteler arası istek sahtekarlıklarından (crosssite request forgeries [CSRF]) korumak için kolay bir metod sağlamaktadır.
Forma CSRF Jetonunun Eklenmesi
1
2
<input type="hidden" name="_token" value="<?php echo cs\
rf_token(); ?>">
Gönderilmiş CSRF Jetonunun Geçerlilik Yoklaması
135
Güvenlik
1
2
3
4
5
Route::post('register', array('before' => 'csrf', funct\
ion()
{
return 'Geçerli bir CSRF jetonu verdiniz!';
}));
HTTP Basic Kimlik Doğrulaması
HTTP Basic Kimlik Doğrulaması, kullanıcıları özel bir “giriş” sayfası açmadan uygulamanıza giriş yapabilmeleri için hızlı bir yoldur.
Bunun için, rotanıza auth.basic filtresi tutturun:
HTTP Basic İle Bir Rotanın Korunması
1
2
3
4
5
Route::get('profil', array('before' => 'auth.basic', fu\
nction()
{
// Sadece kimliği doğrulanmış üyeler girebilir...
}));
Ön tanımlı olarak, bu basic filtresi kimlik doğrulaması yaparken
kullanıcı kaydındaki email sütununu kullanacaktır. Siz başka bir
sütunu kullanmak istiyorsanız, basic metoduna birinci parametre
olarak bu sütunun adını geçirin:
1
2
3
4
Route::filter('auth.basic', function()
{
return Auth::basic('username');
});
Durum Bilgisi Olmaksızın Bir HTTP Basic Filtresi
Ayarlanması
HTTP Basic Kimlik Doğrulamasını oturumda kullanıcı tanıtıcı bir
çerez ayarlamadan da kullanabilirsiniz, bu daha çok API kimlik
136
Güvenlik
doğrulamalarında işe yarayacaktır. Bunu yapmak için, onceBasic
metodu döndüren bir filtre tanımlayın:
1
2
3
4
Route::filter('basic.once', function()
{
return Auth::onceBasic();
});
Eğer PHP FastCGI kullanıyorsanız, HTTP Basic kimlik doğrulaması
ön tanımlı durumda düzgün çalışmayacaktır. Aşağıdaki satırlar
.htaccess dosyanıza eklenmelidir:
1
2
3
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authoriza\
tion}]
Şifre Hatırlatıcıları & Yenileme
Model & Table
Çoğu web uygulaması, kullanıcılarına unutulmuş şifrelerini yenileyecek bir yol verir. Her uygulamada bunu tekrar tekrar yapmaya
zorlamak yerine Laravel size şifre hatırlatıcı mektup gönderme ve
şifre yenilemesi yapılması için pratik metodlar sağlar. Başlamak için
sizin User modelinizin Illuminate\Auth\Reminders\RemindableInterface
sözleşmesini yerine getirdiğini doğrulayın. Tabii ki, Laravel’le gelen
User modeli bu arayüz kontratını zaten yerine getirmektedir ve
bu interface’i implemente etmek için gerekli metodları içermek
için Illuminate\Auth\Reminders\RemindableTrait trait’ini kullanmaktadır.
RemindableInterface Implementasyonu
137
Güvenlik
1
2
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
3
4
5
class User extends Eloquent implements RemindableInterf\
ace {
6
use RemindableTrait;
7
8
9
}
Hatırlatıcı Tablo Migrasyonunun Üretilmesi
Daha sonra, şifre yenileme jetonlarının saklanacağı bir tablo oluşturulmalıdır. Bu tablo için bir migrasyon üretmek için yapacağınız
tek şey auth:reminders-table Artisan komutunu çalıştırmaktır:
1
php artisan auth:reminders-table
2
3
php artisan migrate
Şifre Hatırlatıcı Controller
Artık şifre hatırlatıcı controller üretmeye geçebiliriz. Bir controlleri
otomatik olarak üretmek için, auth:reminders-controller Artisan komutunu kullanabilirsiniz, bu komut sizin app/controllers
dizininizde bir RemindersController.php dosyası oluşturacaktır.
1
php artisan auth:reminders-controller
Üretilen controllerde şifre hatırlatıcı formunuzu gösterilmesini halleden bir getRemind metodu olacaktır. Sizin yapmanız gereken tek
şey bir password.remind viewi¹⁴⁷ oluşturmaktır. Bu view, bir email
¹⁴⁷/docs/responses#views
Güvenlik
138
alanı olan basit bir form olmalıdır. Bu form RemindersController@postRemind
metoduna POST edilmelidir.
password.remind view’inde basit bir form bunun gibi olabilir:
1
2
3
4
5
<form action ="{{ action('RemindersController@postRemind\
') }}" method ="POST">
<input type ="email" name ="email">
<input type ="submit" value ="Hatırlatıcı Gönder">
</form>
Üretilen controllerde getRemind metoduna ek olarak kullacılarınıza
şifre hatırlatıcı e-postalar gönderilmesini halleden bir postRemind
metodu da olacaktır. Bu metod POST değişkenlerinde bir email alanı
mevcut olmasını bekler. Eğer bir hatırlatıcı e-postası kullanıcıya
başarıyla gönderilirse, oturuma bir status mesajı flaşlanacaktır.
Eğer hatırlatıcı yapılamazsa o zaman bunun yerine bir error mesajı
flaşlanacaktır.
Bu postRemind controller metodu içerisinde, kullanıcıya göndermeden önce mesaj olgusu üzerinde değişiklik yapabilirsiniz:
1
2
3
4
5
Password::remind(Input::only('email'), function($messag\
e)
{
$message->subject('Şifre Hatırlatıcı');
});
Kullanıcınız, controllerin getReset metodunu işaret eden bir bağlantısı olan bir e-posta alacaktır. Ayrıca, ilgili bir şifre hatırlatıcı girişimini tanımlamakta kullanılan bir şifre hatırlatıcı tokeni bu controller metoduna geçilecektir. Bu controller metodu bir
password.reset view’i döndürecek şekilde zaten yapılandırılmıştır, ancak bu view’i sizin oluşturmanız gerekiyor. İlgili token view’e geçilecektir ve siz bu tokeni token adlı “hidden” bir form
139
Güvenlik
alanına koymanız gerekiyor. Sizin şifre reset (yenileme) formunuz
bu token‘e ek olarak email, password ve password_confirmation
alanlarını da içermelidir. Bu form RemindersController@postReset
metoduna post edilmelidir.
password.reset view’indeki basit bir form şöyle bir şey olabilir:
1
2
3
4
5
6
7
8
<form action ="{{ action('RemindersController@postReset'\
) }}" method ="POST">
<input type ="hidden" name ="token" value ="{{ $token }}">
<input type ="email" name ="email">
<input type ="password" name ="password">
<input type ="password" name ="password_confirmation">
<input type ="submit" value ="Şifreyi Yenile">
</form>
Son olarak, veritabanındaki şifrenizin gerçekten değiştirilmesinden bu postReset metodu sorumludur. Bu controller eyleminde,
Password::reset metoduna geçilen Closure, User‘in password niteliğini ayarlar ve save metodunu çağırır. Pek tabii, bu Closure sizin
User modelinizin bir Eloquent modeli¹⁴⁸ olmasını beklemektedir;
bununla birlikte siz bu Closure üzerinde uygulamanızın veritabanı
depolama sistemiyle uyumlu olması için gerekli değişiklikler yapmakta özgürsünüz.
Eğer şifre başarılı bir biçimde yenilenirse, kullanıcı uygulamanızın
köküne yönlendirilecektir. Aynı şekilde, siz bu redirect URL’sini
de değiştirme serbestisine sahipsiniz. Eğer şifre yenileme başarısız
olursa, kullanıcı tekrar reset formuna yönlendirilecektir ve session’a
bir error mesajı flaşlanacaktır.
Şifre Geçerlilik Denetimi
Ön tanımlı olarak, Password::reset metodu şifrelerin eşleşiyor
ve >= altı karakter olmasını soruşturacaktır. Siz, parametre olarak
¹⁴⁸/docs/eloquent
140
Güvenlik
bir Closure alan Password::validator metodunu kullanarak bu
kuralları özelleştirebilirsiniz. Bu Closure içerisinde, istediğiniz her
türlü şifre geçerlilik denetimini yapabilirsiniz. Şuna dikkat ediniz:
şifrelerin eşleşiyor olduğunu doğrulamanız gerekmiyor, çünkü bu
kısım framework tarafından otomatik olarak yapılacaktır.
1
2
3
4
Password::validator(function($credentials)
{
return strlen($credentials['password']) >= 8;
});
Not: Ön tanımlı olarak, şifre yenileme tokenlerinin
ömrü bir saat sonra sona erer. Siz app/config/auth.php
dosyanızın reminder.expire seçeneği aracılığıyla bunu değiştirebilirsiniz.
Kriptolama
Laravel, mcrypt PHP uzantısı aracılığıyla güçlü AES kriptolama
imkanı sağlamaktadır:
Bir Değerin Kriptolanması
1
$kriptolu = Crypt::encrypt('secret');
Not: app/config/app.php dosyasının key seçeneğinde
16, 24 veya 32 karakterli rastgele bir string ayarladığınızdan emin olun. Aksi takdirde kriptolanmış değerler
güvenli olmayacaktır.
Kriptolu Bir Değerin Çözülmesi
141
Güvenlik
1
$cozuk = Crypt::decrypt($kriptolu);
Cipher ve Mod Ayarlanması
Ayrıca, kriptocu tarafından kullanılan cipher ve mod da ayarlayabilirsiniz
1
Crypt::setMode('crt');
2
3
Crypt::setCipher($cipher);
Kimlik Doğrulama Sürücüleri
Laravel kutusunda database ve eloquent kimlik doğrulama sürücüleriyle gelir. Diğer kimlik doğrulama sürücüleri eklenmesiyle
ilgili daha fazla bilgi için Authentication genişletme dokümantasyonu¹⁴⁹ kesimini kontrol ediniz.
¹⁴⁹/docs/extending#authentication
IoC Konteyneri
Giriş
Laravel’in “inversion of control (kontrolün tersine çevrilmesi)” konteyneri, sınıf bağımlılıklarının yönetiminde güçlü bir araçtır. Bağımlılık enjeksiyonu ağır kodlanmış sınıf bağımlılıklarının kaldırılması için bir yöntemdir. Bunun yerine, bağımlılıklar çalışma
zamanında enjekte edilmekte, bağımlılık işlemleri kolayca takas
edilebildiği için daha büyük esneklik sağlamaktadır.
Laravel IoC konteyner’inin anlaşılması hem güçlü, büyük bir uygulama oluşturmak için hem de Laravel’in kendi çekirdeğine katkıda
bulunmak için esastır.
Temel Kullanım
Bir Tipin Konteynere Bağlanması
IoC konteyneri bağımlılıkları iki yolla çözebilmektedir: ya Closure geri çağrıları yoluyla ya da otomatik çözülüm yoluyla. Önce
Closure geri çağrılarını ele alalım. Birincisi, bir “tip”, konteynere
bağlanabilir:
1
2
3
4
App::bind('falan', function($app)
{
return new FalanFilan;
});
Bir Tipin Konteynerden Çözümlenmesi
IoC Konteyneri
1
143
$deger = App::make('falan');
App::make metodu çağrıldığı zaman, ilgili Closure callback’i çalış-
tırılacak ve sonuç döndürülecektir.
Konteynere “Paylaşılan” Bir Tip Bağlama
Bazen, konteyner içine sadece bir kez çözümlenmesi ve konteynere
sonraki çağrılarda aynı olgunun döndürülmesi gereken bir şeyler
bağlamak isteyebilirsiniz:
1
2
3
4
App::singleton('falan', function()
{
return new FalanFilan;
});
Mevcut Bir Olgunun Konteynere Bağlanması
instance metodunu kullanarak, konteynere mevcut bir nesne olgu-
sunu da bağlayabilirsiniz:
1
$falan = new Falan;
2
3
App::instance('falan', $falan);
Bağlamaların Kayda Geçirileceği Yer
IoC bağlamaları tıpkı olay işleyiciler ve rota filtreleri gibi genelde
“bootstrap (önce yüklenmesi gereken) kodu” başlığı altına düşer.
Başka bir deyişle, bunlar uygulamanızı istekleri gerçekten işlemeye
hazırlarlar ve genel olarak bunların bir rota veya controller gerçekten çağrılmadan önce çalıştırılması gereklidir. Diğer çoğu bootstrap
koduna benzer olarak, IoC bağlamalarının kayda geçirilmesi için
144
IoC Konteyneri
bir seçenek her zaman olduğu gibi start dosyalarıdır. Alternatif
olarak, bir app/ioc.php (dosya adının ne olduğu önemli değildir)
dosyası oluşturabilir ve bu dosyayı start dosyanızdan “require”
yapabilirsiniz.
Eğer uygulamanızda çok büyük bir sayıda IoC bağlaması varsa veya
siz basitçe IoC bağlamalarınızı kategorilere göre ayrı dosyalarda organize etmek istiyorsanız, bağlamalarınızı bir servis sağlayıcısında
kayda geçirebilirsiniz.
Otomatik Çözümleme
Bir Sınıfın Çözümlenmesi
IoC konteyneri birçok durumda hiçbir yapılandırmaya gerek kalmadan sınıfları çözümleyecek kadar güçlüdür. Örneğin:
1
class FalanFilan {
2
public function __construct(Baz $baz)
{
$this->baz = $baz;
}
3
4
5
6
7
8
}
9
10
$falanFilan = App::make('FalanFilan');
Dikkat ederseniz, FalanFilan sınıfını konteynerde kayıt etmemiş
olsak bile konteyner bu sınıfı hala çözümleyecek, hatta Baz bağımlılığını otomatik olarak enjekte edebilecektir!
Bir tip konteynerde bağlı olmadığı durumlarda, sınıfı görmek ve
sınıf yapıcısının tip dayatmalarını okumak için PHP’nin Reflection
145
IoC Konteyneri
araçlarını kullanacaktır. Konteyner bu bilgiyi kullanmak suretiyle
sınıfın bir olgusunu otomatik olarak inşa edecektir.
Bir Implementasyona Bir Interface Bağlanması
Buna karşın, bazı durumlarda, bir sınıf “somut tipte” olmayıp, arayüz tatbikatına (implementasyonuna) bağımlı olabilir. Böyle olduğu takdirde, hangi arayüz tatbikatının enjekte edileceği konusunda
konteyneri bilgilendirmek için App::bind metodu kullanılmalıdır:
1
App::bind('UyeRepositoryInterface', 'DbUyeRepository');
Şimdi şu denetçiyi ele alalım:
1
class UyeController extends BaseController {
2
public function __construct(UyeRepositoryInterface $uy\
3
4
eler)
{
5
$this->uyeler = $uyeler;
6
}
7
8
9
}
Biz UyeRepositoryInterface‘i somut bir tipe bağlamış olduğumuz
için, UyeController oluşturulduğu zaman DbUserRepository otomatik olarak bu controllere enjekte edilecektir.
Pratik Kullanım
Laravel uygulamanızın esneklik ve test edilebilirliğini artırmak
amacıyla IoC konteyneri kullanmak için çeşitli fırsatlar sağlar. En
başta gelen örnek, denetçilerin çözümlenmesidir. Bütün denetçiler
146
IoC Konteyneri
IoC konteyneri tarafından çözümlenir, yani bir kontroller sınıfının
yapıcı metodunda tip dayatmalı bağımlılıklar verebilirsiniz ve bunlar otomatik olarak enjekte edilecektir.
Tip Dayatmalı Controller Bağımlılıkları
1
class SiparisController extends BaseController {
2
public function __construct(SiparisRepository $siparis\
3
4
ler)
{
5
$this->siparisler = $siparisler;
6
}
7
8
public function getIndex()
{
$all = $this->siparisler->all();
9
10
11
12
return View::make('siparisler', compact('all'));
13
}
14
15
16
}
Bu örnekteki SiparisRepository sınıfı kontroller’e otomatik olarak
enjekte edilecektir. Bu şu anlama gelir: unit testi¹⁵⁰ sırasında “sahte”
bir SiparisRepository konteynere bağlanabilir ve denetçiye enjekte edilebilir, böylece sorunsuz bir veritabanı katmanı etkileşimi
mümkün olur.
¹⁵⁰/docs/testing
147
IoC Konteyneri
Diğer IoC Kullanım Örnekleri
Filtreler¹⁵¹, kompozitörler¹⁵² ve olay işleyicileri¹⁵³ de IoC konteynerinde çözülebilirler. Bunları kayda geçirdiğiniz zaman, sadece
kullanılması gereken sınıfın adını vermeniz yeterlidir:
1
Route::filter('falan', 'FalanFilter');
2
3
View::composer('falan', 'FalanComposer');
4
5
Event::listen('falan', 'FalanHandler');
Hizmet Sağlayıcıları
Hizmet Sağlayıcıları birbirine yakın IoC kayıtlarını tek bir yerleşimde gruplamak için harika bir yoldur. Bunları uygulamanızdaki
bileşenleri önceden yüklemenin bir yolu olarak düşünün. Bir hizmet
sağlayıcısının içinde özel kimlik doğrulama sürücünüzü kayda geçirebilir, uygulamanızın ambar sınıflarını IoC konteyneri ile kayda
geçirebilir, hatta özel bir Artisan komutu dahi kurabilirsiniz.
Aslında, çekirdek Laravel bileşenlerinin pek çoğu hizmet sağlayıcıları içermektedir. Uygulamanızdaki kayıtlı hizmet sağlayıcılarının
hepsi, app/config/app.php yapılandırma dosyasının providers
dizisinde listelenmektedir.
Bir Hizmet Sağlayıcı Tanımlanması
Bir hizmet sağlayıcı oluşturmak için, sadece Illuminate\Support\ServiceProvider
sınıfını genişletin ve bir register metodu tanımlayın:
¹⁵¹/docs/routing#route-filters
¹⁵²/docs/responses#view-composers
¹⁵³/docs/events#using-classes-as-listeners
148
IoC Konteyneri
1
use Illuminate\Support\ServiceProvider;
2
3
class FalanServiceProvider extends ServiceProvider {
4
public function register()
{
$this->app->bind('falan', function()
{
return new Falan;
});
}
5
6
7
8
9
10
11
12
13
}
Bu register metodunda, uygulama IoC konteynerinin $this->app
özelliği aracılığıyla kullanılabildiğini unutmayın. Bir sağlayıcı oluşturdunuz ve uygulamanızla kayda geçirmeye hazırsanız, yapmanız
gereken şey onu app yapılandırma dosyanızdaki providers dizisine
eklemektir.
Bir Hizmet Sağlayıcının Çalışma Zamanında Kayda
Geçirilmesi
Bir hizmet sağlayıcıyı App::register metodunu kullanarak çalışma zamanında da kayda geçirebilirsiniz:
1
App::register('FalanServiceProvider');
Konteyner Olayları
Bir Resolving Dinleyicisinin Kayda Geçirilmesi
Konteyner ne zaman bir nesne çüzümlese bir olay ateşler. resolving
metodunu kullanarak bu olayı dinleyebilirsiniz:
IoC Konteyneri
1
2
3
4
App::resolvingAny(function($object)
{
//
});
5
6
7
8
9
App::resolving('falan', function($falan)
{
//
});
Çözülen nesnenin geri çağrıya geçirileceğini unutmayın.
149
Güvenlik
Yapılandırma
Laravel, kimlik doğrulanması işlerini çok basit hale getirmeyi amaçlamaktadır. Aslında, hemen her şey hazır yapılandırılmış durumdadır. Kimlik doğrulaması yapılandırma dosyası app/config/auth.php
yerleşiminde bulunmaktadır ve kimlik doğrulama araçlarının davranışlarına nasıl ince ayarlar yapılacağı üzerine iyi belgelenmiş
çeşitli seçenekler barındırır.
Ön tanımlı olarak, Laravel app/models dizininde bir User modeli
içermektedir ve bu model ön tanımlı Eloquent kimlik doğrulama
sürücüsü ile kullanıma hazırdır. Bu modelin şemasını oluştururken
şifre alanının en az 60 karakter olmasını temin etmeniz gerektiğini
unutmayın.
Şayet sizin uygulamanız Eloquent kullanmıyorsa, Laravel sorgu
oluşturucusunu kullanan database kimlik doğrulama sürücüsünü
kullanabilirsiniz.
Not: Başlamadan önce users (veya dengi olan) tablonuzun 100 karakterlik string tipinde nullable bir remember_token sütunu taşıdığından emin olun. Bu sütun, uygulamanız tarafından sürdürülecek olan “remember
me (beni hatırla)” session’ları için bir token saklamak amacıyla kullanılacaktır. Bu, bir migrasyonda
$table->rememberToken(); kullanılarak yapılabilir.
151
Güvenlik
Şifrelerin Saklanması
Laravel’deki Hash sınıfı güvenli Bcrypt karıştırması (hashing) sağlar:
Bcrypt Kullanılarak Bir Şifrenin Karıştırılması
1
$parola = Hash::make('secret');
Bir Şifrenin Karıştırılmışa Göre Doğrulanması
1
2
3
4
if (Hash::check('secret', $karistirilmisParola))
{
// Parola doğrulanmıştır...
}
Bir Şifrenin Yeniden Karıştırılması Gerekip
Gerekmediğinin Yoklanması
1
2
3
4
if (Hash::needsRehash($karistirilmis))
{
$karistirilmis = Hash::make('secret');
}
Kullanıcı Kimliklerinin Doğrulanması
Bir kullanıcının uygulamanıza girişi için Auth::attempt metodunu
kullanabilirsiniz.
Güvenlik
1
2
3
4
5
152
if (Auth::attempt(array('email' => $email, 'password' =\
> $parola)))
{
return Redirect::intended('pano');
}
Buradaki email‘in gerekli bir seçenek değil, sadece örnek olsun diye
kullanılmış olduğunu bilin. Veritabanınızda bir “kullanıcı adı”na
(“username”e) karşılık gelen sütunu kullanmanız gerekiyor. Redirect::intended
fonksiyonu, kullanıcıları kimlik doğrulama filtresi tarafından yakalanmadan önce erişmeye çalıştıkları URL’ye yönlendirecektir.
Kullanıcının önceden girmeye çalıştığı bir url olmayan durumlarda
kullanılabilsin diye bu metoda bir dönüş URI parametresi verilebilir.
attempt metodu çağrıldığında, auth.attempt olayı¹⁵⁴ ateşlenecektir. Şayet kimlik doğrulama girişimi başarılı olur ve kullanıcı giriş
yapmış olursa, auth.login olayı da ateşlenecektir.
Bir Kullanıcının Doğrulanmış Olup Olmadığının Tayin
Edilmesi
Bir kullanıcının uygulamanıza zaten giriş yapmış olduğunu tayin
etmek için check metodunu kullanabilirsiniz:
1
2
3
4
if (Auth::check())
{
// Kullanıcı giriş yapmıştır...
}
Bir Kullanıcının Kimliğinin Doğrulanması ve
“Hatırlanması”
Şayet uygulamanıza “beni hatırla” işlevselliği vermek istiyorsanız, attempt metoduna ikinci parametre olarak true geçebilirsiniz,
¹⁵⁴/docs/events
Güvenlik
153
böylece bu kullanıcı süresiz olarak “doğrulanmış” tutulacaktır (ya
da manuel olarak çıkış işlemi yapıncaya kadar). Tabi ki, users
tablonuz “remember me” tokenini saklamakta kullanılacak olan
string remember_token sütunu içermelidir.
1
2
3
4
5
if (Auth::attempt(array('email' => $email, 'password' =\
> $parola), true))
{
// Bu kullanıcı hatırlanacak...
}
Not: attempt metodu true döndürürse, kullanıcı uygulamanıza
girmiş kabul edilir.
Kullanıcının Remember Aracılığıyla mı Doğrulanmış
Olduğunun Tayin Edilmesi
Eğer kullanıcı girişlerini “hatırlıyorsanız”, bir kullanıcının “remember me” (beni hatırla) çerezi kullanılarak doğrulanmış olup olmadığını belirlemek için viaRemember metodunu kullanabilirsiniz:
1
2
3
4
if (Auth::viaRemember())
{
//
}
Bir Kullanıcının Ek Şartlara Göre Doğrulanması
Kimlik doğrulama sorgusuna ekstra şartlar da ekleyebilirsiniz:
154
Güvenlik
1
2
3
4
5
6
if (Auth::attempt(array('email' => $email, 'password' =\
> $parola, 'aktif' => 1)))
{
// Bu kullanıcı aktiftir, üyeliği askıya alınmış de\
ğildir ve mevcuttur.
}
Not: Oturum sabitlemesine karşı koruma amacıyla,
kimlik doğrulaması sonrasında kullanıcının oturum
ID’si otomatik olarak yeniden üretilecektir.
Login Yapmış Kullanıcıya Erişme
Bir kullanıcının kimliği doğrulandıktan sonra, bu kullanıcının modeline / kaydına ulaşabilirsiniz:
1
$email = Auth::user()->email;
Kimliği doğrulanmış bir kullanıcının ID’sini elde etmek için id
metodunu kullanabilirsiniz:
1
$id = Auth::id();
Bir kullanıcıyı sadece ID’si ile uygulamanıza giriş yaptırtmak için
loginUsingId metodunu kullanın:
1
Auth::loginUsingId(1);
Login Olmaksızın Kullanıcı Bilgilerinin Geçerlilik
Denetimi
validate metodu gerçekte uygulamaya giriş yapılmaksızın bir kul-
lanıcının kimlik bilgilerinin geçerlilik denetiminden geçirilmesine
imkan verir:
155
Güvenlik
1
2
3
4
if (Auth::validate($kimlikbilgileri))
{
//
}
Bir Kullanıca Tek Bir İstek İçin Giriş Yapma
Bir kullanıcıyı uygulamanıza tek bir istek için giriş yapmak için de
once metodunu kullanabilirsiniz. Bu durumda oturum veya çerezler
kullanılmayacaktır.
1
2
3
4
if (Auth::once($kimlikbilgileri))
{
//
}
Bir Kullanıcıya Uygulamadan Çıkış Yapma
1
Auth::logout();
Elle Kullanıcı Girişi
Şayet, mevcut bir kullanıcı olgusunu uygulamanıza giriş yaptırmak
istiyorsanız, bu olguda login metodunu çağırmanız yeterlidir:
1
$uye = Uye::find(1);
2
3
Auth::login($uye);
Bu metod, bir kullanıcıyı attempt metodu kullanarak kimlik bilgileri ile giriş yaptırmaya eşdeğerdir.
156
Güvenlik
Rotaların Korunması
Belli bir rotaya sadece kimliği doğrulanmış kullanıcıların erişebilmesini sağlamak amacıyla rota filtreleri kullanılabilir. Laravel ön
tanımlı olarak auth filtresi sağlamıştır ve app/filters.php içinde
tanımlanmıştır.
Bir Rotanın Korunması
1
2
3
4
5
Route::get('profil', array('before' => 'auth', function\
()
{
// Sadece kimliği doğrulanmış üyeler girebilir...
}));
CSRF Koruması
Laravel, uygulamanızı siteler arası istek sahtekarlıklarından (crosssite request forgeries [CSRF]) korumak için kolay bir metod sağlamaktadır.
Forma CSRF Jetonunun Eklenmesi
1
2
<input type="hidden" name="_token" value="<?php echo cs\
rf_token(); ?>">
Gönderilmiş CSRF Jetonunun Geçerlilik Yoklaması
157
Güvenlik
1
2
3
4
5
Route::post('register', array('before' => 'csrf', funct\
ion()
{
return 'Geçerli bir CSRF jetonu verdiniz!';
}));
HTTP Basic Kimlik Doğrulaması
HTTP Basic Kimlik Doğrulaması, kullanıcıları özel bir “giriş” sayfası açmadan uygulamanıza giriş yapabilmeleri için hızlı bir yoldur.
Bunun için, rotanıza auth.basic filtresi tutturun:
HTTP Basic İle Bir Rotanın Korunması
1
2
3
4
5
Route::get('profil', array('before' => 'auth.basic', fu\
nction()
{
// Sadece kimliği doğrulanmış üyeler girebilir...
}));
Ön tanımlı olarak, bu basic filtresi kimlik doğrulaması yaparken
kullanıcı kaydındaki email sütununu kullanacaktır. Siz başka bir
sütunu kullanmak istiyorsanız, basic metoduna birinci parametre
olarak bu sütunun adını geçirin:
1
2
3
4
Route::filter('auth.basic', function()
{
return Auth::basic('username');
});
Durum Bilgisi Olmaksızın Bir HTTP Basic Filtresi
Ayarlanması
HTTP Basic Kimlik Doğrulamasını oturumda kullanıcı tanıtıcı bir
çerez ayarlamadan da kullanabilirsiniz, bu daha çok API kimlik
158
Güvenlik
doğrulamalarında işe yarayacaktır. Bunu yapmak için, onceBasic
metodu döndüren bir filtre tanımlayın:
1
2
3
4
Route::filter('basic.once', function()
{
return Auth::onceBasic();
});
Eğer PHP FastCGI kullanıyorsanız, HTTP Basic kimlik doğrulaması
ön tanımlı durumda düzgün çalışmayacaktır. Aşağıdaki satırlar
.htaccess dosyanıza eklenmelidir:
1
2
3
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authoriza\
tion}]
Şifre Hatırlatıcıları & Yenileme
Model & Table
Çoğu web uygulaması, kullanıcılarına unutulmuş şifrelerini yenileyecek bir yol verir. Her uygulamada bunu tekrar tekrar yapmaya
zorlamak yerine Laravel size şifre hatırlatıcı mektup gönderme ve
şifre yenilemesi yapılması için pratik metodlar sağlar. Başlamak için
sizin User modelinizin Illuminate\Auth\Reminders\RemindableInterface
sözleşmesini yerine getirdiğini doğrulayın. Tabii ki, Laravel’le gelen
User modeli bu arayüz kontratını zaten yerine getirmektedir ve
bu interface’i implemente etmek için gerekli metodları içermek
için Illuminate\Auth\Reminders\RemindableTrait trait’ini kullanmaktadır.
RemindableInterface Implementasyonu
159
Güvenlik
1
2
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
3
4
5
class User extends Eloquent implements RemindableInterf\
ace {
6
use RemindableTrait;
7
8
9
}
Hatırlatıcı Tablo Migrasyonunun Üretilmesi
Daha sonra, şifre yenileme jetonlarının saklanacağı bir tablo oluşturulmalıdır. Bu tablo için bir migrasyon üretmek için yapacağınız
tek şey auth:reminders-table Artisan komutunu çalıştırmaktır:
1
php artisan auth:reminders-table
2
3
php artisan migrate
Şifre Hatırlatıcı Controller
Artık şifre hatırlatıcı controller üretmeye geçebiliriz. Bir controlleri
otomatik olarak üretmek için, auth:reminders-controller Artisan komutunu kullanabilirsiniz, bu komut sizin app/controllers
dizininizde bir RemindersController.php dosyası oluşturacaktır.
1
php artisan auth:reminders-controller
Üretilen controllerde şifre hatırlatıcı formunuzu gösterilmesini halleden bir getRemind metodu olacaktır. Sizin yapmanız gereken tek
şey bir password.remind viewi¹⁵⁵ oluşturmaktır. Bu view, bir email
¹⁵⁵/docs/responses#views
Güvenlik
160
alanı olan basit bir form olmalıdır. Bu form RemindersController@postRemind
metoduna POST edilmelidir.
password.remind view’inde basit bir form bunun gibi olabilir:
1
2
3
4
5
<form action ="{{ action('RemindersController@postRemind\
') }}" method ="POST">
<input type ="email" name ="email">
<input type ="submit" value ="Hatırlatıcı Gönder">
</form>
Üretilen controllerde getRemind metoduna ek olarak kullacılarınıza
şifre hatırlatıcı e-postalar gönderilmesini halleden bir postRemind
metodu da olacaktır. Bu metod POST değişkenlerinde bir email alanı
mevcut olmasını bekler. Eğer bir hatırlatıcı e-postası kullanıcıya
başarıyla gönderilirse, oturuma bir status mesajı flaşlanacaktır.
Eğer hatırlatıcı yapılamazsa o zaman bunun yerine bir error mesajı
flaşlanacaktır.
Bu postRemind controller metodu içerisinde, kullanıcıya göndermeden önce mesaj olgusu üzerinde değişiklik yapabilirsiniz:
1
2
3
4
5
Password::remind(Input::only('email'), function($messag\
e)
{
$message->subject('Şifre Hatırlatıcı');
});
Kullanıcınız, controllerin getReset metodunu işaret eden bir bağlantısı olan bir e-posta alacaktır. Ayrıca, ilgili bir şifre hatırlatıcı girişimini tanımlamakta kullanılan bir şifre hatırlatıcı tokeni bu controller metoduna geçilecektir. Bu controller metodu bir
password.reset view’i döndürecek şekilde zaten yapılandırılmıştır, ancak bu view’i sizin oluşturmanız gerekiyor. İlgili token view’e geçilecektir ve siz bu tokeni token adlı “hidden” bir form
161
Güvenlik
alanına koymanız gerekiyor. Sizin şifre reset (yenileme) formunuz
bu token‘e ek olarak email, password ve password_confirmation
alanlarını da içermelidir. Bu form RemindersController@postReset
metoduna post edilmelidir.
password.reset view’indeki basit bir form şöyle bir şey olabilir:
1
2
3
4
5
6
7
8
<form action ="{{ action('RemindersController@postReset'\
) }}" method ="POST">
<input type ="hidden" name ="token" value ="{{ $token }}">
<input type ="email" name ="email">
<input type ="password" name ="password">
<input type ="password" name ="password_confirmation">
<input type ="submit" value ="Şifreyi Yenile">
</form>
Son olarak, veritabanındaki şifrenizin gerçekten değiştirilmesinden bu postReset metodu sorumludur. Bu controller eyleminde,
Password::reset metoduna geçilen Closure, User‘in password niteliğini ayarlar ve save metodunu çağırır. Pek tabii, bu Closure sizin
User modelinizin bir Eloquent modeli¹⁵⁶ olmasını beklemektedir;
bununla birlikte siz bu Closure üzerinde uygulamanızın veritabanı
depolama sistemiyle uyumlu olması için gerekli değişiklikler yapmakta özgürsünüz.
Eğer şifre başarılı bir biçimde yenilenirse, kullanıcı uygulamanızın
köküne yönlendirilecektir. Aynı şekilde, siz bu redirect URL’sini
de değiştirme serbestisine sahipsiniz. Eğer şifre yenileme başarısız
olursa, kullanıcı tekrar reset formuna yönlendirilecektir ve session’a
bir error mesajı flaşlanacaktır.
Şifre Geçerlilik Denetimi
Ön tanımlı olarak, Password::reset metodu şifrelerin eşleşiyor
ve >= altı karakter olmasını soruşturacaktır. Siz, parametre olarak
¹⁵⁶/docs/eloquent
162
Güvenlik
bir Closure alan Password::validator metodunu kullanarak bu
kuralları özelleştirebilirsiniz. Bu Closure içerisinde, istediğiniz her
türlü şifre geçerlilik denetimini yapabilirsiniz. Şuna dikkat ediniz:
şifrelerin eşleşiyor olduğunu doğrulamanız gerekmiyor, çünkü bu
kısım framework tarafından otomatik olarak yapılacaktır.
1
2
3
4
Password::validator(function($credentials)
{
return strlen($credentials['password']) >= 8;
});
Not: Ön tanımlı olarak, şifre yenileme tokenlerinin
ömrü bir saat sonra sona erer. Siz app/config/auth.php
dosyanızın reminder.expire seçeneği aracılığıyla bunu değiştirebilirsiniz.
Kriptolama
Laravel, mcrypt PHP uzantısı aracılığıyla güçlü AES kriptolama
imkanı sağlamaktadır:
Bir Değerin Kriptolanması
1
$kriptolu = Crypt::encrypt('secret');
Not: app/config/app.php dosyasının key seçeneğinde
16, 24 veya 32 karakterli rastgele bir string ayarladığınızdan emin olun. Aksi takdirde kriptolanmış değerler
güvenli olmayacaktır.
Kriptolu Bir Değerin Çözülmesi
163
Güvenlik
1
$cozuk = Crypt::decrypt($kriptolu);
Cipher ve Mod Ayarlanması
Ayrıca, kriptocu tarafından kullanılan cipher ve mod da ayarlayabilirsiniz
1
Crypt::setMode('crt');
2
3
Crypt::setCipher($cipher);
Kimlik Doğrulama Sürücüleri
Laravel kutusunda database ve eloquent kimlik doğrulama sürücüleriyle gelir. Diğer kimlik doğrulama sürücüleri eklenmesiyle
ilgili daha fazla bilgi için Authentication genişletme dokümantasyonu¹⁵⁷ kesimini kontrol ediniz.
¹⁵⁷/docs/extending#authentication
Kuyruklar
Yapılandırma
Laravel’in Queue (kuyruk) bileşeni bir takım farklı kuyruk servisleri
için tek bir API sağlamaktadır. Kuyruklar e-mail göndermek gibi
zaman harcayan görevleri ileri bir zamana kadar ertelemenize
imkan verir ve böylece uygulamanıza yapılan web istekleri büyük
ölçüde hızlanır.
Kuyruk yapılandırma dosyası app/config/queue.php olarak saklanır. Bu dosyada framework’e dahil edilmiş kuyruk sürücülerinin her birisi için bağlantı yapılandırmaları bulacaksınız. Laravel’deki kuyruk sürücüleri arasında Beanstalkd¹⁵⁸, IronMQ¹⁵⁹, Amazon SQS¹⁶⁰, Redis¹⁶¹ ve senkronize (lokal kullanım için) sürücü yer
almaktadır.
Listelenen bu kuyruk sürücüleri için aşağıdaki bağımlılıklar gereklidir:
• Beanstalkd: pda/pheanstalk ∼2.0
• Amazon SQS: aws/aws-sdk-php
• IronMQ: iron-io/iron_mq
Temel Kullanım
Bir İşin Kuyruğa Sokulması
Kuyruğa yeni bir iş itmek için Queue::push metodunu kullanın:
¹⁵⁸http://kr.github.com/beanstalkd
¹⁵⁹http://iron.io
¹⁶⁰http://aws.amazon.com/sqs
¹⁶¹http://redis.io
165
Kuyruklar
1
Queue::push('SendEmail', array('message' => $message));
Bir İş İşleyicisinin Tanımlanması
push metoduna girilen ilk parametre işi yapmak için kullanılacak
sınıfın adıdır. İkinci parametre işleyiciye geçirilecek veri dizisidir.
Bir iş işleyicisi şu şekilde tanımlanmalıdır:
1
class SendEmail {
2
public function fire($is, $veri)
{
//
}
3
4
5
6
7
8
}
Gerekli olan tek metodun fire olduğuna dikkat edin. Bu metod bir
iş olgusu ve bir de kuyruğa sokulacak veri dizisi parametrelerini
alır.
Özel Bir İşleyici Metodunun Belirlenmesi
Eğer iş’in fire‘den başka bir metod kullanmasını istiyorsanız, işi
sokarken (yani push metodunda) metodu belirleyebilirsiniz:
1
2
Queue::push('SendEmail@send', array('message' => $messa\
ge));
Bir İş İçin Kuyruk / Tüp Belirtilmesi
Bir işin gönderilmesi gereken kuyruğu / tüpü de belirtebilirsiniz:
166
Kuyruklar
1
2
Queue::push('SendEmail@send', array('message' => $messa\
ge), 'emails');
Birden Çok İş İçin Aynı Yükün Geçilmesi
Birkaç kuyruk işi için aynı veriyi geçmeniz gerekiyorsa, Queue::bulk
metodunu kullanabilirsiniz:
1
Queue::bulk(array('SendEmail', 'NotifyUser'), $payload);
Bir İşin Çalıştırılmasının Geciktirilmesi
Kimi zaman sıraya sokulmuş bir işin çalıştırılmasını geciktirmek
isteyebilirsiniz. Örneğin, bir müşteriye kayıt olduktan 15 dakika
sonra bir e-posta gönderen bir işi kuyruğa koymak isteyebilirsiniz.
Bunu Queue::later metodunu kullanarak başarabilirsiniz:
1
$date = Carbon::now()->addMinutes(15);
2
3
4
Queue::later($date, 'SendEmail@send', array('message' =\
> $message));
Bu örnekte, işe atamak istediğimiz gecikme süresini belirtmek için
Carbon¹⁶² date kitaplığını kullanıyoruz. Alternatif olarak geciktirmek istediğiniz saniye sayısını tam sayı olarak geçebilirsiniz.
İşlenmiş Bir İşin Silinmesi
Bir iş işlendikten sonra kuyruktan silinmelidir. Silme işlemi ilgili iş
olgusunda delete metodu kullanılarak yapılabilir:
¹⁶²https://github.com/briannesbitt/Carbon
167
Kuyruklar
1
2
3
public function fire($is, $veri)
{
// İşi işle...
4
$is->delete();
5
6
}
Bir İşin Tekrar Kuyruğa Koyulması
Bir işi tekrar kuyruğa devretmek isterseniz, bunu release metodu
aracılığıyla yapabilirsiniz:
1
2
3
public function fire($is, $veri)
{
// İş sürecini yürüt...
4
$is->release();
5
6
}
İş tekrar salınmadan önce kaç saniye bekleneceğini de belirleyebilirsiniz:
1
$is->release(5);
Çalıştırma Girişimlerinin Sayısını Yoklama
İş işlenirken bir istisna oluşursa, otomatik olarak kuyruğa tekrar
salınacaktır. attempts metodunu kullanarak, işi çalıştırmak için
yapılmış olan girişim sayısını da yoklayabilirsiniz:
168
Kuyruklar
1
2
3
4
if ($is->attempts() > 3)
{
//
}
Bir İşin ID’sine Erişme
İş tanımlayıcılarına da erişebilirsiniz:
1
$is->getJobId();
Kuyruğa Closure Fonksiyonu Ekleme
Kuyruğa bir Closure de push edebilirsiniz. Bu, kuyruğa sokulması
gerekecek hızlı, basit görevler için çok uygundur:
Kuyruğa Bir Closure Sokulması
1
2
3
Queue::push(function($is) use ($id)
{
Account::delete($id);
4
$is->delete();
5
6
});
Not: Kuyruğa sokulmuş Closure’lar için nesneleri use
direktifi aracılığıyla kullanılabilir yapmak yerine, birincil anahtarları geçmeyi ve ilgili modeli kuyruk işiniz
içinden tekrar çekmeyi düşünün. Bu, beklenmedik serileştirme davranışlarını çoğu keresinde önleyecektir.
Iron.io push kuyrukları kullanılıyorken, Closure’ların kuyruğa sokulmasında daha fazla önlem almalısınız. Kuyruk mesajlarızı alan
169
Kuyruklar
son nokta, isteğin gerçekten Iron.io’den mi geldiğini doğrulayacak
bir jeton yoklaması yapmalıdır. Örneğin, sizin push kuyruk son
noktanız şuna benzer bir şey olmalıdır: https://uygulamaniz.com/queue/receive?t
Böylece, kuyruk istek sıralamasından önce uygulamanızdaki gizli
jetonun değerini kontrol edebilirsiniz.
Kuyruk Dinleyicileri Çalıştırma
Laravel, kuyruğa itildikçe yeni işler çalıştıran bir Artisan görevi
içermektedir. Bu görevi çalıştırmak için queue:listen komutunu
kullanabilirsiniz:
Kuyruk Dinleyici Başlatılması
1
php artisan queue:listen
Ayrıca dinleyicinin kullanacağı kuyruk bağlantısını da belirtebilirsiniz:
1
php artisan queue:listen connection
Unutmamanız gereken şey, bu görev başlatıldıktan sonra elle durdurulana kadar çalışmaya devam edeceğidir. Kuyruk dinleyicinin
çalışmayı durdurmamasından emin olmak için Supervisor¹⁶³ gibi
bir süreç monitörü kullanabilirsiniz.
Kuyruk önceliklerini ayarlamak için listen komutuna virgülle
ayrılmış bir kuyruk bağlantıları listesi geçebilirsiniz:
1
php artisan queue:listen --queue=high,low
Bu örnekte, high-connection üzerindeki işler, her zaman için low-connection‘dan
gelen işlere geçmeden önce yürütülecektir.
¹⁶³http://supervisord.org/
170
Kuyruklar
İş Zaman Aşımı Parametresi Belirleme
Ayrıca her işin çalışmasına izin verilecek zaman süresini (saniye
cinsinden) de ayarlayabilirsiniz:
1
php artisan queue:listen --timeout=60
Kuyruk Uyku Süresinin Belirtilmesi
Ek olarak, yeni işin eyleme alınmadan önce beklenileceği süreyi
saniye cinsinden belirtebilirsiniz:
1
php artisan queue:listen --sleep=5
Not: kuyruk sadece kuyrukta iş olmadığı takdirde “uyur”. Eğer
kuyrukta başka işler varsa, kuyruk uyumaksızın onları çalışmaya
devam edecektir.
Kuyruktaki İlk İşin İşleme Geçirilmesi
Kuyruktaki sadece ilk sıradaki işi yürütmek için queue:work komutunu kullanabilirsiniz:
1
php artisan queue:work
Daemon Kuyruk İşçisi
queue:work ayrıca işlerin işlenmesinin framework tekrar boot edil-
meksizin devam etmesi için kuyruk işçisinin zorlanması için bir
--daemon seçeneği içermektedir. Bu, queue:listen komutuyla karşılaştırıldığında CPU kullanımında önemli bir azalmayla sonuçlanır
ama yayımlama sırasında halihazırda çalışmakta olan kuyrukların
drene edilmesi gerekliliği karmaşıklığını ekler.
Bir kuyruk işçisini daemon modunda başlatmak için, --daemon
flagını kullanın:
Kuyruklar
1
171
php artisan queue:work connection --daemon
2
3
php artisan queue:work connection --daemon --sleep=3
4
5
6
php artisan queue:work connection --daemon --sleep=3 --\
tries=3
Gördüğünüz gibi, queue:work komutu queue:listen için kullanılan seçeneklerin pek çoğunu desteklemektedir. Mevcut seçeneklerin
tümünü görmek için php artisan help queue:work komutunu
kullanabilirsiniz.
Daemon Kuyruk İşçileriyle Yayımlama
Bir uygulamayı daemon kuyruk işçileri kullanarak yayımlamanın
en basit yolu yayımlamanızın en başında uygulamanızı bakım
(maintenance) moduna koymaktır. Bu php artisan down komutu
kullanılarak yapılabilir. Uygulama bakım moduna alındıktan sonra,
Laravel artık kuyruğa yeni işler kabul etmeyecektir ama mevcut
işleri işlemeye devam edecektir.
Worker’larınızı yeniden başlatmanın en kolay yolu yayımlama
scriptinize aşağıdaki komutu dahil etmektir:
1
php artisan queue:restart
Bu komut tüm kuyruk işçilerine mevcut işlerini işlemeyi bitirdikten
sonra yeniden başlatmaları talimatı verecektir.
Daemon Kuyruk İşçileri İçin Kodlama
Daemon kuyruk işçileri her biri işlerini işlemeden önce frameworkü
yeniden başlatmazlar. Bu nedenle, işlerinizi bitirmeden önce çok
büyük kaynakları serbest bırakmaya özen göstermelisiniz. Örneğin,
172
Kuyruklar
GD kitaplığıyla resim manipulasyonu yapıyorsanız, yaptıktan sonra imagedestroy ile belleği rahatlatmalısınız.
Benzer şekilde, uzun çalışan daemon’larla kullanıldığı zaman veritabanı bağlantınız kopabilir. Taze bir bağlantınız olmasını temin
etmek için DB::reconnect metodunu kullanabilirsiniz.
Push Kuyrukları
Push kuyrukları size herhangi bir art alan veya arka plan dinleyici
çalıştırmaksızın güçlü Laravel 4 kuyruk araçlarını kullanmanıza
imkan verir. Push kuyrukları şu anda sadece Iron.io¹⁶⁴ sürücüsü
tarafından desteklenmektedir. Başlamak için önce bir Iron.io hesabı
oluşturun ve Iron kimlik bilgilerinizi app/config/queue.php yapılandırma dosyasına ekleyin.
Bir Push Kuyruk Aboneliğinin Kayda Geçirilmesi
Daha sonra, yeni push edilmiş kuyruk işlerini alacak bir URL son
noktasını kayda geçirmek için queue:subscribe Artisan komutunu
kullanabilirsiniz:
1
2
php artisan queue:subscribe queue_name http://falan.com\
/queue/receive
Şimdi, sizin Iron panonuza giriş yaptığınız zaman, yeni push kuyruğunuzu ve abone olunan URL’yi göreceksiniz. Verilen bir kuyruk için istediğiniz kadar çok URL kaydedebilirsiniz. Sonra da,
queue/receive son noktanız için bir rota oluşturun ve Queue::marshal
metodundan cevap döndürün:
¹⁶⁴http://iron.io
173
Kuyruklar
1
2
3
4
Route::post('queue/receive', function()
{
return Queue::marshal();
});
Doğru iş işleyici sınıfının ateşlenmesiyle marshal metodu ilgilenecektir. Push kuyruğundaki işleri ateşlemek için, konvansiyonal
kuyruklar için kullanılan aynı Queue::push metodunu kullanmanız
yeterlidir.
Başarısız İşler
İşler her zaman planladığımız şekilde gitmediğinden, bazen kuyruğa soktuğumuz işler başarılamaz. Dert etmeyin, bu en iyilerimizin
bile başına gelir! Laravel bir işin en fazla kaç defa denenmesi
gerektiğini belirtmeniz için kolay bir yol içerir. Bir iş bu girişme
miktarını aştıktan sonra, failed_jobs (başarısız işler) tablosuna eklenecektir. Başarısız işler tablosunun adını app/config/queue.php
yapılandırma dosyasında ayarlayabilirsiniz.
failed_jobs tablosu için bir migrasyon oluşturmak için, queue:failed-table
komutunu kullanabilirsiniz:
1
php artisan queue:failed-table
Bir işin maksimum kaç defa yapılma girişiminde bulunulacağını
queue:listen komutunda --tries anahtarını kullanarak belirtebilirsiniz:
1
php artisan queue:listen connection-name --tries=3
Eğer bir kuyruk işi başarısız olduğu takdirde çağrılacak bir olay
kayda geçirmek isterseniz, Queue::failing metodunu kullanabi-
Kuyruklar
174
lirsiniz. Bu olay ekibinizi bir e-posta veya HipChat¹⁶⁵ aracılığıyla
bilgilendirmek için harika bir fırsattır.
1
2
3
4
Queue::failing(function($connection, $job, $data)
{
//
});
Başarısız olmuş işlerinizin tümünü görmek için queue:failed Artisan komutunu kullanabilirsiniz:
1
php artisan queue:failed
Bu queue:failed komutu iş ID, bağlantı, kuyruk ve başarısızlık
zamanını listeleyecektir. Bunlardan iş ID başarısız işi yeniden denemek için kullanılabilir. Örneğin, ID’si 5 olan başarısız bir işi yeniden
denemek için aşağıdaki komut verilmelidir:
1
php artisan queue:retry 5
Başarısız bir işi silmek isterseniz, queue:forget komutunu kullanabilirsiniz:
1
php artisan queue:forget 5
Başarısız işlerinizin tümünü silmek için queue:flush komutunu
kullanabilirsiniz:
1
php artisan queue:flush
¹⁶⁵https://www.hipchat.com
Olaylar (Events)
Temel Kullanım
Laravel’in Event sınıfı, uygulamanızdaki olaylara abone olmanıza
ve dinlemenize imkan veren basit bir gözlemci aracıdır.
Bir Olaya Abone Olma
1
2
3
Event::listen('uye.login', function($uye)
{
$uye->last_login = new DateTime;
4
$uye->save();
5
6
});
Bir Olayı Ateşleme
1
$olay = Event::fire('uye.login', array($uye));
Bir Olaya Abone Olurken Öncelik Belirtme
Olaylara abone olurken bir öncelik de belirtebilirsiniz. Daha yüksek
önceliği olan dinleyiciler daha önce çalışacak, aynı önceliğe sahip
dinleyiciler ise abonelik sırasına göre çalışacaklardır.
1
Event::listen('uye.login', 'LoginHandler', 10);
2
3
Event::listen('uye.login', 'DigerHandler', 5);
Olaylar (Events)
176
Bir Olayın Yayılımının Durdurulması
Bazen bir olayın diğer dinleyicilere yayılmasını durdurmak isteyebilirsiniz. Dinleyicinizden false döndürerek bunu gerçekleştirebilirsiniz:
1
2
3
Event::listen('uye.login', function($event)
{
// Olayı işle...
4
return false;
5
6
});
Olayların Kayda Geçirileceği Yer
Tamam, olayların nasıl kayda geçirileceğini biliyorsunuz ama onların nerede kayda geçirileceğini merak ediyor olabilirsiniz. Dert
etmeyin, bu çok sorulan bir şey. Ne yazık ki bu cevaplandırması zor bir soru, çünkü bir olayı neredeyse her yerde kayda
geçirebilirsiniz! Fakat, işte bazı ipuçları. Aynı şekilde, diğer pek
çok bootstrapping (önce yüklenen) koduna benzer olarak, olayları
app/start/global.php gibi start dosyalarınızın birisinde kayda
geçirebilirsiniz.
Eğer start dosyalarınız çok kalabalık bir hale gelirse, bir start dosyanızda “include” edilen ayrı bir app/events.php dosyası oluşturabilirsiniz. Bu, sizin olay kaydetme işinizi, geri kalan bootstrapping
kodundan temiz bir şekilde ayrı tutmanın basit bir çözümüdür. Eğer
sınıf temelli bir yaklaşımı tercih ederseniz, olaylarınızı bir servis
sağlayıcı¹⁶⁶ ile kayda geçirebilirsiniz. Bu yaklaşımlardan hiçbiri
“mutlak” doğru olmadığından, ugulamanızın büyüklüğüne göre
rahatlık hissedeceğiniz bir yaklaşımı seçin.
¹⁶⁶/docs/ioc#service-providers
177
Olaylar (Events)
Joker Dinleyiciler
Joker Olay Dinleyicilerin Kayda Geçirilmesi
Bir olay dinleyiciyi kayda geçirirken, joker dinleyicileri belirtmek
üzere yıldız işareti kullanabilirsiniz:
1
2
3
4
Event::listen('falan.*', function($param)
{
// Olayı işle...
});
Bu dinleyici falan. ile başlayan tüm olayları işleyecektir.
Tam olarak hangi olayın ateşlendiğini tespit etmek için Event::firing
metodunu kullanabilirsiniz:
1
2
3
4
5
6
7
Event::listen('falan.*', function($param)
{
if (Event::firing() == 'falan.filan')
{
//
}
});
Dinleyici Olarak Sınıfları Kullanma
Bazı durumlarda, bir olayı işlemek için bir anonim fonksiyon
yerine bir sınıf kullanmak isteyebilirsiniz. Sınıf olay dinleyicileri
Laravel’in IoC konteyneri¹⁶⁷ ile çözümlenecek, böylece size dinleyicileriniz üzerinde tam bir bağımlılık enjeksiyonu gücü verecektir.
Bir Sınıf Dinleyicinin Kayda Geçirilmesi
¹⁶⁷/docs/ioc
178
Olaylar (Events)
1
Event::listen('uye.login', 'LoginIsleyici');
Bir Olay Dinleyici Sınıfının Tanımlanması
Ön tanımlı olarak, LoginIsleyici sınıfındaki handle metodu çağrılacaktır:
1
class LoginIsleyici {
2
public function handle($data)
{
//
}
3
4
5
6
7
8
}
Hangi Metoda Abone Olunduğunun Tanımlanması
Eğer ön tanımlı handle metodunu kullanmak istemiyorsanız, abone
olunacak metodu belirleyebilirsiniz:
1
Event::listen('uye.login', 'LoginIsleyici@onLogin');
Olayları Sıraya Sokma
Sıralı Bir Olayın Kayda Geçirilmesi
queue ve flush metodlarını kullanarak, bir olayı hemen ateşlemeyip, ateşlenmek üzere “sıraya” sokabilirsiniz:
1
Event::queue('falan', array($uye));
“flusher”ı çalıştırabilir ve flush metodunu kullanarak sıradaki tüm
olayları harekete geçirebilirsiniz:
179
Olaylar (Events)
1
Event::flush('falan');
Olay Abonecileri
Bir Olay Abonecisi Tanımlanması
Olay abonecileri, sınıfın kendi içinden birden çok olaya abone
olabilen sınıflardır. Aboneciler bir subscribe metodu ile tanımlanırlar ve bu metoda parametre olarak bir olay sevkiyatçısı olgusu
geçilecektir:
1
class UyeOlayIsleyici {
2
3
4
5
6
7
8
9
/**
* Uye login olaylarını işle.
*/
public function onUyeLogin($event)
{
//
}
10
11
12
13
14
15
16
17
/**
* Uye logout olaylarını hallet.
*/
public function onUyeLogout($event)
{
//
}
18
19
20
21
22
23
/**
* Abone dinleyicilerini kayda geçir.
*
* @param Illuminate\Events\Dispatcher
* @return array
$events
180
Olaylar (Events)
*/
public function subscribe($events)
{
$events->listen('uye.login', 'UyeOlayIsleyici@onUyeLo\
24
25
26
27
28
gin');
29
$events->listen('uye.logout', 'UyeOlayIsleyici@onUyeL\
30
31
ogout');
}
32
33
34
}
Bir Olay Abonecisinin Kayda Geçirilmesi
Aboneci tanımlandıktan sonra, Event sınıfı kullanılarak kayda geçirilebilir.
1
$aboneci = new UyeOlayIsleyici;
2
3
Event::subscribe($aboneci);
Ayrıca abonecinizi çözümlemek için Laravel IoC konteynerini¹⁶⁸ de
kullanabilirsiniz. Bunu yapmak için subscribe metoduna sadece
abonecinizin ismini geçiniz:
1
Event::subscribe('UyeOlayIsleyici');
¹⁶⁸/docs/ioc
Oturum
Yapılandırma
HTTP odaklı uygulamalar durum bilgisi taşımadıkları için, oturumlar istekler arasında kullanıcı hakkında bilgi saklamak için bir yol
sağlar. Laravel temiz, tek bir API aracılığıyla kullanılabilen çeşitli
oturum back-endleri ile birlikte gelir. İçerisinde Memcached¹⁶⁹, Redis¹⁷⁰ ve veritabanları gibi popüler back-end desteği yer almaktadır.
Oturum yapılandırma ayarları app/config/session.php dosyasında bulunmaktadır. Bu belgede size sunulan iyi belgelenmiş seçenekleri gözden geçirmeyi unutmayın. Ön tanımlı olarak, Laravel
file oturum sürücüsünü kullanmak üzere yapılandırılmıştır ve bu
yapılandırma uygulamaların çoğunda iyi çalışacaktır.
Ayrılmış (Rezerve) Anahtarlar
Laravel framework dahili olarak flash session anahtarını kullanır,
bu nedenle siz oturuma bu isimle bir öğe eklememelisiniz.
Oturum Kullanımı
Oturumda Bir Öğe Saklamak
1
Session::put('anahtar', 'deger');
Dizi Oturum Değerine Bir Değer Eklemek
¹⁶⁹http://memcached.org
¹⁷⁰http://redis.io
182
Oturum
1
Session::push('uyeler.takimlar', 'gelistiriciler');
Oturumdaki Bir Öğeyi Öğrenmek
1
$deger = Session::get('anahtar');
Bir Öğe Almak Veya Varsayılan Bir Değer Döndürmek
1
$deger = Session::get('anahtar', 'default');
2
3
4
$deger = Session::get('anahtar', function() { return 'd\
efault'; });
Bir Öğenin Elde Edilmesi ve Oturumdan Çıkartılması
1
$value = Session::pull('anahtar', 'default');
Oturumdaki Tüm Verileri Almak
1
$veri = Session::all();
Oturumda Bir Öğenin Olup Olmadığını Tespit Etmek
1
2
3
4
if (Session::has('uyeler'))
{
//
}
Oturumdan Bir Öğeyi Çıkartmak
1
Session::forget('anahtar');
Oturumdaki Tüm Öğeleri Çıkartmak
183
Oturum
1
Session::flush();
Tekrar Oturum ID Üretmek
1
Session::regenerate();
Flaş Verisi
Bazen oturumda sadece sonraki istek için öğeler saklamak isteyebilirsiniz. Bunu Session::flash metodunu kullanarak gerçekleştirebilirsiniz:
1
Session::flash('anahtar', 'deger');
Mevcut Flaş Verinin Bir Başka İstek İçin Yeniden
Flaşlanması
1
Session::reflash();
Flaş Verinin Sadece Bir Alt Kümesinin Yeniden
Flaşlanması
1
Session::keep(array('uyeadi', 'email'));
Veritabanı Oturumları
database oturum sürücüsü kullanıyorken, oturum öğelerini taşıyan
bir tablo kurulumu gerekecek. Aşağıda, bu tablo için örnek bir Şema
deklarasyonu gösterilmektedir:
184
Oturum
1
2
3
4
5
6
Schema::create('sessions', function($table)
{
$table->string('id')->unique();
$table->text('payload');
$table->integer('last_activity');
});
Tabii ki, bu migrasyonu üretmek için session:table Artisan komutunu kullanabilirsiniz!
1
php artisan session:table
2
3
composer dump-autoload
4
5
php artisan migrate
Oturum Sürücüleri
Oturum “driver’ı” her istek için oturum verisinin nerede saklanacağını tanımlamaktadır. Laravel çeşitli harika sürücülerle birlikte
gelmektedir.
• file - oturumlar app/storage/sessions klasöründe saklanacaktır.
• cookie - oturumlar güvenli, kriptolanmış çerezlerde saklanacaktır.
• database - oturumlar kendi uygulamanızın kullandığı bir
veritabanında saklanacaktır.
• memcached / redis - oturumlar bu hızlı, önbellekleme tabanlı
depolardan birisinde saklanacaktır.
• array - oturumlar basit bir PHP dizisinde saklanacak ve
istekler arasında sebat etmeyecektir.
Oturum
Not: Array sürücüsü tipik olarak unit testler çalıştırmak için kullanılır, bu yüzden oturum verileri sürdürülmeyecektir.
185
Önbellekleme (Cache)
Yapılandırma
Laravel, çeşitli önbellekleme sistemleri için tümleşik bir API sağlar. Önbellekleme yapılandırma ayarları app/config/cache.php
dosyasında bulunmaktadır. Bu dosyada uygulamanızda varsayılan olarak hangi önbellekleme sürücüsünü kullanmak istediğinizi
belirtebilirsiniz. Laravel, Memcached¹⁷¹ ve Redis¹⁷² gibi popüler
önbellekleme sürücülerini barındırır.
Önbellekleme yapılandırma dosyası ayrıca dosyanın içinde açıklanmış çeşitli seçenekleri de içerir, bu yüzden o seçenekleri de okuduğunuzdan emin olun. Varsayılan olarak, Laravel, serileştirilerek
önbelleklenmiş öğeleri dosya sisteminde depolayan file (dosya)
önbellekleme sürücüsünü kullanmak üzere ayarlanmıştır. Daha
büyük uygulamalar için, Memcached ve APC gibi bir önbellekleme
uygulaması kullanmanız önerilir.
Önbellekleme Kullanımı
Bir Öğeyi Önbelleğe Koymak
1
Cache::put('anahtar', 'değer', $dakika);
Son Kullanım Zamanını Ayarlamak İçin Carbon
Nesneleri Kullanılması
¹⁷¹http://memcached.org
¹⁷²http://redis.io
Önbellekleme (Cache)
1
187
$sonZaman = Carbon::now()->addMinutes(10);
2
3
Cache::put('anahtar', 'değer', $sonZaman);
Eğer Öğe Önbellekte Yoksa, Öğeyi Önbelleğe Koymak
1
Cache::add('anahtar', 'değer', $dakika);
Eğer ilgili öğe önbelleğe gerçekten eklenirse add metodu true
döndürecektir. Aksi takdirde bu metod false döndürecektir.
Öğenin Önbellekte Var Olup Olmadığını Kontrol
Etmek
1
2
3
4
if (Cache::has('anahtar'))
{
//
}
Önbellekten Bir Öğeyi Almak
1
$value = Cache::get('anahtar');
Bir Önbellek Değeri Almak Veya Varsayılan Bir Değer
Döndürmek
1
$value = Cache::get('anahtar', 'varsayılanDeğer');
2
3
4
$value = Cache::get('anahtar', function() { return 'var\
sayılanDeğer'; });
Bir Öğeyi Önbelleğe Kalıcı Olarak Koymak
Önbellekleme (Cache)
1
188
Cache::forever('anahtar', 'değer');
Bazen, önbellekten bir öğeyi almak isteyebilir ve ayrıca talep edilen
öğe yoksa önbellekte varsayılan bir değer saklayabilirsiniz. Bunu,
Cache::remember metodunu kullanarak yapabilirsiniz:
1
2
3
4
5
$value = Cache::remember('kullanicilar', $dakika, funct\
ion()
{
return DB::table('kullanicilar')->get();
});
Ayrıca, remember ve forever methodlarını birlikte kullanabilirsiniz.
1
2
3
4
5
$value = Cache::rememberForever('kullanicilar', functio\
n()
{
return DB::table('kullanicilar')->get();
});
Önbellekte bütün öğelerin serileştirilmiş şekilde saklandığını unutmayın, yani her türlü veriyi saklayabilirsiniz.
Önbellekten Bir Öğe Çekilmesi
Eğer önbellekten bir öğeyi elde etmek ve sonra da onu silmeniz
gerekirse, pull metodunu kullanabilirsiniz:
1
$value = Cache::pull('anahtar');
Önbellekten Bir Öğeyi Silmek
189
Önbellekleme (Cache)
1
Cache::forget('anahtar');
Arttırma & Azaltma
file ve database hariç tüm sürücüler increment (artırma) ve
decrement (azaltma) işlemlerini destekler:
Bir Değeri Arttırmak
1
Cache::increment('anahtar');
2
3
Cache::increment('anahtar', $miktar);
Bir Değeri Azaltmak
1
Cache::decrement('anahtar');
2
3
Cache::decrement('anahtar', $miktar);
Önbellek Etiketleri (Tags)
Not: Önbellek bölümleri file ve database önbellekleme sürücüleri kullanılırken desteklenmemektedir. Ayrıca, “forever” saklanır önbelleklerde birden çok tag
kullanmanız halinde, bayat kayıtları otomatik olarak
temizleyen memcached gibi bir sürücüyle performans
en iyi olacaktır.
Etiketlenmiş Bir Önbelleğe Erişim
Cache tagları cache’deki birbirine yakın öğeleri etiketlemenize ve
daha sonra verilen bir isimle etiketlenmiş tüm cache’leri yok etmenize (flush) imkan verir. Etiketlenmiş bir cache’e erişmek için, tags
metodunu kullanın:
Önbellekleme (Cache)
190
Parametreler olarak sıralı bir tag isimleri listesi geçerek veya parametre olarak sıralı tag isimlerinden oluşan bir dizi geçerek etiketlenmiş bir cache saklayabilirsiniz.
1
2
Cache::tags('insanlar', 'yazarlar')->put('Can', $can, $\
dakika);
3
4
5
Cache::tags(array('insanlar', 'artistler'))->put('Mine'\
, $mine, $dakika);
Tag kombinasyonlarında remember, forever ve rememberForever
gibi herhangi bir cache saklama metodunu kullanabilirsiniz. Ayrıca etiketlenmiş cache’lerde önbelleklenmiş öğelere erişebileceğiniz
gibi, increment ve decrement gibi diğer önbellek metodlarını da
kullanabilirsiniz.
Etiketlenmiş Bir Önbellekteki Öğelere Erişmek
Etiketlenmiş bir cache’ye erişmek için, onu saklarken kullandığınız
aynı sıradaki tag listesini geçiniz.
1
2
$mine = Cache::tags('insanlar', 'artistler')->get('Mine\
');
3
4
5
$can = Cache::tags(array('insanlar', 'yazarlar'))->get(\
'Can');
Bir isim veya bir isim listesi ile etiketlenmiş tüm ögeleri yok edebilirsiniz. Örneğin, aşağıdaki cümle insanlar, yazarlar veya her
ikisi ile de etiketlenmiş tüm cache’leri çıkarıp atacaktır. Dolayısıyla,
cache’den hem “Mine” hem de “Can” çıkartılacaktır:
Önbellekleme (Cache)
1
191
Cache::tags('insanlar', 'yazarlar')->flush();
Tersine, şu cümle sadece yazarlar etiketi verilmiş cache’leri çıkartacaktır, yani “Can” çıkartılacak ama “Mine” çıkartılmayacak.
1
Cache::tags('yazarlar')->flush();
Veritabanı Önbelleği
database önbellek sürücüsü kullandığınız takdirde, önbellek öğelerini içeren bir tablo kurulumu gerekir. Bu tablo için örnek bir şema
aşağıda gösterilmiştir:
1
2
3
4
5
6
Schema::create('cache', function($table)
{
$table->string('key')->unique();
$table->text('value');
$table->integer('expiration');
});
Paket Geliştirme
Giriş
Paketler Laravel’e işlevsellik eklemenin esas yollarıdır. Paketler
tarihlerle çalışmanın harika bir yolu olan Carbon¹⁷³ gibi bir şey ya
da Behat¹⁷⁴ gibi tam bir BDD test framework’ü olabilir.
Farklı paket türleri bulunmaktadır. Bazı paketler kendi başınadır,
yani sadece Laravel değil herhangi bir framework ile çalışırlar: Carbon ve Behat her ikisi de bu tür stand-alone paket örnekleridir. Bu
paketler sadece composer.json dosyasında istek yapılmak suretiyle
Laravel’le kullanılabilmektedir.
Öte yandan, diğer bazı paketler özellikle Laravel ile kullanım için tasarlanmıştır. Önceki Laravel sürümlerinde, bu tip paketlere “bundle” deniyordu. Bu paketlerde özellikle bir Laravel uygulamasını güçlendirmeyi amaçlamış rotalar, denetçiler (controllers), görünümler,
yapılandırmalar ve migrasyonlar olabilir. Kendi başına türde bir
paket geliştirmek için gerekli özel bir süreç olmadığı için, bu kılavuz
esas itibarıyla Laravel’e özgü olanların geliştirilmesini kapsamaktadır.
Tüm Laravel paketleri Packagist¹⁷⁵ ve Composer¹⁷⁶ aracılığıyla dağıtılır, bu yüzden bu harika PHP paket dağıtım araçlarını öğrenmek
esastır.
¹⁷³https://github.com/briannesbitt/Carbon
¹⁷⁴https://github.com/Behat/Behat
¹⁷⁵http://packagist.org
¹⁷⁶http://getcomposer.org
193
Paket Geliştirme
Bir Paket Oluşturma
Laravel’le kullanmak üzere yeni bir paket oluşturmanın en kolay
yolu workbench Artisan komutudur. Öncelikle, app/config/workbench.php
dosyasında birkaç seçeneği ayarlamanız gerekiyor. Bu dosyada,
bir name ve email seçeneği bulacaksınız. Bu değerler sizin yeni
paketiniz için bir composer.json dosyası üretmekte kullanılacaktır.
Bu değerleri girdikten sonra, bir tezgah (workbench) paketi oluşturmaya hazırsınız!
Workbench Artisan Komutunun Verilmesi
1
php artisan workbench satıcıadı/paketadı --resources
Satıcıadı sizin paketinizi farklı yazarlardan gelen aynı isimli diğer
paketlerden ayırt etmenin bir yoludur. Örneğin ben (Taylor Otwell)
“Zapper” adında yeni bir paket oluşturacaksam, satıcıadı Taylor,
paketadı ise Zapper olacaktır. Ön tanımlı olarak, bu workbench
komutu framework bilinemez paketler oluşturur; ancak, resources
komutu workbench’e migrations, views, config ve bunlar gibi
Laravel’e özgü dizinleri olan paketler üretmesini söyler.
workbench komutu çalıştırıldıktan sonra sizin paketiniz Laravel
kurulumunuzun workbench dizini içerisinde hazırlanmış olacaktır.
Daha sonra, paketiniz için oluşturulmuş olan ServiceProvider‘i
kayda geçireceksiniz. Bu hizmet sağlayıcının adını app/config/app.php
dosyasındaki providers dizisine ekleyerek kayda geçirebilirsiniz.
Bu, Laravel’e uygulamanız başladığı zaman sizin paketinizi yüklemesi talimatı verecektir. Hizmet sağlayıcıları [Paket]ServiceProvider
şeklinde bir isimlendirme geleneği kullanırlar. Öyleyse, yukarıdaki
örnek için providers dizisine Taylor\Zapper\ZapperServiceProvider
ekleyeceğiz.
Sağlayıcıyı kayda geçirdikten sonra artık paketinizi geliştirmeye
başlayabilirsiniz! Bununla birlikte, bu konuya geçmeden önce, paket
194
Paket Geliştirme
yapısı ve geliştirme iş akışını daha yakından tanımak için aşağıdaki
kesimleri gözden geçirmenizde yarar var.
Not: Servis sağlayıcınız bulunamıyorsa uygulamanızın
ana dizininde php artisan dump-autoload komutunu
çalıştırınız.
Paket Yapısı
workbench komutu kullanılırken, paketiniz, paketinizin Laravel fra-
meworkün diğer kısımlarıyla iyi bütünleşmesine imkan veren geleneklerle kurulur:
Temel Paket Dizin Yapısı
1
/src
/Satici
2
/Paket
3
PaketServiceProvider.php
4
/config
/lang
/migrations
/views
5
6
7
8
9
10
/tests
/public
Bu yapıyı biraz daha açalım. Buradaki src/Satici/Paket dizini sizin paketinizin ServiceProvider de dahil olmak üzere tüm sınıflarının evidir. config, lang, migrations ve views dizinleri ise, tahmin
edebileceğiniz gibi paketinizdeki kaynakların kendilerine tekabül
edenlerini içermektedir. Paketlerde, tıpkı “normal” uygulamalarda
olduğu gibi bu kaynaklardan birileri olabilir.
195
Paket Geliştirme
Hizmet Sağlayıcıları
Hizmet sağlayıcıları paketleriniz için tamamen önceden yükleme
(bootstrap) sınıflarıdır. Ön tanımlı olarak bunlar iki metod taşırlar:
boot ve register. Bu metodların içerisinde, istediğiniz her şeyi
yapabilirsiniz: bir rota dosyası dahil etmek, IoC konteynerinde
bağlayıcı kayda geçirmek, olaylar tutturmak veya istediğiniz daha
başka bir şey.
Bunlardan register metodu, hizmet sağlayıcı kayıt edilir edilmez
çağrılır, boot komutu ise sadece bir istek rotalandırılmadan önce
çağrılır. Bu nedenle, eğer sizin hizmet sağlayıcınızdaki eylemler,
zaten kaydı yapılmış başka bir hizmet sağlayıcısına dayanıyorsa
veya başka bir sağlayıcı tarafından bağlanan hizmetleri geçersiz
bırakıyorsanız, boot metodunu kullanmalısınız.
workbench kullanarak bir paket oluşturulurken, boot komutu zaten
bir eylem içerir:
1
$this->package('satici/paket');
Bu metod Laravel’in uygulamanız için görünüm, konfigürasyon ve
diğer kaynakları nasıl düzgünce yükleyeceğini bilmesine imkan verir. Genelde, paket kurulumunu workbench gelenekleri kullanarak
yapacağı için bu kod satırını değiştirmenin bir gereği yoktur.
Ön tanımlı olarak, bir paketin kayda geçirilmesinden sonra, onun
kaynakları satici/paket‘in “paket” yarısı kullanılarak erişilebilir
olacaktır. Bununla birlikte, bu davranışı geçersiz kılıp değiştirmek
için package metoduna ikinci bir parametre geçebilirsiniz. Örneğin:
196
Paket Geliştirme
1
2
// Package metoduna özel aduzayı geçilmesi
$this->package('satici/paket', 'ozel-aduzay');
3
4
5
6
// Paket kaynaklarına artık özel aduzayı aracılıyla eri\
şilir
$view = View::make('ozel-aduzay::falan');
Servis sağlayıcı sınıfları için “varsayılan yer” söz konusu değildir.
Bunları istediğiniz yere konumlandırabilirsiniz, belki bunları app
dizini içinde Providers aduzayı ile organize edersiniz. Dosya,
Composer’ın otomatik yükleme araçları¹⁷⁷ sınıfı yükleyebilmek için
dosyanın nerede bulunduğunu bildiği sürece istediğiniz yere konumlandırılabilir.
Paketinizin kaynaklarının, örneğin yapılandırma dosyaları veya
view’lerin konumunu değiştirirseniz, package metoduna kaynaklarınızın konumunu belirten üçüncü bir parametre geçmelisiniz:
1
2
$this->package('satici/paket', null, '/kaynaklara/dosya\
/yolu');
Ertelenmiş Sağlayıcılar
Eğer yapılandırma dosyaları ve view’ler gibi hiçbir kaynağı kayda
geçirmeyen bir hizmet sağlayıcı yazıyorsanız, sağlayıcınızı “ertelenmiş (deferred)” yapmayı seçebilirsiniz. Ertelenmiş bir servis sağlayıcı sadece sağladığı hizmetlerden birisi uygulamanın IoC konteyneri tarafından gerçekten gerektiği zaman yüklenecek ve kayda
geçirilecektir. Verilen bir istek döngüsü boyunca bu sağlayıcının
servislerinden hiçbirisi gerekli olmazsa, sağlayıcı asla yüklenmeyecektir.
Servis sağlayıcınızın çalışmasını ertelemek için sağlayıcının defer
özelliğini true olarak ayarlayın:
¹⁷⁷http://getcomposer.org01-basic-usage.md#autoloading
197
Paket Geliştirme
1
protected $defer = true;
Ondan sonra da taban Illuminate\Support\ServiceProvider sınıfından gelen provides metodunu override etmeniz ve sağlayıcınızın IoC konteynerine eklediği bağlamaların tamamından oluşan
bir dizi döndürmeniz gerekiyor. Örneğin, eğer sizin sağlayıcınız
IoC konteynerine paket.hizmet ve paket.diger-hizmet kayda
geçiriyorsa, sizin provides metodu bunun gibi gözükmelidir:
1
2
3
4
public function provides()
{
return array('paket.hizmet', 'paket.diger-hizmet');
}
Paket Gelenekleri
Bir paketten gelen kaynaklar kullanılırken, örneğin yapılandırma
öğeleri veya görünümler için genelde çift iki nokta üst üste sözdizimi kullanılır:
Bir Paketteki Bir Görünümü Yükleme
1
return View::make('package::gorunum.isim');
Bir Paket Yapılandırma Öğesinin Öğrenilmesi
1
return Config::get('package::grup.secenek');
Not: Eğer paketinizde migrasyonlar varsa, başka paketlerle olası sınıf adı çatışmalarını önlemek amacıyla
migrasyon isimlerine paketinizin adını ön ek vermeyi
düşünün.
198
Paket Geliştirme
Geliştirme İş Akışı
Bir paket geliştirirken bir uygulama kapsamı içerisinde geliştiriyor
olabilmek yararlı olur ve size kolaylıkla görmek ve şablonlarınızla
denemek ve benzeri imkanlar verir. Bu nedenle, bu işe başlarken
Laravel’in yeni bir kopyasını yükleyin, sonra da paket yapınızı
oluşturmak için workbench komutunu kullanın.
workbench komutunun paketinizi oluşturmasından sonra, workbench/[satici]/[pak
dizininden git init yapabilir ve paketinizi doğrudan workbench’tan
git push yapabilirsiniz! Bu size sürekli composer update komut-
larıyla batağa saplanmaksızın bir uygulama bağlamında uygun bir
şekilde paket geliştirmenize imkan verecektir.
Sizin paketleriniz workbench dizininde olduğundan, Composer’in
sizin paketinizin dosyalarını otomatik yüklemeyi nereden bileceğini
merak ediyor olabilirsiniz. Bu workbench dizini mevcut olduğu zaman, Laravel akıllı bir şekilde paket var mı diye bu dizini tarayacak,
uygulama başladığında bunların Composer autoload dosyalarını
yükleyecektir!
Eğer paketinizin autoload dosyalarını tekrar üretmeniz gerekirse, php artisan dump-autoload komutunu kullanabilirsiniz. Bu
komut, sizin kök projenizdekiler yanında, oluşturmuş olduğunuz
workbench’lerdeki autoload dosyalarını da tekrardan üretecektir.
Artisan Autoload Komutunun Çalıştırılması
1
php artisan dump-autoload
Paket Rotaları
Laravel’in önceki sürümlerinde, bir paketin hangi URI’lere cevap
vereceğini belirtmek için handles cümleciği kullanılırdı. Ancak,
Laravel 4’te, bir paket her URI’ye cevap verebilir. Paketiniz için bir
199
Paket Geliştirme
rota dosyasını yüklemek için, hizmet sağlayıcınızın boot metodu
içerisinde onu include etmeniz yeterlidir.
Bir Hizmet Sağlayıcısından Bir Rota Dosyasının Dahil
Edilmesi
1
2
3
public function boot()
{
$this->package('satici/paket');
4
include __DIR__.'/../../routes.php';
5
6
}
Not: Şayet paketiniz denetçiler (controllers) kullanıyorsa, bunların sizin composer.json dosyanızın autoload kesiminde düzgün bir şekilde yapılandırılmış olduğundan emin olun.
Paket Yapılandırması
Paket Yapılandırma Dosyalarına Erişme
Bazı paketler yapılandırma dosyaları gerektirebilir. Bu dosyalar
tipik uygulama yapılandırma dosyalarıyla aynı şekilde tanımlanmalıdır. Ve, hizmet sağlayıcınızda kaynakları kayda geçirmede ön
tanımlı $this->package metodunu kullanıyorken, olağan “çift iki
nokta üst üste” sözdizimini kullanarak erişebilirsiniz:
1
Config::get('paket::dosya.secenek');
Tek Dosyalı Paket Yapılandırmasına Erişme
Ancak eğer paketiniz tek bir yapılandırma dosyası içeriyorsa, adına
sadece config.php diyebilirsiniz. Böyle yapmışsanız, dosya adını
belirtmenize gerek kalmadan seçeneklere doğrudan erişebilirsiniz:
Paket Geliştirme
1
200
Config::get('paket::secenek');
Bir Kaynak Aduzayının Elle Kayda Geçirilmesi
Bazen, görünümler gibi paket kaynaklarınızı tipik $this->package
metodundan başka türlü kayda geçirmek isteyebilirsiniz. Tipik olarak bu sadece kaynaklar konvansiyonel bir yerleşimde olmadıkları
takdirde yapılacaktır. Bu kaynakları elle kayda geçirmek için View,
Lang ve Config sınıflarının addNamespace metodunu kullanabilirsiniz:
1
2
View::addNamespace('paket', __DIR__.'/views/dosya/yolu'\
);
Aduzayı kayda geçirildikten sonra, kaynağa erişmek için aduzayının adını ve “çift iki nokta üst üste” söz dizimini kullanabilirsiniz:
1
return View::make('paket::view.isim');
View, Lang ve Config sınıflarında addNamespace için metod biçimi
aynıdır.
Basamaklı Yapılandırma Dosyaları
Diğer geliştiriciler sizin paketlerinizi yükledikleri zaman yapılandırma seçeneklerinden bir kısmını geçersiz kılmak ve değiştirmek
isteyebilirler. Ancak, eğer sizin paket kaynak kodunuzdaki değerleri
değiştirirlerse, Composer’in daha sonraki paket güncellemesinde
bunun üzerine yazılacaktır, tekrar sizin yazdığınız hale gelecektir.
O yüzden, bunun yerine config:publish artisan komutu kullanılmalıdır:
201
Paket Geliştirme
1
php artisan config:publish satici/paket
Bu komut çalıştırıldığında, sizin uygulamanız için olan konfigürasyon dosyaları app/config/packages/satici/paket dizinine kopyalanacak, burada geliştiriciler tarafından güvenle değiştirilebilecektir!
Not: Geliştiriciler ayrıca onları app/config/packages/satici/paket/environ
koyarak sizin paketiniz için ortama özgü yapılandırma
dosyaları da oluşturabilirler.
Paket View’leri
Eğer uygulamanızda bir paket kullanıyorsanız, kimi zaman paketin view’lerini özelleştirmek isteyebilirsiniz. Artisan view:publish
komutunu kullanarak paket view’lerini sizin kendi app/views dizininize kolaylıkla ihraç edebilirsiniz:
1
php artisan view:publish satici/paket
Bu komut paketin view’lerini app/views/packages dizinine taşıyacaktır. Şayet bu dizin önceden mevcut değilse, komutu çalıştırıldığınız zaman oluşturulacaktır. View’leri bu şekilde yayımladıktan
sonra, onlarda kendi zevkinize göre değişiklikler yapabilirsiniz!
İhraç edilen view’ler, paketin kendi view dosyalarına göre otomatik
olarak öncelik alacaktır.
Paket Migrasyonları
Workbench Paketleri İçin Migrasyon Oluşturulması
Paketleriniz için kolayca migrasyon oluşturabilir ve çalıştırabilirsiniz. workbench’de bir paket için bir migrasyon oluşturmak için
--bench seçeneğini kullanın:
202
Paket Geliştirme
1
2
php artisan migrate:make create_users_table --bench="sa\
tici/paket"
Workbench Paketleri İçin Migrasyonların
Çalıştırılması
1
php artisan migrate --bench="satici/paket"
Yüklenmiş Bir Paket İçin Migrasyonların
Çalıştırılması
vendor dizinine Composer tarafından yüklenmiş bitmiş bir paket
için migrasyonlar çalıştırmak için --package yönergesini kullana-
bilirsiniz:
1
php artisan migrate --package="satici/paket"
Paket Varlıkları
Paket Varlıklarının Public Dizinine Taşınması
Bazı paketlerde JavaScript, CSS ve resimler gibi varlıklar olabilir.
Ancak biz satici veya workbench dizinlerinde varlıklara bağlanamayız, öyleyse bu varlıkları uygulamamızın public dizinine taşıyacak bir yola ihtiyacımız var. Sizin için bununla asset:publish
komutu ilgilenecektir:
1
php artisan asset:publish
2
3
php artisan asset:publish satici/paket
Eğer paket hala workbench‘de ise, --bench yönergesini kullanın:
Paket Geliştirme
1
203
php artisan asset:publish --bench="satici/paket"
Bu komut varlıkları satıcı ve paket ismine göre public/packages
dizinine taşıyacaktır. Yani, userscape/kudos adındaki bir paket
kendi varlıklarını public/packages/userscape/kudos dizinine taşıyacaktır. Bu varlık yayımlama geleneğinin kullanılması, kendi paketlerinizin görünümlerinde varlık path’lerini güvenle kodlamanıza
imkan verir.
Paketlerin Yayımlanması
Paketiniz yayımlanmaya hazır olduğunda, paketi Packagist¹⁷⁸ ambarına yollayacaksınız. Eğer paketiniz Laravel’e özgü ise, paketinizin composer.json dosyasına bir laravel etiketi eklemeyi düşünün.
Ayrıca, geliştiriciler kendi composer.json dosyalarında sizin paketinize istek yaptıklarında stabil sürümlere bağlı olabilmeleri için
sürümlerinizi de etiketlemeniz hoş ve yardımcı olacaktır. Şayet
stabil bir sürüm hazır değilse, branch-alias Composer direktifini
kullanmayı düşünün.
Paketinizi yayımladıktan sonra, workbench tarafından oluşturulan
uygulama bağlamı içinde onu geliştirmeye devam etmekte özgürsünüz. Bu, paketinizi yayımladıktan sonra bile rahat bir şekilde
geliştirmek için muazzam bir yoldur.
Bazı kuruluşlar kendi geliştiricileri için paketlerini kendi özel ambarlarında barındırmayı tercih ediyorlar. Siz de böyle yapmayı düşünürseniz, Composer ekibi tarafından sağlanan Satis¹⁷⁹ belgelerini
inceleyin.
¹⁷⁸http://packagist.org
¹⁷⁹http://github.com/composer/satis
Posta
Yapılandırma
Laravel popüler SwiftMailer¹⁸⁰ kitaplığı üzerinden temiz ve basit bir
API sağlamaktadır. Posta yapılandırma dosyası app/config/mail.php‘dir
ve sizin SMTP host, port ve kimlik bilgilerizi değiştirmenize, bunun
yanında bu kitaplığın yolladığı tüm mesajlar için global bir from adresi ayarlamanıza imkan veren seçenekler içermektedir. İstediğiniz
herhangi bir SMTP sunucusunu kullanabilirsiniz. Posta göndermek
için şayet PHP’nin mail fonksiyonunu kullanmak istiyorsanız, yapılandırma dosyasındaki driver‘ı mail‘e değiştiriniz. Bir sendmail
sürücüsü de bulunmaktadır.
API Sürücüleri
Laravel ayrıca Mailgun ve Mandrill HTTP API’ları için sürücüler
içermektedir. Bu API’lar SMTP sunucularından çoğu kez daha basit
ve hızlıdırlar. Bu sürücülerden her ikisi de uygulamanızda Guzzle
4 HTTP kitaplığının yüklenmiş olmasını gerektirir. composer.json
dosyanıza aşağıdaki satırı eklemek suretiyle Guzzle 4’ü projenize
ekleyebilirsiniz:
1
"guzzlehttp/guzzle": "~4.0"
Mailgun Sürücüsü
Mailgun sürücüsünü kullanmak için, app/config/mail.php yapılandırma dosyanızdaki driver seçeneğini mailgun olarak ayarlayın. Sonra da, projenizde zaten mevcut değilse bir app/config/services.php
¹⁸⁰http://swiftmailer.org
205
Posta
yapılandırma dosyası oluşturun. Bu dosyanın aşağıdaki seçenekleri
taşıdığını doğrulayın:
1
2
3
4
'mailgun' => array(
'domain' => 'your-mailgun-domain',
'secret' => 'your-mailgun-key',
),
Mandrill Sürücüsü
Mandrill sürücüsünü kullanmak için, app/config/mail.php yapılandırma dosyanızdaki driver seçeneğini mandrill olarak ayarlayın. Sonra da, projenizde zaten mevcut değilse bir app/config/services.php
yapılandırma dosyası oluşturun. Bu dosyanın aşağıdaki seçenekleri
taşıdığını doğrulayın:
1
2
3
'mandrill' => array(
'secret' => 'your-mandrill-key',
),
Log Sürücüsü
app/config/mail.php yapılandırma dosyanızdaki driver seçeneği
log olarak ayarlanmışsa, bütün e-mailler log dosyalarınıza ya-
zılacak ve alıcıların hiçbirisine gerçekten gönderilmeyecektir. Bu
esas olarak hızlı, local hata ayıklama ve içerik doğrulaması için
yararlıdır.
Temel Kullanım
Bir e-posta mesajı göndermek için Mail::send metodu kullanılabilir:
206
Posta
1
2
3
4
5
Mail::send('emails.welcome', $data, function($message)
{
$message->to('falan@numune.com', 'Can Simitci')->subje\
ct('Hoş geldiniz!');
});
Burada send metoduna geçilen ilk parametre e-posta gövde metni
olarak kullanılacak görünümün (“view”in) ismidir ve ikinci parametre $data ise bu görünüme geçilecek veriyi temsil eder. Üçüncü
parametremiz e-posta mesajında çeşitli seçenekler belirlememize
imkan veren bir anonim fonksiyondur.
Not: E-posta görünümlerine mutlaka bir $message değişkeni geçilir ve bu değişken bize ataşmanların yazı
içine gömülmesi imkanı verir. Dolayısıyla sizin görünüm elemanlarınız arasında bir message değişkeni
olmaması iyi olur.
Bir HTML görünümüne ek olarak düz metin görünümü kullanmayı
da belirtebilirsiniz:
1
2
Mail::send(array('html.view', 'text.view'), $data, $cal\
lback);
Veya, html ya da text keylerini kullanmak suretiyle sadece bir tip
görünüm belirleyebilirsiniz:
1
Mail::send(array('text' => 'view'), $data, $callback);
E-posta mesajınızda bunlar yanında, karbon kopyalar veya ataşmanlar gibi başka seçenekler de belirtebilirsiniz:
207
Posta
1
2
3
Mail::send('emails.welcome', $data, function($message)
{
$message->from('bizden@numune.com', 'Laravel');
4
$message->to('falan@numune.com')->cc('filan@numune.com\
5
6
');
7
$message->attach($eklenecekDosyaVeriYolu);
8
9
});
Bir mesaja dosya eklediğinizde, bir MIME tipi ve / veya ne adla
görüneceğini de belirleyebilirsiniz:
1
2
$message->attach($eklenecekDosya, array('as' => $gorune\
cekAd, 'mime' => $mime));
Not: Bir Mail::send closure fonksiyonuna geçilen “message” olgusu, SwiftMailer’in message sınıfını genişleterek, e-posta mesajlarınızı oluşturmak için sınıf üzerinden her türlü metodu çağırabilmenize imkan verir.
Ataşmanların Yazı İçine Gömülmesi
Ataşmanların yazı içine gömülmesi tipik olarak zahmetlidir; ama
Laravel size e-postalarınıza resimler eklemek ve uygun CID elde
etmeniz için pratik bir yol sağlar.
Bir E-Posta Görünümüne Bir Resim Gömülmesi
208
Posta
1
<body>
İşte bir resim:
2
3
<img src ="<?php echo $message->embed($resimDosyaYolu);\
4
5
6
?>">
</body>
Bir E-Posta Görünümüne Ham Veri Gömülmesi
1
<body>
Burada ise ham veriden elde edilen resim görüyoruz:
2
3
<img src ="<?php echo $message->embedData($data, $name)\
4
5
6
; ?>">
</body>
Mail sınıfı tarafından e-mail görünümlerine bu $message değişke-
ninin MUTLAKA geçileceğini unutmayın.
Postaların Sıraya Sokulması
E-mail mesajlarının gönderilmesi uygulamanızın cevap zamanını
önemli ölçüde uzatabileceği için, birçok geliştirici e-posta mesajlarını arka planda gönderilmek üzere kuyruğa sokmayı tercih eder.
Laravel, dahili kuyruk API¹⁸¹‘sini kullanarak bunu kolaylaştırır. Bir
e-posta mesajını kuyruğa sokmak için tek yapmanız gereken şey,
Mail sınıfının queue metodunu kullanmaktır:
Bir Mail Mesajının Kuyruğa Sokulması
¹⁸¹/docs/queues
209
Posta
1
2
3
4
5
Mail::queue('emails.welcome', $data, function($message)
{
$message->to('falan@numune.com', 'Can Simitci')->subje\
ct('Hoş geldiniz!');
});
later metodunu kullanarak mail mesajınızın gönderilmek için
bekleyeceği saniye sayısını da belirleyebilirsiniz:
1
2
3
4
5
6
Mail::later(5, 'emails.welcome', $data, function($messa\
ge)
{
$message->to('falan@numune.com', 'Can Simitci')->subje\
ct('Hoş geldiniz!');
});
Mesajı yollamak için belirli bir kuyruk veya “tüpgeçit” belirlemek
istiyorsanız bunu queueOn ve laterOn metodlarını kullanarak gerçekleştirebilirsiniz:
1
2
3
4
5
6
Mail::queueOn('queue-name', 'emails.welcome', $data, fu\
nction($message)
{
$message->to('falan@numune.com', 'Can Simitci')->subje\
ct('Hoş geldiniz!');
});
Posta & Yerel Geliştirme
E-posta gönderen bir uygulama geliştirilirken, genelde lokal veya
geliştirme ortamında mesaj göndermenin devre dışı bırakılması
arzu edilmektedir. Bunu yapmak için, ya Mail::pretend metodunu
çağırın ya da app/config/mail.php yapılandırma dosyanızdaki
210
Posta
pretend seçeneğini true olarak ayarlayın. Mailer pretend modun-
da olduğu zaman, mesajlar alıcıya gönderilmek yerine uygulamanızın günlük dosyalarına yazılacaktır.
Taklit Posta Modunun Etkinleştirilmesi
1
Mail::pretend();
Sayfalama
Yapılandırma
Diğer frameworkler’de, sayfalama oldukça sıkıntılı olabilir. Laravel
bu işi çocuk oyuncağı gibi yapar. app/config/view.php dosyasında bir tek yapılandırma seçeneği bulunmaktadır. Bu dosyadaki
pagination seçeneği sayfalama bağlantıları (links) oluşturmak için
kullanılması gereken görünümü (view) belirtir. Varsayılan olarak,
Laravel iki görünüm içerir.
pagination::slider görünümü mevcut sayfaya dayalı olarak akıllı
bir bağlantı aralığı gösterirken, pagination::simple görünümü
sadece “önceki” ve “sonraki” butonlarını gösterecektir. Her iki
görünüm de Twitter Bootstrap ile uyumludur
Kullanım
Öğeleri sayfalamak için çeşitli yollar vardır. En basiti sorgu oluşturucusunda veya bir Eloquent modelinde paginate metodunu
kullanmaktır.
Veritabanı Sonuçlarının Sayfalandırılması
1
$uyeler = DB::table('users')->paginate(15);
Not: Şu an için, bir groupBy cümlesi kullanan pagination işlemleri Laravel tarafından verimli bir biçimde
çalıştırılamamaktadır. Eğer sayfalanmış bir sonuç kümesinde bir groupBy kullanmanız gerekiyorsa, veritabanını elle sorgulamanız ve Paginator::make kullanmanız önerilir.
Sayfalama
212
Bir Eloquent Modelinin Sayfalandırılması
Eloquent¹⁸² modellerini de sayfalandırabilirsiniz:
1
$uyeler = User::paginate(15);
2
3
$uyeler = User::where('votes', '>', 100)->paginate(15);
paginate metoduna geçilen argüman sayfa başına görüntülemek
istediğiniz öğelerin sayısıdır. Bir kez sonuçları aldıktan sonra görünümde görüntüleyebilir ve links metodunu kullanarak sayfalama
bağlantıları oluşturabilirsiniz:
1
2
3
4
5
<div class ="container">
<?php foreach ($uyeler as $uye): ?>
<?php echo $uye->isim; ?>
<?php endforeach; ?>
</div>
6
7
<?php echo $uyeler->links(); ?>
Sayfalama sistemi oluşturmak işte bu kadar! Unutmayın, mevcut
sayfa için frameworke bilgi vermedik. Laravel bunu sizin için
otomatik olarak belirleyecektir.
Sayfalama için kullanılacak özel bir view belirtmek isterseniz, links
metoduna bir view geçebilirsiniz:
1
<?php echo $uyeler->links('view.ismi'); ?>
Ayrıca aşağıdaki metodlar aracılığıyla diğer sayfalama bilgilerine
erişebilirsiniz:
¹⁸²/docs/eloquent
213
Sayfalama
•
•
•
•
•
•
•
getCurrentPage
getLastPage
getPerPage
getTotal
getFrom
getTo
count
“Basit Sayfalandırma”
Eğer sayfalandırma view’inizde sadece “Sonraki” ve “Önceki” linklerini gösteriyorsanız, daha etkin bir sorgulama gerçekleştirmek
için simplePaginate metodunu kullanma seçeneğine sahipsiniz.
Bu, view’inizde tam sayfa numaraları gösterilmesi gerekmediğinde,
büyük veri setleri için kullanışlıdır:
1
2
$uyeler = User::where('votes', '>', 100)->simplePaginat\
e(15);
Elle Bir Sayfalandırıcı Oluşturmak
Bazen bir sayfalama olgusunu kendiniz bir öğeler dizisi geçerek
oluşturmak isteyebilirsiniz. Bunu Paginator::make metodunu kullanarak yapabilirsiniz:
1
2
$sayfalandirici = Paginator::make($ogeler, $toplamOgeAd\
edi, $sayfaBasinaAdet);
Sayfalama URI’ını Özelleştirmek
setBaseUrl metodu aracılığıyla, sayfalandırıcı tarafından URI’yi de
özelleştirebilirsiniz:
Sayfalama
1
214
$uyeler = Uye::paginate();
2
3
$uyeler->setBaseUrl('ozel/url');
Yukarıdaki örnek böyle bir URL oluşturacaktır: http://ornek.com/ozel/url?page =2
Sayfalama Linklerine Ekleme Yapmak
Sayfalandırıcı üzerinde appends metodunu kullanarak sayfalama
linklerinize sorgu katarı (query string) ekleyebilirsiniz:
1
2
<?php echo $uyeler->appends(array('sira' => 'oylar'))->\
links(); ?>
Bu kod, sayfalama linkine “&sira =oylar” ekleyecek ve şöyle bir URL
üretecektir:
1
http://ornek.com/birsey?page =2&sira =oylar
Eğer sayfalandırıcının URL’sine bir “hash fragmanı” eklemek istiyorsanız, fragment metodunu kullanabilirsiniz:
1
<?php echo $uyeler->fragment('falan')->links(); ?>
Bu metod bunun gibi gözüken URL’ler üretecektir:
1
http://ornek.com/birsey?page =2#falan
215
Sayfalama
JSON’a Dönüştürme
Paginator sınıfı Illuminate\Support\Contracts\JsonableInterface
sözleşmesini implemente eder ve toJson metoduna sahiptir. Bir
Paginator olgusunu bir rotadan döndürerek de onu JSON’a çevirebilirsiniz. Bu olgunun JSON’lanmış biçimi total, current_page,
last_page, from ve to gibi bazı “meta” bilgilerini de içerecektir. Olgunun verileri JSON dizisindeki data anahtarı aracılığı ile erişebilir
olacaktır.
Özel Sunumcular
Laravelle geldiği haliyle ön tanımlı sayfalama sunumcusu Bootstrap
uyumludur; ancak siz bunu kendi seçeceğiniz bir sunumcu ile
özelleştirebilirsiniz.
Soyut Sunumcunun Genişletilmesi
Illuminate\Pagination\Presenter sınıfını genişletin ve onun so-
yut (abstract) metodlarını implemente edin. Zurb Foundation için
örnek bir sunumcu bunun gibi gözükebilir:
1
2
class ZurbPresenter extends Illuminate\Pagination\Prese\
nter {
3
4
5
6
7
8
public function getActivePageWrapper($text)
{
return '<li class ="current"><a href ="">'.$text.\
'</a></li>';
}
9
10
11
public function getDisabledTextWrapper($text)
{
216
Sayfalama
return '<li class ="unavailable">'.$text.'</li>';
12
}
13
14
15
16
17
18
19
public function getPageLinkWrapper($url, $page)
{
return '<li><a href ="'.$url.'">'.$page.'</a></l\
i>';
}
20
21
}
Özel Sunumcunun Kullanılması
Önce app/views dizininizde sizin özel sunumcunuz olarak hizmet
edecek bir view oluşturun. Ondan sonra, app/config/view.php
yapılandırma dosyasındaki pagination seçeneğini yeni view’in
adıyla değiştirin. Son olarak, özel sunumcu view’inizde aşağıdaki
kodu koyacaksınız:
1
2
3
4
<ul class ="pagination">
<?php echo with(new ZurbPresenter($paginator))->ren\
der(); ?>
</ul>
Şablonlar
Denetçi (Controller) Düzenleri
Laravel’de şablon kullanma yöntemlerinden birisi denetçi düzenleri üzerinden gerçekleştirilir. İlgili denetçideki layout özelliğinin
belirlenmesiyle, belirlemiş olduğunuz görünüm oluşturulacak ve
eylemlerden dönmüş cevap olarak kabul edilecektir.
Bir Denetçide Bir Düzen Tanımlanması
1
class UyeController extends BaseController {
2
/**
* Cevaplar için kullanılacak olan düzen.
*/
protected $layout = 'layouts.master';
3
4
5
6
7
/**
* Uye profilini göster.
*/
public function showProfil()
{
$this->layout->content = View::make('uye.profil');
}
8
9
10
11
12
13
14
15
16
}
218
Şablonlar
Blade Şablonları
Blade Laravel’le gelen basit ama güçlü bir şablon motorudur. Denetçi düzenlerinden farklı olarak, Blade şablon kalıtımı ve kesimler (sections) ile yürütülür. Tüm Blade şablonlarının uzantısı
.blade.php olmalıdır.
Bir Blade Düzeninin Tanımlanması
1
2
<!-- app/views/layouts/master.blade.php'de bulunmaktadı\
r-->
3
4
<html>
<body>
5
@section('sidebar')
This is the master sidebar.
@show
6
7
8
9
<div class ="container">
@yield('content')
</div>
10
11
12
</body>
13
14
</html>
Bir Blade Düzeninin Kullanılması
219
Şablonlar
1
@extends('layouts.master')
2
3
4
@section('sidebar')
@parent
5
<p>Burası master sidebar'a eklenmiştir.</p>
6
7
@stop
8
9
10
11
@section('content')
<p>Burası kendi content bölümümdür.</p>
@stop
Bir Blade düzenini genişleten (extend) görünümlerin, düzenden
gelen kesimleri değiştirmekten başka bir şey yapmadığını unutmayın. İlgili düzenin içeriği bir kesimde @parent direktifi kullanılarak
çocuk görünüme katılabilir, böylece bir kenar çubuğu veya altbilgi
gibi bir düzen kesimine eklemeler yapabilirsiniz.
Kimi zaman, örneğin bir kesimin tanımlanmış olup olmadığından
emin olmadığınız durumlarda, @yield direktifine ön tanımlı bir
değer geçmek isteyebilirsiniz. Bu ön tanımlı değer ikinci parametre
olarak geçilebilir.
1
@yield('section', 'Ön Tanımlı İçerik');
Diğer Blade Kontrol Yapıları
Veri Yazdırılması
1
Merhaba {{{ $isim }}}.
2
3
Şu anki UNIX zaman damgası {{{ time() }}}'dır.
Şablonlar
220
Verinin Varlığını Yokladıktan Sonra Yazdırılması
Bazen bir değişkeni echo yapmak isteyebilir ama değişkenin ayarlanmış olup olmadığından emin olmayabilirsiniz. Temel olarak
bunu yapmak istersiniz:
1
{{{ isset($isim) ? $isim : 'Default' }}}
Bununla birlikte, bir ternary cümlesi yazmak yerine, Blade size
aşağıdaki kullanışlı kısayolu kullanma imkanu verir:
1
{{{ $isim or 'Default' }}}
Küme Parantezi İle Ham Metin Görüntülemek
Küme parantezleri ile sarmalanmış bir metni görüntülemek isterseniz, küme parantezi önüne @ sembolü ilave ederek Blade davranışını
devredışı bırakabilirsiniz.
1
@{{ Bu metin Blade tarafından işleme alınmayacaktır }}
Tabii ki, kullanıcılardan gelen tüm veriler escape edilmeli ya da
arındırılmalıdır. Çıktıyı escape etmek için, üçlü küme parantezi
sözdizimini kullanabilirsiniz:
1
Merhaba {{{ $isim }}}.
Eğer verinin escape edilmesini istemiyorsanız, ikili küme parantezi
kullanabilirsiniz:
1
Merhaba, {{ $isim }}.
Not: Uygulamanızın kullanıcılarından gelen verileri
yazdıracağınız zaman çok dikkatli olun. İçerikte olabilecek HTML antitelerini escape etmek amacıyla her
zaman için üçlü küme parantezi sözdizimi kullanın.
221
Şablonlar
If Cümleleri
1
2
3
4
5
6
7
@if (count($records) === 1)
Tek kayıt var!
@elseif (count($records) > 1)
Birden çok kayıt var!
@else
Hiç kayıt yok!
@endif
8
9
10
11
@unless (Auth::check())
Giriş yapmadınız.
@endunless
Döngüler
1
2
3
@for ($i = 0; $i < 10; $i++)
Şu anki değer {{ $i }}'dir.
@endfor
4
5
6
7
@foreach ($uyeler as $uye)
<p>Bu, üye {{ $uye->id }}'dir.</p>
@endforeach
8
9
10
11
12
13
@forelse($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>Bir üye yok</p>
@endforelse
14
15
16
17
@while (true)
<p>Sonsuz döngüdeyim.</p>
@endwhile
Alt Görünümlerin Dahil Edilmesi
222
Şablonlar
1
@include('view.ismi')
Dahil edilen görünüme bir veri dizisi de geçebilirsiniz:
1
@include('view.ismi', array('birsey'=>'veri'))
Kesimlerin Üzerine Yazmak
Ön tanımlı olarak, section’lar sectionda önceden mevcut olan bir
içeriğe eklenirler. Bir section’u, öncekini geçersiz kılarak tümden
üzerine yazmak için overwrite cümlesini kullanabilirsiniz:
1
@extends('list.item.container')
2
3
4
5
@section('list.item.content')
<p>Bu {{ $item->type }} tipinde bir öğedir</p>
@overwrite
Dil Satırlarının Gösterilmesi
1
@lang('language.line')
2
3
@choice('language.line', 1);
Yorumlar
1
2
{{-- Bu yorum, gösterilen HTML içerisinde olmayacaktır \
--}}
Blade’in Genişletilmesi
Blade sizin kendi özel kontrol yapılarınızı tanımlamanıza dahi
imkan verir. Bir Blade dosyası derlendiği zaman, her bir özel genişletme, görünüm içerikleriyle çağrılarak basit manipülasyonlardan
Şablonlar
223
daha karmaşık düzenli ifadelere kadar her türlü şeyi yapmanıza izin
verir.
Blade derleyicisi sizin kendi özel direktiflerinizi inşa etmeniz için
gerekli ifadeleri üreten createMatcher ve createPlainMatcher yardımcı metodlarıyla birlikte gelir.
Bunlardan createPlainMatcher metodu bir parametre almayan
@endif ve @stop gibi direktifler için kullanılır, createMatcher ise
parametreli direktifler için kullanılır.
Aşağıdaki örnek, basitçe $var üzerinde ->format() metodunu çağıran bir @datetime($var) direktifi oluşturur:
1
2
3
Blade::extend(function($view, $compiler)
{
$pattern = $compiler->createMatcher('datetime');
4
5
6
7
return preg_replace($pattern, '$1<?php echo $2->format\
(\'m/d/Y H:i\'); ?>', $view);
});
SSH
Yapılandırma
Laravel uzak sunuculara SSH (Secure Shell) iletişimi ve komutlar
çalıştırmak için basit bir yol içerir ve uzak sunucularda çalışan
Artisan görevlerini kolayca inşa etmenize imkan verir. SSH facade’ı
uzak sunucularınıza bağlanmanız ve komutlar çalıştırmanız için
erişim noktası sağlar.
Yapılandırma dosyası app/config/remote.php konumundadır ve
uzak bağlantılarınızı yapılandırmak için gerekli tüm seçenekleri
içerir. Bu dosyadaki connections dizisi, sürücülerinizin isimlerine
göre anahtarlanmış bir listesini taşır. Bu connections dizisindeki host, username, password, key gibi erişim güven bilgilerini
(credentials) doldurduktan sonra uzak görevleri çalıştırmaya hazır
olacaksınız. Unutmayın, SSH, ya bir password ya da bir SSH key
kullanarak kimlik doğrulaması yapabilmektedir.
Not: Uzak sunucunuzda çeşitli görevleri kolayca çalıştırma ihtiyacınız mı var? Envoy görev çalıştırıcısına bir
bakın!
Temel Kullanım
Komutları Default Sunucuda Çalıştırmak
Komutlarınızı default uzak bağlantınızda çalıştırmak için SSH::run
metodunu kullanın:
225
SSH
1
2
3
4
SSH::run(array(
'cd /var/www',
'git pull origin master',
));
Komutları Belirli Bir Bağlantıda Çalıştırmak
Alternatif olarak, into metodunu kullanmak suretiyle komutları
belirli bir bağlantı üzerinde çalıştırabilirsiniz:
1
2
3
4
SSH::into('staging')->run(array(
'cd /var/www',
'git pull origin master',
));
Komut Çıktılarını Yakalamak
run metoduna bir Closure geçmek suretiyle, uzak komutlarınızın
“canlı” çıktısını yakalayabilirsiniz:
1
2
3
4
SSH::run($commands, function($line)
{
echo $line.PHP_EOL;
});
Görevler
Eğer her zaman birlikte çalışması gereken bir grup komut tanımlamanız gerekiyorsa, bir task (görev) tanımlamak için define
metodunu kullanabilirsiniz:
226
SSH
1
2
3
4
5
SSH::into('staging')->define('deploy', array(
'cd /var/www',
'git pull origin master',
'php artisan migrate',
));
Bu şekilde bir task tanımladıktan sonra, onu çalıştırmak için task
metodunu kullanabilirsiniz:
1
2
3
4
SSH::into('staging')->task('deploy', function($line)
{
echo $line.PHP_EOL;
});
SFTP Dosya İndirmeleri
SSH sınıfı get ve getString metodları kullanılarak, dosyalar indir-
mek için basit bir yol sağlar:
1
SSH::into('staging')->get($remotePath, $localPath);
2
3
4
$contents = SSH::into('staging')->getString($remotePath\
);
SFTP Dosya Göndermeleri
SSH sınıfı aynı zamanda put ve putString metodları kullanılarak
sunucuya dosyalar, hatta stringler upload etmek için de basit bir
yol içerir:
227
SSH
1
SSH::into('staging')->put($localFile, $remotePath);
2
3
SSH::into('staging')->putString($remotePath, 'Falan');
Uzak Günlüklerin İzlenmesi
Laravel sizin uzak bağlantılarınızın herhangi birindeki laravel.log
dosyalarının izlenmesi için yararlı bir komut içermektedir. Bunun
için basitçe tail Artisan komutunu kullanın ve izlemek istediğiniz
uzak bağlantının adını belirtin:
1
php artisan tail staging
2
3
php artisan tail staging --path=/path/to/log.file
Envoy Görev Çalıştırıcısı
•
•
•
•
•
•
•
Yükleme
Görevlerin Çalıştırılması
Birden Çok Sunucu
Paralel Çalıştırma
Task Makroları
Bildirimler
Envoy’in Güncellenmesi
Laravel Envoy, uzak sunucularınızda ortak görevler tanımlanması
için temiz, minimal bir sözdizimi sağlar. Blade¹⁸³ tarzı bir sözdizimi kullanarak yayımlama, Artisan komutları ve başka şeyler için
kolayca görevler inşa edebilirsiniz.
Not: Envoy, PHP versiyon 5.4 veya daha üstünü gerektirir ve sadece Mac / Linux işletim sistemlerinde çalışır.
¹⁸³/docs/templates#blade-templating
228
SSH
Yükleme
Önce, Composer global komutunu kullanarak Envoy’u yükleyin:
1
composer global require "laravel/envoy =~1.0"
Terminalinizde envoy komutunu çalıştırdığınız zaman envoy çalıştırılabilir dosyasının bulunabilmesi için PATH ayarınızda ∼/.composer/vendor/bin
dizininin yer aldığından emin olun.
Sonra da, projenizin kökünde bir Envoy.blade.php dosyası oluşturun. İşte başlayabileceğiniz bir örnek:
1
@servers(['web' => '192.168.1.1'])
2
3
4
5
@task('falan', ['on' => 'web'])
ls -la
@endtask
Görebileceğiniz gibi, dosyanın en üstünde bir @servers dizisi tanımlanır. Bu sunucuları, task (görev) deklarasyonlarınızın on seçeneğinde refere edebilirsiniz. Bu @task deklarasyonlarınızın içerisine, task çalıştırıldığı zaman sunucunuzda çalıştırılacak olan Bash
kodunu koyacaksınız.
Bir iskelet Envoy dosyasını kolayca oluşturmak için init komutu
kullanılabilir:
1
envoy init user@192.168.1.1
Görevlerin Çalıştırılması
Bir görevi çalıştırmak için Envoy yüklemenizin run komutunu
kullanın:
229
SSH
1
envoy run falan
Eğer gerekliyse, komut satırı seçeneklerini kullanarak Envoy dosyasına değişkenler geçebilirsiniz:
1
envoy run deploy --branch=master
Bu seçenekleri, kullandığınız Blade sözdizimi aracılığıyla kullanabilirsiniz:
1
@servers(['web' => '192.168.1.1'])
2
3
4
5
6
7
@task('deploy', ['on' => 'web'])
cd site
git pull origin {{ $branch }}
php artisan migrate
@endtask
Bootstrapping
Envoy dosyasının içinde değişkenler deklare etmek ve genel PHP
işi yapmak için @setup direktifini kullanabilirsiniz:
1
2
@setup
$now = new DateTime();
3
4
5
$environment = isset($env) ? $env : "testing";
@endsetup
Ayrıca bir PHP dosyası include etmek için @include kullanabilirsiniz:
230
SSH
1
@include('vendor/autoload.php');
Birden Çok Sunucu
Bir görevi birden çok sunucuda kolaylıkla çalıştırabilirsiniz. Sadece
task deklarasyonunda sunucuları listeleyin:
1
2
@servers(['web-1' => '192.168.1.1', 'web-2' => '192.168\
.1.2'])
3
4
5
6
7
8
@task('deploy', ['on' => ['web-1', 'web-2']])
cd site
git pull origin {{ $branch }}
php artisan migrate
@endtask
Ön tanımlı olarak, ilgili görev her bir sunucuda seri olarak çalıştırılacaktır. Yani, görev bir sonraki sunucuda çalışmaya başlamadan
önce, önceki çalışmasını tamamlayacaktır.
Paralel Çalıştırma
Eğer bir görevi birden çok sunucuda paralel olarak çalıştırmak istiyorsanız, yapmanız gereken tek şey task deklarasyonunuza parallel
seçeneğini eklemektir:
231
SSH
1
2
@servers(['web-1' => '192.168.1.1', 'web-2' => '192.168\
.1.2'])
3
4
5
6
7
8
9
@task('deploy', ['on' => ['web-1', 'web-2'], 'parallel'\
=> true])
cd site
git pull origin {{ $branch }}
php artisan migrate
@endtask
Task Makroları
Makrolar basit bir komut kullanarak sıralı bir biçimde çalışacak bir
görev kümesi tanımlamanıza imkan verirler. Örneğin:
1
@servers(['web' => '192.168.1.1'])
2
3
4
5
6
@macro('deploy')
falan
filan
@endmacro
7
8
9
10
@task('falan')
echo "MERHABA"
@endtask
11
12
13
14
@task('filan')
echo "DÜNYA"
@endtask
Artık bu deploy makrosu tek, basit bir komut aracılığı ile çalıştırılabilecektir:
232
SSH
1
envoy run deploy
Bildirimler
HipChat
Bir görevi çalıştırdıktan sonra, basit @hipchat direktifini kullanarak
ekibinizin HipChat odasına bir bildirim gönderebilirsiniz:
1
@servers(['web' => '192.168.1.1'])
2
3
4
5
@task('falan', ['on' => 'web'])
ls -la
@endtask
6
7
@after
8
@hipchat('token', 'room', 'Envoy')
@endafter
9
Ayrıca hipchat odasına, özel bir mesaj da belirtebilirsiniz. @setup
içinde deklare edilen veya @include ile dahil edilen her değişkenin
mesajda kullanılması mümkündür:
1
@after
2
@hipchat('token', 'room', 'Envoy', "$task ran on [$env\
ironment]")
@endafter
3
4
Bu, ekibinizi sunucu üzerinde çalıştırılan görevler hakkında haberdar tutmak için inanılmaz basit bir yoludur.
233
SSH
Slack
Slack’a¹⁸⁴ bir bildirim göndermek için aşağıdaki sözdizimi kullanılabilir:
1
@after
2
@slack('team', 'token', 'channel')
@endafter
3
Envoy’un Güncellenmesi
Envoy’u güncellemek için, tek yapacağınız self-update komutunu
çalıştırmaktır:
1
envoy self-update
Eğer Envoy yüklediğiniz yer /usr/local/bin ise, sudo kullanmanız
gerekebilir:
1
sudo envoy self-update
¹⁸⁴https://slack.com
Unit Testing
Giriş
Laravel hazırlanırken birim testler ile hazırlandı. Açıkçası, PHPUnit
ile test desteği halihazırda var ve uygulamanız için hazırlanmış
phpunit.xml dosyası da Laravel ile birlikte geliyor. PHPUnit’in
haricinde, Laravel ayrıca Symfony HttpKernel, DomCrawler ve
BrowserKit bileşenlerinden de yararlanıyor ki, kullanıcılar testler
sırasında görünümleri inceleyebilsin ve müdahale edebilsin. Bu
bileşenler ile temsili bir tarayıcıya sahip oluyorsunuz.
Örnek bir test dosyası app/tests dizininde bulunmaktadır. Yeni bir
Laravel uygulaması kurulumundan sonra, komut satırında phpunit
komutuyla testlerinizi çalıştırabilirsiniz.
Testleri Tanımlamak ve Çalıştırmak
Yeni bir test durumu oluşturmak için, app/test dizini içerisinde
yeni bir test dosyası oluşturmanız yeterli. Test sınıflarınız TestCase
sınıfını extend ediyor olmalıdır. Bu şekilde normalde PHPUnit ile
hazırladığınız test metodlarını aynı şekilde oluşturabilirsiniz.
Örnek Bir Test Sınıfı
235
Unit Testing
1
class FooTest extends TestCase {
2
public function testSomethingIsTrue()
{
$this->assertTrue(true);
}
3
4
5
6
7
8
}
Daha sonra komut satırında phpunit ile uygulamanızın tüm testlerini çalıştırabilirsiniz.
Not: Eğer kendi setUp methodunuzu tanımlarsanız,
parent::setUp kodunu çalıştırdığınızdan emin olun.
Test Ortamı
Testleri çalıştırırken, Laravel otomatik olarak ortam yapılandırmasını testing‘e alacaktır. Ayrıca, Laravel’de test ortamında önbellekleme
ve oturum için özel ayar dosyaları bulunmaktadır. İki sürücü de
bir dizi olacak şekilde ayarlanmış olup, test yaparkenki oturum ve
önbellek verilerinin kalıcı olmaması sağlanmıştır. Test ortamı için
gerektiğinde başka ayarlar yapmakta özgürsünüz.
Testlerin İçerisinden Rotaları Çağırmak
Test Dosyasından Bir Rota Çağırmak
Testleriniz içerisinde call metodu ile rahatlıkla rotaları çağırabilirsiniz:
Unit Testing
1
236
$response = $this->call('GET', 'user/profile');
2
3
4
$response = $this->call($method, $uri, $parameters, $fi\
les, $server, $content);
Daha sonra Illuminate\Http\Response nesnesini inceleyebilirsiniz:
1
2
$this->assertEquals('Hello World', $response->getConten\
t());
Test Dosyasından Bir Denetçi Çağırmak
Ayrıca bir test dosyasından denetçileri de çağırabilirsiniz:
1
2
$response = $this->action('GET', 'HomeController@index'\
);
3
4
5
$response = $this->action('GET', 'UserController@profil\
e', array('user' => 1));
getContent metodu cevap olarak değerlendirilmiş string içeriğini
döndürecektir. Eğer rotanız bir Görünüm döndürüyorsa, original
özelliği ile buna ulaşabilirsiniz:
1
$view = $response->original;
2
3
$this->assertEquals('Tuana Şeyma', $view['name']);
Bir HTTPS rotayı çağırmak için, callSecure metodunu kullanabilirsiniz.
237
Unit Testing
1
$response = $this->callSecure('GET', 'falan/filan');
Not: Testing ortamında olduğunuzda rota filtreleri devre dışı bırakılır. Bunları etkinleştirmek için testinize
Route::enableFilters() ekleyin.
DOM Böceği
Ayrıca bir rota çağırıp, bir DOM Böceği nesnesi alarak içeriği
inceleyebilirsiniz:
1
$crawler = $this->client->request('GET', '/');
2
3
$this->assertTrue($this->client->getResponse()->isOk());
4
5
6
$this->assertCount(1, $crawler->filter('h1:contains("He\
llo World!")'));
Böceği nasıl kullanacağınız hakkında detaylı bilgi için kendi dökümantasyonunu¹⁸⁵ okuyabilirsiniz.
Facade’ları Taklit Etmek
Test yaparken, sabit Laravel facadelarını taklit etmeniz gerekecektir.
Örneğin, şu denetçi aksiyonunu varsayalım:
¹⁸⁵http://symfony.commaster/components/dom_crawler.html
238
Unit Testing
1
2
3
public function getIndex()
{
Event::fire('falan', array('name' => 'Sergin Arı'));
4
return 'Herşey yolunda!';
5
6
}
Event sınıfına yapılan çağrıyı taklit edebilmek için Facade üzerinde
shouldReceive metodunu kullanabilirsiniz, bu metod bir Moc-
kery¹⁸⁶ olgusu döndürecek.
Bir Facade’ı Taklit Etmek
1
2
3
4
public function testGetIndex()
{
Event::shouldReceive('fire')->once()->with(array('name\
' => 'Sergin Arı'));
5
$this->call('GET', '/');
6
7
}
Not: Request metodunu taklit etmemelisiniz. Bunun
yerine, testlerinizi çalıştırırken istediğiniz girdileri call
metodunda belirtin.
Çatının Assert Metodları
Laravel test yapımını kolaylaştırmak için halihazırda bazı assert
metodlarıyla gelir:
Yanıtın Başarıyla Geldiği Ispatlamak
¹⁸⁶https://github.com/padraic/mockery
239
Unit Testing
1
2
3
public function testMethod()
{
$this->call('GET', '/');
4
$this->assertResponseOk();
5
6
}
Yanıt Kodlarını Ispatlamak
1
$this->assertResponseStatus(403);
Yanıtın Bir Yönlendirme Olduğunu Ispatlamak
1
$this->assertRedirectedTo('falan');
2
3
$this->assertRedirectedToRoute('route.name');
4
5
$this->assertRedirectedToAction('Controller@method');
Bir Görünümde Veri Olduğunu Ispatlamak
1
2
3
public function testMethod()
{
$this->call('GET', '/');
4
$this->assertViewHas('name');
$this->assertViewHas('age', $value);
5
6
7
}
Oturumda Bir Verinin Kayıtlı Olduğunu Ispatlamak
Unit Testing
1
2
3
240
public function testMethod()
{
$this->call('GET', '/');
4
$this->assertSessionHas('name');
$this->assertSessionHas('age', $value);
5
6
7
}
Session’da Hatalar Olup Olmadığını Ispatlama
1
2
3
public function testMethod()
{
$this->call('GET', '/');
4
5
$this->assertSessionHasErrors();
6
7
8
9
// Verilen bir anahtar için sessionda hata olup olmadı\
ğına bakmak...
$this->assertSessionHasErrors('name');
10
11
12
13
14
// Birkaç anahtar için sessionda hata olup olmadığına \
bakmak...
$this->assertSessionHasErrors(array('name', 'age'));
}
Eski Girdide Veri Olduğunu Ispatlamak
241
Unit Testing
1
2
3
public function testMethod()
{
$this->call('GET', '/');
4
$this->assertHasOldInput();
5
6
}
Yardımcı Metodlar
Test yapımını kolaylaştırmak için TestCase sınıfı bazı yardımcı
metodlarla birlikte gelir.
Test İçerisinden Oturum Tanımlamak ve Silmek
1
$this->session(['falan' => 'filan']);
2
3
$this->flushSession();
Oturum Açmış Kullanıcıyı Belirleme
Mevcut oturum açmış kullanıcıyı be metodu ile belirleyebilirsiniz.
1
$user = new User(array('name' => 'Tuana Şeyma'));
2
3
$this->be($user);
Bir test içerisinden seed metoduyla veritabanınıza yeniden veri
ekebilirsiniz:
Test İçerisinden Veritabanına Yeniden Veri Ekmek
242
Unit Testing
1
$this->seed();
2
3
$this->seed($connection);
Veri Ekmeyle ilgili daha fazla bilgiyi dökümantasyonun migrasyon
ve veri ekme¹⁸⁷ bölümünde bulabilirsiniz.
Application’ın Tazelenmesi
Belki de zaten bildiğiniz gibi, Laravel Application / IoC Konteynerinize herhangi bir test metodundan $this->app aracılığıyla erişebilirsiniz. Bu Application olgusu her test sınıfı için tazelenir. Şayet
siz Application’ı verilen bir metod için elle tazelenmeye zorlamak
istiyorsanız, test metodunuzdan refreshApplication metodunu
kullanabilirsiniz. Bu, test durumu çalıştırılmaya başlandıktan itibaren IoC konteynerine konmuş olan herhangi bir ekstra bağlamayı,
örneğin mocks (taklit)’ları resetleyecektir.
¹⁸⁷/docs/migrations#database-seeding
Yardımcı (Helper)
Fonksiyonları
Arrayler (Diziler)
array_add
array_add fonksiyonu, verilen anahtar / değer çiftini, eğer daha
önce eklenmemişse array’e eklemeye yarar.
1
$array = array('foo' => 'bar');
2
3
$array = array_add($array, 'key', 'value');
array_divide
array_divide fonksiyonu, birincisi anahtarlar, ikincisi değerler
olacak şekilde iki farklı array döndürür.
1
$array = array('foo' => 'bar');
2
3
list($keys, $values) = array_divide($array);
array_dot
array_dot fonksiyonu, çok boyutlu bir array’i derinlikleri ‘nokta
(dot)’ notasyonunu sağlayacak şekilde 1 boyutlu array’e çevirir.
Yardımcı (Helper) Fonksiyonları
1
244
$array = array('foo' => array('bar' => 'baz'));
2
3
$array = array_dot($array);
4
5
// array('foo.bar' => 'baz');
array_except
array_except fonksiyonu, verilen anahtar / değer çiftini array’den
siler.
1
2
$array = array_except($array, array('keys', 'to', 'remo\
ve'));
array_fetch
array_fetch metodu seçilen bir iç elemanı içeren düz bir dizi
döndürür.
1
2
3
4
$array = array(
array('developer' => array('name' => 'Taylor')),
array('developer' => array('name' => 'Dayle')),
);
5
6
$array = array_fetch($array, 'developer.name');
7
8
// array('Taylor', 'Dayle');
array_first
array_first fonksiyonu, verilen doğruluk testine uyan ilk array
elemanını döndürür.
245
Yardımcı (Helper) Fonksiyonları
1
$array = array(100, 200, 300);
2
3
4
5
6
$value = array_first($array, function($key, $value)
{
return $value >= 150;
});
Ayrıca varsayılan bir değer, üçüncü eleman olarak verilebilir:
1
$value = array_first($array, $callback, $default);
array_last
array_last metodu verilen doğruluk testine uyan son array elema-
nını döndürür.
1
$array = array(350, 400, 500, 300, 200, 100);
2
3
4
5
6
$value = array_last($array, function($key, $value)
{
return $value > 350;
});
7
8
// 500
Ayrıca varsayılan bir değer, üçüncü eleman olarak geçilebilir:
1
$value = array_last($array, $callback, $default);
array_flatten
array_flatten metodu çok boyutlu bir diziyi tek düzey halinde
düzleştirir.
246
Yardımcı (Helper) Fonksiyonları
1
2
$array = array('name' => 'Joe', 'languages' => array('P\
HP', 'Ruby'));
3
4
$array = array_flatten($array);
5
6
// array('Joe', 'PHP', 'Ruby');
array_forget
array_forget metodu “dot” notasyonu kullanarak, derin bir iç içe
diziden belirli bir anahtar / değer çiftini kaldıracaktır.
1
2
$array = array('names' => array('joe' => array('program\
mer')));
3
4
array_forget($array, 'names.joe');
array_get
array_get metodu nokta notasyonu kullanarak derin bir iç içe
diziden belirli bir değeri döndürür.
1
2
$array = array('names' => array('joe' => array('program\
mer')));
3
4
$value = array_get($array, 'names.joe');
Not: array_get gibi birşey ama onun yerine nesneler
mi istiyorsunuz? object_get kullanın.
array_only
array_only fonksiyonu, array’den sadece verilen anahtar / değer
çiftlerini döndürür.
247
Yardımcı (Helper) Fonksiyonları
1
2
$array = array('name' => 'Joe', 'age' => 27, 'votes' =>\
1);
3
4
$array = array_only($array, array('name', 'votes'));
array_pluck
array_pluck metodu verilen bir anahtar / değer çiftleri listesini
diziden koparacaktır.
1
2
$array = array(array('name' => 'Taylor'), array('name' \
=> 'Dayle'));
3
4
$array = array_pluck($array, 'name');
5
6
// array('Taylor', 'Dayle');
array_pull
array_pull metodu diziden belirli bir anahtar / değer çifti döndü-
recek, aynı zamanda bu çifti diziden çıkartacaktır.
1
$array = array('name' => 'Taylor', 'age' => 27);
2
3
$name = array_pull($array, 'name');
array_set
array_set metodu nokta notasyonu kullanarak, derin bir iç içe
dizide bir değer ayarlar.
Yardımcı (Helper) Fonksiyonları
1
248
$array = array('names' => array('programmer' => 'Joe'));
2
3
array_set($array, 'names.editor', 'Taylor');
array_sort
array_sort metodu bir diziyi verilen bir Closure sonuçlarına göre
sıralar.
1
2
3
4
$array = array(
array('name' => 'Jill'),
array('name' => 'Barry'),
);
5
6
7
8
9
10
$array = array_values(array_sort($array, function($valu\
e)
{
return $value['name'];
}));
array_where
Bir diziyi verilen Closure kullanarak filtreler.
1
$array = array(100, '200', 300, '400', 500);
2
3
4
5
6
$array = array_where($array, function($key, $value)
{
return is_string($value);
});
7
8
// Array ( [1] => 200 [3] => 400 )
249
Yardımcı (Helper) Fonksiyonları
head
Dizideki ilk elemanı döndürür. PHP 5.3.x’deki metod zincirleme
işine yarar.
1
$first = head($this->returnsArray('foo'));
last
Dizideki son elemanı döndürür. Metod zincirlemesinde işe yarar.
1
$last = last($this->returnsArray('foo'));
Dosya Yolları
app_path
app dizininin tam dosya yolunu getirir.
1
$path = app_path();
base_path
Uygulamanın ana dizininin tam dosya yolunu getirir.
public_path
public dizininin tam dosya yolunu getirir.
storage_path
app/storage dizininin tam dosya yolunu getirir.
250
Yardımcı (Helper) Fonksiyonları
Yazı İşlemleri
camel_case
Yazıyı camelCase olacak şekilde düzenler.
1
$camel = camsel_case('foo_bar');
2
3
// fooBar
class_basename
Verilen class’ın namespace’ler olmadan sadece adını dondürür.
1
$class = class_basename('Foo\Bar\Baz');
2
3
// Baz
e
Verilen yazıya UTF-8 desteğiyle htmlentities fonksiyonunu uygular.
1
$entities = e('<html>foo</html>');
ends_with
Bir stringin verilen değerle bitip bitmediğini tespit eder.
1
$value = ends_with('This is my name', 'name');
snake_case
Yazıyı snake_case olacak şekilde düzenler.
251
Yardımcı (Helper) Fonksiyonları
1
$snake = snake_case('fooBar');
2
3
// foo_bar
str_limit
Bir stringin karakter sayısını sınırlar.
1
str_limit($value, $limit = 100, $end = '...')
Örnek:
1
2
$value = str_limit('The PHP framework for web artisans.\
', 7);
3
4
// The PHP...
starts_with
Bir stringin verilen değerle başlayıp başlamadığını tespit eder.
1
$value = starts_with('This is my name', 'This');
str_contains
Verilen yazının içinde verilen değerin olup olmadığına karar verir.
1
$value = str_contains('This is my name', 'my');
str_finish
Verilen yazının sonuna verilen değeri ekler. Verilen değerden oluşan
ekstraları yok eder.
252
Yardımcı (Helper) Fonksiyonları
1
$string = str_finish('this/string', '/');
2
3
// this/string/
str_is
Verilen yazıyla verilen değerin eşleşip eşleşmediğine karar verir.
Yıldız işareti (*) genel arama karakteri olarak kullanılabilir.
1
$value = str_is('foo*', 'foobar');
str_plural
Verilen kelimeyi çoğul hale getirir (Sadece ingilizce için geçerli).
1
$plural = str_plural('car');
str_random
Verilen değer kadar uzunlukta rastgele karakterlerden oluşan bir
yazı üretir.
1
$string = str_random(40);
str_singular
Verilen kelimeyi tekil hale getirir (Sadece ingilizce için geçerli).
1
$singular = str_singular('cars');
studly_case
Verilen yazıyı StudlyCase olacak şekilde düzenler.
253
Yardımcı (Helper) Fonksiyonları
1
$value = studly_case('foo_bar');
2
3
// FooBar
trans
Verilen dil satırını çevirir. Lang::get fonksiyonunun kısayolu.
1
$value = trans('validation.required'):
trans_choice
Verilen dil satırını çekimli çevirir. Lang::choice fonksiyonunun
kısayolu.
1
$value = trans_choice('foo.bar', $count);
URL İşlemleri
action
Belirli bir denetçi eylemi için bir URL üretir.
1
$url = action('HomeController@getIndex', $params);
route
Verilen isimli rota için URL oluştur.
1
$url = route('routeName', $params);
asset
Bir varlık için bir URL üretir.
254
Yardımcı (Helper) Fonksiyonları
1
$url = asset('img/photo.jpg');
link_to
Verilen URL’e gerekli HTML linkini oluşturur.
1
2
echo link_to('foo/bar', $title, $attributes = array(), \
$secure = null);
link_to_asset
Verilen varlık için bir HTML bağlantısı üretir.
1
2
echo link_to_asset('foo/bar.zip', $title, $attributes =\
array(), $secure = null);
link_to_route
Verilen rota için gerekli HTML linkini oluşturur.
1
2
echo link_to_route('route.name', $title, $parameters = \
array(), $attributes = array());
link_to_action
Verilen bir denetçi eylemi için bir HTML linki oluşturur.
1
2
echo link_to_action('HomeController@getIndex', $title, \
$parameters = array(), $attributes = array());
secure_asset
Verilen eleman için gerekli HTML linkini HTTPS kullanarak oluşturur.
255
Yardımcı (Helper) Fonksiyonları
1
2
echo secure_asset('foo/bar.zip', $title, $attributes = \
array());
secure_url
Verilen URL’e gerekli HTML linkini HTTPS kullanarak oluşturur.
1
echo secure_url('foo/bar', $parameters = array());
url
Verilen bir dosya yolu için tam kalifiye bir URL üretir.
1
2
echo url('foo/bar', $parameters = array(), $secure = nu\
ll);
Diğer
csrf_token
CSRF token’inin güncel değerini döndürür.
1
$token = csrf_token();
dd
Verilen veriyi ekrana basar ve uygulamayı durdurur.
1
dd($value);
256
Yardımcı (Helper) Fonksiyonları
value
Eğer verilen değer anonim bir fonksiyonsa, değer olarak anonim
fonksiyonun döndürdüğü değeri döndürür. Eğer değilse direkt değeri döndürür.
1
$value = value(function() { return 'bar'; });
with
Verilen nesneyi döndürür. PHP 5.3.x kullanımında metod zincirleme işlemi için çok yararlı.
1
$value = with(new Foo)->doWork();
Yerelleştirme
Giriş
Laravel’in Lang sınıfı farklı dillerdeki yazılara ulaşabileceğiniz bir
hizmet verir, bu sayede uygulamanızda rahatlıkla çoklu dil desteği
verebilirsiniz.
Dil Dosyaları
Diller için kayıtlar app/lang dizininin içerisindeki dosyalarda tutulur. Bu dizin içerisinde desteklenen her dil için bir klasör oluşturulmalıdır.
1
2
3
/app
/lang
/en
mesajlar.php
4
5
6
/tr
mesajlar.php
Örnek Dil Dosyası
Dil dosyaları basitçe anahtarlı bir şekilde kayıtları barındıran bir
dizi döndürür. Örneğin:
258
Yerelleştirme
1
<?php
2
3
4
5
return array(
'hosgeldiniz' => 'Uygulamamıza hoş geldiniz!'
);
Varsayılan Dili Çalışma Esnasında Değiştirmek
Uygulamanız için varsayılan dil app/config/app.php ayar dosyasında tutulmaktadır. Bunun dışında, aktif dili App::setLocale
metoduyla çalışma esnasında da değiştirebilirsiniz.
1
App::setLocale('tr');
Yedek Dil Ayarı
Etkin dil verilen bir dil satırını içermediğinde kullanılacak olan bir
“yedek dil” de yapılandırabilirsiniz. Varsayılan dile benzer şekilde,
yedek dil de app/config/app.php yapılandırma dosyasında yapılandırılır:
1
'fallback_locale' => 'en',
Temel Kullanım
Bir Dil Dosyasından Satırları Almak
1
echo Lang::get('mesajlar.hosgeldin');
get metoduna verilen parametrenin ilk kısmı dil dosyasının adını,
ikinci kısım ise alınmak istenen satırın anahtarını içerir.
Not: Eğer istenen dil satırı bulunmuyorsa, get metodu
anahtarı döndürecektir.
259
Yerelleştirme
Lang::get() ile aynı parametreleri kullanan ve bunun kısaltması
olan trans() yardımcı metodunu kullanabilirsiniz:
1
echo trans('mesajlar.hosgeldin');
Satırlarda Değişiklik Yapmak
Ayrıca dil satırlarınızda yer tutucular tanımlayabilirsiniz:
1
'hosgeldin' => 'Hoşgeldin, :isim',
Daha sonra, Lang::get metoduna ikinci bir parametreyle yapılacak
değişiklikleri belirtin:
1
2
echo Lang::get('mesajlar.hosgeldin', array('isim' => 'E\
krem'));
Bir Dil Dosyasının İstenen Satıra Sahip Olup
Olmadığını Kontrol Etmek
1
2
3
4
if (Lang::has('mesajlar.hosgeldin'))
{
//
}
Çoğullaştırma
Çoğullaştırma karmaşık bir problemdir, çünkü her dilin farklı ve
karmaşık çoğullaştırma kuralları vardır. Dil dosyalarınızda bunu
kolaylıkla yönetebilirsiniz. dik çubuk karakteri ile, bir çevirinin
tekil ve çoğul hallerini birbirinden ayırabilirsiniz:
Yerelleştirme
1
260
'elmalar' => 'Bir elma var|Bir sürü elma var',
Daha sonra Lang::choise metoduyla satırı alabilirsiniz:
1
echo Lang::choice('mesajlar.elmalar', 10);
Ayrıca dili belirtmek için bir locale parametresi de verebilirsiniz.
Örneğin, eğer Rusca (ru) dili kullanmak istiyorsanız:
1
2
echo Lang::choice('товар|товара|товаров', $count, array\
(), 'ru');
Laravel’in tercümecisi gücünü Symfony’nin tercüme bileşeninden
aldığı için, daha belirgin çoğullaştırma kuralları da belirleyebilirsiniz:
1
2
'elmalar' => '{0} Hiç elma yok|[1,19] Bir kaç elma var|\
[20,Inf] Çok fazla elma var',
Geçerlilik Denetimi Yerelleştirmesi
Geçerlilik Denetimi hatalarının ve mesajlarının yerelleştirmesi için
dokümantasyonun Geçerlilik Denetimi¹⁸⁸ bölümüne bakınız.
Paket Dil Dosyalarının Ezilmesi
Birçok paket kendi dil satırlarıyla gelir. Bu satırları değiştirmek için
paketin çekirdek dosyalarıyla oynamak yerine, app/lang/packages/{locale}/{pack
dizinine dosyalar koymak suretiyle onları ezebilirsiniz. Dolayısıyla, örneğin, eğer skyrim/hearthfire adındaki bir paket için
¹⁸⁸validation#localization
Yerelleştirme
261
messages.php‘yi Türkçe dil satırlarıyla ezmeniz gerekiyorsa koyacağınız dil dosyası şudur: app/lang/packages/tr/hearthfire/messages.php.
Bu dosyada sadece ezmek istediğiniz dil satırlarını tanımlayacaksınız. Ezmediğiniz dil satırları paketin dil dosyalarından yüklenmeye
devam edecektir.
Temel Veritabanı Kullanımı
Yapılandırma
Laravel, veritabanı bağlantısını ve sorguları çalıştırmayı fazlasıyla
kolay kılar. Veritabanı yapılandırma ayarları app/config/database.php
dosyasında bulunmaktadır. Bu dosyada hem tüm veritabanı bağlantılarını tanımlayabilir, hem de hangi bağlantının varsayılan olarak
kullanılacağını seçebilirsiniz. Bu dosyada, desteklenen veritabanı
sistemlerinin tümü için örnekler verilmiştir.
Laravel tarafından desteklenen veritabanı sistemleri: MySQL, Postgres, SQLite, ve SQL Server.
Okuma / Yazma Bağlantıları
Bazen SELECT sorguları için bir bağlantı ve diğer sorgular için başka bir bağlantı kullanmak isteyebilirsiniz. Laravel bunu inanılmaz
bir şekilde kolaylaştırır ve ister düz sorgu, ister sorgu oluşturucu
(query builder) veya ister Eloquent ORM kullansanız bile hepsi için
doğru bağlantıyı kullanır.
Okuma / yazma bağlantılarının nasıl yapılandırıldığını görmek için
bu örneği inceleyebilirsiniz:
Temel Veritabanı Kullanımı
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
263
'mysql' => array(
'read' => array(
'host' => '192.168.1.1',
),
'write' => array(
'host' => '196.168.1.2'
),
'driver'
=> 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset'
=> 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix'
=> '',
),
Yapılandırma dizisine eklenen iki anahtara dikkat edin: read ve
write. İkisi de sadece host anahtarını barındıran bir dizi. read
ve write bağlantılarının geri kalan tüm veritabanı seçenekleri ise
ana mysql dizisinden alınıp birleştirilecektir. Yani read ve write
dizilerine sadece ana dizideki değerlerden değiştirmek istediğimiz
kalemleri girmemiz gereklidir. Bu durumda read bağlantısı olarak
192.168.1.1 kullanılırken, write bağlantısı olarak 192.168.1.2
kullanılacaktır. Ana mysql dizisindeki username, password, prefix,
character set ve diğer tüm seçenekler her iki bağlantı için paylaşılacaktır.
Sorguları Çalıştırma
Veritabanı bağlantılarını bir kere yapılandırdıktan sonra DB sınıfını
kullanarak sorguları çalıştırabilirsiniz.
Kayıt Çekme (Select)
Temel Veritabanı Kullanımı
1
2
264
$sonuclar = DB::select('select * from uyeler where id =\
?', array(1));
select metodu sonuçları her zaman dizi tipinde döndürür.
Yeni Kayıt Ekleme (Insert)
1
2
DB::insert('insert into uyeler (id, isim) values (?, ?)\
', array(1, 'Emre'));
Kayıt Güncelleme (Update)
1
2
DB::update('update uyeler set oy = 100 where isim = ?',\
array('Hakan'));
Kayıt Silme (Delete)
1
DB::delete('delete from uyeler');
Not: update ve delete sorguları, bu işlemlerden etkilenen satır sayısını döndürür.
Genel Bir Sorgu Çalıştırma
1
DB::statement('drop table uyeler');
Sorgu Olaylarını Dinleme
DB::listen metodunu kullanarak sorgu olaylarını dinleyebilirsiniz:
Temel Veritabanı Kullanımı
1
2
3
4
265
DB::listen(function($sql, $bindings, $time)
{
//
});
Veritabanı İşlemleri
Bir veritabanı işleminde, birden fazla işlemi birden gerçekleştirmek
için, ‘transaction’ metodunu kullanabilirsiniz:
1
2
3
DB::transaction(function()
{
DB::table('uyeler')->update(array('votes' => 1));
4
DB::table('posts')->delete();
5
6
});
Not: transaction metoduna girilen anonim fonksiyonunda oluşan herhangi bir istisna, transaction işleminin otomatik olarak geri sarılmasına (rollback edilmesine) sebep olur.
Transaction’ı elle başlatmanız gerekirse:
1
DB::beginTransaction();
Transaction’ı geri sarmanız gerekirse:
1
DB::rollback();
Transaction’ı tamamlamak için:
Temel Veritabanı Kullanımı
1
266
DB::commit();
Bağlantılara Erişme
Birden fazla bağlantı kullandığınız durumlarda, bu bağlantılara
DB::connection metodu aracılığı ile ulaşabilirsiniz.
1
$uyeler = DB::connection('foo')->select(...);
Ayrıca temel PDO örneğine de ulaşabilirsiniz:
1
$pdo = DB::connection()->getPdo();
Bazen veritabanına tekrar bağlanmaya ihtiyacınız olabilir.
1
DB::reconnect('foo');
Veritabanıyla, PDO nesnesinin max_connections limiti aşıldığı için
bağlantıyı koparmanız gerekirse disconnect metodunu kullanabilirsiniz:
1
DB::disconnect('foo');
Sorgu Günlükleme
Varsayılan olarak, Laravel güncel istek için çalıştırılabilecek tüm
sorgular için bellekte bir günlük tutar. Bununla birlikte, bu bazı
durumlarda, örneğin çok sayıda satır eklerken, uygulamanın aşırı
bellek kullanmasına neden olabilir. Günlüğü devre dışı bırakmak
için disableQueryLog metodunu kullanabilirsiniz.
Temel Veritabanı Kullanımı
1
267
DB::connection()->disableQueryLog();
Çalıştırılan sorguların listesini bir dizi olarak almak için getQueryLog
metodunu kullanabilirsiniz:
1
$queries = DB::getQueryLog();
Sorgu Oluşturucusu
Giriş
Veritabanı sorgu oluşturucusu veritabanı sorguları oluşturulması ve
çalıştırılması için kullanışlı ve akıcı bir arayüz sağlar. Uygulamanızdaki pek çok veritabanı işlemini bununla gerçekleştirebilirsiniz ve
desteklenen tüm veritabanı sistemlerinde çalışmaktadır.
Not: Laravel sorgu oluşturucusu, uygulamanızı SQL
enjeksiyon saldırılarına karşı korumak için PDO parametre bağlayıcı kullanmaktadır. Bağlayıcı olarak geçirilen yazıların temizlenmesine gerek yoktur. Temizlenmeyen yalnızca iki metod vardır, bunlar groupBy ve
orderBy‘dır. Kullanıcı girdilerini bu metodlara doğrudan geçmemelisiniz.
Seçmeler
Bir Tablonun Bütün Satırlarının Alınması
1
$uyeler = DB::table('uyeler')->get();
2
3
4
5
6
foreach (uyeler as $uye)
{
var_dump($uye->isim);
}
Bir Tablonun Tek Bir Satırının Alınması
Sorgu Oluşturucusu
1
2
269
$uye = DB::table('uyeler')->where('isim', 'Can')->first\
();
3
4
var_dump($uye->isim);
Bir Satırın Tek Bir Sütununun Alınması
1
2
$isim = DB::table('uyeler')->where('isim', 'Can')->pluc\
k('isim');
Sütun Değerlerinden Oluşan Bir Liste Elde Edilmesi
1
$roller = DB::table('roller')->lists('unvan');
Bu metod rol ünvanlarından oluşan bir dizi döndürecektir. Döndürülen dizi için özel bir anahtar sütun da belirleyebilirsiniz:
1
$roller = DB::table('roller')->lists('unvan', 'isim');
Bir Select Bendinin Belirlenmesi
1
2
$uyeler = DB::table('uyeler')->select('isim', 'email')-\
>get();
3
4
$uyeler = DB::table('uyeler')->distinct()->get();
5
6
7
$uyeler = DB::table('uyeler')->select('isim as uye_adi'\
)->get();
Mevcut Bir Sorguya Bir Select Bendinin Eklenmesi
270
Sorgu Oluşturucusu
1
$sorgu = DB::table('uyeler')->select('isim');
2
3
$uyeler = $query->addSelect('yas')->get();
Where Kullanımı
1
2
$uyeler = DB::table('uyeler')->where('puan', '>', 100)-\
>get();
Or Cümleleri
1
2
3
4
$uyeler = DB::table('uyeler')
->where('puan', '>', 100)
->orWhere('isim', 'Can')
->get();
Where Between Kullanımı
1
2
3
$uyeler = DB::table('uyeler')
->whereBetween('puan', array(1, 100\
))->get();
Where Not Between Kullanımı
1
2
3
$users = DB::table('users')
->whereNotBetween('puan', array(1, \
100))->get();
Bir Dizi Aracılığıyla Where In Kullanımı
271
Sorgu Oluşturucusu
1
2
3
$uyeler = DB::table('uyeler')
->whereIn('id', array(1, 2, 3))->ge\
t();
4
5
6
7
$uyeler = DB::table('uyeler')
->whereNotIn('id', array(1, 2, 3))-\
>get();
Değer Girilmemiş Kayıtları Bulmak için Where Null
Kullanımı
1
2
3
$uyeler = DB::table('uyeler')
->whereNull('guncelleme_vakti')->ge\
t();
Order By, Group By ve Having
1
2
3
4
5
$uyeler = DB::table('uyeler')
->orderBy('name', 'desc')
->groupBy('count')
->having('count', '>', 100)
->get();
Offset ve Limit
1
$uyeler = DB::table('uyeler')->skip(10)->take(5)->get();
Joinler
Sorgu oluşturucusu join cümleleri yazmak için de kullanılabilir. Şu
örneklere bir bakın:
Temel Join Cümleleri
272
Sorgu Oluşturucusu
1
2
3
4
5
6
7
8
DB::table('uyeler')
->join('kisiler', 'uyeler.id', '=', 'kisile\
r.uye_id')
->join('siparisler', 'uyeler.id', '=', 'sip\
arisler.uye_id')
->select('uyeler.id', 'kisiler.telefon', 's\
iparisler.fiyat')
->get();
Left Join Cümlesi
1
2
3
4
DB::table('uyeler')
->leftJoin('makaleler', 'uyeler.id', '=', 'makalel\
er.uye_id')
->get();
Daha ileri join cümleleri de tanımlayabilirsiniz:
1
2
3
4
5
6
7
DB::table('uyeler')
->join('kisiler', function($join)
{
$join->on('uyeler.id', '=', 'kisiler.uye_id')-\
>orOn(...);
})
->get();
Şayet joinlerinizde “where” biçiminde bir cümlecik kullanmak isterseniz, bir join üzerinde where ve orWhere metodlarını kullanabilirsiniz. Bu metodlar iki sütunu karşılaştırmak yerine, sütunu bir
değer açısından karşılaştıracaktır:
273
Sorgu Oluşturucusu
1
2
3
4
5
6
7
DB::table('uyeler')
->join('kisiler', function($join)
{
$join->on('uyeler.id', '=', 'kisiler.uye_id')
->where('kisiler.uye_id', '>', 5);
})
->get();
İleri Where Cümleleri
Parametre Gruplaması
Kimi zaman “where exists” veya içi içe parametre gruplaması gibi
daha ileri where cümleleri oluşturmanız gerekebilir. Laravel sorgu
oluşturucusu bunu da halledecektir:
1
2
3
4
5
6
7
8
DB::table('uyeler')
->where('isim', '=', 'Can')
->orWhere(function($query)
{
$query->where('puan', '>', 100)
->where('unvan', '<>', 'Müdür');
})
->get();
Yukardaki sorgu aşağıdaki SQL cümlesini oluşturacaktır:
1
2
select * from uyeler where isim = 'Can' or (puan > 100 \
and unvan <> 'Müdür')
Exists Cümleleri
Sorgu Oluşturucusu
1
2
3
4
5
6
7
8
9
274
DB::table('uyeler')
->whereExists(function($query)
{
$query->select(DB::raw(1))
->from('siparisler')
->whereRaw('siparisler.uye_id = uyel\
er.id');
})
->get();
Yukardaki sorgu aşağıdaki SQL cümlesini oluşturacaktır:
1
2
3
4
5
select * from uyeler
where exists (
select 1 from siparisler where siparisler.uye_id = uye\
ler.id
)
Kümeleme (Aggregate) İşlemleri
Sorgu oluşturucusu count, max, min, avg ve sum gibi çeşitli kümeleme metodları da sağlamaktadır.
Aggregate Metodlarının Kullanımı
275
Sorgu Oluşturucusu
1
$uyeler = DB::table('uyeler')->count();
2
3
$fiyat = DB::table('siparisler')->max('fiyat');
4
5
$fiyat = DB::table('siparisler')->min('fiyat');
6
7
$fiyat = DB::table('siparisler')->avg('fiyat');
8
9
$toplam = DB::table('uyeler')->sum('puan');
Ham İfadeler
Bazen bir sorguda ham ifade kullanma ihtiyacı duyabilirsiniz. Bu
ifadeler sorguya doğrudan yazı olarak enjekte edileceğinden, bir
SQL enjeksiyon noktası oluşturmamaya özen gösteriniz. Ham ifade
oluşturmak için DB::raw metodunu kullanabilirsiniz:
Ham İfade Kullanımı
1
2
3
4
5
$uyeler = DB::table('uyeler')
->select(DB::raw('count(*) as uye_adedi, durum'))
->where('durum', '<>', 1)
->groupBy('durum')
->get();
Bir Sütun Değerinin Artırılması veya Azaltılması
276
Sorgu Oluşturucusu
1
DB::table('uyeler')->increment('puan');
2
3
DB::table('uyeler')->increment('puan', 5);
4
5
DB::table('uyeler')->decrement('puan');
6
7
DB::table('uyeler')->decrement('puan', 5);
Ayrıca, güncellenecek ek sütunlar belirtebilirsiniz:
1
2
DB::table('uyeler')->increment('puan', 1, array('isim' \
=> 'Tuana Şeyma'));
Eklemeler
Bir Tabloya Kayıt Eklenmesi
1
2
3
DB::table('uyeler')->insert(
array('email' => 'can@numune.com', 'puan' => 0)
);
Otomatik Artan Bir Id Alanı Olan Tabloya Kayıt
Eklenmesi
Şayet tabloda otomatik artan bir id alanı varsa, bir kayıt eklemek
ve oluşan otomatik id’i öğrenmek için insertGetId metodu kullanılabilir:
1
2
3
$id = DB::table('uyeler')->insertGetId(
array('email' => 'can@numune.com', 'puan' => 0)
);
Not: PostgreSQL ile kullanıldığı zaman insertGetId
metodu, otomatik artan alanın adının da “id” olmasını
bekler.
277
Sorgu Oluşturucusu
Bir Tabloya Birden Çok Kayıt Eklenmesi
1
2
3
4
DB::table('uyeler')->insert(array(
array('email' => 'sinan@numune.com', 'puan' => 0),
array('email' => 'ozan@numune.com', 'puan' => 0),
));
Güncellemeler
Bir Tablodaki Kayıtların Güncellenmesi
1
2
3
DB::table('uyeler')
->where('id', 1)
->update(array('puan' => 1));
Silmeler
Bir Tablodaki Kayıtların Silinmesi
1
DB::table('uyeler')->where('puan', '<', 100)->delete();
Bir Tablodaki Tüm Kayıtların Silinmesi
1
DB::table('uyeler')->delete();
Bir Tablonun Budanması
1
DB::table('uyeler')->truncate();
Birleştirmeler
Sorgu oluşturucusu, iki ayrı sorgunun tek bir “birlik” haline getirilmesi için de hızlı bir yol sağlamaktadır:
278
Sorgu Oluşturucusu
1
$ilksorgu = DB::table('uyeler')->whereNull('ismi');
2
3
4
$uyeler = DB::table('uyeler')->whereNull('soy_ismi')->u\
nion($ilksorgu)->get();
Ayrıca unionAll metodu da mevcut olup, aynı union gibi kullanılır.
Pesimistik Kilitleme
Sorgu oluşturucusu SELECT cümleleriniz üzerinde “pesimistik kilitleme” yapmanıza yardımcı olacak birkaç fonksiyon içermektedir.
Bir SELECT cümlesini bir “shared lock (paylaşılan kilit)” ile çalıştırmak için bir sorgu üzerinde sharedLock metodunu kullanabilirsiniz:
1
2
DB::table('uyeler')->where('puan', '>', 100)->sharedLoc\
k()->get();
Bir SELECT cümlesinde “güncelleme için kilitlemek” için bir sorgu
üzerinde lockForUpdate metodunu kullanabilirsiniz:
1
2
DB::table('uyeler')->where('puan', '>', 100)->lockForUp\
date()->get();
Sorguların Bellekte Saklanması
Bir sorgunun sonuçları remember metodu kullanılarak bellekte saklanabilir:
1
$uyeler = DB::table('uyeler')->remember(10)->get();
Sorgu Oluşturucusu
279
Bu örnekte, sorgunun sonuçları on dakika süreyle bellekte saklanacaktır. Sonuçlar bellekte tutulduğu süre boyunca bu sorgu artık
veritabanında çalıştırılmayacak, onun yerine sonuçlar uygulamanız
için belirlediğiniz ön tanımlı bellekleme sürücüsü tarafından yüklenecektir.
Eğer cache taglarını destekleyen bir cache sürücüsü¹⁸⁹ kullanıyorsanız, önbelleğe taglar da ekleyebilirsiniz:
1
2
$uyeler = DB::table('uyeler')->cacheTags(array('insanla\
r', 'yazarlar'))->remember(10)->get();
¹⁸⁹/docs/cache#cache-tags
Eloquent ORM
Giriş
Laravel ile gelen Eloquent ORM, veritabanınızla çalışırken kullanacağınız güzel ve sade bir ActiveRecord uygulaması sağlamaktadır.
Her veritabanı tablosu, bu tabloyla etkileşim için kullanılacak kendine has bir “Model” sahibidir.
Başlamadan önce, app/config/database.php‘de bir veritabanı bağlantısı yapılandırmış olduğunuzdan emin olun.
Temel Kullanım
Öncelikle bir Eloquent modeli oluşturunuz. Modeller tipik olarak
app/models klasöründe yer alır, fakat siz modellerinizi composer.json
dosyanıza göre otomatik yükleme yapabileceğiniz başka bir yere de
koyabilirsiniz.
Bir Eloquent Modelinin Tanımlanması
1
class Uye extends Eloquent {}
Dikkat ederseniz Eloquent’e Uye modelimiz için hangi tabloyu
kullanacağımızı söylemedik. Eğer açıkça başka bir isim belirtilmezse tablo isimi olarak sınıf adının ingilizde çoğulunun küçük
harf hali kullanılacaktır. Dolayısıyla bizim örneğimizde Eloquent,
Uye modelinin uyes tablosundaki kayıtları tutacağını varsayacaktır.
Tablo ismini açıkça belirtmek için modelinizde bir table özelliği
tanımlayınız:
281
Eloquent ORM
1
class Uye extends Eloquent {
2
protected $table = 'uyeler';
3
4
5
}
Not: Eloquent’in başka bir ön kabulü de her tablonun
id adında bir primer key sütunu olduğudur. Bu kuralı
aşmak için de bir primaryKey özelliği tanımlamanız
gerekecek. Benzer şekilde, modeliniz kullanılacağı zaman kullanılacak veritabanı bağlantısının adını değiştirmek için bir connection özelliği tanımlayabilirsiniz.
Bir model tanımladıktan sonra artık tablonuzda kayıt oluşturmaya
ve ondan kayıt getirmeye başlayabilirsiniz. Tablolarınıza ön tanımlı
olarak updated_at ve created_at sütunları koymanız gerektiğine
dikkat ediniz. Şayet bu sütunların otomatik olarak tutulmasını
istemiyorsanız, modelinizdeki $timestamps özelliğini false olarak
ayarlayınız.
Tüm Modellerin Alınması
1
$uyeler = Uye::all();
Birincil Anahtara Göre Bir Kaydın Alınması
1
$uye = Uye::find(1);
2
3
var_dump($uye->isim);
Not: Sorgu Oluşturucusu¹⁹⁰‘nda bulunan tüm metodlar
Eloquent modellerini sorgularken de kullanılabilir.
¹⁹⁰/docs/queries
282
Eloquent ORM
Birincil Anahtara Göre Bir Model Alınması ya da
Ortaya Bir İstisna Çıkartılması
Bazı durumlarda bir model bulunamadığında bir istisna çıkartmak,
böylece bir App::error işleyicisi kullanarak istisnayı yakalayabilmek ve bir 404 sayfası göstermek isteyebilirsiniz.
1
$model = Uye::findOrFail(1);
2
3
$model = Uye::where('oylar', '>', 100)->firstOrFail();
Bu hata işleyicinin kaydını yapmak için ModelNotFoundException‘i
dinlemek gerekir.
1
use Illuminate\Database\Eloquent\ModelNotFoundException;
2
3
4
5
6
App::error(function(ModelNotFoundException $e)
{
return Response::make('Bulunamadı', 404);
});
Eloquent Modelleri Kullanarak Sorgu Yapma
1
$uyeler = Uye::where('puan', '>', 100)->take(10)->get();
2
3
4
5
6
foreach ($uyeler as $uye)
{
var_dump($uye->isim);
}
Eloquent Küme Metodları
Tabi ki, sorgu oluşturucusunun kümeleme fonksiyonlarını da kullanabilirsiniz.
283
Eloquent ORM
1
$adet = Uye::where('puan', '>', 100)->count();
Gereken sorguyu fluent arayüzüyle üretemediğiniz zaman whereRaw
kullanabilirsiniz:
1
2
$uyeler = Uye::whereRaw('yas > ? and puan = 100', array\
(25))->get();
Sonuçları Öbeklere Bölme
Eğer bir sürü (binlerce) Eloquent kaydını işlemeniz gerekiyorsa,
chunk komutunun kullanılması tüm bunları RAM’inizi yemeden
yapmanıza imkan verecektir:
1
2
3
4
5
6
7
Uye::chunk(200, function($uyeler)
{
foreach ($uyeler as $uye)
{
//
}
});
Metoda geçilen birinci parametre “öbek” başına almak istediğiniz
kayıt sayısıdır. Veritabanından çekilen her bir öbek için ikinci
parametre olarak geçilen Closure çağrılacaktır.
Query Bağlantısının Belirtilmesi
Bir Eloquent sorgusu çalıştırırken hangi bağlantının kullanılacağını
da belirleyebilirsiniz. On metodunu kullanmanız yeterlidir:
1
$uyeler = Uye::on('bağlantı-adı')->find(1);
284
Eloquent ORM
Toplu Atama
Yeni bir model oluşturulurken model oluşturucuya niteliklerden
oluşan bir dizi geçersiniz. Bu nitelikler bu durumda modele “toplu
atama” aracılığıyla atanır. Bu gayet uygun bir yaklaşımdır, fakat
bir kullanıcı girdisi bir modele körleme geçirildiği takdirde ciddi
bir güvenlik sorunu olabilecektir. Kullanıcı girdisi bir modele körlemesine geçirilirse, bu kullanıcı modelin niteliklerinin birisini (any)
ve hepsini (all) değiştirebilecektir. Bu sebepler yüzünden, tüm
Eloquent modelleri ön tanımlı olarak toplu atamaya karşı koyar.
Başlamak için modelinizde fillable veya guarded özelliğini ayarlayınız.
Bir Modelde Fillable Niteliklerin Tanımlanması
Bunlardan fillable özelliği hangi niteliklerin toplu atanacaklarını
belirler. Bu işlem sınıf ya da olgu düzeyinde ayarlanabilir.
1
class Uye extends Eloquent {
2
protected $fillable = array('ismi', 'soy_ismi', 'email\
3
4
');
5
6
}
Bu örnekte, sadece belirttiğimiz üç nitelik toplu atanabilecektir.
Bir Modelde Guarded Niteliklerin Tanımlanması
fillable‘in tersi guarded‘dır ve bir “beyaz-liste” yerine bir “kara-
liste” olarak iş görür:
285
Eloquent ORM
1
class Uye extends Eloquent {
2
protected $guarded = array('id', 'parola');
3
4
5
}
Not: guarded kullanıyorken de, yine bir save veya
update metoduna Input::get() veya kullanıcının kontrolündeki herhangi bir ham diziyi hiçbir zaman için
geçmemelisiniz, çünkü öyle yaptığınızda guarded olmayan herhangi bir sütun güncellenebilir.
Toplu Atamanın Tüm Nitelikler İçin Engellenmesi
Yukardaki örneğe göre id ve parola nitelikleri toplu atana mayacaktır. Diğer tüm nitelikler toplu atanabilecektir. Toplu atamayı
niteliklerin hepsi için bloke etmeyi de seçebilirsiniz:
1
protected $guarded = array('*');
Ekleme, Güncelleme, Silme
Veritabanında bir modelden yeni bir kayıt oluşturmak için, yeni bir
model olgusu oluşturun ve save metodunu çağırın.
Yeni Bir Modelin Kaydedilmesi
Eloquent ORM
1
286
$uye = new Uye;
2
3
$uye->isim = 'Can';
4
5
$uye->save();
Not: Tipik olarak, Eloquent modellerinizde otomatik
artan anahtarlar olacaktır. Ama siz kendi keylerinizi belirlemek isterseniz, modelinizdeki incrementing
özelliğini false olarak ayarlayın.
Yeni bir modeli tek satırda kaydetmek için create metodunu kullanabilirsiniz. Eklenen model olgusu bu metoddan döndürülecektir.
Ancak, tüm Elequent modelleri toplu atamaya karşı korunumlu
oldukları için, bunu yapmadan önce modelinizde bir fillable veya
guarded özelliği belirlemeniz gerekecektir.
Otomatik artan IDler kullanan yeni bir modelin kaydedilmesi (olgu
oluşturup, değer atanıp, “save” kullanılması) veya oluşturulması
(üç işlemin hepsini birden yapan “create” metodunun kullanılması)
sonrasında, nesnenin id niteliğine erişerek bu ID’i öğrenebilirsiniz:
1
$insertedId = $user->id;
Modeldeki Korunumlu Niteliklerin Ayarlanması
1
class Uye extends Eloquent {
2
protected $guarded = array('id', 'hesap_no');
3
4
5
}
Model Create Metodunun Kullanımı
Eloquent ORM
1
2
287
// Veritabanında yeni bir üye oluştur...
$uye = Uye::create(array('isim' => 'Can'));
3
4
5
6
// Bazı alanlarına göre üyeyi getir ya da öyle bir üye \
yoksa oluştur...
$user = User::firstOrCreate(array('name' => 'John'));
7
8
9
10
// Bazı alanlarına göre üyeyi getir ya da yeni bir üye \
olgusu başlat...
$user = User::firstOrNew(array('name' => 'John'));
Getirilen Bir Modelin Güncellenmesi
Bir modeli güncellemek için onu getirir, bir niteliğini değiştirir,
sonra da save metodunu kullanabilirsiniz:
1
$uye = Uye::find(1);
2
3
$uye->email = 'can@filan.com';
4
5
$uye->save();
Bir Model ve İlişkilerinin Kaydedilmesi
Bazen sadece bir modeli değil, onun bütün ilişkilerini de kaydetmek
isteyebilirsiniz. Bunu yapmak için push metodunu kullanın:
1
$uye->push();
Ayrıca, bir modeller kümesinde güncelleme sorguları da çalıştırabilirsiniz:
288
Eloquent ORM
1
2
$satirSayisi = Uye::where('puan', '>', 100)->update(arr\
ay('durum' => 2));
Not: Eloquent sorgu oluşturucu aracılığıyla bir modeller kümesi güncellendiği zaman herhangi bir model
olayı ateşlenmez.
Mevcut Bir Modelin Silinmesi
Bir modeli silmek için olgu üzerinde delete metodunu çağırın:
1
$uye = Uye::find(1);
2
3
$uye->delete();
Mevcut Bir Modelin Key Aracılığıyla Silinmesi
1
Uye::destroy(1);
2
3
Uye::destroy(array(1, 2, 3));
4
5
Uye::destroy(1, 2, 3);
Elbette, bir modeller kümesinde bir silme sorgusu da çalıştırabilirsiniz:
1
$satirSayisi = Uye::where('puan', '>', 100)->delete();
Bir Modelin Sadece Zaman Damgalarının
Güncellenmesi
Eğer bir modelde sadece zaman damgalarını güncellemek istiyorsanız, touch metodunu kullanabilirsiniz:
289
Eloquent ORM
1
$uye->touch();
Belirsiz Silme
Bir model belirsiz silindiğinde, aslında veritabanınızdan çıkartılmaz. Onun yerinde kayıttaki bir deleted_at zaman damgası ayarlanır. Bir model için belirsiz silmeler yapılabilmesi için modelinize
‘SoftDeletingTrait’ uygulamanız gerekir:
1
use Illuminate\Database\Eloquent\SoftDeletingTrait;
2
3
class Uye extends Eloquent {
4
use SoftDeletingTrait;
5
6
protected $dates = ['deleted_at'];
7
8
9
}
Tablonuza bir deleted_at sütunu eklemek için ise, bir migrasyondan softDeletes metodunu kullanabilirsiniz:
1
$table->softDeletes();
Şimdi, artık modelinizde delete metodunu çağırdığınız zaman,
bu deleted_at sütunu güncel zaman damgasına ayarlanacaktır.
Belirsiz silme kullanılan bir model sorgulandığında, “silinmiş olan”
modeller sorgu sonuçlarına dahil edilmeyecektir.
Belirsiz Silinmiş Modelleri Sonuçlara Girmeye
Zorlama
Bir sonuç kümesinde belirsiz silinmiş modellerin gözükmesini zorlamak için sorgunuzda withTrashed metodunu kullanınız:
Eloquent ORM
1
2
290
$uyeler = Uye::withTrashed()->where('hesap_no', 1)->get\
();
Bu withTrashed metodu tanımlanmış bir ilişki üzerinde kullanılabilir:
1
$user->posts()->withTrashed()->get();
Sonuç kümenizde sadece belirsiz silinmiş modellerin olmasını istiyorsanız, onlyTrashed metodunu kullanabilirsiniz:
1
2
$uyeler = Uye::onlyTrashed()->where('hesap_no', 1)->get\
();
Belirsiz silinmiş bir modeli tekrar etkin hale getirmek için, restore
metodunu kullanın:
1
$uye->restore();
restore metodunu bir sorguda da kullanabilirsiniz:
1
Uye::withTrashed()->where('hesap_no', 1)->restore();
restore metodu ilişkilerde de kullanılabilir:
1
$uye->postalar()->restore();
Bir modeli veritabanından gerçekten çıkartmak istediğinizde, forceDelete
metodunu kullanabilirsiniz:
291
Eloquent ORM
1
$uye->forceDelete();
forceDelete metodu ilişkilerde de çalışır:
1
$uye->postalar()->forceDelete();
Belli bir model olgusunun belirsiz silme özelliğine sahip olup olmadığını öğrenmek için, trashed metodunu kullanabilirsiniz:
1
2
3
4
if ($uye->trashed())
{
//
}
Zaman Damgaları
Ön tanımlı olarak, veritabanı tablonuzdaki created_at ve updated_at sütunlarının idamesini otomatik olarak Eloquent yapacaktır. Size
tek düşen datetime tipindeki bu iki alanı tablonuza eklemektir, geri
kalan işleri Eloquent üstlenecektir. Şayet siz bu sütunların idamesini Eloquent’in yapmasını istemiyorsanız, modelinize şu özelliği
eklemeniz gerekir:
Otomatik Zaman Damgalarının Devre Dışı
Bırakılması
292
Eloquent ORM
1
class Uye extends Eloquent {
2
protected $table = 'uyeler';
3
4
public $timestamps = false;
5
6
7
}
Özel Bir Zaman Damgası Biçiminin Şart Koşulması
Zaman damgalarınızın biçimini özelleştirmek isterseniz, modelinizdeki freshTimestamp metodunu ezebilirsiniz (override):
1
class Uye extends Eloquent {
2
public function freshTimestamp()
{
return time();
}
3
4
5
6
7
8
}
Sorgu Kapsamları
Bir Sorgu Kapsamının Tanımlanması
Kapsamlar size sorgu mantığınızı modellerinizde tekrar tekrar kullanma imkanı verir. Bir kapsam tanımlamak için bir model metodunun başına scope getirmeniz yeterlidir:
293
Eloquent ORM
1
class Uye extends Eloquent {
2
public function scopePopular($query)
{
return $query->where('puan', '>', 100);
}
3
4
5
6
7
public function scopeKadin($query)
{
return $query->whereGender('W');
}
8
9
10
11
12
13
}
Bir Sorgu Kapsamının Kullanılması
1
2
$uyeler = Uye::popular()->kadin()->orderBy('created_at'\
)->get();
Dinamik Kapsamlar
Bazen parametreler kabul eden kapsam tanımlamak isteyebilirsiniz.
Yapmanız gereken kapsam metoduna parametrelerinizi eklemek:
1
class Uye extends Eloquent {
2
public function scopeOfType($query, $type)
{
return $query->whereType($type);
}
3
4
5
6
7
8
}
Parametreyi kapsamın çağrısına geçin:
294
Eloquent ORM
1
$uyeler = Uye::ofType('moderator')->get();
Küresel Kapsamlar
Bazen, bir model üzerinde yapılan tüm sorgular için uygulanan bir
scope tanımlamak isteyebilirsiniz. Aslında, Eloquent’in kendi “belirsiz silme” özelliği bu şekilde çalışmaktadır. Global scope’lar PHP
trait’leri ve bir Illuminate\Database\Eloquent\ScopeInterface
implementasyonu birlikte kullanılarak tanımlanırlar.
İlk olarak, bir trait tanımlayalım. Bu örnek için Laravel’le birlikte
gelen SoftDeletingTrait kullanacağız:
1
trait SoftDeletingTrait {
2
/**
* Boot the soft deleting trait for a model.
*
* @return void
*/
public static function bootSoftDeletingTrait()
{
static::addGlobalScope(new SoftDeletingScope);
}
3
4
5
6
7
8
9
10
11
12
13
}
Eğer bir Eloquent modeli bir bootTraitIsmi isimlendirme kuralına
uyan bir metoda sahip olan bir trait kullanırsa, bu Elequent modeli
boot edildiği zaman o trait metodu çağrılacaktır. Bu size küresel bir
kapsamı kayda geçirme ya da istediğiniz başka bir şey yapma fırsatı
vermektedir. Bir scope ScopeInterface interface’ini implemente
etmelidir, bu interface iki metoda sahiptir: apply ve remove.
Eloquent ORM
295
Bunlardan apply metodu bir Illuminate\Database\Eloquent\Builder
sorgu oluşturucu nesnesi alır ve bu kapsama eklemek istediğiniz ilave where cümlelerinin eklenmesinden sorumludur. remove
metodu da bir Builder nesnesi alır ve apply tarafından gerçekleştirilen eylemlerin geri döndürülmesinden sorumludur. Başka
bir deyişle, remove metodu eklenmiş olan where cümlesini (veya herhangi bir başka cümleyi) çıkarmalıdır. Dolayısıyla, bizim
SoftDeletingScope için, bu metodlar buna benzer gözükecektir:
1
2
3
4
5
6
7
8
9
10
11
/**
* Verilen bir Eloquent sorgu oluşturucusuna scope uygu\
la.
*
* @param \Illuminate\Database\Eloquent\Builder $buil\
der
* @return void
*/
public function apply(Builder $builder)
{
$model = $builder->getModel();
12
$builder->whereNull($model->getQualifiedDeletedAtColum\
13
14
15
n());
}
16
17
18
19
20
21
22
23
24
25
26
/**
* Verilen Eloquent sorgu oluşturucusundan scope'u kald\
ır.
*
* @param \Illuminate\Database\Eloquent\Builder $buil\
der
* @return void
*/
public function remove(Builder $builder)
{
296
Eloquent ORM
27
28
$column = $builder->getModel()->getQualifiedDeletedAtC\
olumn();
29
$query = $builder->getQuery();
30
31
32
33
34
35
36
37
38
39
40
41
42
foreach ((array) $query->wheres as $key => $where)
{
// Eğer where cümlesi bir belirsiz silme date sınırla\
ması ise, onu sorgudan
// kaldıracağız ve wheres'deki key'leri resetleyeceği\
z. Bu, bu geliştiriciye,
// tembel yüklenen bir ilişki sonuç kümesinde silinmi\
ş modeli dahil etme imkanı verir.
if ($this->isSoftDeleteConstraint($where, $column))
{
unset($query->wheres[$key]);
43
$query->wheres = array_values($query->wheres);
44
}
45
}
46
47
}
İlişkiler
Pek tabii, veritabanı tablolarınız büyük ihtimalle bir diğeriyle ilişkilidir. Örneğin bir blog yazısında çok sayıda yorum olabilir veya bir
sipariş onu ısmarlayan kullanıcı ile ilişkili olacaktır. Eloquent bu
ilişkileri kolayca yönetmenizi ve rahat çalışmanızı sağlar. Laravel
birçok ilişki tipini desteklemektedir:
• Birden Bire
• Birden Birçoğa
• Birçoktan Birçoğa
297
Eloquent ORM
• Aracılığıyla Birçoğa Sahip (Has Many Through)
• Çokbiçimli İlişkiler
• Birçoktan Birçoğa Çokbiçimli İlişkiler
Birden Bire
Birden Bire Tarzı İlişki Tanımlama
Birden bire şeklindeki bir ilişki çok basit bir ilişkidir. Örneğin, bir
Uye modelinin bir Telefon‘u olabilir. Eloquent’de bu ilişkiyi şöyle
tanımlayabiliriz:
1
class Uye extends Eloquent {
2
public function tel()
{
return $this->hasOne('Telefon');
}
3
4
5
6
7
8
}
hasOne metoduna geçirilen ilk parametre ilişkili modelin adıdır.
İlişki tanımlandıktan sonra onu Eloquent’in dinamik özellikler‘ini
kullanarak elde edebiliriz:
1
$tel = Uye::find(1)->tel;
Bu cümlenin gerçekleştirdiği SQL şunlardır (tablo isimleri model
tanımında özel olarak belirtilmedi ise tablo ismi olarak model
isminin küçük harfli çoğul halinin kullanıldığını hatırlayınız):
Eloquent ORM
1
298
select * from uyes where id = 1
2
3
select * from telefons where uye_id = 1
Eloquent’in ilişkideki yabancı key’in ne olduğuna model adına göre
karar verdiğine dikkat ediniz. Şimdiki örnekte Telefon modelinin
uye_id adlı bir yabancı key kullandığı varsayılmaktadır. Siz bu ön
kuralı değiştirmek istiyorsanız hasOne metoduna ikinci bir parametre geçebilirsiniz. Dahası, ilişki için hangi local alanın kullanılması gerektiğini belirtmek için üçüncü bir parametre geçebilirsiniz:
1
return $this->hasOne('Telefon', 'foreign_key');
2
3
4
return $this->hasOne('Telefon', 'foreign_key', 'local_k\
ey');
Bir İlişkinin Tersinin Tanımlanması
Telefon modeli üzerinde ilişkinin tersini tanımlamak için, belongsTo
metodunu kullanınız:
1
class Telefon extends Eloquent {
2
public function uye()
{
return $this->belongsTo('Uye');
}
3
4
5
6
7
8
}
Yukarıdaki örnekte, Eloquent, telefons tablosunda bir user_id
alanı arayacaktır. Eğer farklı bir yabancı anahtar sütunu tanımlamak isterseniz, onu belongsTo metoduna ikinci parametre olarak
geçebilirsiniz:
299
Eloquent ORM
1
class Telefon extends Eloquent {
2
public function uye()
{
return $this->belongsTo('Uye', 'local_key');
}
3
4
5
6
7
8
}
Ek olarak, ebeveyn tabloda ilişkilendirilen sütunun adını belirten
üçüncü bir parametre geçebilirsiniz:
1
class Telefon extends Eloquent {
2
public function uye()
{
return $this->belongsTo('Uye', 'local_key', 'parent_k\
3
4
5
6
ey');
}
7
8
9
}
Birden Birçoğa
Birden birçoğa ilişki örneği olarak birçok yorum yapılmış bir blog
yazısı verilebilir. Bu ilişkiyi de şöyle modelleyebiliriz:
Eloquent ORM
1
300
class Makale extends Eloquent {
2
public function yorumlar()
{
return $this->hasMany('Yorum');
}
3
4
5
6
7
8
}
Şimdi artık bir makalenin yorumlarına dinamik özellik aracılığıyla
ulaşabiliriz:
1
$yorumlar = Makale::find(1)->yorumlar;
Hangi yorumların alınacağını daha da kısıtlamak için yorumlar
metodunu çağırabilir ve şartlar koşmayı sürdürebilirsiniz:
1
2
$yorumlar = Makale::find(1)->yorumlar()->where('baslik'\
, '=', 'bu')->first();
Tıpkı hasOne’de olduğu gibi konvansiyonel yabancı key varsayımını hasMany metoduna ikinci bir parametre geçerek değiştirebilirsiniz. Ve, aynı şekilde local sütun da belirtilebilir:
1
return $this->hasMany('Yorum', 'foreign_key');
2
3
4
return $this->hasMany('Yorum', 'foreign_key', 'local_ke\
y');
Bir İlişkinin Tersinin Tanımlanması
İlişkinin tersini Yorum modelinde tanımlamak için, belongsTo metodu kullanılmaktadır:
301
Eloquent ORM
1
class Yorum extends Eloquent {
2
public function makale()
{
return $this->belongsTo('Makale');
}
3
4
5
6
7
8
}
Birçoktan Birçoğa
Birçoktan birçoğa ilişkiler daha karmaşık bir ilişki tipidir. Bu tarz bir
ilişki örneği bir üyenin birçok rolü olması, aynı zamanda bu rollerin
başka kullanıcılar tarafından da paylaşılmasıdır. Örneğin birçok
üye “Müdür” rolünde olabilir. Bu ilişki için üç veritabanı tablosu
gereklidir: uyeler, roller ve rol_uye. Bu rol_uye tablosu ilişkili
model isimlerinin alfabetik sıralamasına göre adlandırılır ve uye_id
ve rol_id sütunlarına sahip olmalıdır (model isimlerine alttire ve
id eklenmiş iki alan).
Birçoktan birçoğa ilişkileri belongsToMany metodunu kullanarak
tanımlayabiliyoruz:
1
class Uye extends Eloquent {
2
public function roller()
{
return $this->belongsToMany('Rol');
}
3
4
5
6
7
8
}
Artık rolleri Uye modeli aracılığıyla getirebiliriz:
Eloquent ORM
1
302
$roller = Uye::find(1)->roller;
Pivot tablo ismi olarak ön kabullü tablo ismi yerine başka bir
isim kullanmak isterseniz, bunu belongsToMany metoduna ikinci bir
parametre geçerek gerçekleştirebilirsiniz:
1
return $this->belongsToMany('Rol', 'uye_rolleri');
İlişkili keyler için konvansiyonel yaklaşımı da değiştirebilirsiniz:
1
2
return $this->belongsToMany('Rol', 'uye_rolleri', 'uye_\
id', 'foo_id');
Ve tabii ki ilişkinin tersini Rol modelinde de tanımlayabilirsiniz:
1
class Rol extends Eloquent {
2
public function uyeler()
{
return $this->belongsToMany('Uye');
}
3
4
5
6
7
8
}
Aracılığıyla Birçoğa Sahip (Has Many Through)
Bu “has many through” ilişkisi, aradaki bir ilişki aracılığıyla uzak
ilişkilere erişim için uygun bir kestirme yol sağlar. Örneğin, bir
Memleket modeli bir Uye modeli aracılığıyla bir çok Post sahibi
olabilir. Bu ilişkinin tabloları şunun gibi gözükecektir:
Eloquent ORM
1
2
3
303
memlekets
id - integer
isim - string
4
5
uyes
id - integer
memleket_id - integer
isim - string
6
7
8
9
10
posts
id - integer
uye_id - integer
baslik - string
11
12
13
Bu posts tablosunda bir memleket_id sütunu olmamasına rağmen,
hasManyThrough ilişkisi bir memleketin post’larına $memleket->posts
aracılığıyla erişebilmemize imkan verecektir. Önce bu ilişkiyi tanımlayalım:
1
class Memleket extends Eloquent {
2
public function posts()
{
return $this->hasManyThrough('Post', 'Uye');
}
3
4
5
6
7
8
}
Eğer ilişkinin keylerini elle belirtmek isterseniz, metoda üçüncü ve
dördüncü parametreler geçebilirsiniz:
304
Eloquent ORM
1
class Memleket extends Eloquent {
2
3
4
5
6
7
public function posts()
{
return $this->hasManyThrough('Post', 'Uye', 'memleket\
_id', 'uye_id');
}
8
9
}
Çokbiçimli İlişkiler
Çokbiçimli (Polimorfik) İlişkiler bir modelin tek bir ilişkilendirme
ile birden çok modele ait olmasına imkan verir. Örneğin, kendisi
ya bir personel modeline ya da bir siparis modeline ait olan bir foto
modeliniz olduğunu düşünün. Bu ilişkiyi şu şekilde tanımlayacağız:
1
class Foto extends Eloquent {
2
public function resim()
{
return $this->morphTo();
}
3
4
5
6
7
8
}
9
10
class Personel extends Eloquent {
11
public function fotolar()
{
return $this->morphMany('Foto', 'resim');
}
12
13
14
15
16
17
}
Eloquent ORM
305
18
19
class Siparis extends Eloquent {
20
public function fotolar()
{
return $this->morphMany('Foto', 'resim');
}
21
22
23
24
25
26
}
Çokbiçimli Bir İlişkinin Getirilmesi
Artık bir personel ya da siparişe ait fotoları elde edebiliriz:
1
$personel = Personel::find(1);
2
3
4
5
6
foreach ($personel->fotolar as $foto)
{
//
}
Çokbiçimli Bir İlişkinin Sahibinin Getirilmesi
Ancak, “çokbiçimli” ilişkinin gerçek farkını bir personel veya siparişe Foto modelinden erişebilmekle görürsünüz:
1
$foto = Foto::find(1);
2
3
$resim = $foto->resim;
Foto modelindeki resim ilişkisi, fotonun sahibi olan modele bağlı
olarak ya bir Personel ya da bir Siparis olgusu döndürecektir.
306
Eloquent ORM
Çokbiçimli İlişki Tablo Yapısı
Bunun nasıl çalıştığını anlamanıza yardımcı olmak için bir polimorfik ilişkinin veritabanı yapısını keşfedelim:
1
2
3
personel
id - integer
isim - string
4
5
6
7
siparisler
id - integer
fiyat - integer
8
9
10
11
12
13
fotolar
id - integer
dosyayolu - string
resim_id - integer
resim_type - string
Buradaki anahtar alanların fotolar tablosundaki resim_id and
resim_type olduğuna dikkat ediniz. Buradaki ID, fotonun sahibi
olan personel veya siparişin ID’ini, TYPE ise sahip olan modelin
sınıf adını tutacaktır. Böylece ORM, resim ilişkisiyle erişildiğinde
döndürülecek sahip modelin hangisi olduğunu tespit edebilecektir.
Birçoktan Birçoğa Çokbiçimli İlişkiler
Çokbiçimli Birçoktan Birçoğa İlişkilerin Tablo Yapısı
Geleneksel çokbiçimli ilişkilere ek olarak, birçoktan birçoğa çokbiçimli ilişkiler de belirleyebilirsiniz. Örneğin, bir blog Post ve Video
modeli bir Tag modeline polimorfik bir ilişki paylaşabilirler. Önce,
tablo yapısını inceleyelim:
Eloquent ORM
1
307
posts
id - integer
name - string
2
3
4
5
videos
id - integer
name - string
6
7
8
9
tags
id - integer
name - string
10
11
12
13
14
15
16
taggables
tag_id - integer
taggable_id - integer
taggable_type - string
Sonra da, model üzerinde ilişkileri kurmaya geçelim. Post ve Video
modellerinin her ikisi de bir tags metodu aracılığıyla bir morphToMany
ilişkisine sahip olacaktır:
1
class Post extends Eloquent {
2
public function tags()
{
return $this->morphToMany('Tag', 'taggable');
}
3
4
5
6
7
8
}
Tag modeli ise ilişkilerinin her biri için bir metod tanımlayabilir:
308
Eloquent ORM
1
class Tag extends Eloquent {
2
public function posts()
{
return $this->morphedByMany('Post', 'taggable');
}
3
4
5
6
7
public function videos()
{
return $this->morphedByMany('Video', 'taggable');
}
8
9
10
11
12
13
}
İlişkilerin Sorgulanması
Seçerken İlişkilerin Yoklanması
Bir modelin kayıtlarına erişirken, sonuçları bir ilişki varlığına göre
sınırlamak isteyebilirsiniz. Diyelim ki, en az bir yorum yapılmış
tüm blog makalelerini çekmek istediniz. Bunu yapmak için has
metodunu kullanabilirsiniz:
1
$makaleler = Makale::has('yorumlar')->get();
Ayrıca, bir işlemci ve bir sayı da belirleyebilirsiniz, örneğin üç ve
daha çok yorum almış makaleleri getirmek için:
1
$makaleler = Makale::has('yorumlar', '>=', 3)->get();
Hatta daha fazla güce ihtiyacınız varsa, has sorgularınıza “where”
şartları koymak için whereHas ve orWhereHas metodlarını kullanabilirsiniz:
309
Eloquent ORM
1
2
3
$makaleler = Makale::whereHas('yorumlar', function($q)
{
$q->where('content', 'like', 'filan%');
4
5
})->get();
Dinamik Özellikler
Eloquent, ilişkilerinize dinamik özellikler yoluyla erişme imkanı
verir. Eloquent ilişkiyi sizin için otomatik olarak yükleyecektir.
Hatta, get (birden birçoğa ilişkiler için) metodunun mu yoksa first
(birden bire ilişkiler için) metodunun mu çağırılacağını bilecek
kadar akılllıdır. İlişkiyle aynı isimli dinamik bir özellik aracılığı ile
erişilebilir olacaktır. Örneğin, şu $telefon modelinde:
1
class Telefon extends Eloquent {
2
public function uye()
{
return $this->belongsTo('Uye');
}
3
4
5
6
7
8
}
9
10
$telefon= Telefon::find(1);
Bu üyenin email’ini şu şekilde göstermek yerine:
1
echo $telefon->uye()->first()->email;
Buradaki gibi basit bir hale kısaltılabilir:
310
Eloquent ORM
1
echo $telefon->uye->email;
Not: Çoklu sonuç döndüren ilişkiler bir Illuminate\Database\Eloquent\Coll
sınıf olgusu döndürecektir.
Ateşli (Eager) Yüklemeler
Ateşli yükleme N + 1 sorgu problemini gidermek içindir. Örnek
olarak, Yazar ile ilişkilendirilmiş bir Kitap modelini düşünün. İlişki
de şöyle tanımlanmış olsun:
1
class Kitap extends Eloquent {
2
public function yazar()
{
return $this->belongsTo('Yazar');
}
3
4
5
6
7
8
}
Şimdi, şu kodu ele alalım:
1
2
3
4
foreach (Kitap::all() as $kitap)
{
echo $kitap->yazar->isim;
}
Bu döngü tablodaki kitapların hepsini almak için 1 sorgu çalıştıracak, sonra da yazarını elde etmek için her bir kitabı sorgulayacaktır.
Yani, eğer 25 kitabımız varsa bu döngü 26 sorgu çalıştıracaktır.
Neyseki, sorgu sayısını büyük ölçüde azaltan ateşli yükleme kullanabiliriz. Ateşli yüklenecek ilişkiler with metodu aracılığıyla belirlenebilmektedir:
311
Eloquent ORM
1
2
3
4
foreach (Kitap::with('yazar')->get() as $kitap)
{
echo $kitap->yazar->isim;
}
Yukardaki döngüde sadece iki sorgu çalıştırılacaktır (model tanımında tablo isimleri açıkça belirtilmediyse ingilizce küçük harf
çoğul kabulünü hatırlayınız):
1
select * from kitaps
2
3
select * from yazars where id in (1, 2, 3, 4, 5, ...)
Ateşli yüklemenin akıllıca kullanımı uygulamanızın performansını
önemli ölçüde artırabilir.
Tabii ki, bir defada birden çok ilişkiyi ateşli yükleyebilirsiniz:
1
$kitaplar = Kitap::with('yazar', 'kitabevi')->get();
Hatta içi içe ilişkileri de ateşleyebilirsiniz:
1
$kitaplar = Kitap::with('yazar.kisiler')->get();
Yukarıdaki örnekte yazar ilişkisi ateşli yüklenecektir ve yazarın
kisiler ilişkisi de ateşli yüklenecektir.
Ateşli Yükleme Sınırlamaları
Bazen bir ilişkiyi ateşli yüklemek, ama ateşli yükleme için de bir
şart belirlemek isteyebiliriz. İşte bir örnek:
312
Eloquent ORM
1
2
3
4
$uyeler = Uye::with(array('makaleler' => function($quer\
y)
{
$query->where('baslik', 'like', '%birinci%');
5
6
}))->get();
Bu örnekte üyenin makalelerinden sadece baslik alanında “birinci”
kelimesi geçen makalelerini ateşli yüklüyoruz.
Tabii ki, ateşli yükleme Closure’ları “sınırlamalara” sınırlı değildir.
Sıralama da yapabilirsiniz:
1
2
3
4
$uyeler = Uye::with(array('makaleler' => function($quer\
y)
{
$query->orderBy('created_at', 'desc');
5
6
}))->get();
Tembel Ateşli Yükleme
İlişkili modelleri, direkt olarak önceden mevcut model koleksiyonundan ateşli yüklemek de mümkündür. Bu özellikle ilişkili modeli
önbellekleme ile birlikte yükleyip yüklememeye dinamik karar
vereceğiniz zaman işe yarayabilir.
1
$kitaplar= Kitap::all();
2
3
$kitaplar->load('yazar', 'kitabevi');
313
Eloquent ORM
İlişkili Modelleri Ekleme
İlişkili Bir Modelin Eklenmesi
Yeni ilişkili model ekleme ihtiyacınız çok olacaktır. Örneğin, bir
makale için yeni bir yorum eklemek isteyebilirsiniz. Model üzerinde
makale_id yabancı key alanını elle ayarlamak yerine, doğrudan
ebeveyn Makale modelinden yeni yorum ekleyebilirsiniz:
1
$yorum = new Yorum(array('mesaj' => 'Yeni bir yorum.'));
2
3
$makale = Makale::find(1);
4
5
$yorum = $makale->yorumlar()->save($yorum);
Bu örnekte eklenen yorumdaki makale_id alanı otomatik olarak
ayarlanmaktadır.
Eğer birden çok sayıda ilişkili model kaydetmeniz gerekirse:
1
2
3
4
5
$yorumlar =
new
new
new
);
array(
Yorum(array('mesaj' => 'Yeni bir yorum.')),
Yorum(array('mesaj' => 'Bir başka yorum.')),
Yorum(array('mesaj' => 'Son bir yorum.'))
6
7
$makale = Makale::find(1);
8
9
$yorum = $makale->yorumlar()->saveMany($yorumlar);
Modellerin Üye Yapılması (Belongs To)
Bir belongsTo ilişkisi güncellenirken, associate metodunu kullanabilirsiniz. Bu metod çocuk modeldeki yabancı anahtarı ayarlayacaktır:
Eloquent ORM
1
314
$hesap = Hesap::find(10);
2
3
$uye->hesap()->associate($hesap);
4
5
$uye->save();
İlişkili Model Ekleme (Birçoktan Birçoğa)
Birçoktan birçoğa ilişkilerle çalışırken de ilişkili model ekleyebilirsiniz. Daha önceki örneğimiz Uye ve Rol modellerini kullanmaya
devam edelim. Bir üyeye yeni roller eklemeyi attach metodu ile
yapabiliriz:
Birçoktan Birçoğa Modellerinin Eklenmesi
1
$uye = Uye::find(1);
2
3
$uye->roller()->attach(1);
İlişkiler için pivot tabloda tutulan nitelikleri bir dizi olarak da
geçebilirsiniz:
1
2
$uye->roller()->attach(1, array('sonaerme' => $sonaerme\
));
Tabii, attach‘in ters işlemi detach‘tir:
1
$uye->roller()->detach(1);
Birçoktan Birçoğa Model Bağlamak İçin Sync
Kullanımı
İlişkili modelleri bağlamak için sync metodunu da kullanabilirsiniz. Bu sync metodu parametre olarak pivot tablodaki yerlerin
Eloquent ORM
315
id’lerinden oluşan bir dizi geçirilmesini ister. Bu işlem tamamlandıktan sonra, model için kullanılacak ara tabloda sadece bu id’ler
olacaktır:
1
$uye->roller()->sync(array(1, 2, 3));
Sync Yaparken Pivot Veri Eklenmesi
Belli id değerleri olan başka pivot tabloyu da ilişkilendirebilirsiniz:
1
2
$uye->roller()->sync(array(1 => array('sonaerme' => tru\
e)));
Bazen yeni bir ilişkili model oluşturmak ve tek bir komutla bunu
eklemek isteyebilirsiniz. Bu işlem için, save metodunu kullanabilirsiniz:
1
$rol = new Rol(array('isim' => 'Editor'));
2
3
Uye::find(1)->roller()->save($rol);
Bu örnekte, yeni bir Rol modeli kaydedilecek ve uye modeline
eklenecektir. Bu işlem için bağlı tablolardaki niteliklerden oluşan
bir dizi de geçebilirsiniz:
1
2
Uye::find(1)->roller()->save($rol, array('sonaerme' => \
$sonaerme));
Ebeveyn Zaman Damgalarına Dokunma
Bir Yorum‘un bir Makale‘ye ait olması örneğimizdeki gibi, bir model
başka bir modele ait (belongsTo) olduğu takdirde, çocuk modeli
316
Eloquent ORM
güncellediğiniz zaman ebeveyn zaman damgasını da güncellemek
iyidir. Örneğin, bir Yorum güncellendiğinde, bunun sahibi olan
Makale‘nin updated_at zaman damgasını otomatikman güncellemek isteyebilirsiniz. Bunu gerçekleştirmek için tek yapacağınız
şey, çocuk modele ilişkilerin isimlerini içeren bir touches özelliği
eklemektir:
1
class Yorum extends Eloquent {
2
protected $touches = array('makale');
3
4
public function makale()
{
return $this->belongsTo('Makale');
}
5
6
7
8
9
10
}
Bunu yaptıktan sonra artık bir Yorum güncellediğinizde, sahibi olan
Makale de güncellenmiş bir updated_at sütununa sahip olacaktır:
1
$yorum = Yorum::find(1);
2
3
$yorum->text = 'Bu yorumu düzelt!';
4
5
$yorum->save();
Pivot Tablolarla Çalışmak
Daha önce öğrendiğiniz gibi, birçoktan birçoğa ilişkilerle çalışmak
bir ara tablonun olmasını gerektirir. Eloquent işte bu tablo ile etkileşim için çok yararlı bazı yollar sağlamaktadır. Örneğin bizim bir Uye
nesnemiz, bir de onun bağlı olduğu birçok Rol nesnelerimiz olsun.
Eloquent ORM
317
Bu ilişkiye eriştikten sonra, pivot tabloya modellerimiz üzerinden
erişebiliriz:
1
$uye = Uye::find(1);
2
3
4
5
6
foreach ($uye->roller as $rol)
{
echo $rol->pivot->created_at;
}
Dikkat ederseniz, elde ettiğimiz her bir Rol modeline otomatikman
bir pivot niteliği atanmıştır. Bu nitelik, ara tabloyu temsil eden bir
modeli taşır ve herhangi bir Eloquent modeli gibi kullanılabilir.
Ön tanımlı olarak, pivot nesnesinde sadece keyler olacaktır. Şayet
pivot tablonuzda bunlardan başka nitelikler varsa, bunları ilişki
tanımlama sırasında belirtmelisiniz:
1
2
return $this->belongsToMany('Rol')->withPivot('falan', \
'filan');
Şimdi Rol modelinin pivot nesnesinde falan ve filan nitelikleri
erişilebilir olacaktır.
Eğer pivot tablonuzun created_at ve updated_at zaman damgalarını otomatik olarak halletmesini istiyorsanız, ilişki tanımlamasında
withTimestamps metodunu kullanın:
1
return $this->belongsToMany('Rol')->withTimestamps();
Bir Pivot Tablodaki Kayıtların Silinmesi
Bir modelin pivot tablosundaki tüm kayıtları silmek için, detach
metodunu kullanabilirsiniz:
318
Eloquent ORM
1
Uye::find(1)->roller()->detach();
Bu operasyonun roller tablosundan kayıt silmediğine, sadece pivot tablodan sildiğine dikkat ediniz.
Bir Pivot Tablodaki Bir Kaydın Güncellenmesi
Bazen pivot tablonuzu güncellemeniz ama onu detach etmemeniz
gerekebilir. Eğer pivot tablonuzu “yerinde” güncellemek istiyorsanız aşağıdakine benzer şekilde updateExistingPivot metodunu
kullanabilirsiniz:
1
2
Uye::find(1)->roller()->updateExistingPivot($roleId, $a\
ttributes);
Özel Bir Pivot Model Tanımlanması
Laravel size özel bir Pivot model tanımlama imkanı da verir. Özel
bir model tanımlamak için, öncelikle Eloquent‘i genişleten kendi
“Taban” model sınıfınızı oluşturun. Diğer Eloquent modellerinizde,
defaut Eloquent taban yerine bu özel taban modeli genişletin. Taban modelinize, sizin özel Pivot modelinizin bir olgusunu döndüren
aşağıdaki fonksiyonu ekleyin:
1
2
3
4
5
6
public function newPivot(Model $parent, array $attribut\
es, $table, $exists)
{
return new YourCustomPivot($parent, $attributes, $tabl\
e, $exists);
}
Koleksiyonlar
Eloquent tarafından get metodu veya bir relationship (ilişki)
aracılığıyla döndürülen tüm çoklu sonuç kümeleri bir Eloquent
319
Eloquent ORM
Collection nesnesi döndürecektir. Bu nesne PHP’nin IteratorAggregate
arayüzünün bir uygulama biçimidir ve tıpkı bir dizide dolaşır gibi
dolaşılabilinmektedir. Bunun yanında, bu nesne sonuç kümeleriyle
çalışırken işe yarayan başka bir takım metodlara da sahiptir.
Bir Koleksiyonun Bir Key Taşıyıp Taşımadığının
Yoklanması
Örneğin biz contains metodunu kullanarak bir sonuç kümesinin
belli bir primer key içerip içermediğini tespit edebiliriz:
1
$roller = Uye::find(1)->roller;
2
3
4
5
6
if ($roller->contains(2))
{
//
}
Koleksiyonlar aynı zamanda bir dizi ya da JSON’a dünüştürülebilmektedir:
1
$roller = Uye::find(1)->roller->toArray();
2
3
$roller = Uye::find(1)->roller->toJson();
Eğer bir koleksiyon bir string kalıbına çevrilirse JSON olarak döndürülecektir:
1
$roller = (string) Uye::find(1)->roller;
Koleksiyonlarda Tekrarlı İşlemler
Eloquent koleksiyonları içerdikleri elemanları dolaşmak ve filtre
etmekle ilgili bazı metodlara da sahiptir:
320
Eloquent ORM
1
2
$roller = $uye->roller->each(function($rol)
{
3
4
});
Koleksiyonlarda Filtreleme
Verilen Closure (callback) array_filter()¹⁹¹ için fonksiyon olarak
kullanılacak.
1
2
3
4
$uyeler = $uyeler->filter(function($uye)
{
return $uye->isAdmin();
});
Not: Bir koleksiyonu filtreler ve onu JSON’a döndürürken, dizinin keylerini reset etmek için önce values
fonksiyonunu çağırmayı deneyin.
Her Bir Koleksiyon Nesnesine Bir Anonim Fonksiyon
(Callback) Uygulamak
1
$roller = Uye::find(1)->roller;
2
3
4
5
6
$roller->each(function($rol)
{
//
});
Bir Koleksiyonu Bir Değere Göre Sıralama
¹⁹¹http://php.net/manual/en/function.array-filter.php
321
Eloquent ORM
1
2
3
4
$roller = $roller->sortBy(function($rol)
{
return $rol->created_at;
});
Bir Koleksiyonu Bir Değere Göre Sıralama
1
$roller = $roller->sortBy('created_at');
Özel Bir Koleksiyon Tipinin Döndürülmesi
Bazen de, kendi eklediğiniz metodları olan özel bir koleksiyon
nesnesi döndürmek isteyebilirsiniz. Bunu, Eloquent modeliniz üzerinde newCollection metodunu ezerek yapabilirsiniz:
1
class Uye extends Eloquent {
2
public function newCollection(array $models = array())
{
return new CustomCollection($models);
}
3
4
5
6
7
8
}
Erişimciler & Değiştiriciler (Accessors &
Mutators)
Bir Erişimci Tanımlanması
Eloquent model niteliklerini alıp getirirken veya onları ayarlarken
dönüşüm yapmak için uygun bir yol sağlar. Bir erişimci beyan etmek için modeliniz üzerinde sadece bir getFilanAttribute metodu
tanımlamak yeterlidir. Yalnız unutmamanız gereken şey, veritabanı
322
Eloquent ORM
sütunlarınızın isimleri yılan tarzı (küçük harfli kelimelerin boşluk
olmaksızın alt tire ile birbirine bağlanması) olsa dahi, metodlarınızın deve tarzı (birinci kelimenin tümü küçük harf olmak ve sonraki
kelimelerin ilk harfi büyük diğer hafleri küçük olmak üzere boşluk
olmaksızın kelimelerin yanyana dizilmesi) olması gerektiğidir:
1
class Uye extends Eloquent {
2
public function getSoyAdiAttribute($value)
{
return ucfirst($value);
}
3
4
5
6
7
8
}
Yukarıdaki örnekte soy_adi sütununun bir erişimcisi vardır. Niteliğin değerinin erişimciye geçildiğine dikkat ediniz.
Bir Değiştirici Tanımlanması
Değiştiriciler de benzer şekilde deklare edilir:
1
class Uye extends Eloquent {
2
public function setSoyAdiAttribute($value)
{
$this->attributes['soy_adi'] = strtolower($value);
}
3
4
5
6
7
8
}
323
Eloquent ORM
Tarih Değiştiricileri
Ön tanımlı olarak, Eloquent created_at ve updated_at sütunlarını
Carbon¹⁹², olgularına çevirecektir. Carbon çeşitli yardımcı metodlar
sağlar ve PHP’nin DateTime sınıfını genişletir.
Siz hangi alanların otomatik olarak değiştirileceğini isteğinize göre ayarlayabilirsiniz, hatta modeldeki getDates metodunu ezmek
suretiyle bu davranışı tamamen devre dışı bırakabilirsiniz:
1
2
3
4
public function getDates()
{
return array('created_at');
}
Bir sütun bir tarih olarak kabul edildiğinde, bunun değerini bir
UNIX timetamp, date string (Y-m-d), date-time string ve tabii ki bir
DateTime / Carbon olgusuna ayarlayabilirsiniz.
Tarih değiştiricilerini tümden devre dışı bırakmak için getDates
metodunda boş bir dizi döndürünüz:
1
2
3
4
public function getDates()
{
return array();
}
Model Olayları
Eloquent modelleri bazı olayları tetikleyerek, modelin yaşam döngüsündeki çeşitli noktalarda müdahale etmenize imkan verir. Bu
amaçla şu metodlar kullanılmaktadır: creating, created, updating,
updated, saving, saved, deleting, deleted, restoring, restored.
¹⁹²https://github.com/briannesbitt/Carbon
324
Eloquent ORM
Yeni bir öğe ilk defa kaydedilir kaydedilmez creating ve created
olayları ateşlenecektir. Eğer bir öğe yeni değilse ve save metodu
çağrılırsa, updating / updated olayları ateşlenecektir. Her iki durumda da saving / saved olayları ateşlenecektir.
Saklama Operasyonlarının Olaylar Aracığıyla İptal
Edilmesi
Eğer creating, updating, saving veya deleting olaylarından false
döndürülürse, eylem iptal edilecektir:
1
2
3
4
Uye::creating(function($uye)
{
if ( ! $uye->isValid()) return false;
});
Bir Model Boot Metodunun Ayarlanması
Eloquent modelleri bunun dışında static bir boot metodu içermekte
olup, olay bağlamanızı kayıt etmeniz için uygun bir yerdir.
1
class Uye extends Eloquent {
2
public static function boot()
{
parent::boot();
3
4
5
6
// Olay bağlamayı ayarla...
7
}
8
9
10
}
325
Eloquent ORM
Model Gözlemcileri
Model olaylarının işlenmesini pekiştirmek için, bir model gözlemcisi kaydı yapabilirsiniz. Bir gözlemci sınıfında çeşitli model olaylarına tekabül eden metodlar bulunabilir. Örneğin bir gözlemcide,
diğer model olay isimlerine ek olarak creating, updating, saving
metodları olabilir.
Yani, bir model gözlemcisi şöyle olabilir:
1
class UyeGozlemcisi {
2
public function saving($model)
{
//
}
3
4
5
6
7
public function saved($model)
{
//
}
8
9
10
11
12
13
}
Modelinizde observe metodunu kullanarak bir gözlemci olgusu
kaydı yapabilirsiniz:
1
Uye::observe(new UyeGozlemcisi);
Diziye / JSON’a Çevirme
Bir Modelin Bir Diziye Çevrilmesi
JSON APIler oluşturulurken, çoğu defa modellerinizi ve ilişkilerini
dizilere veya JSON’a çevirmeniz gerekecektir. Bu yüzden Eloqu-
326
Eloquent ORM
ent bunları yapacak metodlar içermektedir. Bir modeli ve onun
yüklenen ilişkilerini bir diziye çevirmek için toArray metodunu
kullanabilirsiniz:
1
$uye = Uye::with('roller')->first();
2
3
return $uye->toArray();
Modellerin koleksiyonlarının da bütün olarak dizilere dönüştürülebildiğini unutmayın:
1
return Uye::all()->toArray();
Bir Modelin JSON’a Çevrilmesi
Bir Modeli JSON’a çevirmek için, toJson metodunu kullanabilirsiniz:
1
return Uye::find(1)->toJson();
Bir Modelin Bir Rotadan Döndürülmesi
Bir model veya koleksiyon bir string kalıbına sokulduğu takdirde,
JSON’a çevrileceğine dikkat ediniz. Yani Elequent nesnelerini direkt
olarak uygulamanızın rotalarından döndürebilirsiniz!
1
2
3
4
Route::get('uyeler', function()
{
return Uye:all();
});
Niteliklerin Dizi veya JSON’a Çevrilmekten
Saklanması
Bazen bazı nitelikleri (örneğin şifreleri) modelinizin dizi veya JSON
biçimlerinden hariç tutmak isteyebilirsiniz. Bunu yapmak için modelinize bir hidden özelliği ekleyiniz:
Eloquent ORM
1
327
class Uye extends Eloquent {
2
protected $hidden = array('parola');
3
4
5
}
Not: İlişkileri gizlerken dinamik erişimci ismini değil
ilişkinin metod ismini kullanın.
Alternatif olarak, beyaz bir liste tanımlamak için visible özelliğini
kullanabilirsiniz:
1
protected $visible = array('adi', 'soy_adi');
Kimi durumlarda, veritabanınızdaki bir sütuna tekabül etmeyen
dizi nitelikleri eklemeniz gerekebilir. Bunu yapmak için, değer için
bir erişimci tanımlamanız yeterlidir:
1
2
3
4
public function getIsAdminAttribute()
{
return $this->attributes['admin'] == 'yes';
}
Erişimciyi oluşturduktan sonra, ilgili modeldeki appends özelliğine
değeri ekleyin:
1
protected $appends = array('is_admin');
Nitelik appends listesine eklendikten sonra modelin hem dizi hem
de JSON formlarına dahil edilecektir.
Şema Oluşturucusu
Giriş
Laravel’in Schema sınıfı tablolara müdahale etmekte veritabanı
bilinmesine gerek kalmaz bir yol sağlar. Laravel’in desteklediği tüm
veritabanlarıyla sağlıklı çalışır ve bu sistemlerin tümünde aynı olan
bir API’ye sahiptir.
Tabloların Oluşturulması ve Yok
Edilmesi
Yeni bir veritabanı tablosu oluşturmak için Schema::create metodu
kullanılır:
1
2
3
4
Schema::create('uyeler', function($table)
{
$table->increments('id');
});
Bu create metoduna geçilen ilk parametre tablonun adıdır ve
ikincisi bu yeni tabloyu tanımlamakta kullanılabilecek bir proje
(Blueprint) nesnesi alacak bir anonim fonksiyondur (Closure) .
Mevcut bir veritabanı tablosunun adını değiştirmek için rename
metodu kullanılabilir:
1
Schema::rename($eskisinden, $yeniye);
Şema operasyonunun gerçekleştirileceği bağlantıyı belirlemek için
Schema::connection metodunu kullanınız:
Şema Oluşturucusu
1
2
3
4
5
329
Schema::connection('falan')->create('uyeler', function(\
$table)
{
$table->increments('id');
});
Bir tabloyu yok etmek için, Schema::drop metodunu kullanabilirsiniz:
1
Schema::drop('uyeler');
2
3
Schema::dropIfExists('uyeler');
Sütunların Eklenmesi
Mevcut bir tabloda sütun ekleme için Schema::table metodunu
kullanıyoruz:
1
2
3
4
Schema::table('uyeler', function($table)
{
$table->string('email');
});
Tablo oluşturma zamanında ise tablo oluşturucusunda bulunan
çeşitli sütun tiplerini kullanabilirsiniz:
Komut | Açıklama ————- | ————- $table->bigIncrements('id');
| “big integer” eşdeğeri. $table->bigInteger('puan'); | BIGINT
eşdeğeri sütun $table->binary('veri'); | BLOB eşdeğeri sütun
$table->boolean('teyit'); | BOOLEAN eşdeğeri sütun $table->char('isim',
4); | bir uzunluğu olan CHAR eşdeğeri $table->date('created_at'); | DATE eşdeğeri sütun $table->dateTime('created_at'); |
DATETIME eşdeğeri sütun $table->decimal('miktar', 5, 2); |
Şema Oluşturucusu
330
basamak ve ondalık basamak sayısı belirlenmiş DECIMAL eşdeğeri
sütun $table->double('column', 15, 8); | DOUBLE eşdeğeri
sütun $table->enum('tercihler', array('falan', 'filan'));
| ENUM eşdeğeri sütun $table->float('miktar'); | FLOAT eşdeğeri sütun $table->increments('id'); | Giderek artan ID alanı ekler (birincil anahtar). $table->integer('puan'); | INTEGER eşdeğeri sütun $table->longText('description'); | LONGTEXT eşdeğeri $table->mediumInteger('numbers'); | MEDIUMINT eşdeğeri $table->mediumText('description'); | MEDIUMTEXT eşdeğeri $table->morphs('taggable'); | INTEGER taggable_id ve
STRING taggable_type alanlarını ekler $table->nullableTimestamps();
| NULLlara izin vermek dışında timestamps() ile aynı $table->smallInteger('puan
| SMALLINT eşdeğeri sütun $table->tinyInteger('numbers'); |
TINYINT eşdeğeri $table->softDeletes(); | Belirsiz silmeler için
deleted_at sütunu ekler $table->string('email'); | VARCHAR
eşdeğeri sütun $table->string('isim', 100); | belli uzunlukta VARCHAR eşdeğeri sütun $table->text('izahat'); | TEXT
eşdeğeri sütun $table->time('ikindi'); | TIME eşdeğeri sütun
$table->timestamp('eklenme_vakti'); | TIMESTAMP eşdeğeri
sütun $table->timestamps(); | created_at ve updated_at sütunlarını ekler $table->rememberToken(); | VARCHAR(100) NULL
olarak remember_token ekler ->nullable() | İlgili sütunun NULL
değerleri olabilir demektir ->default($deger) | Bir sütun için ön
tanımlı bir değer tanımlar ->unsigned() | INTEGER’i UNSIGNED
olarak ayarlar
MySQL Veritabanında After Kullanımı
Şayet MySQL veritabanı kullanıyorsanız, sütunların sıralamasını
belirlemek için after metodunu kullanabilirsiniz:
1
$table->string('isim')->after('email');
Şema Oluşturucusu
331
Sütun İsimlerinin Değiştirilmesi
Bir sütun ismini değiştirmek için Şema Oluşturucusunda renameColumn
metodunu kullanabilirsiniz:
1
2
3
4
Schema::table('uyeler', function($table)
{
$table->renameColumn('eski', 'yeni');
});
Not: enum sütun tipleri için isim değiştirme desteklenmemektedir.
Sütunların Yok Edilmesi
Bir Veritabanı Tablosundan Bir Sütunun Yok Edilmesi
1
2
3
4
Schema::table('uyeler', function($table)
{
$table->dropColumn('puan');
});
Bir Veritabanı Tablosundan Birden Çok Sütunun Yok
Edilmesi
1
2
3
4
5
Schema::table('uyeler', function($table)
{
$table->dropColumn(array('puan', 'avatar', 'ikametgah'\
));
});
332
Şema Oluşturucusu
Mevcutluk Yoklanması
Tablonun Var Olduğunun Yoklanması
hasTable ve hasColumn metodlarını kullanarak bir tablo ya da
sütunun var olup olmadığını kolayca yoklayabilirsiniz:
1
2
3
4
if (Schema::hasTable('uyeler'))
{
//
}
Sütunların Var Olduğunun Yoklanması
1
2
3
4
if (Schema::hasColumn('uyeler', 'email'))
{
//
}
İndeks Eklenmesi
Şema oluşturucusu çeşitli indeks tiplerini desteklemektedir. Bunları
iki şekilde ekleyebilirsiniz. Birinci yol bir sütun tanımı sırasında
tanımlamak, ikinci yol ise ayrıca eklemektir:
1
$table->string('email')->unique();
Ya da, ayrı satırlarda indeks ekleme yolunu seçebilirsiniz. Aşağıda,
kullanılabilecek tüm indeks tiplerinin bir listesi verilmiştir:
Komut | Açıklama ————- | ————- $table->primary('id');
| Bir birincil anahtar eklenmesi $table->primary(array('ilk',
'son')); | Bileşik keylerin eklenmesi $table->unique('email');
| Benzersiz bir indeks eklenmesi $table->index('il'); | Basit bir
indeks eklenmesi
Şema Oluşturucusu
333
Yabancı Anahtar (Foreign Key)
Laravel, tablolarınıza yabancı key sınırlaması eklemeniz için de
destek verir:
1
2
$table->foreign('uye_id')->references('id')->on('uyeler\
');
Bu örnekte, uye_id sütununun uyeler tablosundaki id sütununu
referans aldığını beyan ediyoruz.
Ayrıca, güncelleme ve silme (“on delete” ve “on update”) eylemi
sınırlamaları için seçenekler de belirleyebilirsiniz:
1
2
3
$table->foreign('uye_id')
->references('id')->on('uyeler')
->onDelete('cascade');
Bir yabancı keyi yok etmek için, dropForeign metodunu kullanabilirsiniz. Yabancı key için de diğer indeksler için kullanılan
isimlendirme geleneği kullanılır:
1
$table->dropForeign('makaleler_uye_id_foreign');
Not: Otomatik artan bir tam sayıya başvuran bir foreign key oluşturulurken, foreign key sütununu her
zaman için unsigned yapmayı unutmayın.
İndekslerin Yok Edilmesi
Bir indeksi yok etmek için indeksin adını belirtmelisiniz. Laravel,
ön tanımlı olarak indekslere makul bir isim tahsis eder. Tablo adını,
334
Şema Oluşturucusu
indekslenen alan adlarını ve indeks tipini art arda ekler. İşte bazı
örnekler:
Komut | Açıklama ————- | ————- $table->dropPrimary('uyeler_id_primary'); | “uyeler” tablosundan primer key’in yok edilmesi
$table->dropUnique('uyeler_email_unique'); | “uyeler” tablosundan benzersiz bir indeksin yok edilmesi $table->dropIndex('geo_il_index'); | “geo” tablosundan basit bir indeksin yok edilmesi
Zaman Damgaları ve Belirsiz Silmelerin
Yok Edilmesi
timestamps, nullableTimestamps veya softDeletes sütun türleri-
nin yok edilmesi için aşağıdaki metodları kullanabilirsiniz:
Komut | Açıklama ————- | ————- $table->dropTimestamps();
| Tablodan created_at ve updated_at sütunlarının düşürülmesi
$table->dropSoftDeletes(); | Tablodan deleted_at sütununun
düşürülmesi
Depolama Motorları
Bir tablo için depolama motoru ayarlamak için, şema oluşturucusunda engine özelliğini ayarlayınız:
1
2
3
Schema::create('uyeler', function($table)
{
$table->engine = 'InnoDB';
4
$table->string('email');
5
6
});
Migrasyon (Migration) ve
Veri Ekme (Seeding)
Giriş
Migrasyonlar veritabanı için bir sürüm kontrol türüdür. Bir ekibin
veritabanı şemasını değiştirmesine ve son şema durumuna güncel
kalmalarına imkan verir. Migrasyonlar uygulama şemasını kolayca
yönetmek amacıyla tipik olarak Şema (Schema) Kurucu¹⁹³ ile eşleştirilirler.
Migrasyonların Oluşturulması
Bir migrasyon oluşturmak için, Artisan KSA’da (Artisan Komut
Satırı Arayüzü) migrate:make komutunu kullanabilirsiniz:
1
php artisan migrate:make kullanicilar_tablosunu_olustur
Migrasyon app/database/migrations dizininize konumlandırılır
ve Laravel’in migrasyonların sırasını belirlemesine imkan veren bir
zaman damgası içerir.
Migrasyonu oluştururken bir patika --path seçeneği de belirtebilirsiniz. Patika, kurulum kök dizinine göreceli olmalıdır:
1
2
php artisan migrate:make falancaMigrasyon --path=app/mi\
grations
Tablo ismini ve yeni bir tablonun oluşturulacağını da, --table ve
--create seçeneklerini kullanarak belirtebilirsiniz:
¹⁹³/docs/schema
Migrasyon (Migration) ve Veri Ekme (Seeding)
1
2
336
php artisan migrate:make kullanicilar_tablosunu_olustur\
--table=users
3
4
5
php artisan migrate:make kullanicilar_tablosuna_oy_vere\
nler_ekle --create=users
Migrasyonların Çalıştırılması
Bekleyen Migrasyonların Hepsinin Birden
Çalıştırılması
1
php artisan migrate
Bir Patikadaki Migrasyonların Çalıştırılması
1
php artisan migrate --path=app/falancaDizin/migrations
Bir Paketin Tüm Bekleyen Migrasyonlarının
Çalıştırılması
1
php artisan migrate --package=vendor/package
Not: Migrasyonlar çalıştırırken, “class not found” (sınıf
bulunamadı) hatası alırsanız, composer dump-autoload
komutunu çalıştırarak deneyiniz.
Üretim Ortamında Migrasyonların Zorlanması
Bazı migration işlemleri yıkıcıdır, yani verilerinizi kaybetmenize
yol açabilir. Bu komutları üretim veritabanınızda çalıştırmanızdan
korumak amacıyla, bu komutları çalıştırdığınızda sizden teyit etmeniz istenecektir. Bu komutların böyle bir istek olmadan çalışmasını
zorlamak için --force flamasını kullanın:
337
Migrasyon (Migration) ve Veri Ekme (Seeding)
1
php artisan migrate --force
Migrasyonların Geriye Döndürülmesi
Son Migrasyon İşleminin Geriye Döndürülmesi
1
php artisan migrate:rollback
Tüm Migrasyon İşlemlerinin Geriye Döndürülmesi
1
php artisan migrate:reset
Tüm Migrasyon İşlemlerinin Geriye Döndürülmesi ve
Hepsinin Tekrardan Çalıştırılması
1
2
php artisan migrate:refresh
eden
//Veri ekmeler dahil edilm\
3
4
5
php artisan migrate:refresh --seed
edilerek
//Veri ekmeler dahil\
Veritabanına Veri Ekme
Veri Ekme (seeding), migrasyon ile oluşturulacak veritabanı tablosunda gerekli olacak ilk veri kayıtlarının (seed data) oluşturulması
işlemidir(:çevirenin notu). Laravel, veritabanınızın deneme verisi
ile veri ekme için kolaylık sağlayacak olan veri ekme (seed) sınıflarını bulundurur. Bütün veri ekme sınıfları app/database/seeds
dizininde konumlandırılır. Veri ekme sınıflarına istediğiniz isimleri
verebilirsiniz. Fakat isimlendirirken anlaşılacak belli bir geleneğe
uyulması lehinizedir, örneğin KullanicilarTablosunaVeriEkme,
vb. Ön tanımlı olarak, sizin için bir DatabaseSeeder sınıfı tanımlanmıştır. Veri ekme sırasını denetlemenize imkan verecek olan, bu
Migrasyon (Migration) ve Veri Ekme (Seeding)
338
sınıfın ‘çağır’ call metodunu kullanarak diğer veri ekme sınıflarınızı çalıştırabilirsiniz.
Veritabanı Veri Ekme Sınıfı Örneği
1
class DatabaseSeeder extends Seeder {
2
public function run()
{
$this->call('KullanicilarTablosunaVeriEkme');
3
4
5
6
$this->command->info('Kullanıcı tablosuna veri ekildi\
7
8
!');
}
9
10
11
}
12
13
class KullanicilarTablosunaVeriEkme extends Seeder {
14
public function run()
{
DB::table('kullanicilar')->delete();
15
16
17
18
User::create(array('email' => 'falanca@filanca.com'));
19
}
20
21
22
}
Veritabanına veri ekmek için, Artisan KSA’da db:seed (veri ek)
komutunu kullanabilirsiniz:
1
php artisan db:seed
Ön tanımlı olarak, bu db:seed komutu DatabaseSeeder sınıfını
çalıştırır (bu sınıf diğer ekme sınıflarını çağırmak için kullanılabil-
Migrasyon (Migration) ve Veri Ekme (Seeding)
339
mektedir). Buna karşın bireysel olarak çalıştırılacak belirli bir seeder
sınıfını belirtmek için --class seçeneğini kullanabilirsiniz:
1
2
php artisan db:seed --class=KullanicilarTablosunaVeriEk\
me
Veritabanına migrate:refresh (yenile) komutunu kullanarak da
veri ekebilirsiniz, bu komut aynı zamanda bütün migrasyonları
geriye döndürüp, hepsini tekrardan çalıştıracaktır:
1
php artisan migrate:refresh --seed
Redis
Giriş
Redis¹⁹⁴ açık kaynak, gelişmiş bir anahtar-değer deposudur. Anahtarlar stringler¹⁹⁵, hashler¹⁹⁶, listeler¹⁹⁷, kümeler¹⁹⁸ ve sıralı kümeler¹⁹⁹ taşıyabildikleri için sıklıkla bir veri yapısı sunucusu olarak da
ifade edilmektedir.
Not: Eğer PECL aracılığıyla yüklenmiş Redis PHP eklentiniz varsa, app/config/app.php dosyanızda Redis
için kullanılan lakabın ismini değiştirmeniz gereklidir.
Yapılandırma
Uygulamanızdaki Redis yapılandırması app/config/database.php
dosyasında saklanır. Bu dosya içerisinde, uygulamanız tarafından
kullanılan Redis sunucularını içeren bir redis dizisi göreceksiniz:
¹⁹⁴http://redis.io
¹⁹⁵http://redis.io/topics/data-types#strings
¹⁹⁶http://redis.io/topics/data-types#hashes
¹⁹⁷http://redis.io/topics/data-types#lists
¹⁹⁸http://redis.io/topics/data-types#sets
¹⁹⁹http://redis.io/topics/data-types#sorted-sets
341
Redis
1
'redis' => array(
2
'cluster' => true,
3
4
'default' => array('host' => '127.0.0.1', 'port' => 63\
5
6
79),
7
8
),
Geliştirme için bu “default” sunucu yapılandırması yeterlidir. Yine
de siz ortamınıza göre bu diziyi değiştirmekte serbestsiniz. Sadece
her Redis sunucusuna bir ad verin ve bu sunucu tarafından kullanılan ana bilgisayarı (host) ve bağlantı noktasını (port) belirtin.
Buradaki cluster seçeneği Laravel Redis istemcisine Redis düğümleriniz arasında istemci taraflı bölümlendirme (sharding) yapmasını söylemektedir. Böylece siz düğüm havuzu ve büyük miktarda kullanılabilir RAM oluşturabilirsiniz. Bununla birlikte istemci
taraflı bölümlendirmenin başarısızlık durumlarını halledemediğini
unutmayın. Bu nedenle, istemci taraflı bölümlendirme, esasında
başka bir asıl veri deposunda olup da önbelleğe alınmış veriler için
uygundurlar.
Şayet sizin Redis serveriniz authentication istiyorsa, Redis server
yapılandırma dizinize bir password anahtar / değer çifti eklemek
suretiyle bir şifre sağlayabilirsiniz.
Kullanım
Bir Redis olgusunu Redis::connection metodunu çağırarak getirebilirsiniz:
1
$redis = Redis::connection();
Redis
342
Bu size “default” Redis sunucusunun bir olgusunu verecektir. Eğer
sunucu öbekleme (clustering) kullanmıyorsanız, Redis yapılandırmanızda tanımlanan belirli bir sunucuyu getirmek için connection
metodunda parametre olarak o sunucunun adını geçersiniz:
1
$redis = Redis::connection('digerSunucu');
Redis istemci olgusu oluşturduktan sonra, artık bu olguya her
türlü Redis komutu²⁰⁰ verebiliriz. Laravel Redis sunucusuna komut
geçerken sihirli metodlar tekniğini kullanır:
1
$redis->set('isim', 'Tuana Şeyma');
2
3
$isim = $redis->get('isim');
4
5
$degerler = $redis->lrange('isimler', 5, 10);
Görüldüğü gibi komut parametreleri basitçe sihirli metodlara geçilmektedir. Tabii ki siz sihirli metod tekniğini kullanmak zorunda
değilsiniz, command metodunu kullanarak da sunucuya komut geçebilirsiniz:
1
$degerler = $redis->command('lrange', array(5, 10));
Komutlarınızı sadece “default” bağlantıda çalıştıracağınız zaman,
direkt Redis sınıfındaki statik sihirli metodları kullanın:
²⁰⁰http://redis.io/commands
343
Redis
1
Redis::set('isim', 'Tuana Şeyma');
2
3
$isim = Redis::get('isim');
4
5
$degerler = Redis::lrange('isimler', 5, 10);
Not: Redis Önbellekleme²⁰¹ ve Oturum²⁰² sürücüleri
Laravel’de mevcuttur.
Pipeline Kullanma
Bir operasyonda sunucuya birçok komut göndermeniz gerektiğinde
pipeline kullanılmalıdır. Bunu yapmak için pipeline komutunu
kullanın:
Sunucularınıza Birden Çok Komutun Döşenmesi
1
2
3
4
5
6
7
Redis::pipeline(function($pipe)
{
for ($i = 0; $i < 1000; $i++)
{
$pipe->set("key:$i", $i);
}
});
²⁰¹/docs/cache
²⁰²/docs/session
Artisan CLI
Giriş
Artisan, Laravel içerisinde gelen CLI’ın (Command-line Interface) adıdır. Artisan size uygulamanızı geliştirirken birçok yardımcı
komut sağlar. Artisan, güçlü Symfony Console bileşeni üzerinden
geliştirilmiştir.
Kullanım
Tüm Kullanılabilir Komutların Listelenmesi
Tüm Artisan komutlarının bir listesini görmek için list komutunu
kullanabilirsiniz:
1
php artisan list
Bir Komut için Yardım Ekranının Görüntülenmesi
Tüm komutların özel bir “yardım” ekranı vardır ve komut hakkındaki argüman sırası ile ayarlar gibi bilgilerin açıklanmasını sağlar.
Bir yardım ekranını görüntülemek için komut adından önce help
yazın:
1
php artisan help migrate
Yapılandırma Ortamının Belirtilmesi
--env anahtarını kullanarak bir komut çalıştırılırken kullanılacak
olan yapılandırma ortamını belirtebilirsiniz:
Artisan CLI
1
345
php artisan migrate --env=local
Güncel Laravel Sürümünüzün Gösterilmesi
Ayrıca Laravel yüklemenizin güncel sürümünü de --version seçeneğini kullanarak görebilirsiniz:
1
php artisan --version
Artisan’ın Geliştirilmesi
Giriş
Artisan’da mevcut olan komutlara ilaveten, uygulamanız ile çalışacak olan kendi özel komutlarınızı inşa edebilirsiniz. Bu özel komutlarınızı app/commands dizininde depolayabilirsiniz. Komutlarınızı
kendi istediğiniz başka bir dizinde de depolayabilirsiniz. Bunun için,
bu komutlarınızın composer.json ayarlarınız bazında “autoload”
edilebiliyor olması gerekmektedir.
Komut Oluşturulması
Sınıfının Oluşturulmması
Yeni bir komut oluşturmak için, command:make Artisan komutunu
kullanabilirsiniz. Bu komut, başlamanızda size yardımcı olmak için
yeni bir komut taslağı oluşturacaktır.
Yeni Bir Komut Sınıfının Oluşturulması
1
php artisan command:make FalancaKomut
Ön tanımlı olarak, oluşturulan komutlar app/commands dizininde
depolanırlar. Fakat, siz başka bir dizin veya bir ‘namespace’ de
belirleyebilirsiniz.
1
2
php artisan command:make FalancaKomut --path=app/classe\
s --namespace=Siniflar
347
Artisan’ın Geliştirilmesi
Bir komut oluşturulurken terminal komut adı atamak için --command
seçeneği kullanılabilir:
1
2
php artisan command:make AssignUsers --command=users:as\
sign
Komutun Yazılışı
Komut oluşturulduktan sonra, komutu list ekranında görüntülerken kullanılacak olan, sınıf ismi name ve tanımı description
özellikleri doldurulmalıdır.
Komut çalıştırıldığında fire (ateşle) metodu çağırılmaktadır. Bu
metoda, istenecek herhangi bir komut mantığı yerleştirebilinir.
Argümanlar & Seçenekler
Komutunuzun alacağı argüman veya seçenekleri tanımlayabileceğiniz yerler getArguments ve getOptions metodlarıdır. Bu metodların her ikisi de birer komut dizisi verirler. Bu komut dizileri, bir
‘dizi seçenekleri listesi’ ile tarif edilirler.
Argümanları (arguments) belirlerlerken, dizi tanımı değerleri şunları belirler: (ismi, modu, tanımı, ön değeri)
1
array($name, $mode, $description, $defaultValue)
Modu argümanı mode şunlardan herhangi biri olabilir: InputArgument::REQUIRED
(mecburi) veya InputArgument::OPTIONAL (isteğe bağlı).
Seçenekleri (options) belirlerken, dizi tanımı değerleri şunları belirler: (ismi, kısayolu, modu, tanımı, ön değeri)
Artisan’ın Geliştirilmesi
1
2
348
array($name, $shortcut, $mode, $description, $defaultVa\
lue)
Seçenekler için, modu argümanı mode şunlardan biri olabilir: InputOption::VALUE_REQUIRED (Girdi Seçeneği: mecburi), InputOption::VALUE_OPTIONAL
(isteğe bağlı), InputOption::VALUE_IS_ARRAY (dizi), InputOption::VALUE_NONE (yok).
VALUE_IS_ARRAY (Girdi Seçeneği: dizi) modu, komut çağırılırken,
anahtarın birden çok kez kullanılabilir oldugunu belirtir:
1
php artisan falan --option=filan --option=fesmekan
VALUE_NONE (Girdi Seçeneği: yok) modu, seçeneğin sadece bir “anah-
tar” olarak kullanıldığını belirtir.
1
php artisan falan --option
Girdilerin Çağırılması
Komutunuz çalışırken, uygulamanızın kabul edeceği argüman ve
seçenek değerlerine ulaşabilmeniz gerekecektir. Bunu yapabilmek
için argüman argument ve seçenek option metodlarını kullanabilirsiniz:
Bir Komut Argüman Değerinin Çağırılması
1
$value = $this->argument('ismi');
Tüm Argümanların Birden Çağırılması
349
Artisan’ın Geliştirilmesi
1
$arguments = $this->argument();
Bir Komut Seçeneği Değerinin Çağırılması
1
$value = $this->option('ismi');
Tüm Seçeneklerin Birden Çağırılması
1
$options = $this->option();
Çıktı Yazılışı
Çıktının konsola gönderilmesi için, info (bilgi), comment (not),
question (soru) ve error (hata) metodlarını kullanabilirsiniz. Bu
metodların her biri, kendi amaçlarına uygun olan ANSI renklerini
kullanacaktır.
Konsola Bilgi Gönderilmesi
1
$this->info('Bunu ekranda göster');
Konsola Bir Hata Mesajı Gönderilmesi
1
$this->error('Bir hata oluştu!');
Soruların Soruluşu
Kullanıcıdan bir girdi talep etmek için, ask (sor) ve confirm (onayla)
metodlarını kullanabilirsiniz.
Kullanıcıya Girdi Bilgisinin Soruluşu
Artisan’ın Geliştirilmesi
1
350
$name = $this->ask('İsminiz nedir?');
Kullanıcıya Gizli Şifre Bilgisinin Soruluşu
1
$password = $this->secret('Lütfen şifrenizi giriniz!');
Kullanıcıya Onayının Soruluşu
1
2
3
4
5
if ($this->confirm('Devam etmek istiyor musunuz? [evet|\
hayır]'))
{
//
}
İsterseniz confirm (onayla) metoduna, true (evet) ve false (hayır)
seçeneklerinden birini varsayılan ön değer olarak belirleyebilirsiniz
:
1
$this->confirm($soru, true);
Komutların Kayıt Ettirilmesi
Bir Artisan Komutunun Kayıt Ettirilişi
Komutunuzun inşa edilmesi tamamlandığında, kullanılmaya hazır
olabilmesi için, Artisan’da kayıt ettirmeniz gerekir. Bu, genelde
app/start/artisan.php dosyası içerisinde yapılır. Bu dosya içerisinde, kayıt ettirmek için Artisan::add metodunu kullanabilirsiniz.
1
Artisan::add(new FalancaKomut);
Artisan’ın Geliştirilmesi
351
IoC Container’da Olan Bir Komutun Kayıt Ettirilişi
Eğer komutunuz IoC container²⁰³ uygulamasında kayıtlı ise, Artisan’da da kullanılabilir olması için Artisan::resolve metodunu
kullanabilirsiniz.
1
Artisan::resolve('binding.ismi');
Komutların Bir Hizmet Sağlayıcısında Kayda
Geçirilmesi
Eğer komutları bir hizmet sağlayıcısı içerisinden kayda geçirmeniz
gerekirse, sağlayıcının boot metodundan commands metodunu çağırmalı ve çağırırken ilgili komutun IoC konteyneri²⁰⁴ bağlamasını
geçmelisiniz:
1
2
3
4
public function boot()
{
$this->commands('command.binding');
}
Diğer Komutların Çağırılması
Bazı durumlarda, komutunuzun içerisinden başka bir komutu çağırmak isteyebilirsiniz. Bunu, call metodunu kullanarak yapabilirsiniz:
1
2
$this->call('command.ismi', array('argument' => 'falan'\
, '--option' => 'filan'));
²⁰³/docs/ioc
²⁰⁴/docs/ioc