Sıfırdan İleri Seviyeye Modern PHP Kursu
1.1 PHP’ye Giriş ve Çalışma Mantığı
PHP (Hypertext Preprocessor), dinamik web siteleri geliştirmek için tasarlanmış sunucu taraflı bir betik dilidir. HTML içine gömülebilir ve özellikle veritabanı işlemlerinde çok güçlüdür. Dünyadaki web sitelerinin büyük bir çoğunluğu (WordPress, Facebook vb.) PHP altyapısını kullanır.
PHP Nedir ve Ne İşe Yarar?
- Sunucu Taraflı Dil: PHP kodu, kullanıcının tarayıcısında değil, web sunucusunda çalıştırılır.
- Dinamik İçerik: Kullanıcı isteğine göre anlık olarak HTML, CSS veya diğer çıktıları üretebilir.
- Veritabanı Entegrasyonu: MySQL, PostgreSQL gibi popüler veritabanlarıyla kolayca etkileşime girer.
- Uzandı: PHP dosyaları daima
.phpuzantısına sahiptir.
PHP'nin Çalışma Mantığı (Arka Plan)
- İstek: Kullanıcı tarayıcıdan (Örn:
index.php) adresine istek gönderir. - Sunucuya Ulaşma: İstek, Web Sunucusuna (Apache veya Nginx) ulaşır.
- PHP Yorumlayıcısı: Sunucu,
.phpuzantılı dosyayı fark eder ve PHP yorumlayıcısına (Engine) gönderir. - Kod Yürütme: PHP yorumlayıcısı, PHP kodlarını çalıştırır (ve veritabanı işlemlerini yapar).
- HTML Üretimi: Yorumlayıcı, PHP kodlarını çalıştırdıktan sonra geriye sadece saf HTML/CSS/JS çıktısı bırakır.
- Cevap: Sunucu, bu saf HTML çıktısını tarayıcıya gönderir. Kullanıcı, PHP kodunu asla görmez.
1.2 Kurulum ve Ortam Ayarları (XAMPP/WAMP)
PHP kodlarını çalıştırabilmek için bir web sunucusu (Apache), PHP yorumlayıcısı ve bir veritabanına (MySQL/MariaDB) ihtiyacınız vardır. Bu bileşenleri tek pakette sunan çözümler kullanmak en pratik yoldur.
Paket Seçenekleri ve Kullanım
- XAMPP: En popüler seçenektir. (Cross-Platform / Çapraz Platform: Windows, Linux, macOS).
- WAMP: Sadece Windows kullanıcıları için tasarlanmıştır.
- MAMP: macOS kullanıcıları için popülerdir.
Önemli Not: Bu paketlerden birini kurduktan sonra, PHP dosyalarınızı çalıştırmak için dosyayı XAMPP'te htdocs veya WAMP'te www klasörüne kaydetmeli ve tarayıcıdan localhost/dosya_adi.php şeklinde çağırmalısınız.
PHP Sürümleri ve Farkları
PHP sürekli gelişmektedir. Öğrenmeye başlarken daima **PHP 8.x** veya daha yeni bir sürümle başlayın. Yeni sürümler, performans, güvenlik ve daha modern sözdizimi açısından büyük avantajlar sunar.
1.3 PHP Temel Sözdizimi
PHP kodu, HTML belgesi içinde özel etiketlerle ayrıştırılır. Kod yazarken temiz ve standartlara uygun olmak önemlidir.
PHP Etiketleri
Standart ve önerilen kullanım biçimidir:
<?php
echo "Bu bir PHP kodudur.";
?>
Noktalı Virgül ve Büyük/Küçük Harf Duyarlılığı
- Noktalı Virgül (
;): PHP'de her komutun sonuna mutlaka;konulmalıdır. Unutulması, yaygın bir hatadır. - Büyük/Küçük Harf Duyarlılığı:
- Değişkenler: **Duyarlıdır.**
$isimve$Isimfarklı değişkenlerdir. - Fonksiyonlar ve Anahtar Kelimeler: Duyarlı değildir.
echo,ECHOveEcHoaynı şekilde çalışır (ancak küçük harf kullanılması önerilir).
- Değişkenler: **Duyarlıdır.**
Yorum Satırları
Kodun açıklanması veya geçici olarak devre dışı bırakılması için kullanılır.
<?php
// Tek satırlık yorum satırı için çift eğik çizgi
# Alternatif tek satırlık yorum satırı
/*
Birden fazla satırı kapsayan
yorum bloğu
*/
echo "Selam";
?>
1.4 Değişkenler ve Veri Tipleri
Değişkenler, verileri depolamak için kullanılan isimlendirilmiş bellek konumlarıdır. PHP'de değişkenler daima $ işaretiyle başlar.
Değişken Tanımlama Kuralları
- Mutlaka
$işaretiyle başlamalıdır. - Bir harf veya alt çizgi (
_) ile başlamalıdır. (Sayı ile başlayamaz). - Sadece alfanümerik karakterler (A-z, 0-9) ve alt çizgiler içerebilir.
- Büyük-küçük harf duyarlıdır.
Temel Veri Tipleri
| Tip | Açıklama | Örnek |
|---|---|---|
| String | Metin verisi. Çift veya tek tırnak içinde. | $ad = "Ahmet"; |
| Integer | Tam sayılar (pozitif veya negatif). | $yas = 30; |
| Float/Double | Ondalıklı sayılar. | $fiyat = 19.99; |
| Boolean | Mantıksal değer (true veya false). | $durum = true; |
| Array | Birden fazla değeri tek bir değişkende saklar. | $liste = [1, 2, 3]; |
| Object | Sınıfların örneği (ilerleyen konularda). |
var_dump() ve gettype() Kullanımı
Bir değişkenin tipini ve değerini öğrenmek için kullanılır.
<?php
$sayi = 15; // int
$isim = "Mehmet"; // string
var_dump($sayi); // Çıktı: int(15)
echo "<br>Değişken Tipi: " . gettype($isim); // Çıktı: Değişken Tipi: string
?>
1.5 Sabitler (Constants)
Sabitler, tanımlandıktan sonra değeri asla değiştirilemeyen değerlerdir. Genellikle büyük harflerle isimlendirilirler.
define() Fonksiyonu ile Tanımlama
PHP'nin eski versiyonlarında ve koşullu tanımlama için kullanılır.
<?php
define("SITE_ADI", "Robotik Hocasi");
define("PI", 3.14);
echo SITE_ADI; // Çıktı: Robotik Hocasi
?>
const Anahtar Kelimesi ile Tanımlama (Önerilen)
Sınıf içinde veya global alanda, daha modern bir tanımlama yöntemidir. Daha hızlı çalışır.
<?php
const VERSIYON = "1.0.1";
echo VERSIYON; // Çıktı: 1.0.1
?>
1.6 Operatörler
Operatörler, değişkenler ve değerler üzerinde işlemler yapmak için kullanılır. PHP'de birçok operatör grubu bulunur.
Aritmetik Operatörler
| + | Toplama | - | Çıkarma |
| * | Çarpma | / | Bölme |
| % | Modülüs (Kalan) | ** | Üs Alma (PHP 5.6+) |
Atama Operatörleri
Bir değere değişken atamak için kullanılır.
$x = 10;(Değer atama)$x += 5;($x = $x + 5;ile aynıdır)$y .= "dunya";($y = $y . "dunya";String birleştirme)
Karşılaştırma Operatörleri (Koşullar için kritik)
== | Değer Eşitliği | != | Değer Eşitsizliği |
=== | Değer ve Tip Eşitliği | !== | Değer veya Tip Eşitsizliği |
> | Büyüktür | < | Küçüktür |
🚨 ÖNEMLİ: == (sadece değer) ve === (değer ve tip) arasındaki fark çok önemlidir:
<?php
$a = 5; // int
$b = "5"; // string
var_dump($a == $b); // Çıktı: bool(true) - Değerler eşit
var_dump($a === $b); // Çıktı: bool(false) - Tipler farklı
?>
Mantıksal Operatörler
Birden fazla koşulu birleştirmek için kullanılır.
&&(AND): Tüm koşullar doğruysa doğru.||(OR): Koşullardan en az biri doğruysa doğru.!(NOT): Koşulun tersini alır.
Artırma / Azaltma Operatörleri
Sayısal değişkenin değerini 1 artırır veya azaltır.
$i++(Post-increment): Önce kullan, sonra artır.++$i(Pre-increment): Önce artır, sonra kullan.
1.7 Koşul İfadeleri (if, else, switch)
Kodun akışını ve hangi bloğun çalışacağını kontrol etmek için koşul ifadeleri kullanılır.
if, else, elseif Yapısı
En temel kontrol yapısıdır. Birden fazla koşulu sırayla kontrol etmenizi sağlar.
<?php
$puan = 85;
if ($puan >= 90) {
echo "A";
} elseif ($puan >= 80) {
echo "B"; // Çıktı: B
} else {
echo "C";
}
?>
switch-case Yapısı
Bir değişkenin alabileceği birden fazla olası değeri kontrol etmek için kullanılır. Daha düzenlidir.
<?php
$gun = "Salı";
switch ($gun) {
case "Pazartesi":
echo "Haftanın başı";
break;
case "Salı":
echo "Çalışma zamanı"; // Çıktı: Çalışma zamanı
break;
default:
echo "Hafta sonu veya geçersiz gün";
}
?>
🚨 **ÖNEMLİ:** Her case bloğunun sonunda break; kullanmayı unutmayın, aksi takdirde alttaki case bloğu da çalışır (fall-through).
Üçlü (Ternary) Operatör
Kısa ve tek satırlık if-else ifadeleri için kullanılır.
<?php
$login = true;
$mesaj = $login ? "Hoş geldiniz" : "Giriş yapınız"; // Koşul ? (Doğruysa) : (Yanlışsa)
echo $mesaj; // Çıktı: Hoş geldiniz
?>
1.8 Döngüler (for, while, foreach)
Döngüler, aynı kod bloğunu belirli bir koşul doğru olduğu sürece veya belirli sayıda tekrarlamak için kullanılır.
for Döngüsü
Başlangıç, bitiş ve artış miktarının önceden belirlendiği durumlarda kullanılır.
<?php
for ($i = 0; $i < 5; $i++) {
echo "Sayı: " . $i . "<br>";
}
// Çıktı: 0, 1, 2, 3, 4
?>
while Döngüsü
Koşul doğru olduğu sürece çalışmaya devam eder. Kaç kez döneceği net olmayan durumlarda idealdir.
<?php
$sayac = 1;
while ($sayac <= 3) {
echo "Tekrar: " . $sayac . "<br>";
$sayac++; // Sayacı artırmayı unutmayın! Sonsuz döngüden kaçının.
}
// Çıktı: 1, 2, 3
?>
do-while Döngüsü
Blok, koşul kontrol edilmeden **en az bir kez** çalışır, ardından koşul kontrol edilir.
<?php
$j = 10;
do {
echo "Bu bir kez çalıştı.<br>"; // Koşul (10 < 5) yanlış olsa bile çalışır
$j++;
} while ($j < 5);
?>
foreach Döngüsü (Diziler için en iyisi)
Dizilerdeki her bir eleman üzerinde döngü yapmak için tasarlanmıştır. En çok kullanılan döngü tipidir.
<?php
$renkler = ["Kırmızı", "Mavi", "Yeşil"];
foreach ($renkler as $deger) {
echo "Renk: " . $deger . "<br>";
}
?>
1.9 Diziler (Arrays)
Diziler, tek bir değişkende birden fazla değeri depolamak için kullanılır. PHP'de diziler son derece esnektir.
Dizi Tanımlama
İki yöntem de geçerlidir, ancak [] modern ve önerilen yoldur.
$meyveler = array("elma", "armut", "muz");$meyveler = ["elma", "armut", "muz"];(Önerilen)
İndeksli (Indexed) Diziler
Elemanlara 0'dan başlayan sayısal indekslerle erişilir.
<?php
$markalar = ["BMW", "Audi", "Mercedes"];
echo $markalar[1]; // Çıktı: Audi
?>
İlişkisel (Associative) Diziler
Elemanlara sayı yerine özel anahtar (key) isimleriyle erişilir.
<?php
$kullanici = [
'ad' => 'Ayşe',
'soyad' => 'Yılmaz',
'yas' => 28
];
echo $kullanici['ad']; // Çıktı: Ayşe
?>
Çok Boyutlu Diziler
Bir dizinin elemanları başka bir dizi olduğunda oluşur (örneğin veritabanı tabloları).
<?php
$arabalar = [
['marka' => 'Toyota', 'model' => 'Corolla'],
['marka' => 'Honda', 'model' => 'Civic']
];
echo $arabalar[0]['model']; // Çıktı: Corolla
?>
Dizi Fonksiyonları
count($dizi): Dizideki eleman sayısını verir.array_push($dizi, $deger): Dizinin sonuna eleman ekler.in_array($deger, $dizi): Değerin dizide olup olmadığını kontrol eder (boolean).print_r($dizi): Bir dizinin tüm içeriğini okunabilir bir formatta görüntüler (hata ayıklama için önemlidir).
1.10 String İşlemleri ve Fonksiyonları
Metin verisi (String) PHP'de en çok kullanılan tiptir. PHP, String'leri manipüle etmek için çok zengin bir fonksiyona sahiptir.
Birleştirme (Concatenation)
String'leri birleştirmek için nokta (.) operatörü kullanılır.
<?php
$ad = "Veli";
$soyad = "Kara";
$tam_ad = $ad . " " . $soyad; // Çıktı: Veli Kara
?>
String Interpolation (Değişken Yerleştirme)
Çift tırnak (") içinde değişkenleri doğrudan kullanabilirsiniz. Tek tırnak (') bunu desteklemez.
<?php
$urun = "Laptop";
echo "Sepetinizde bir adet $urun var."; // Çalışır
echo 'Sepetinizde bir adet $urun var.'; // Çalışmaz, çıktı: $urun var.
?>
Önemli String Fonksiyonları
strlen() | String'in uzunluğunu verir. |
str_replace() | Metin içinde arama yapıp değiştirir. |
substr() | String'in bir bölümünü keser. |
explode() | String'i bir ayraca göre diziye çevirir. |
implode() | Diziyi bir ayraca göre String'e çevirir. |
1.11 Fonksiyonlar (Parametre, Global/Local)
Fonksiyonlar, bir görevi yerine getiren, tekrar kullanılabilir kod bloklarıdır. Kod tekrarını önler ve okunabilirliği artırır.
Fonksiyon Tanımlama ve Kullanımı
Fonksiyonlar function anahtar kelimesiyle başlar.
<?php
function selamla($isim) { // Parametre alıyor
return "Merhaba, $isim!"; // Değer döndürüyor
}
echo selamla("Ece"); // Çıktı: Merhaba, Ece!
?>
Global ve Local Değişkenler
Fonksiyon içinde tanımlanan değişkenler (local) dışarıdan erişilemez. Dışarıdaki bir değişkene (global) erişmek için global anahtar kelimesi kullanılmalıdır.
<?php
$sayac = 0; // Global değişken
function artir() {
global $sayac; // Global değişkeni kullanmak için tanımlandı
$sayac++;
$local_degisken = 5; // Local değişken
}
artir();
echo $sayac; // Çıktı: 1
// echo $local_degisken; // HATA! Erişim yok.
?>
Anonim Fonksiyonlar (Closure)
İsmi olmayan fonksiyonlardır. Genellikle bir değişkene atanır veya başka fonksiyonlara parametre olarak gönderilirler (ileri düzey konularda daha çok kullanılır).
1.12 Form İşlemleri (GET/POST)
PHP'nin en temel görevi, kullanıcıdan HTML formları aracılığıyla veri almaktır. Veri alımı, **Süper Global** değişkenler aracılığıyla yapılır.
GET Metodu
Veriyi URL'de gönderir (Örn: ?ad=Ali&yas=30). Az miktarda ve hassas olmayan veriler için uygundur (Arama motorları, filtreler).
POST Metodu
Veriyi HTTP isteği gövdesinde (body) gizli bir şekilde gönderir. Hassas veriler (şifreler) ve büyük veri setleri için kullanılır.
$_GET ve $_POST Kullanımı
Formdan gelen verilere bu iki Süper Global dizi üzerinden erişilir.
// Kullanıcının adını alma (Eğer form method="GET" ise)
$kullanici_adi = $_GET['ad'];
// Kullanıcının şifresini alma (Eğer form method="POST" ise)
$parola = $_POST['sifre'];
Örnek: Form Doğrulama (Basit)
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["email"])) {
echo "Email alanı zorunludur!";
} else {
echo "Giriş başarılı!";
}
}
?>
1.13 PHP’de Dahil Etme (include/require)
Tekrar eden kod bloklarını (başlık, altbilgi, veritabanı bağlantısı) ayrı dosyalarda tutmak ve projeye dahil etmek için kullanılır.
include vs. require
include 'dosya.php';: Dosya bulunamazsa veya hata oluşursa **bir uyarı (Warning) verir**, ancak kodun geri kalanını çalıştırmaya devam eder.require 'dosya.php';: Dosya bulunamazsa veya hata oluşursa **ölümcül bir hata (Fatal Error) verir** ve kodun çalışmasını durdurur. (Genellikle hayati önem taşıyan dosyalar için tercih edilir).
Tek Sefer Dahil Etme (Önerilen)
Aynı dosyanın birden fazla kez dahil edilmesini engeller. Fonksiyon veya sınıf tanımlarının çakışmasını önler.
include_once 'ayar.php';require_once 'veritabani.php';(En çok kullanılan budur)
1.14 Süper Global Değişkenler
PHP'de kodun her yerinden (fonksiyonlar içinde bile) otomatik olarak erişilebilen özel, büyük harfli dizilerdir. Sunucu, kullanıcı ve ortam bilgilerini tutarlar.
En Önemli Süper Global Değişkenler
$_GET: URL üzerinden gelen veriler.$_POST: Formdan (method="POST") gelen veriler.$_REQUEST: Hem GET hem de POST verilerini içerir (ÖNERİLMEZ, $_GET ve $_POST kullanın).$_SERVER: Web sunucusu ve çalıştırma ortamı hakkında bilgiler (IP adresi, dosya yolu, sayfa adı, vb.).$_SESSION: Kullanıcı oturum verilerini tutar. (Giriş işlemleri, sepet bilgileri)$_COOKIE: Kullanıcının bilgisayarında saklanan küçük veri parçaları.$_FILES: Form aracılığıyla yüklenen dosyalarla ilgili bilgiler.
Örnek: $_SERVER Kullanımı
Kullanıcının hangi IP adresinden geldiğini ve hangi sayfayı istediğini öğrenme.
<?php
echo "IP Adresiniz: " . $_SERVER['REMOTE_ADDR'] . "<br>";
echo "İstenen Sayfa: " . $_SERVER['PHP_SELF'];
?>
2.1 Dosya İşlemleri (Okuma/Yazma)
PHP, web sunucusunda dosya oluşturma, okuma, yazma ve silme gibi işlemleri yapmanıza olanak tanır. Bu, loglama, veri önbellekleme veya basit depolama için kritik öneme sahiptir.
Temel Dosya Fonksiyonları
| Fonksiyon | Açıklama |
|---|---|
fopen() | Bir dosyayı açar veya oluşturur. İşlem modunu belirtmek gerekir. |
fread() / file_get_contents() | Açılan dosyadan veri okur / Dosyanın tüm içeriğini tek seferde okur. |
fwrite() / file_put_contents() | Dosyaya veri yazar / Dosyaya tek seferde veri yazar, dosya yoksa oluşturur. |
fclose() | Açılan dosyayı kapatır ve kaynakları serbest bırakır. |
file_exists() | Belirtilen dosyanın var olup olmadığını kontrol eder. |
Dosya Modları (fopen() için)
r: Sadece okuma. Dosya işaretçisi başlangıçta. Dosya yoksa hata verir.w: Sadece yazma. Dosya işaretçisi başlangıçta. Dosya varsa **içeriği siler**, yoksa oluşturur.a: Sadece yazma. Dosya işaretçisi sonda (ekleme modu). Dosya yoksa oluşturur. **İçeriği silmez.**r+: Okuma ve yazma. Dosya işaretçisi başlangıçta.w+: Okuma ve yazma. Dosya varsa içeriği siler, yoksa oluşturur.
Örnek 1: Dosyaya Veri Yazma (Ekleme Modu)
Her çalıştığında log.txt dosyasına yeni bir satır ekler.
<?php
$dosya = 'log.txt';
$icerik = "Yeni log girişi: " . date("Y-m-d H:i:s") . "\n";
// 'a' modu ile dosyayı aç (yoksa oluştur, varsa sona ekle)
$isleyici = fopen($dosya, 'a');
if ($isleyici) {
fwrite($isleyici, $icerik); // Veriyi dosyaya yaz
fclose($isleyici); // Dosyayı kapat
echo "Log dosyasına başarıyla yazıldı.";
} else {
echo "Dosya açılamadı.";
}
?>
Örnek 2: Dosya İçeriğini Okuma (Kısa Yöntem)
file_get_contents() ile dosyanın tüm içeriği tek satırda alınabilir.
<?php
$dosya = 'log.txt';
if (file_exists($dosya)) {
$icerik = file_get_contents($dosya);
echo "<pre>" . $icerik . "</pre>"; // <pre> etiketi ile formatı korur
} else {
echo "Okunacak dosya bulunamadı.";
}
?>
2.2 Cookie ve Session Yönetimi
HTTP protokolü "stateless" (durum bilgisi tutmayan) bir yapıdadır. Kullanıcıların durumunu (giriş yapılıp yapılmadığı, sepet içeriği, dil seçimi) web siteleri için **Cookie** ve **Session** mekanizmaları kullanılır.
Cookie (Çerez) Nedir?
- Tanım: Sunucunun, kullanıcının tarayıcısına depolaması için gönderdiği küçük veri parçalarıdır.
- Depolama: Kullanıcının **bilgisayarında** saklanır.
- Erişim: Hem sunucu (
$_COOKIE) hem de istemci (JavaScript) tarafından erişilebilir. - Kullanım: "Beni Hatırla", kişiselleştirme ayarları, tema tercihleri.
Cookie Oluşturma ve Silme
setcookie() fonksiyonu, HTML çıktısından önce çağrılmalıdır!
<?php
// Cookie Oluşturma: 30 gün geçerli
$sure = time() + (86400 * 30); // 86400 saniye = 1 gün
setcookie("kullanici_ad", "Ali", $sure, "/");
// Cookie Okuma
if(isset($_COOKIE["kullanici_ad"])) {
echo "Hoş geldiniz, " . $_COOKIE["kullanici_ad"];
}
// Cookie Silme: Süresini geçmiş bir zamana ayarla
setcookie("kullanici_ad", "", time() - 3600, "/");
?>
Session (Oturum) Nedir?
- Tanım: Veriler sunucuda saklanır, kullanıcıya sadece bu verilere erişimi sağlayan benzersiz bir kimlik (Session ID) gönderilir.
- Depolama: Veri **web sunucusunda** saklanır. (Session ID, Cookie olarak tutulur).
- Erişim: Sadece sunucu tarafından (
$_SESSION) erişilebilir. - Kullanım: Üye girişi, sepet içeriği, hassas ve geçici veriler.
Session Başlatma ve Kullanımı
Session kullanmadan önce mutlaka session_start() çağrılmalıdır (genellikle sayfanın en başına).
<?php
session_start();
// Session Değeri Atama (Kullanıcı Girişi)
$_SESSION["kullanici_id"] = 105;
$_SESSION["giris_zamani"] = time();
echo "Kullanıcı ID: " . $_SESSION["kullanici_id"];
// Session Değeri Silme (Oturumu Kapatma)
unset($_SESSION["kullanici_id"]); // Tek bir değişkeni sil
// Tüm oturumu yok et
session_destroy();
?>
2.3 Hata Yönetimi (try-catch)
Bir uygulamanın güvenilirliği için hata ve istisna (exception) yönetimi hayati önem taşır. PHP, hataları ve istisnaları farklı şekillerde ele alır.
PHP Hata Seviyeleri (Errors)
- Fatal Error (E_ERROR): En ciddi hatadır, kodun çalışmasını durdurur (Örn: Tanımlanmamış sınıf çağırmak).
- Warning (E_WARNING): Kritik olmayan bir hatadır, kod çalışmaya devam eder (Örn: Var olmayan bir dosya dahil etmek).
- Notice (E_NOTICE): Önemsiz bir uyarıdır, genellikle iyi kodlama pratiğine aykırı durumlarda ortaya çıkar (Örn: Tanımlanmamış değişken kullanmak).
Hata Görüntüleme Ayarları
Geliştirme aşamasında hataları görmelisiniz, ancak canlı (prod) ortamda kapatmalısınız.
<?php
// Geliştirme (Development) Ortamı İçin:
ini_set('display_errors', 1);
error_reporting(E_ALL);
// Canlı (Production) Ortamı İçin:
// ini_set('display_errors', 0);
// error_reporting(0);
?>
İstisna (Exception) Yönetimi: try-catch
İstisnalar, bir sorun oluştuğunda program akışını düzenli bir şekilde değiştirmek için kullanılır. Bu, kodun kontrol edilebilir bir şekilde başarısız olmasını sağlar.
try | Hata oluşturma potansiyeli olan kod bloğu buraya yazılır. |
catch | try bloğunda bir istisna yakalanırsa, bu blok çalışır. |
throw new Exception() | Geliştiricinin kendisinin manuel olarak istisna oluşturması. |
Örnek: try-catch Kullanımı
Sıfıra bölme gibi olası hatalı durumları yakalama örneği.
<?php
function bolme($sayi1, $sayi2) {
if ($sayi2 == 0) {
// Manuel olarak istisna fırlat
throw new Exception("Sıfıra bölme hatası!");
}
return $sayi1 / $sayi2;
}
try {
echo bolme(10, 0); // Hata burada oluşacak
} catch (Exception $e) {
// Hata yakalandı, kullanıcıya düzenli mesaj göster
echo "Hata Oluştu: " . $e->getMessage(); // Çıktı: Hata Oluştu: Sıfıra bölme hatası!
}
?>
2.4 Zaman ve Tarih Fonksiyonları
PHP, tarih ve saat işlemleri için güçlü yerleşik fonksiyonlara sahiptir. Zamanı tutmanın standart yolu **Unix Zaman Damgası (Timestamp)** kullanmaktır.
Unix Zaman Damgası (Timestamp) Nedir?
1 Ocak 1970 00:00:00 UTC tarihinden bu yana geçen saniye sayısıdır. Tüm zaman hesaplamaları için en güvenilir yöntemdir.
time(): Mevcut Unix zaman damgasını döndürür.mktime(): Belirtilen tarih ve saat için zaman damgası oluşturur.strtotime(): İngilizce metinleri zaman damgasına çevirir (Örn: "next monday", "now", "+1 week").
date() Fonksiyonu
Zaman damgasını, okunabilir bir tarih/saat formatına dönüştürmek için kullanılır. İlk parametre formatı belirler.
| Karakter | Açıklama | Örnek Çıktı |
|---|---|---|
Y | Dört basamaklı yıl | 2025 |
m / d | Sayısal ay (01-12) / Gün (01-31) | 03 / 28 |
H / i / s | 24-saat (00-23) / Dakika / Saniye | 15 / 35 / 05 |
l (küçük L) | Haftanın tam İngilizce günü | Tuesday |
Örnek: date() ve strtotime() Kullanımı
<?php
// 1. Mevcut Tarih ve Saat
echo "Bugün: " . date("Y-m-d H:i:s") . "<br>";
// 2. Türkçe Gün/Ay Kullanımı (Manuel çeviri gerekebilir veya setlocale)
$gun = date("l");
echo "Bugün: " . str_replace("Tuesday", "Salı", $gun) . "<br>";
// 3. Gelecek Zaman Hesaplama
$hafta_sonra = strtotime("+1 week");
echo "Bir hafta sonra: " . date("d.m.Y", $hafta_sonra) . "<br>";
// 4. İki Tarih Arasındaki Farkı Bulma (DateTime nesnesi ile daha kolaydır - İleri Konu)
$simdi = time();
$gelecek = strtotime("2026-01-01");
$fark_saniye = $gelecek - $simdi;
$fark_gun = floor($fark_saniye / (60 * 60 * 24));
echo "Yeni yıla $fark_gun gün kaldı.";
?>
2.5 PHP ile Mail Gönderme (PHPMailer)
PHP'nin yerleşik mail() fonksiyonu genellikle karmaşık SMTP ayarları, güvenlik sorunları (spam olarak işaretlenme) ve eksik özellikler nedeniyle profesyonel projelerde **kullanılmaz**. Bunun yerine **PHPMailer** gibi kütüphaneler tercih edilir.
Neden PHPMailer Kullanmalıyız?
- SMTP Desteği: Gmail, Outlook gibi harici posta sunucularına güvenli (SSL/TLS) bağlantı kurar.
- Güvenilir: Gönderilen e-postaların spam olarak işaretlenme olasılığını azaltır.
- Zengin Özellik: HTML içerik, dosya ekleme, CC/BCC, farklı karakter setleri (UTF-8) gibi gelişmiş özellikler sunar.
PHPMailer Temel Kurulum ve Kullanımı (Özet)
PHPMailer bir harici kütüphane olduğu için öncelikle projenize Composer ile dahil edilmelidir. (Bkz: 4.2 Composer Konusu)
Kurulum Komutu (Varsayılan): composer require phpmailer/phpmailer
Örnek: PHPMailer ile Güvenli Mail Gönderme
Bu örnek, Gmail gibi bir SMTP sunucusu kullanarak mail gönderme mantığını gösterir. (Gerçek sunucu bilgileri ile değiştirilmelidir.)
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
// Kütüphane dosyalarını dahil et (Composer kullanılıyorsa autoload.php yeterlidir)
// require 'vendor/autoload.php';
$mail = new PHPMailer(true);
try {
// Sunucu Ayarları
$mail->isSMTP();
$mail->Host = 'smtp.example.com'; // Örn: 'smtp.gmail.com'
$mail->SMTPAuth = true;
$mail->Username = 'mailiniz@example.com'; // SMTP Kullanıcı Adınız
$mail->Password = 'sifreniz'; // SMTP Şifreniz
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; // Güvenlik Protokolü
$mail->Port = 465; // veya 587 (TLS için)
// Gönderici ve Alıcı Ayarları
$mail->setFrom('gonderen@example.com', 'Robotik Hocası');
$mail->addAddress('alici@deneme.com', 'Deneme Alıcısı');
// İçerik
$mail->isHTML(true); // E-postayı HTML olarak ayarla
$mail->Subject = 'PHPMailer ile gönderilen ilk mail';
$mail->Body = '<h1 style="color: blue;">Tebrikler!</h1> Bu, başarılı bir testtir.';
$mail->AltBody = 'Bu bir HTML olmayan e-posta metnidir.'; // HTML desteklemeyenler için
$mail->send();
echo 'Mesaj başarıyla gönderildi.';
} catch (Exception $e) {
echo "Mesaj gönderilemedi. Hata: {$mail->ErrorInfo}";
}
?>
2.6 Form Güvenliği ve Doğrulama
Kullanıcıdan gelen her türlü veriye şüpheyle yaklaşılmalıdır. Güvenlik ve veri bütünlüğü için hem **Doğrulama (Validation)** hem de **Temizleme (Sanitization)** yapılmalıdır.
1. Veri Doğrulama (Validation)
Verinin doğru formatta ve doğru tipte olup olmadığını kontrol etme.
- Boşluk Kontrolü:
empty()fonksiyonu ile alanın boş bırakılıp bırakılmadığını kontrol etme. - Tipi Kontrolü:
is_numeric(),is_int()gibi fonksiyonlarla veri tipini kontrol etme. - Filtreleme Fonksiyonları:
filter_var()ile e-posta ve URL formatlarını kontrol etme.
Örnek: Basit Doğrulama
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$email = $_POST["email"];
$yas = $_POST["yas"];
// E-posta formatı kontrolü
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "Geçersiz e-posta formatı!";
}
// Yaşın sayı olup olmadığını kontrolü
if (!filter_var($yas, FILTER_VALIDATE_INT)) {
echo "Yaş alanı sayı olmalıdır!";
}
}
?>
2. Veri Temizleme (Sanitization) - Güvenlik Önlemleri
Kötü niyetli kodları veya karakterleri veriden çıkarma. Bu, özellikle XSS (Cross-Site Scripting) saldırılarını önlemek için zorunludur.
- XSS Koruması: Kullanıcının girdiği HTML etiketlerini ve zararlı kodları etkisiz hale getirir.
htmlspecialchars() Kullanımı
Bu fonksiyon, bir metin içindeki <, >, & gibi özel HTML karakterlerini, tarayıcının yorumlayamayacağı eşdeğerlerine (<, >, &) çevirir.
<?php
$kullanici_girisi = '<script>alert("Hacked!")</script>';
// Veriyi temizlemeden ekrana basmak (TEHLİKELİ)
echo "Temizlenmemiş: " . $kullanici_girisi . "<br>";
// Veriyi temizledikten sonra ekrana basmak (GÜVENLİ)
$guvenli_cikti = htmlspecialchars($kullanici_girisi);
echo "Güvenli Çıktı: " . $guvenli_cikti;
?>
Veritabanı Güvenliği Notu
SQL enjeksiyonu saldırısını önlemek için, veritabanına veri yazmadan önce **mutlaka** **Hazırlanmış Sorgular (Prepared Statements)** kullanılmalıdır (Bkz: 3.3 Konusu).
3.1 MySQL Bağlantısı (mysqli ve PDO)
PHP'nin MySQL veritabanlarına bağlanmak için iki temel yöntemi vardır: **MySQLi (MySQL Improved)** ve **PDO (PHP Data Objects)**. Modern ve güvenli uygulamalar için **PDO kullanılması şiddetle önerilir**.
PDO (PHP Data Objects) Nedir? (ÖNERİLEN)
- Veritabanı Bağımsızlığı: PDO, sadece MySQL değil, PostgreSQL, SQLite, MS SQL gibi birçok farklı veritabanına aynı arayüzle bağlanmanızı sağlar.
- Güvenlik: Hazırlanmış sorguları (Prepared Statements) destekleyerek SQL enjeksiyonu saldırılarını otomatik olarak engeller.
- Esneklik: Hata yönetimi ve sorgu sonuçlarını işleme konusunda daha esnek seçenekler sunar.
PDO ile Bağlantı Kurulumu (Try-Catch ile Hata Yönetimi)
PDO, istisna (exception) tabanlı çalıştığı için bağlantı hatalarını kolayca yakalamak mümkündür.
<?php
$host = 'localhost';
$db = 'veritabani_adi';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // Hataları istisna olarak fırlat
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // Verileri ilişkisel dizi olarak getir
PDO::ATTR_EMULATE_PREPARES => false, // Gerçek Prepared Statement kullan
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
echo "Veritabanı bağlantısı başarılı!";
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
die("Veritabanı bağlantı hatası: " . $e->getMessage());
}
?>
MySQLi Kullanımı (Prosedürel vs. Nesne Tabanlı)
MySQLi, sadece MySQL'e özgüdür. Hem prosedürel (fonksiyon tabanlı) hem de nesne yönelimli (OOP) olarak kullanılabilir. OOP yaklaşımı daha modern kabul edilir.
MySQLi (OOP) ile Bağlantı:
<?php
$mysqli = new mysqli("localhost", "root", "", "veritabani_adi");
// Bağlantı kontrolü
if ($mysqli->connect_errno) {
die("Bağlantı hatası: " . $mysqli->connect_error);
}
echo "MySQLi bağlantısı başarılı!";
$mysqli->close(); // Bağlantıyı kapat
?>
3.2 Temel Veritabanı İşlemleri (CRUD)
CRUD, bir uygulama için gerekli olan dört temel işlevi temsil eder: **Create** (Oluşturma), **Read** (Okuma), **Update** (Güncelleme) ve **Delete** (Silme). Tüm web uygulamalarının temelinde bu işlemler yer alır.
CREATE (Veri Ekleme - INSERT)
Veritabanına yeni bir kayıt eklemek için kullanılır. **Güvenlik nedeniyle 3.3 konusunda göreceğiniz Prepared Statements kullanılmalıdır.** Aşağıdaki örnek sadece mantığı gösterir.
<?php
// PDO Bağlantısı $pdo'nun kurulduğunu varsayalım...
$baslik = 'Yeni Makale Başlığı';
$icerik = 'Bu bir deneme makalesidir.';
// GÜVENLİ OLMAYAN SORGULAMA ÖRNEĞİ (SADECE GÖSTERİM AMAÇLI)
$sql = "INSERT INTO makaleler (baslik, icerik) VALUES ('$baslik', '$icerik')";
$etkilenen_satir = $pdo->exec($sql);
if ($etkilenen_satir) {
echo "Başarıyla $etkilenen_satir adet kayıt eklendi. Son ID: " . $pdo->lastInsertId();
} else {
echo "Kayıt eklenirken hata oluştu.";
}
?>
READ (Veri Okuma - SELECT)
Veritabanından veri çekmek için kullanılır. En yaygın kullanılan işlemdir.
<?php
// PDO Bağlantısı $pdo'nun kurulduğunu varsayalım...
$sql = "SELECT id, baslik, icerik FROM makaleler WHERE id = 1";
// Sorguyu çalıştır
$stmt = $pdo->query($sql);
// Tek bir satır getir
$makale = $stmt->fetch();
if ($makale) {
echo "Makale ID: " . $makale['id'] . "<br>";
echo "Başlık: " . $makale['baslik'];
} else {
echo "Makale bulunamadı.";
}
// Tüm makaleleri getirme örneği (Döngü ile)
$tum_makaleler = $pdo->query("SELECT baslik FROM makaleler")->fetchAll();
foreach ($tum_makaleler as $m) {
echo "<li>" . $m['baslik'] . "</li>";
}
?>
UPDATE (Veri Güncelleme)
Mevcut bir kaydı değiştirmek için kullanılır.
<?php
// PDO Bağlantısı $pdo'nun kurulduğunu varsayalım...
$yeni_baslik = 'Güncel Başlık';
$id = 1;
// GÜVENLİ OLMAYAN SORGULAMA ÖRNEĞİ
$sql = "UPDATE makaleler SET baslik = '$yeni_baslik' WHERE id = $id";
$etkilenen_satir = $pdo->exec($sql);
if ($etkilenen_satir) {
echo "Başarıyla $etkilenen_satir adet kayıt güncellendi.";
}
?>
DELETE (Veri Silme)
Belirli bir kaydı veritabanından tamamen kaldırmak için kullanılır.
<?php
// PDO Bağlantısı $pdo'nun kurulduğunu varsayalım...
$id_sil = 2;
// GÜVENLİ OLMAYAN SORGULAMA ÖRNEĞİ
$sql = "DELETE FROM makaleler WHERE id = $id_sil";
$etkilenen_satir = $pdo->exec($sql);
if ($etkilenen_satir) {
echo "Başarıyla $etkilenen_satir adet kayıt silindi.";
}
?>
3.3 Hazırlanmış Sorgular (Prepared Statements)
Hazırlanmış Sorgular (Prepared Statements), veritabanı işlemlerinde **SQL Enjeksiyonu** saldırısını önlemenin ve performansı artırmanın en güvenli ve önerilen yoludur. Özellikle kullanıcıdan gelen verileri (form verileri) işlerken zorunludur.
SQL Enjeksiyonu Nedir?
Kötü niyetli kullanıcıların form alanlarına SQL komutları girmesi ve bu komutların veritabanı tarafından çalıştırılmasıdır. Örn: Şifre alanına ' OR 1=1 -- girmek.
Prepared Statements Çalışma Mantığı
- **Hazırlık (Prepare):** SQL sorgusunu, verinin geleceği yerleri yer tutucular (placeholder:
?veya:ad) kullanarak veritabanına gönderirsiniz. (Veritabanı bu sorgu planını önbelleğe alır.) - **Bağlama (Bind):** Daha sonra, verileri ayrı bir adımda yer tutuculara bağlarsınız.
- **Çalıştırma (Execute):** Sorgu çalıştırılır. Veritabanı, bu verilerin sadece veri olduğunu, komut olmadığını bilir.
PDO ile Prepared Statements Örnekleri (Güvenli Yöntem)
1. Veri Ekleme (INSERT) Örneği:
<?php
// PDO Bağlantısı $pdo'nun kurulduğunu varsayalım...
$yeni_baslik = $_POST['baslik']; // Güvenli değil ama bind ile korunacak
$yeni_icerik = $_POST['icerik'];
$sql = "INSERT INTO makaleler (baslik, icerik) VALUES (?, ?)"; // Yer tutucular '?'
$stmt = $pdo->prepare($sql);
$stmt->execute([$yeni_baslik, $yeni_icerik]); // Verileri dizi olarak bağla ve çalıştır
echo "Güvenli ekleme başarılı!";
?>
2. Veri Okuma (SELECT) ve Bağlama (Named Placeholder) Örneği:
Adlandırılmış yer tutucular (:id) daha okunabilirdir.
<?php
// PDO Bağlantısı $pdo'nun kurulduğunu varsayalım...
$istenen_id = 5;
$sql = "SELECT baslik, icerik FROM makaleler WHERE id = :id";
$stmt = $pdo->prepare($sql);
// Veriyi isimle bağla (BindParam veya BindValue kullanılabilir)
$stmt->bindParam(':id', $istenen_id, PDO::PARAM_INT);
$stmt->execute();
$makale = $stmt->fetch();
if ($makale) {
echo "Makale Başlığı (Güvenli): " . $makale['baslik'];
}
?>
**UYARI:** Prepared Statements kullanmak, her zaman kullanıcıdan gelen verileri işlerken veritabanı güvenliği için bir numaralı kuraldır.
3.4 CRUD Uygulaması Geliştirme
Bu bölümde, önceki konularda öğrendiğimiz HTML formları, PDO bağlantısı ve Hazırlanmış Sorguları birleştirerek tam çalışan basit bir **Kullanıcı Yönetim Sistemi (CRUD)** uygulamasının temel mantığı özetlenecektir.
Uygulama Bileşenleri
- **
config.php:** Veritabanı bağlantısını PDO ile kuran ve bağlantı değişkenini ($pdo) içeren dosya. (require_onceile dahil edilir) - **
index.php:** Tüm kullanıcıların listelendiği (READ) ve yeni kullanıcı ekleme (CREATE) formunun bulunduğu ana sayfa. - **
duzenle.php:** Seçilen kullanıcının bilgilerinin gösterilip güncellendiği (UPDATE) sayfa. - **Silme İşlemi:** Genellikle
index.php'de bir link üzerinden GET isteği ile tetiklenir ve hemen ardından yönlendirme yapılır (DELETE).
Örnek: Tek Bir Dosyada Basit CRUD Akışı (INSERT/READ)
1. Veritabanı Bağlantısı (PDO):
<?php
// ... Bağlantı ayarları $pdo değişkenine atandı ... (Bkz. 3.1)
// CREATE - Yeni Kullanıcı Ekleme İşlemi
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ekle'])) {
$ad = $_POST['ad'];
$eposta = $_POST['eposta'];
try {
$stmt = $pdo->prepare("INSERT INTO kullanicilar (ad, eposta) VALUES (?, ?)");
$stmt->execute([$ad, $eposta]);
echo "<p style='color:green;'>Kullanıcı başarıyla eklendi.</p>";
} catch (Exception $e) {
echo "<p style='color:red;'>Hata: " . $e->getMessage() . "</p>";
}
}
// READ - Tüm Kullanıcıları Listeleme
$kullanicilar = $pdo->query("SELECT id, ad, eposta FROM kullanicilar")->fetchAll(PDO::FETCH_ASSOC);
?>
<!-- HTML Form ve Liste Başlangıcı -->
<h4>Yeni Kullanıcı Ekle</h4>
<form method="POST">
<input type="text" name="ad" placeholder="Ad" required><br>
<input type="email" name="eposta" placeholder="E-posta" required><br>
<button type="submit" name="ekle">Ekle</button>
</form>
<h4>Mevcut Kullanıcılar</h4>
<table border="1">
<tr><th>ID</th><th>Ad</th><th>E-posta</th><th>İşlemler</th></tr>
<?php foreach ($kullanicilar as $k): ?>
<tr>
<td><?= $k['id'] ?></td>
<td><?= $k['ad'] ?></td>
<td><?= $k['eposta'] ?></td>
<td>
<a href="duzenle.php?id=<?= $k['id'] ?>">Düzenle</a> |
<a href="index.php?sil_id=<?= $k['id'] ?>">Sil</a>
</td>
</tr>
<?php endforeach; ?>
</table>
Bu temel yapı, tüm CRUD işlemlerini uygulamanın başlangıcıdır. Güncelleme ve Silme işlemleri de aynı PDO ve Prepared Statements mantığıyla ilerler.
4.1 Nesne Yönelimli Programlama (OOP)
Nesne Yönelimli Programlama (Object-Oriented Programming - OOP), programlamayı gerçek dünyadaki nesneler gibi organize etme yaklaşımıdır. Bu, karmaşık projelerin daha düzenli, esnek ve sürdürülebilir olmasını sağlar.
Temel OOP Kavramları
- Sınıf (Class): Nesne oluşturmak için kullanılan bir taslak, şablon veya plandır. (Örn: Araba planı)
- Nesne (Object): Sınıfın somut bir örneğidir. (Örn: Kırmızı Renkli Fiat Araba)
- Özellik (Property): Nesnenin nitelikleridir (Değişkenler). (Örn: $hiz, $renk)
- Metot (Method): Nesnenin gerçekleştirebileceği eylemlerdir (Fonksiyonlar). (Örn: hizlan(), dur())
Örnek: Sınıf ve Nesne Tanımlama
<?php
class Araba {
// Özellikler
public $marka;
public $hiz = 0;
// Yapıcı Metot (Constructor) - Nesne oluşturulurken otomatik çalışır
public function __construct($marka) {
$this->marka = $marka;
}
// Metotlar
public function hizlan($artis) {
$this->hiz += $artis;
return "$this->marka hızı $this->hiz km/s oldu.";
}
}
// Nesne Oluşturma
$oto = new Araba("BMW");
echo $oto->hizlan(50); // Çıktı: BMW hızı 50 km/s oldu.
?>
OOP'nin Dört Ana Prensibi
- **Encapsulation (Kapsülleme):** Nesne özelliklerinin doğrudan erişimini engeller ve bu verilere erişimi (get/set metotları gibi) kontrollü hale getirir.
public: Her yerden erişilebilir.protected: Sadece sınıfın kendisi ve miras alan alt sınıflar erişebilir.private: Sadece sınıfın kendisi erişebilir.
- **Inheritance (Kalıtım):** Bir sınıfın (Alt Sınıf), başka bir sınıfın (Üst Sınıf) tüm özellik ve metotlarını miras almasıdır. Kod tekrarını azaltır (
extendsanahtar kelimesi). - **Polymorphism (Çok Biçimlilik):** Farklı nesnelerin aynı metoda farklı şekillerde tepki vermesidir. (Örn:
SesCikar()metodu Kedi sınıfında "Miyav", Köpek sınıfında "Hav Hav" çıktısı verebilir). - **Abstraction (Soyutlama):** Kullanıcının sadece bilmesi gereken önemli detayları göstermek, karmaşık iç işleyişi gizlemektir. (
abstract classveinterfacekullanılır).
4.2 Namespace, Autoloading ve Composer
Modern PHP, büyük ve organize projeler yazmak için bu üç kritik araca dayanır. Bu yapılar, kodun karmaşasını azaltır ve harici kütüphaneleri yönetmeyi kolaylaştırır.
1. Namespace (İsim Alanı)
Namespace, farklı kütüphanelerden veya modüllerden gelen aynı isimli sınıfların çakışmasını engeller (Örn: Hem kendi yazdığınız hem de harici bir kütüphaneden gelen Kullanici sınıfı).
İsim alanları, dosya dizin yapısını taklit eder.
Örnek Kullanım:
// Dosya: App/Veritabani/DB.php
namespace App\Veritabani;
class DB {
public function baglan() {
echo "App\\Veritabani\\DB bağlantısı kuruldu.";
}
}
// Başka bir dosya: index.php
use App\Veritabani\DB;
$vt = new DB();
$vt->baglan();
?>
2. Autoloading (Otomatik Yükleme)
Eskiden bir sınıfı kullanmadan önce require 'class/Kullanici.php'; şeklinde elle dahil etmek gerekiyordu. Autoloading, bir sınıf çağrıldığında (Örn: new Kullanici()), PHP'nin bu sınıfın dosyasını otomatik olarak bulup dahil etmesini sağlar. Bu işlem, genellikle Composer tarafından yönetilen **PSR-4** standardına göre yapılır.
Bu sayede yüzlerce require satırından kurtulunur.
3. Composer (Bağımlılık Yöneticisi)
Composer, PHP için birincil paket ve bağımlılık yöneticisidir. Node.js'teki npm veya Python'daki pip gibi düşünülebilir.
- Kütüphane Yönetimi: Uygulamanızın ihtiyaç duyduğu tüm harici kütüphaneleri (PHPMailer, Framework bileşenleri vb.) otomatik olarak indirir ve günceller.
- Autoloading Desteği: Composer, projeye dahil ettiği kütüphaneler için otomatik yükleme dosyalarını (
vendor/autoload.php) oluşturur. - **
composer.json:** Projenin bağımlılıklarını ve ayarlarını tutan temel dosyadır.
Composer Temel Adımlar:
- Projeyi Başlatma:
composer init - Kütüphane Ekleme:
composer require monolog/monolog - Otomatik Yüklemeyi Dahil Etme:
require 'vendor/autoload.php';
// index.php'nin en başında sadece bunu dahil etmek yeterlidir.
require 'vendor/autoload.php';
// Monolog kütüphanesini kullanmak için artık ek require gerekmez.
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = new Logger('name');
$log->pushHandler(new StreamHandler('log/uygulama.log', Logger::WARNING));
$log->warning('Bu, bir uyarı mesajıdır.');
?>
4.3 PHP Frameworkleri ve MVC Mimarisi
Framework'ler, web uygulamaları geliştirmek için yapılandırılmış, standartlaştırılmış bir dizi araç, kütüphane ve kural setidir. PHP dünyasının en popüler Framework'leri **Laravel** ve **Symfony**'dir. Büyük projelerde bu Framework'leri kullanmak, hızlı geliştirme ve güçlü yapı sağlar.
Neden Framework Kullanılmalı?
- Hız: Sık kullanılan görevler (veritabanı, oturum, yönlendirme) önceden yazılmış fonksiyonlarla çok hızlı yapılır.
- Güvenlik: SQL Enjeksiyonu, CSRF gibi yaygın saldırılara karşı yerleşik koruma sağlar.
- Organizasyon: Kodun belirli bir mimariye (çoğunlukla MVC) uymasını zorunlu kılar.
MVC Mimarisi Nedir? (Model-View-Controller)
MVC, bir uygulamanın iş mantığını, verilerini ve sunumunu (arayüzünü) ayırarak geliştirmeyi kolaylaştıran bir yazılım tasarım desenidir.
| Bileşen | Görevi | Örnek Eylem |
|---|---|---|
| **Model** | Veri ve İş Mantığı. Veritabanı ile doğrudan iletişime geçer. | Veritabanından tüm kullanıcıları çekmek, kullanıcıyı kaydetmek. |
| **View** | Kullanıcı Arayüzü. Kullanıcıya gösterilen HTML yapısıdır. | Kullanıcı listesini gösteren tabloyu oluşturmak. |
| **Controller** | Uygulamanın beyni. Kullanıcı isteğini alır, Model'i çağırır ve View'i hazırlar. | /kullanicilar isteğini yakalamak ve Model'den veriyi alıp View'e göndermek. |
Framework'lerin Rolü
Framework'ler (Laravel, Symfony) bu MVC yapısını sağlamanın yanı sıra; URL yönlendirme (Routing), Veritabanı Soyutlama (Eloquent ORM), Oturum Yönetimi ve Test araçları gibi yüzlerce kolaylaştırıcı bileşen sunar.
Laravel Örneği (Sözde Kod):
Route::get('/kullanicilar', [KullaniciController::class, 'index']);
Bu tek satır, Framework sayesinde **Routing** işlemini yapar ve gelen isteği otomatik olarak KullaniciController'ın index metoduna yönlendirir.
4.4 API Geliştirme ve RESTful Mantığı
API (Application Programming Interface - Uygulama Programlama Arayüzü), iki farklı yazılımın birbirleriyle güvenli ve standart bir şekilde konuşmasını sağlayan kurallar setidir. Modern web ve mobil uygulamalarda en yaygın API mimarisi **RESTful** API'lerdir.
REST (Representational State Transfer) Nedir?
- Durumsuzluk (Stateless): Her istek (Request) bağımsızdır. Sunucu, önceki istekleri hatırlamaz (Oturum bilgisi hariç).
- Kaynak Odaklılık: Veriler, URL'ler (Endpoint) aracılığıyla bir kaynak olarak ele alınır (Örn:
/api/kullanicilar). - Standart HTTP Metotları: CRUD işlemleri için standart HTTP metotları kullanılır.
HTTP Metotları ve CRUD Eşleşmesi
RESTful API'lerde, bir kaynak üzerindeki işlemi belirtmek için HTTP fiilleri kullanılır:
| HTTP Metot | CRUD İşlemi | Açıklama |
|---|---|---|
| **GET** | READ | Kaynakları getir (listeleme veya tekil okuma). |
| **POST** | CREATE | Yeni bir kaynak oluştur. |
| **PUT/PATCH** | UPDATE | Kaynağın tamamını (PUT) veya bir kısmını (PATCH) güncelle. |
| **DELETE** | DELETE | Kaynağı sil. |
PHP ile Basit API Cevabı (JSON)
API'ler genellikle veriyi JSON (JavaScript Object Notation) formatında döndürür. PHP'de dizileri JSON'a çevirmek çok kolaydır.
<?php
// 1. Cevap başlığını JSON olarak ayarla
header('Content-Type: application/json');
// 2. HTTP metodunu kontrol et (RESTful yapının temeli)
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
// Veritabanından gelen veri olduğunu varsayalım
$kullanicilar = [
['id' => 1, 'ad' => 'Ahmet', 'email' => 'a@test.com'],
['id' => 2, 'ad' => 'Zeynep', 'email' => 'z@test.com']
];
// 3. PHP dizisini JSON formatına dönüştür ve ekrana bas
echo json_encode($kullanicilar);
} else {
http_response_code(405); // Metot İzin Verilmiyor
echo json_encode(['hata' => 'Bu kaynak sadece GET metodunu destekler.']);
}
?>
4.5 İleri PHP Güvenlik Uygulamaları
Temel güvenlik (XSS, Prepared Statements) dışında, profesyonel uygulamaların olmazsa olmazı ileri düzey güvenlik önlemleridir.
1. Parola Güvenliği (Hashing)
Parolalar hiçbir zaman açık metin (plaintext) olarak veritabanında saklanmamalıdır. Bunun yerine, geri döndürülemez bir şekilde karmaşık bir değere (Hash) dönüştürülmelidir.
- **
md5()/sha1()Kullanmayın:** Bu algoritmalar çok hızlıdır ve kolayca tersine çevrilebilir. - **
password_hash()Kullanın:** PHP'nin yerleşik ve en güvenli hashing mekanizmasıdır. Otomatik olarak güvenli bir algoritma (şu an için Argon2 veya Bcrypt) kullanır ve tuzlama (salting) işlemini yapar.
Örnek: Parola Hashleme
<?php
$girilen_sifre = 'gizli_sifrem123';
// Parolayı hash'le (Veritabanına yazılacak olan)
$hashed_sifre = password_hash($girilen_sifre, PASSWORD_DEFAULT);
echo "Hashed Parola: " . $hashed_sifre . "<br>";
// Giriş Kontrolü (Login)
$db_hash = $hashed_sifre; // DB'den çekildiğini varsayalım
if (password_verify($girilen_sifre, $db_hash)) {
echo "Giriş başarılı!";
} else {
echo "Hatalı şifre!";
}
?>
2. CSRF (Cross-Site Request Forgery) Koruması
Kullanıcının, farkında olmadan kötü niyetli bir site üzerinden uygulamanıza istek göndermesini (Örn: banka havalesi yapmasını) engeller.
Çözüm: Formlara benzersiz, rastgele oluşturulmuş bir gizli alan (CSRF Token) eklemek. Sunucuya POST isteği geldiğinde, gönderilen token'ın Session'daki token ile aynı olup olmadığı kontrol edilir.
3. HTTP Güvenlik Başlıkları
Sunucunun tarayıcılara gönderdiği özel başlıklar aracılığıyla çeşitli güvenlik önlemleri aktif edilir.
- **HSTS (Strict-Transport-Security):** Tarayıcıları her zaman HTTPS kullanmaya zorlar.
- **Content-Security-Policy (CSP):** Hangi kaynaklardan (script, stil) yükleme yapılabileceğini belirleyerek XSS riskini büyük ölçüde azaltır.
- **X-Frame-Options:** Uygulamanızın başka bir sitede iframe içinde gösterilmesini engeller (Clickjacking koruması).
Örnek: Güvenlik Başlığı Ekleme
<?php
header("X-Frame-Options: DENY"); // Iframe kullanımını engelle
header("Content-Security-Policy: default-src 'self'"); // Sadece kendi domaininizden script/stil yükle
?>
4.6 PHP ve Front-End Etkileşimi (AJAX/JSON)
Geleneksel PHP'de, bir veriyi güncellemek için sayfanın tamamı yeniden yüklenir. Modern uygulamalar, sayfa yenilenmeden arka planda veri alışverişi yapmak için **AJAX** (Asynchronous JavaScript and XML) veya daha modern adıyla **Fetch API** kullanır.
AJAX/Fetch Mantığı
AJAX, istemci (tarayıcıdaki JavaScript) ile sunucu (PHP) arasında eş zamansız (asenkron) iletişim sağlar. İstemci, bir PHP betiğine istek gönderir, PHP ise genellikle JSON formatında veri döndürür. Bu, kullanıcı deneyimini önemli ölçüde artırır (Örn: Instagram'da sayfayı yenilemeden yeni yorum eklenmesi).
JSON Formatı (JavaScript Object Notation)
AJAX çağrılarında en popüler veri değişim formatıdır. PHP dizileri (array) ve nesneleri (object) kolayca JSON'a dönüştürülebilir ve tersi de geçerlidir.
| PHP Fonksiyonu | Görevi |
|---|---|
json_encode($dizi) | PHP dizi/nesnesini JSON string'ine çevirir. (PHP -> JS) |
json_decode($json, true) | JSON string'ini PHP dizi/nesnesine çevirir. (JS -> PHP) |
PHP Tarafı (API Endpoint) Örneği
veri-al.php dosyası, AJAX isteği aldığında sadece JSON döndürecektir.
<?php
// Yalnızca JSON yanıtı gönderileceğini belirtir
header('Content-Type: application/json');
$veriler = [
'durum' => 'basarili',
'kullanici_sayisi' => 120,
'son_giris' => date('H:i:s')
];
echo json_encode($veriler);
?>
JavaScript Tarafı (Fetch API) Örneği
Tarayıcıda sayfa yenilenmeden veri-al.php'ye istek gönderir.
<script>
document.getElementById('veriGoster').addEventListener('click', () => {
fetch('veri-al.php') // PHP dosyasına istek gönder
.then(response => response.json()) // JSON cevabını parse et
.then(data => {
console.log("Sunucudan gelen veri:", data);
document.getElementById('sonuc').innerHTML =
`Kullanıcı Sayısı: ${data.kullanici_sayisi} (Son Giriş: ${data.son_giris})`;
})
.catch(error => console.error('Hata:', error));
});
</script>
<button id="veriGoster">Veri Al</button>
<div id="sonuc"></div>