PHP Kodlama Standartları

Bu bölüm, Drupal kodlama standartlarının geri kalanının üzerine kurulduğu temel PHP biçimlendirme ve yapısal kurallarını ele alıyor. Hiçbirini ezberlemenize gerek yok aslında — gözden kaçırdığınız her şeyi PHP_CodeSniffer ve Drupal kural seti (bkz. Bölüm 12) zaten yakalayacak. Ama arkasındaki mantığı bilmek sizi daha hızlı yapıyor ve phpcs çıktısını sadece uyulması gereken bir şey olmaktan çıkarıp anlamlı hale getiriyor.

1. Girintileme ve Boşluk

Drupal girintide 2 boşluk kullanır, tab asla kullanılmaz. PSR-12 tarafından geliyorsanız genelde ilk şaşırdığınız şey bu olur — PSR-12'de bu 4.

php
// ❌ Yanlış: 4 boşluklu girinti.
if ($condition) {
    do_something();
}

// ✅ Doğru: 2 boşluklu girinti.
if ($condition) {
  do_something();
}

Buna birkaç boşluk kuralı daha eklenir: satır sonunda boşluk bırakılmaz, satır sonu karakteri olarak Windows (\r\n) değil Unix (\n) kullanılır ve dosya tam olarak bir yeni satırla biter. Yalnızca PHP içeren dosyalarda kapanış ?> etiketi tamamen atlanır — bunun nedeni basit: istenmeyen boşluk çıktısı ve sebepsiz yere karşılaşacağınız bir "headers already sent" hatası.

php
// ❌ Yanlış: dosya kapanış etiketiyle bitiyor.
<?php
mymodule_function();
?>

// ✅ Doğru: kapanış etiketi yok, tek bir sondaki yeni satır.
<?php
mymodule_function();

2. Satır Uzunluğu

Kod satırları genelde 80 karakterde sınırlanır, ama bu esnek bir sınır — bir satırı bölmek okunabilirliğe zarar verecekse, okunabilirlik kazanır. Uzun koşul ifadeleri, keyfi bir sütun sayısına sıkıştırılmak yerine mantıklı bir noktadan bölünmeli.

Yorum ve doc block satırlarında bu esneklik yok — orada 80 karakter kesin bir sınır. Uzunluktan bağımsız olarak, bir satırda her zaman tek bir ifade olur.

php
// ❌ Yanlış: bir satırda iki ifade.
$a = 1; $b = 2;

// ✅ Doğru.
$a = 1;
$b = 2;

3. Operatörler ve Boşluk Kullanımı

İkili operatörler — =, +, -, *, ==, ===, ., =>, &&, ||, ?? ve benzerleri — her iki tarafta da boşluk alır. Tekli operatörler (!, ++, --, eksi işareti) ise hiç boşluk almaz.

php
// ❌ Yanlış.
$total=$price*$quantity;
$name = 'Prefix '.$suffix;
if(!$valid){

// ✅ Doğru.
$total = $price * $quantity;
$name = 'Prefix ' . $suffix;
if (!$valid) {

Başka PHP ekiplerinden gelenlerin genelde takıldığı bir nokta: birleştirme operatörü de boşluklu yazılır — 'a' . $b, 'a'.$b değil.

Tip dönüşümleri de aynı mantığı izler: (int) $value, dönüşümden sonra boşlukla — (int)$value değil.

4. Diziler

Kısa dizi sözdizimi — [] — her yerde zorunlu. Eski array() biçiminin yeni kodda yeri yok.

php
// ❌ Yanlış.
$values = array('one', 'two', 'three');

// ✅ Doğru.
$values = ['one', 'two', 'three'];

Çok satırlı bir dizide her öğe kendi satırında yer alır, dizinin kendisinden bir seviye içeride girintilenir ve kapanış parantezi diziyi açan satırla hizalanır. Son öğeden sonra bir virgül eklemek de küçük ama işe yarayan bir alışkanlık — gelecekteki diff'lerin gereksiz yere o satıra dokunmasını engeller.

php
// ❌ Yanlış: sondaki virgül eksik.
$options = [
  'status' => TRUE,
  'type' => 'article',
  'sticky' => FALSE
];

// ✅ Doğru: son ögeden sonra virgül var.
$options = [
  'status' => TRUE,
  'type' => 'article',
  'sticky' => FALSE,
];

Bütün bunlar, zaten tek satıra sığan kısa dizileri kapsamıyor — çok satırlı kural kendi başına bir amaç değil, okunabilirliğe hizmet ediyor.

5. Kontrol Yapıları

if, foreach, while, switch ve fonksiyon gövdelerinde açılış parantezi anahtar kelimeyle aynı satırda, önünde bir boşlukla yer alır. Bir kontrol anahtar kelimesi her zaman kendi ( işaretinden önce boşluk alır, ama bir fonksiyon adı hiçbir zaman almaz.

php
// ❌ Yanlış.
if($valid){
  do_something();
}
else if ($other) {
  do_other_thing();
}

// ✅ Doğru.
if ($valid) {
  do_something();
}
elseif ($other) {
  do_other_thing();
}

Bir not daha: Drupal, else if yerine elseif'i tek kelime olarak yazar. Bir switch ifadesinde case etiketleri switch'ten bir seviye, her case'in gövdesi ise bir seviye daha içeride durur.

php
// ❌ Yanlış: case etiketleri switch ile aynı girintide.
switch ($type) {
case 'article':
do_article_things();
break;

default:
do_default_things();
}

// ✅ Doğru: case bir seviye içeride, gövdesi bir seviye daha içeride.
switch ($type) {
  case 'article':
    do_article_things();
    break;

  case 'page':
    do_page_things();
    break;

  default:
    do_default_things();
}

6. Fonksiyon ve Method Tanımları

function anahtar kelimesinden sonra bir boşluk gelir, parametre listesinin kapanış parantezinden önce boşluk olmaz ve parametreler arasındaki her virgülden sonra bir boşluk vardır, öncesinde değil.

php
// ❌ Yanlış.
function mymodule_process($a,$b , $c) {
}

// ✅ Doğru.
function mymodule_process($a, $b, $c) {
}

Varsayılan değerler = işaretinin iki tarafında da boşlukla yazılır ve beklendiği gibi, varsayılan değeri olan parametreler her zaman zorunlu parametrelerden sonra gelir:

php
// ❌ Yanlış: zorunlu parametre, varsayılan değerli parametreden sonra.
public function importProducts(bool $overwrite = FALSE, array $items): int {
}

// ✅ Doğru: varsayılan değerli parametreler zorunlu olanlardan sonra gelir.
public function importProducts(array $items, bool $overwrite = FALSE): int {
}

Bir public veya protected method'un adı amacını zaten açıklamıyorsa, bir doc block taşımalıdır. Bunun tam etiket biçimi Dokümantasyon Standartları bölümünde.

7. Tip Tanımlamaları

PHP 8.1 ve üzerinde, güncel Drupal kodunun API'nin izin verdiği her yerde tip belirtmesi bekleniyor: parametre tipleri, dönüş tipleri, tipli sınıf özellikleri — hepsi.

php
// ❌ Yanlış: tip tanımlamaları yok.
class ProductImporter {

  protected $logger;

  protected $batchSize = 50;

  public function importOne($data) {
    // ...
  }

}

// ✅ Doğru: parametre, dönüş ve özellik tipleri belirtilmiş.
class ProductImporter {

  protected LoggerChannelInterface $logger;

  protected int $batchSize = 50;

  public function importOne(array $data): ?Product {
    // ...
  }

}

Bir method meşru şekilde hiçbir şey döndürmeyebiliyorsa nullable tip (?Type), gerçekten birden fazla somut tip mümkünse union tip (int|string) kullanılır — ikisi de, doğru olan tek tipi seçmenin yerine geçen bir kısayol değildir.

8. Sınıf Yapısı ve Görünürlük

Her özellik ve method görünürlüğünü açıkça belirtir. PHP'nin örtük public varsayılanına hiçbir zaman güvenilmez.

php
// ❌ Yanlış: görünürlük anahtar kelimesi yok.
class ProductImporter {
  $logger;
  function importOne() {}
}

// ✅ Doğru.
class ProductImporter {
  protected LoggerChannelInterface $logger;
  public function importOne(): void {}
}

Bir sınıfın içinde üyeler tutarlı bir sırada durur — önce sabitler, sonra özellikler, sonra constructor, sonra geri kalan her şey. İçe aktarılan sınıflar için use ifadeleri kendi satırında, alfabetik sırayla ve başında ters eğik çizgi olmadan yazılır.

php
use Drupal\Core\Logger\LoggerChannelInterface;
use Drupal\node\NodeInterface;
use GuzzleHttp\ClientInterface;

Son güncelleme: 17.09.2026 16:37