# Composer'a geçiş: PHP bağımlılıklarını elle yönetmeyi bırakmak

> require yığınından modern bağımlılık yönetimine geçişin pratiği: composer.json, autoload ve paket kurma.

- Yayın: 2014-02-02
- Kategori: Araçlar & Teknolojiler
- Etiketler: PHP, Composer
- Okuma süresi: 3 dk okuma
- Kaynak: https://www.muhammetsafak.com.tr/blog/composera-gecis-php-bagimliliklarini-elle-yonetmeyi-birakmak/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
Birkaç ay öncesine kadar her yeni projeye başladığımda yaptığım şey şuydu: ihtiyaç duyduğum kütüphanelerin zip dosyasını indirmek, `lib/` ya da `vendor/` adını verdiğim bir klasöre atmak ve dosyanın tepesine elle `require` satırı yazmak. Sonra o kütüphane güncelleme aldığında yine aynı işlemi tekrarlamak. Bir projede üç farklı kütüphanenin bağımlılıkları çakışınca ne yapacağımı bilememek.

Bu düzensizliği gidermek için **Composer**'a geçtim. Şimdiye kadar kullandığım en doğru araç kararlarından biri olduğunu söyleyebilirim. Hâlâ öğreniyorum, ama artık eskiye dönmek istemiyorum.

## Composer nedir?

**Dependency Manager (bağımlılık yöneticisi)**, PHP projesinin hangi dış kütüphaneleri kullandığını takip eden, bunları yükleyen ve güncelleyen bir araçtır. Composer, PHP ekosistemi için tam olarak bunu yapar.

Ruby'deki Bundler'dan, Node.js'teki npm'den esinlenilmiş. PHP dünyasına 2012'de geldi; 2014'te artık ciddi projelerde standart sayılıyor.

Kurulumu tek satır:

```bash
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
```

Bundan sonra `composer` komutu her yerden çalışır.

## composer.json nedir ve ne işe yarar?

Projenin kök dizinine koyduğunuz `composer.json` dosyası, projenin ihtiyaç duyduğu paketleri ve sürüm kısıtlamalarını tanımlar. Önceki elle yönetilen `require` yığınının yerini alır.

Basit bir örnek:

```json
{
    "require": {
        "monolog/monolog": "1.11.*",
        "guzzlehttp/guzzle": "4.2.*"
    }
}
```

`composer install` çalıştırdığınızda Composer bu paketleri [Packagist](https://packagist.org)'ten indirir ve `vendor/` klasörüne yerleştirir. Bir de `composer.lock` dosyası oluşturur; bu dosya kullandığınız tam sürümleri kaydeder. Takım çalışmasında veya sunucuya taşırken `composer install` aynı sürümleri kurar, beklenmedik sürüm farklarının önüne geçer.

Paketi güncellemek için:

```bash
composer update monolog/monolog
```

Ya da tüm bağımlılıkları güncellemek için sadece `composer update`.

## Otomatik yükleme (Autoloading)

Composer'ın en büyük kazancı paket kurmanın yanı sıra **autoloading** sağlamasıdır. Artık her dosyaya `require_once` yazmak zorunda değilsiniz.

`composer.json`'a bir `autoload` bölümü ekleyip projenizin kaynak klasörünü belirtiyorsunuz:

```json
{
    "require": {
        "monolog/monolog": "1.11.*"
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}
```

Ardından `composer dump-autoload` çalıştırıyorsunuz. Bu noktadan itibaren `src/` altındaki `App\` ad alanıyla (namespace) yazılmış her sınıf otomatik olarak bulunur. Projenizin giriş dosyasına tek satır eklemeniz yeterli:

```php
<?php
require 'vendor/autoload.php';
```

Tek satır, tüm kütüphaneler ve kendi sınıflarınız kullanılabilir hale gelir.

## Yeni paket eklemek

Bir paket kurmak artık şu kadar:

```bash
composer require guzzlehttp/guzzle:~4.2
```

Composer `composer.json`'ı günceller, paketi indirir ve autoload haritasını yeniler. Elle hiçbir şey yazmıyorsunuz.

## Geliştirme bağımlılıkları

Test ve geliştirme araçları canlı ortamda bulunmamalıdır. `require-dev` ile bunları ayırabilirsiniz:

```json
{
    "require": {
        "monolog/monolog": "1.11.*"
    },
    "require-dev": {
        "phpunit/phpunit": "4.0.*"
    }
}
```

Canlı sunucuda `composer install --no-dev` ile geliştirme araçlarını atlamak mümkün.

## composer.lock ve sürüm tutarlılığı

`composer.lock` dosyasını versiyon kontrolüne eklemek önemli. Bu dosya olmadan iki farklı bilgisayarda ya da geliştirme ile canlı sunucuda `composer install` çalıştırmak farklı küçük sürümler getirebilir. Kütüphanelerin küçük güncellemeleri zaman zaman beklenmedik davranış değişikliğine yol açıyor. `composer.lock` sayesinde takımdaki herkes ve sunucu aynı bayt-bayt özdeş sürümleri kullanıyor. `composer.json` niyeti, `composer.lock` gerçeği temsil ediyor diyebilirim.

## Neden bu geçişi geciktirdim?

Dürüst olmak gerekirse, "bende çalışıyor" mantığıyla epey zaman harcadım. Composer'ı öğrenmek birkaç saatlik bir yatırım istiyor ama bir kez alışınca elle bağımlılık yönetiminin ne kadar verimsiz olduğunu fark ediyorsunuz. Özellikle birden fazla projeyi aynı anda yönetiyorsanız bu fark çok belirgin.

Packagist'te on binlerce paket var ve hepsi tek komutla erişilebilir. Bundan böyle bir kütüphane ihtiyacı duyduğumda önce Packagist'te bakıyorum, sonra `composer require` yazıyorum.

Küçük bir değişiklik gibi görünebilir ama çalışma biçimimi gerçekten değiştirdi.
