Etiket arşivi: laravel

Laravel’de Middleware kullanımı ve yanıt süresini loglama

Aslında sadece yanıt süresini loglamayı anlatıcaktım ama burada işimiz Middleware ile olacağı için onun da ne olduğunu anlatayım istedim. Middleware, kelime anlamıyla, “ara katman – orta katman” anlamına gelir. Kelime anlamıyla çok uyumlu bir programlama terimi. Bu sefer Laravel’in bir uydurması değil, zaten olan birşey. Bu yazımda “Laravel süper isimlendiriyor yawww” diye övmeyeceğim.

Laravel’de middleware, HTTP istekleri ile isteğin gerçekleşmesi arasında ya da http isteği gerçekleştikten sonra çalışacak şekilde durur. Şöyle ki, Laravel ile yazılmış site.com/hakkimizda sayfasını açmak istediğinizde, Laravel önce router dosyasına bakar, işler ve ilgili controller methodunu çalıştırır. Hah, işte tam bu noktada; router isteği işledikten sonra, controller’a yönlendirmeden önce -eğer tanımlandıysa- middleware sınıfımıza yönlendirir. Middleware çalışır, istenilen kontroller/güncellemeler yapılır, eğer middleware izin verirse controller’a yönlendirilir. (controller’a ne kadar acayip bi kelime ya)

Yani middleware, route ile controller arasında bir ARA KATMANdır. Ara katman’ı büyük yazdım çünkü, sadece Laravel’deki kullanımına bakarsak, controller&route arasındaki katman olduğunu zannedebiliriz. Oysa araya girme niyetindeki herşey bir middleware olabilir. Google Translate’teki tanımına bakalım:

“`software that acts as a bridge between an operating system or database and applications, especially on a network.“`

Yani diyor ki, “bir işletim sistemi/veritabanı ve uygulamalar arasında köprü görevi gören yazılımlardır.” Özellikle bir networkte diye belirtmiş. “Bir network”ü ben şu şekilde yorumluyorum: bir sistemde/yapıda. Dahili bir biçimde. Neyse çok detaya girip kafa karıştırmayayım, benim kafam karıştı bile. Yine de girmek isteyen olursa katkılarını eklerim.

Laravel’de Middleware

Middleware ile ilgili dökümantasyon şurada bulunuyor: https://laravel.com/docs/master/middleware Laravel 2 tip middleware oluşturmuş. Birincisi, aşina olduğumuz request-controller arası çalışan middleware. Diğeri de response verildikten sonra çalışan “terminable” middleware.

Aşina olduğumuz middleware için şu örneği verebiliriz: Girilen sayfaya, bir kullanıcının yetkisinin olup olmadığını kontrol eden middleware. Kodu ise şu şekildedir:

<?php

    public function handle($request, Closure $next)
    {
       //burada gerekli işlemleri yapıyoruz. örneğin üyenin yetkisi var mı yok mu kontrol edebiliriz.
       //ya da buna benzer şeyler. 

        return $next($request);
    }

$request değişkenimiz, IlluminateHttpRequest sınıfının ta kendisi. Yani bizim o anki isteğimiz ile ilgili herşeyi bilen sınıf. (Bence birisi bu sınıf üzerine bir yazı yazmalı.) O an hangi route çalışıyor, hangi parametreler almış, sessionda neler var, cookiede neler var vs vs gibi onlarca sorunun cevabı bu sınıf içerisinde. Bu bilgiler ışığında istediğiniz kontrolü yapabilirsiniz. Tabi middleware sadece “kontrol etmek” için kullanılmıyor. Aynı zamanda sisteme yeni parçalar da dahil edebilirsiniz. Herşey sizin elinizde.

Terminable Middleware

Bu middleware sınıfı, HTTP sonucu, yani Response, tarayıcıya (istemciye) gönderildikten sonra çalışır. Bitiş middlewarelerinde handle methodundan farklı olarak bir de terminate methodu çalışır. Ve bu method $request sınıfına sahip olmakla birlikte, bir de $response sınıfına sahiptir. Response sınıfı sayesinde, istemciye ne sonuç gönderildiğini biliriz ve buna göre istediğimiz işlemi yaparız.

<?php

    public function terminate($request, $response)
    {
        // burada bişeyler yapabiliriz.
        // artık response tarayıcıya gönderildi. 
        // örneğin, responsu kontrol ederiz. diyelim ki 422 sonuç kodu dönüyor.
        // o zaman bunu loglatalım, gibi fantazi işler yapılabilir. 
    }

Laravel’de derleme süresini öğrenme

Laravel’deki  public/index.php dosyasına baktığımızda, LARAVEL_START adında bir sabit değişken tanımlandığını görürüz. Bu, Laravel’e ilk istek geldiği anda tanımlanır. Yani ilk çalışan kodumuzdur. Şimdi bir de yapmamız gereken, en son çalışma anında süreyi tespit etmek ve aradaki farkı loglara göndermek.

Bunun için standart bir middleware oluşturalım. php artisan make:middleware ResponseTimeMiddleware güzel bir başlangıç olacaktır. Daha sonra bu middleware’i AppHttpKernel dosyamızdaki $middleware dizisi içerisine ekleyelim. Böylece tüm requestlerde bu eklediğimiz middleware çalışmış olacak. Yeni oluşturduğumuz middleware’e aşağıdaki terminate fonksiyonunu ekleyelim:

<?php

    ....

    public function terminate(Request $request, Response $response)
    {
        \Log::debug($request->getPathInfo().' =>  '.(microtime(true) - LARAVEL_START));
    }

Böylece uygulama başlangıcından itibarek geçen süreyi loglarımıza yazdırmış olduk. Response süresini loglara yazdırıp debug yapmak çok etkili bir yöntem gibi gözükmese de bazen çok hızlı biçimde sorunlu sayfaları bulmanıza yardımcı olabiliyor. Ama ben genelde production ortamında, daha detaylı bilgi veren NewRelic hizmetini kullanıyorum. Hem sayfaların ortalama response sürelerini kolayca öğrenebiliyorum hem de veritabanı sorgularını detaylıca inceleyebiliyorum. Hangi query ne kadar sürmüş vs diye. Tavsiye ederim.

Laravel’de UUID kullanımı

Buraya kadar geldiğinize göre muhtemelen ne olduğunu biliyorsunuzdur ama yine de Laravel’de UUID’nin nasıl kullanıldığını anlatmaya başlamadan önce kısaca bir UUID tanımını yapalım ve ne olduğunu anlatmaya çalışalım.

UUID, “Universally unique identifier” nin kısaltılmışıdır. Kabaca çevirirsek, evrensel(?) benzersiz tanımlayıcı diyebiliriz. Normalde veritabanında satırları tanımlayıcı olarak integer kullanırız. UUID ise, 36 karakterlik, sayılar ve harflerden oluşan, bir settir. Ve en önemli özelliği, yüksek derecede benzersiz olmasıdır. (Bilgisayarda rastgele üretilen hiçbir şey aslında tam olarak rastgele değildir. Rastgeleliği arttırabiliriz. Değişik bi konu.)

Örnek olarak şöyle bir kaç tane gösterebilirim:

UUID genellikle büyük projelerde işe yarayabiliyor. Biliyorsunuz, veritabanında integer alanının maximum değeri var. Mysql’deki değeleri şuradan görebilirsiniz: https://dev.mysql.com/doc/refman/5.7/en/integer-types.html

Burada minimum-maximum değerlere bir paragraf açıyorum. Veritabanında id alanı, Primary Key olarak tanımlanır. PrimaryKey alanı doğası gereği unsigned olarak tanımlanır. Bu yüzden ilgilendiğiniz alan unsigned olmalı. Peki unsigned değer ne demek? Negatif olmayan sayılar demek. Linkteki tabloya baktığımızda, TinyInt türü için signed [-127, 127] aralığındayken, unsigned [0, 255] aralığında değer alabiliyor.

Primary key, varsayılan olarak INT, unsigned tanımlanır. Bu da demektir ki, o tabloya maksimum 4294967295 kayıt eklenebilir. Sanırsam, 4 milyar 294 milyon 967 bin 295 kayıt. Her ne kadar çok büyük bir sayı olsa da, sonsuz değil. Eğer uuid olarak tanımlarsanız, sonsuz kayıt ekleyebilirsiniz. (Acaba öyle mi? Keşke birisi bunun doğrulamasını yapsa) Maksimum kaç kayıt eklenebileceği ile ilgili yanıt: https://twitter.com/hkanaktas/status/906891710155849730

Bunun haricinde, çok olası değil ama, bir tablonuz dağıtık biçimde çalışıyorsa, primary key alanınızın çakışmasını önler. Farazi bir örnek verelim. Diyelim ki kullanıcının gezdiği sayfaları kayıt altına alıyorsunuz. Öyle ki, çok yoğun bir sistem ve kayıtları %50 A sunucusundaki logs tablosuna, %50 B sunucusundaki logs tablosuna kaydediyorsunuz. Günün sonunda verileri C sunucusunda birleştirmek istediğinizde, id alanı çakışacaktır. Bunun için idleri yeniden vermeniz gerekmektedir. Fakat uuid kullanırsanız, herhangi bir yenileme yapmadan doğrudan verileri birleştirebilirsiniz.

Son olarak şunu söyleyeyim, tahmin edilmesi oldukça zordur. Örneğin kullanıcılar tablomuzda int kullansaydık, üye kayıtları 1,2,3,4,5 diye düzenli olarak gidecekti. Ve emin olun saldırganlar ilk olarak url’deki idleri değiştirerek erişim sağlamaya çalışır. Gerekli kontrolleri aldıysanız sıkıntı olmaz. Fakat uuid ile bu sıkıntı daha da az yaşanır. Çünkü bir sonraki kullanıcının id’si tahmin edilemez hale gelir. Siz yine de arka tarafta gerekli kontrolleri yapmayı unutmayın.

Gelelim Laravel Kulanımına

UUID’leri üretmek için ek paket kullanmamız gerekiyor. Ben ramsey/uuid paketini kullanıyorum.

$ composer require ramsey/uuid

Bu paket sayesinde artık UUID üretebiliriz. README dosyasında kullanımı var, ama kısaca ben de buradan tekrar edeyim:

<?php
 // Generate a version 1 (time-based) UUID object
    $uuid1 = Uuid::uuid1();
    echo $uuid1->toString() . "n"; // i.e. e4eaaaf2-d142-11e1-b3e4-080027620cdd

    // Generate a version 3 (name-based and hashed with MD5) UUID object
    $uuid3 = Uuid::uuid3(Uuid::NAMESPACE_DNS, 'php.net');
    echo $uuid3->toString() . "n"; // i.e. 11a38b9a-b3da-360f-9353-a5a725514269

    // Generate a version 4 (random) UUID object
    $uuid4 = Uuid::uuid4();
    echo $uuid4->toString() . "n"; // i.e. 25769c6c-d34d-4bfe-ba98-e0ee856f3e7a

    // Generate a version 5 (name-based and hashed with SHA1) UUID object
    $uuid5 = Uuid::uuid5(Uuid::NAMESPACE_DNS, 'php.net');
    echo $uuid5->toString() . "n"; // i.e. c4a760a8-dbcf-5254-a0d9-6a4474bd1b62

Bu pakette toplam 4 çeşit üretme yöntemi var. Hangisini kullanacağınız konusunda tercih size kalmış. Ben farklarını bilmiyorum, araştırmadım.

Göç yolları, göründü bize

Paketi yükledikten sonra, ilk değişikliğimiz migration yazımında karşımıza çıkıyor.

Normalde bir migration oluşturduğunuzda şu şekilde oluyor:

$table->increments('id');

Bu fonksiyonun detayına baktığımızda, unsignedInteger tipinde oluşturduğunu göreceksiniz. Bunun yerine şunu yazmamız daha manidar:

$table->uuid('id')->primary();

ID alanımızın uuid türünde olduğunu, ve bu alanın tablomuzun birincil alanı(reyizi) olduğunu söyleyerek tablomuu oluşturuyoruz. Bu da aslında özel bir kolon türü değil, 36 karakterlik char alanı oluşturuyor tablomuzda.

Model dosyalarında değişiklik

İlk önce modelin primary key’in otomatik artma özelliğini kapatalım. Eloquent’te primary key, varsayılan olarak int, auto increment olarak kabul edilir. Bunu değiştirelim.

<?php

class Bilmemne extends \Illuminate\Database\Eloquent\Model {
 
    public $incrementing = false;

}

Otomatik arttırmayı kapattık ama, şimdi de bir modeli kaydetmek istediğimizde, otomatik olarak sayı yazmaya çalışacak eloquent. Bunun için Eloquent event’lerinden yararlanıyoruz:

<?php

class Bilmemne extends \Illuminate\Database\Eloquent\Model {
 
    public $incrementing = false;

    protected static function boot()
    {
        parent::boot();
 
        static::creating(function ($model) {
            $model->{$model->getKeyName()} = \Ramsey\Uuid\Uuid::uuid1()->toString();
        });
    }

}

Peki bu kod ne yapıyor? $model->save() komutunu çalıştırdığınızda, model verileri, veritabanına kaydedilmek üzere hazırlanıyor. Bu kod sayesinde, modelimiz veritabanına kaydedilmeden önce ‘id’ alanının değerini uuid ile değiştiriyoruz.

Hepsi bu! Artık id alanımız integer yerine uuid olarak kaydediliyor. Fakat burada göze güzel görünmeyen birşey var. Bu kodu tüm modellere tek tek kopyalayıp yapıştıracağız. Bunun önüne geçmek için yapabileceğimiz 2 şey var. Birincisi, extend edilen sınıfı değiştirmek. İkincisi ise Trait kullanmak.

1. Yöntem: Extend edilen sınıfı değiştirmek

Öncelikle yeni bir model sınıfı üretelim.

<?php

class MyModel extends \Illuminate\Database\Eloquent\Model
{
    public $incrementing = false;

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            $model->{$model->getKeyName()} = \Ramsey\Uuid\Uuid::uuid1()->toString();
        });
    }
}

Daha sonra kendi sınıfımızın ayarlarıyla oynayalım:

<?php 

class Bilmemne extends MyModel { 

}

Bilmemne modelimiz artık integer yerine uuid üretiyor!

2. Yöntem: Trait kullanmak

Bildiğiniz gibi bir sınıf birden fazla sınıftan türetilemiyor(extend edilemiyor). Siz birden fazla sınıfın özelliğini kullanmak isterseniz ya hepsini birbirinden extend edeceksiniz -ki etmeyin- ya da trait kullanarak istediğiniz methodları kullanacaksanız. Laravel’e baktığımızda trait kullanımının yoğun olduğunu görürüz. Traitler bize kodların yeniden kullanımı konusunda yardımcı olur. Tekrar yazımların önüne geçer. Kodumuzu parçalara bölebilmemizi sağlar ve kodun kolay takibini sağlar. Örnek olarak Laravel’in model sınıfının neler kullandığına bakalım:

<?php

abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable, QueueableEntity, UrlRoutable
{
    use ConcernsHasAttributes,
        ConcernsHasEvents,
        ConcernsHasGlobalScopes,
        ConcernsHasRelationships,
        ConcernsHasTimestamps,
        ConcernsHidesAttributes,
        ConcernsGuardsAttributes;
}

Model sınıfı yorumlar da dahil 1460 satır. Traitlerin içindeki methodları da bu sınıfa dahil etseydik kim bilir kaç satır olacaktı. Kodun birbiriyle ilgili bölümlerini alıp trait içerisine koyup, traiti de model içerisinde sadece use ile çağırmak oldukça güzel bir fikir. Daha övülecek çok yanı vardır da, hem şimdi aklıma gelmiyor(hepsini bilmiyor da olabilirim) hem de artık kendi trait kodumuza geçelim.

<?php

trait UuidsTrait
{
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            $model->{$model->getKeyName()} = \Ramsey\Uuid\Uuid::uuid1()->toString();
        });
    }
}

Tek yapmamız gereken, bunu modelimiz içerisinde kullanmak:

<?php

class Bilmemne extends \Illuminate\Eloquent\Database\Model { 
    
    use UuidsTrait;
}

Bu da tam olarak istediğimiz gibi sonuç verecek ve integer yerine uuid kullanmamızı sağlayacak.

Trait olarak kullanmak ve extend etmek arasında belli farklar var fakat onları başka bir yazı konusu yapabiliriz. Şimdilik ben size bu iş için trait kullanmanızı öneririm.

Esenlikle kalın.

 

Laravel 5.3 change mail configuration dynamically

If you are developing CMS software or a SaaS product, your customers needs to set their mail sending credentials for sending mails from their system. By default, you can set mail configuration to .env file.

But if your customer don’t have access to .env file and command line to execute artisan config:clear command, they need to change credentials from their panel. Here is an example:

I store these values at database. So, i need to change mail config before sending email. But, Laravel’s

config()->set('mail',$values);

doesn’t work. Because, SwiftMailer instance registers when compiling Service Providers with default parameters which are coming from .env file. So, there is two option for override this instance.

1- Create new Swift_Mailer instance and set it before sending email.

<?php
$swiftMailer = new Swift_Mailer();
//do your configuration with swift mailer
Mail::setSwiftMailer($swiftMailer);
Mail::to('mail')
->send();

But, i do not use this metod. I don’t want to fight with SwiftMailer’s configuration. And also, it’s bad architect. It stand againts Dependency Injection.

2- Override MailService Provider

It has 3 step to set-up.

a) Create AppManagerMailTransportManager. (You can use your namespace.) In this file, we will get mail configuration from database (or wherever you save) and will set to laravel’s config.

<?php
/**
 * @author Guven Atbakan
 */

namespace AppManager;

use AppModulesSettingServiceSettingService;
use IlluminateMailTransportManager;

class MailTransportManager extends TransportManager
{
    public function __construct(IlluminateFoundationApplication $app)
    {
        $settings = []; //get your settings from somewhere

        /
            $this->setDefaultDriver('smtp');
            $this->app['config']['mail'] = [
                'driver' => 'smtp',
                'host' => $settings['mailHost'] ?? 'smtp.yandex.net',
                'port' => $settings['mailPort'] ?? 465,
                'from' => [
                    'address' => $settings['mailFromAddress'] ?? '',
                    'name' => $settings['mailFromName'] ?? '',
                ],
                'encryption' => 'tls',
                'username' => $settings['mailUsername'] ?? '-',
                'password' => $settings['mailPassword'] ?? '-',
                'sendmail' => $settings['mailSendmailPath'] ?? '/usr/sbin/sendmail -bs',
                'pretend' => false,
            ];

            config()->set('mail', $this->app['config']['mail']);
            //i'm not sure if its necessary.
    }
}

b) Create AppProvidersCustomMailServiceProvider. In this file, we will tell  to swift mailer, use our MailTransportManager.

<?php

namespace AppProviders;

use AppManagerMailTransportManager;
use IlluminateMailMailServiceProvider;

class CustomMailServiceProvider extends MailServiceProvider
{
    protected function registerSwiftTransport()
    {
        $this->app['swift.transport'] = $this->app->share(function ($app) {
            return new MailTransportManager($app);
        });
    }
}

 

c) By using config/app.php, we will disable default MailServiceProvider and register our CustomMailServiceProvider. It’s easy.

<?php
//IlluminateMailMailServiceProvider::class,
AppProvidersCustomMailServiceProvider::class,

Ali’ye cevaben: Neden Laravel kullanıyorum?

Ali Gündoğdu, Neden Laravel Kullanmıyorum başlıklı bir yazı yayınlamış. Çok fazla yazacak şey bulamıyorum, fırsat bulmuşken bir yazayım dedim. Hem Laravel kullandığım için söz hakkı düştüğünü düşündün hem de polemik olsun dedim. Gerçi burada Laravel’i düşündüğünüz kadar savunmayacağım.

PHP’de aşağı yukarı herkesin hikayesi aynıdır. Önce fonksiyonlar.php dosyası vardır, sonra sınıf kavramıyla tanışılır. Bir klasör içerisinde resim yükleme, form doğrulama, veritabanı, email gönderme, belki smarty gibi bir template motoru vardır ve artık bunları kullanmaya başlarız. Tebrikler, kendi frameworkümüzü yapmayı başardık :)

Zaman geçtikçe bu bize yetmez. Gerek yapmaya başladığımız projeler büyür, gerek bizim ufkumuz genişler. Adım adım, büyürüz ve gerçek bir framework ile tanışırız. (Bu arada direkt büyük projenin içine düşen ya da araştırmacı ruhuyla programlamaya düzgün başlayan bazı şanslı veletler vardır, onlara dicek söz yok. Döngüyü bozdunuz ulan!)

Mesela ben bu frameworklerden ilk olarak Yii ile tanıştım (ismen tanıştık). Bir yazılımcı abimiz; böyle böyle bişey var, süper, şunu yapıyo, bunu yapıyo gibi şeyler söyleyince neymiş la bu bir bakayım dedim. Baktım ve hiç bir şey anlamadım. Bana bir kaç gömlek üstün geldi. Çünkü framework nedir bilmiyorken direkt Yii ile başlamak, ağır bir model kavramı ile tanışmak zordu. Gel zaman git zaman, rahmetli Codeigniter abimiz ile tanıştım. CI’yi öğrenmem yaklaşık 1 günümü aldı. Çünkü gerçekten çok basit bir dökümantasyonu vardı. “+Ne yapmak istiyorsun? -Resim yükleyeceğim. +Buyur, bu şekilde yapabilirsin” gibi net cevaplar içeren bir dökümantasyon. Düşünmene gerek yok, fazla araştırmana gerek yok. Copy-paste yeterli :) Neyse, CI beni uzun bir süre götürdü. Ben bunu baya baya kullandım.

Gün geldi, ihtiyaçlar büyüdü. CI’nin geliştirmesi durduruldu, zaten sürekli $this-> yazmaktan kollarım yoruldu. Daha sonra Ali’yle bir projeye başladık. Çok şükür, CI’nin adı bile geçmedi projede. En azından o bilinç varmış. Ali’nin yazısında bahsettiği, Symfony/Silex, ZF1, Doctrine içeren yapıyı kullanmaya başladık. Ne de iyi yapmışız!

Peki Laravel bu yazının neresinde? Başlayalım Laravel kısmına. Kendi yönettiğin projelerde belki kendine has bir yapı kullanmak güzel, fakat ileride projeyi devretmen gerekirse ya da projeye birilerini dahil etmen gerekirse sıkıntı yaşayabilirsin. Bunun temel sebebi dökümantasyondur. Ne nasıl yapılırın cevabını iyi vermen gerekiyor. Bunun için eğer kendi yapını kullanacaksan, en başından itibaren sürekli dökümantasyon yazman gerekiyor. Kod yorumlarından bahsetmiyorum, bildiğin framework dökümantasyonu gibi yazman gerekiyor. Burada bir parantez açıyorum. Kullandığınız her parçanın bir dökümantasyonu var. Her biri süper dökümantasyon olsa da sizin yapınızda bir bütün oluşturmayacak. Sizin yazdığınız dökümantasyonda bu parçaları birleştirmeniz gerekiyor.

Laravel’in dökümantasyonu, öğrenme açısından oldukça iyi hazırlanmış durumda. Tam benim gibi üşengeç, dummy(bu tam olarak ne demek bilmiyorum, havalı durur diye düşündüm) tiplere hitap ediyor. Öğrenmesi kolay, geliştirme yapması hızlı. Ama burada, Ali’nin bahsettiği, geriye dönük dökümantasyon sorunu ortaya çıkıyor. Bugün 5 sürümü hazırlanan Laravel için 1 yıl sonra 4 sürümüne ait dökümantasyona erişebilecek miyiz ve tüm talepleri karşılayabilecek mi? Evet, versiyonlama sistemi başlı başına sıkıntılı. Ben belki de bu geriye dönük dökümantasyonu ve versiyonlamayı göz ardı ederek bir hata yapıyorum ama burada tercih ettiğim şey hızlı öğrenme süreci. Hızlı öğrenme süreci sayesinde hem projeyi daha hızlı gerçekleştirebilir hem de gelecekte birisinin projeye dahil olması durumunda adaptasyon kolay olur ki zaten bugün elini sallasan Laravel bilen birine çarpıyor. (Eskiden CI öyleydi :))

Bu konudaki sorulması gereken soru şu: Kullandığın frameworkün geriye dönük desteğinin kısıtlı olmasına ne kadar tölerans gösterebilirsin?

Diğer bir noktadan, “kendi yapını oluşturmak” bir takım sıkıntıları daha doğuruyor. Bunlardan ilki dökümantasyondu. İkinci problem ise, her ne kadar güçlü frameworkleri arkana alsan da, sen gerek mimari açıdan gerekse pratik açıdan doğru bir yapı kurabiliyor musun? Örneğin ben bunu kesinlikle göze alamıyorum. Tek başıma girdiğim bir projede artık kendi yapımı kullanamam. Çünkü bunu oluşturabilecek kadar yeterli teknik bilgiye sahip değilim. Hatta şöyle diyelim, eskisi kadar cahil değilim, bu yüzden kendi yapımı oluşturamam :) Ama 2-3 kişi olursun, herkes belli bir bilgi birikimine sahiptir, o zaman kendi yapını kurma girişimlerine başlayabilirsin. Gerek doğru/en iyi mimariyi kurabilmek, gerek hataların takibini yapabilmek ve sorunları çözebilmek, gerek ne bileyim başka şeyler için bir ekip olmak bu konuda çok işe yarayacaktır. Ki biz Ali ile kendi yapımızı kullanalım dediğimizde sadece ikimiz oluşturmadık bunu. Dışarıdan arkadaşlar da buna gerek fikir gerek kod anlamında katkıda bulundu ve hala daha geliştirmeye devam ediyoruz. (Geliştirmeden kasıt, örneğin composer ile yeni araçlar ekliyoruz, değiştiriyoruz. Ya da klasör yapımızda değişiklikler yapıyoruz. Kendimiz için en mükemmel yapıyı oluşturmaya çalışıyoruz)

Peki ya Laravel’de Taylor’un tek adamcılığı? Biz bu tabloya ülkemizden alışığız, o yüzden beni çok rahatsız etmedi, desem yanlış olur. Ama Laravel üzerindeki tartışılması gereken en büyük konu bu değil. Zira, Laravel bir özgür yazılım. İsteyen aynı kodlardan Paraver adında bir framework yapar. (Gerçi MIT lisans bu kadar özgür mü bilmiyorum, birisi aydınlatırsa çok sevinirim.) Neyse, aslında demek istediğim bu değildi ama demiş bulundum. Şunu diyecektim; Laravel üzerindeki tüm kararları tek bir kişi versin. Belki bu kullanmamak için bir sebep olabilir. Ama bunun kilit bir şey olduğunu düşünmüyorum. Bununla birlikte Ali’nin yazısında Ubuntu’nun pencere kapatma butonlarını topluluk ısrarlarına rağmen solda tutmasına atıfta bulunularak bir kıyaslama yapılmış. Ben bir Ubuntu kullanıcısıyım. Bazı dayatmalarından, hatta spyware’a varan uygulamalarından rahatsızım. Ubuntu’dan daha iyisi var. Arch linux. Ama sırf kurulumu bile ömrümden ömür çalıyor. Ki daha hiç kuramadım (çok uğraşmadım). Ubuntu(Canonical) her ne kadar saçma sapan kararlar verse de, bu onu kullanmayacağım anlamına gelmiyor. Bir gün çizmeyi aşar, o zaman bırakır ve ona en yakın dağıtıma geçerim. (Gerçi spyware a doğru yol alması çizmeyi aştığını göstermez mi?) Örneğin Mint. Ubuntu’nun tüm paketlerini destekliyor. Demek istediğim de bu, Laravel konusunda tek adamcılık en büyük sorun değil. Bugün böyle bir sıkıntı varsa, yarın başka birisi Laravel ile %100 uyumlu başka bir framework çıkartır, oradan yürünür. Bu konudaki özet ise şu; Laravel’i seven Taylor Otwell ile sevsin. Sevmeyen de sevmesin.

Ali’nin yazısına büyük çoğunlukla yanıt vermekle birlikte neden Laravel kullandığımı özetlemeye çalıştım. Belki söyleyecek daha çok şey var ama uzadıkça uzayacak gibi duruyor. En iyisi burada bırakmak. Son olarak şunu söylemek istiyorum; Laravel’i “mükemmel” olduğu için kullanmıyorum. Zaten mükemmel de değil. Kullanma sebebim, kurması, geliştirme yapması, öğrenmesi hızlı olması. Bazen kararlılığa bakarsınız, bazen hıza bakarsınız. (Mesela telefonumda stabil olan Samsung firmwarelerini kullanmak yerine Cyanogen modun, telefonum için unofficial modunu kullanıyorum. Cyanogen mod bile unofficial iken ben onun unofficial sürümünü kullanıyorum düşünün :))

Dipnotlar:

* Kendi yapın dediğimiz kavramı biraz açmak gerekli. Burada kastedilen şey “kendi framework”ün değil. Belli başlı frameworkleri arkana alıyorsun, belki sadece beğendiğin kısımlarını alıyorsun ve kendine göre onları kullanıyorsun. Ama burada yine kafana göre bir kullanma geliştirmiyorsun. Bu konuda dahi belli başlı standartlar, teknik konular var. Belki dizin yapın farklı olur, belki config dosyaların ve kullanımın farklı olur. Ama en nihayetinde temelde hepsi aynıdır.

* Kendi yapınızı oluşturma konusunda şu kaynak oldukça fayda sağlayacaktır: https://github.com/fabpot/Create-Your-Framework