30 Ekim 2025

ESP32 İle Web Sunucusu Kurulumu: İki LED'i İnternet Üzerinden Kontrol Edin

ESP32, güçlü Wi-Fi yetenekleri ve düşük güç tüketimi sayesinde Nesnelerin İnterneti (IoT) projeleri için mükemmel bir mikrodenetleyicidir. Bu projede, ESP32'yi kullanarak yerel ağınızdaki herhangi bir cihazdan (telefon, tablet veya bilgisayar) iki ayrı LED'i kontrol etmenizi sağlayacak bağımsız (standalone) bir web sunucusu oluşturacağız.

🛠️ Neler Gerekiyor?

Bu projeyi tamamlamak için ihtiyacınız olan temel bileşenler şunlardır:

  • ESP32 Geliştirme Kartı: (Herhangi bir modeli kullanabilirsiniz)
  • İki Adet LED: (Farklı renklerde olabilir)
  • İki Adet Akım Sınırlayıcı Direnç: (Genellikle 220 ohm idealdir)
  • Breadboard (Devre Tahtası)
  • Jumper Kabloları
  • Arduino IDE: (Gerekli ESP32 kart desteği kurulu olmalıdır)

🛠️ Devre Şeması ve Bileşenler

Bu projede, iki LED'i kontrol etmek için ESP32'nin iki farklı GPIO pinini kullanıyoruz:

BileşenESP32 PiniAçıklama
Yeşil LEDGPIO 2 (D2)Açma/Kapama komutları bu pini kontrol eder.
Kırmızı LEDGPIO 4 (D4)Açma/Kapama komutları bu pini kontrol eder.
Direnç (220 ohm)SerideHer iki LED'in de akımını sınırlamak için kullanılır.

Kurulum Adımları:

  1. Yeşil LED Bağlantısı: LED'in uzun bacağını (anot) bir 220 Ohm direnç ile seri bağlayın ve bu direncin diğer ucunu GPIO 2'ye takın. LED'in kısa bacağını (katot) ESP32'deki GND pinine bağlayın.
  2. Kırmızı LED Bağlantısı: Aynı işlemi Kırmızı LED için tekrarlayın: LED'in anodu, bir 220 Ohm direnç üzerinden GPIO 4'e bağlanır. Katot ucu ise GND'ye bağlanır.

Bu kurulum, LED'lerin güvenliğini sağlarken ESP32 üzerinden kontrol edilebilmelerini mümkün kılar.

Arduino IDE Kodumuz

// Load Wi-Fi library
#include <WiFi.h>

// Wi-Fi Ağ Bilgilerinizi Buraya Girin
const char* ssid = "SSID";       // Ağınızın Adı (SSID)
const char* password = "password"; // Ağınızın Şifresi

// Web Sunucusu 80. Portta Çalışacak
WiFiServer server(80);

// HTTP İsteğini Depolayacak Değişken
String header;

// LED Durumlarını Saklayacak Yardımcı Değişkenler
String greenLedState = "off";
String redLedState = "off";

// LED'lerin Bağlı Olduğu GPIO Pinleri
const int greenLed = 2; // D2 -> Yeşil LED (ESP32 için GPIO 2)
const int redLed = 4;   // D4 -> Kırmızı LED (ESP32 için GPIO 4)

// Zamanlama Değişkenleri (İstemci Zaman Aşımı İçin)
unsigned long currentTime = millis();
unsigned long previousTime = 0; 
const long timeoutTime = 2000; // 2 saniye zaman aşımı

void setup() {
  Serial.begin(115200);

  // Pinleri Çıkış Olarak Ayarla
  pinMode(greenLed, OUTPUT);
  pinMode(redLed, OUTPUT);

  // Başlangıçta Tüm LED'leri Kapat
  digitalWrite(greenLed, LOW);
  digitalWrite(redLed, LOW);

  // Wi-Fi Ağına Bağlan
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  // Bağlantı Başarılı Olana Kadar Bekle
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  // IP Adresini Yazdır ve Sunucuyu Başlat
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop() {
  // Yeni İstemci Bağlantısı Kontrolü
  WiFiClient client = server.available();

  if (client) {
    currentTime = millis();
    previousTime = currentTime;
    Serial.println("New Client.");
    String currentLine = "";

    // İstemci Bağlı Olduğu Sürece Veya Zaman Aşımı Dolana Kadar Oku
    while (client.connected() && currentTime - previousTime <= timeoutTime) {
      currentTime = millis();
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        header += c;
        if (c == '\n') {
          // HTTP İsteğinin Sonuna Gelindi
          if (currentLine.length() == 0) {

            // HTTP Cevap Başlıkları
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            // ===================================
            // LED Kontrol Mantığı (HTTP İsteğine Göre)
            // ===================================
            
            if (header.indexOf("GET /green/on") >= 0) {
              Serial.println("Green LED ON");
              greenLedState = "on";
              digitalWrite(greenLed, HIGH);
            } else if (header.indexOf("GET /green/off") >= 0) {
              Serial.println("Green LED OFF");
              greenLedState = "off";
              digitalWrite(greenLed, LOW);
            } else if (header.indexOf("GET /red/on") >= 0) {
              Serial.println("Red LED ON");
              redLedState = "on";
              digitalWrite(redLed, HIGH);
            } else if (header.indexOf("GET /red/off") >= 0) {
              Serial.println("Red LED OFF");
              redLedState = "off";
              digitalWrite(redLed, LOW);
            }

            // ===================================
            // Web Sayfası İçeriği (HTML/CSS)
            // ===================================

            client.println("<!DOCTYPE html><html lang='tr'>");
            client.println("<head><meta name='viewport' content='width=device-width, initial-scale=1'>");
            client.println("<link rel='icon' href='data:,'>");
            
            // CSS Stilleri (Mobil Uyumlu Tasarım)
            client.println("<style>");
            client.println("html, body { font-family: 'Segoe UI', Helvetica, Arial, sans-serif; background: linear-gradient(135deg, #1f1c2c, #928dab); color: #fff; text-align: center; height: 100%; margin: 0; }");
            client.println("h1 { font-size: 2.5rem; margin-top: 40px; letter-spacing: 2px; }");
            client.println("h2 { margin-top: 30px; font-weight: 500; color: #ffe082; }");
            client.println("p { font-size: 1.2rem; margin: 10px 0; }");
            client.println(".button { display: inline-block; background: #00c853; border: none; color: white; padding: 16px 50px; text-decoration: none; font-size: 22px; margin: 10px; cursor: pointer; border-radius: 10px; transition: 0.3s; }");
            client.println(".button:hover { background: #00e676; transform: scale(1.05); }");
            client.println(".button2 { background: #ff1744; }");
            client.println(".button2:hover { background: #ff5252; transform: scale(1.05); }");
            client.println(".led-section { background: rgba(255,255,255,0.1); margin: 30px auto; width: 80%; max-width: 400px; padding: 20px; border-radius: 15px; box-shadow: 0 0 20px rgba(0,0,0,0.3); }");
            client.println("</style></head>");
            
            client.println("<body>");
            client.println("<h1>ESP32 LED Kontrol Paneli</h1>");
            client.println("<p>Yerel Ag Uzerinden IoT Kontrolu</p>");

            // Yeşil LED Bölümü (Dinamik Buton)
            client.println("<div class='led-section'>");
            client.println("<h2>Yesil LED (D2)</h2>");
            client.println("<p>Durum: " + greenLedState + "</p>");
            if (greenLedState == "off") {
              client.println("<p><a href='/green/on'><button class='button'>AÇ</button></a></p>");
            } else {
              client.println("<p><a href='/green/off'><button class='button button2'>KAPAT</button></a></p>");
            }
            client.println("</div>");

            // Kırmızı LED Bölümü (Dinamik Buton)
            client.println("<div class='led-section'>");
            client.println("<h2>Kirmizi LED (D4)</h2>");
            client.println("<p>Durum: " + redLedState + "</p>");
            if (redLedState == "off") {
              client.println("<p><a href='/red/on'><button class='button'>AÇ</button></a></p>");
            } else {
              client.println("<p><a href='/red/off'><button class='button button2'>KAPAT</button></a></p>");
            }
            client.println("</div>");

            client.println("</body></html>");

            // Cevabı Gönderdikten Sonra Döngüden Çık
            break;
          } else { 
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }
    }

    // Başlık Değişkenini Temizle ve Bağlantıyı Kapat
    header = "";
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

Projeyi Derleme ve Çalıştırma

  1. Kod Güncelleme: Kod içindeki Wi-Fi bilgilerinizi (ssid ve password) kendi ağ bilgilerinize göre güncelleyin.
  2. Yükleme: Kodu ESP32 kartınıza yükleyin.
  3. Erişim: Seri Monitörden elde ettiğiniz IP adresini (Örnek: 192.168.1.42) cep telefonunuzun veya bilgisayarınızın web tarayıcısına girin.
  4. Kontrol: Karşınıza çıkan şık kontrol paneli ile her iki LED'i de anında açıp kapatabilirsiniz. Sayfayı cep telefonunuzda açtığınızda, düğmelerin parmağınızla kolayca dokunulabilir boyutta olduğunu göreceksiniz.

Bu proje, temel donanım kontrolünü modern ve kararlı bir web arayüzüyle birleştirmenin harika bir örneğidir. Projenizin bir sonraki aşamasında bu yapıya sensör verilerini veya daha fazla çıkışı kolayca entegre edebilirsiniz!


15 Ocak 2025

PHP'de hata yönetimi (error handling)

 PHP'de hata yönetimi (error handling) çok önemlidir çünkü veritabanı bağlantıları ve sorgular sırasında oluşabilecek hatalar uygulamanızın düzgün çalışmasını engelleyebilir. Bu tür hataları yönetmek için PDO kullanıyorsanız, $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) kodu, hata ayıklama ve hata yönetimini daha etkili hale getirir.

1. PDO ve setAttribute Metodu

PDO (PHP Data Objects), PHP'nin veritabanlarına güvenli ve esnek bir şekilde bağlanmasını sağlayan bir sınıftır. PDO, veritabanı bağlantıları, sorgu çalıştırma, hata yönetimi gibi işlemleri daha düzenli bir şekilde yapmanıza yardımcı olur.

setAttribute() metodu, PDO nesnesinin çeşitli ayarlarını yapmanıza olanak tanır. Bu metod, PDO'yu daha özelleştirilebilir hale getirir.

2. Hata Yönetimi ve ATTR_ERRMODE

PDO::ATTR_ERRMODE PDO'nun hata yönetimi ile ilgilidir. Bu, veritabanı bağlantısında ve sorgularda oluşan hataların nasıl yönetileceğini belirler.

Hata yönetimi modları:

  • PDO::ERRMODE_SILENT (Varsayılan): Hatalar gizlenir. PDO hata mesajlarını göstermez.
  • PDO::ERRMODE_WARNING: PDO, hata mesajlarını sadece uyarı olarak gösterir. Uyarılar, PHP'nin normal hata ayıklama sistemine benzer.
  • PDO::ERRMODE_EXCEPTION: PDO, hata meydana geldiğinde bir exception (istisna) fırlatır. Bu, hata ayıklamayı daha kolay hale getirir, çünkü hataları yakalamak için try-catch blokları kullanabilirsiniz.
ÖRNEK:
<?php try { $db = new PDO('mysql:host=localhost;dbname=testdb', 'root', ''); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Hata yönetimini ayarlıyoruz // Bir sorgu çalıştırıyoruz $query = $db->query("SELECT * FROM non_existent_table"); } catch (PDOException $e) { // Hata meydana geldiğinde exception yakalanır echo "Hata: " . $e->getMessage(); } ?>

Açıklama:

  • try bloğu: PDO nesnesini oluşturup sorgu çalıştırdığınız kısımdır. Eğer burada bir hata oluşursa, PDO bir exception fırlatacaktır.
  • catch bloğu: Eğer bir exception fırlatılırsa, bu blok devreye girer. PDOException sınıfı, PDO ile ilgili hataları yakalar. Bu hatayı $e->getMessage() ile ekrana yazdırabilirsiniz.

Avantajlar:

  • Hatalar hakkında daha fazla bilgi edinirsiniz.
  • Hata mesajları özelleştirilebilir ve hata ayıklama çok daha kolay olur.
  • Exception kullanarak hatalarla başa çıkmak, programın geri kalanının düzgün çalışmasını sağlar, çünkü hatayı kontrol edebilir ve uygun şekilde yanıt verebilirsiniz.

14 Ocak 2025

Php Static Kullanımı

static anahtar kelimesi, PHP'de sınıfa bağlı özellikler (properties) ve metotlar (methods) tanımlamak için kullanılır. Bu özellik ve metotlara bir nesne oluşturmadan doğrudan sınıf üzerinden erişilebilir.

Normalde bir sınıftaki özellik veya metoda erişmek için bir nesne oluşturman gerekir. Ancak static kullanıldığında, o özellik veya metot sınıfa bağlı hale gelir ve nesne oluşturmadan kullanılabilir.


Static Özellik ve Metotlar

  • Static Özellikler: Sınıfa özgüdür ve tüm nesneler için ortak bir değer taşır.
  • Static Metotlar: Bir nesne yerine sınıf üzerinden çalıştırılır. Static metotlar içinde $this kullanılamaz, çünkü $this bir nesneyi temsil eder.

Static Kullanımına Örnek

<?php class Matematik { // Static bir özellik (tüm sınıflar için ortak) public static $pi = 3.14159; // Static bir metot public static function alanHesapla($yaricap) { return self::$pi * $yaricap * $yaricap; } } // Nesne oluşturmadan static özelliğe erişim echo Matematik::$pi; // Çıktı: 3.14159 // Nesne oluşturmadan static metoda erişim echo Matematik::alanHesapla(5); // Çıktı: 78.53975 ?>

Önemli Notlar:

  1. Static özelliklere ve metotlara self:: veya ClassName:: kullanarak erişilir.
  2. Static özellik ve metotlar nesneye değil, doğrudan sınıfa bağlıdır.
  3. self:: → Sınıf içinden static özelliğe/metoda erişim için kullanılır.
  4. ClassName:: → Sınıf dışından static özelliğe/metoda erişim için kullanılır.

Static Özelliklerin Durumunu Değiştirme

Static özellikler, sınıfa özgü olduğu için her nesnede aynı değeri taşır. Örneğin:

<?php class Sayaç { public static $sayi = 0; public static function arttir() { self::$sayi++; } } // Static özelliği güncelleme ve okuma Sayaç::arttir(); Sayaç::arttir(); echo Sayaç::$sayi; // Çıktı: 2 ?>

Static ile Diğer Özelliklerin Farkı

Eğer static kullanmazsan, her nesne için özellikler farklı olur. Static ise ortak bir özellik/metot sağlar.


Static ve Late Static Binding

Eğer bir sınıftan türeyen sınıflarda static metodun sınıfa özgü davranmasını istersen, static:: kullanmalısın. Örneğin:

<?php class A { public static function kimimBen() { return static::class; // Late Static Binding } } class B extends A { } echo A::kimimBen(); // Çıktı: A echo B::kimimBen(); // Çıktı: B ?>

Php Nesne Yönelimli Programlama Giriş Erişilebilirlik

 <?php


/*
Erişilebilirlik

public
Her yerden erişilebilir.

private
Sadece sınıf içerisinden erişilebilir.

protected
Dışarıdan erişilmez.
Sınıf içinde erişilebilir.
Miras alma yoluyla kullanılabilir.

*/

class User{
public $email;
private $name;
protected $surname;


public function getEmail()
{
return $this->email;
}


public function setEmail($email): void
{
$this->email = $email;
}

public function getSurname()
{
return $this->surname;
}

public function setSurname($surname): void
{
$this->surname = $surname;
}

public function getName()
{
return $this->name;
}

public function setName($name): void
{
$this->name = $name;
}


}

$User = new User();

$User->setName("Mustafa");
$User->setSurname("Yilmaz");
$User->setEmail("email@deneme.com");

echo $User->getEmail();
echo "<br>";
echo $User->getName();
echo "<br>";
echo $User->getSurname();

?>

Php Nesne Yönelimli Programlama Giriş

Nesne Yönelimli Programlama (OOP), PHP'de yazılım geliştirirken kodunu daha düzenli ve tekrar kullanılabilir hale getirmenin güçlü bir yoludur. OOP'yi anlamak, daha büyük projelerde çok işine yarayacak.

OOP'nin temel kavramlarını tanıyalım: Sınıflar (Classes), Nesneler (Objects), Özellikler (Properties), Metotlar (Methods), ve Erişim Belirleyiciler (Access Modifiers).

Basit bir OOP Örneği

Aşağıdaki örnek, OOP'ye giriş için temel bir sınıf ve nesne kullanımını gösterir:

<?php

// 1. Bir sınıf tanımlıyoruz
class Araba {
    // Özellikler (properties)
    public $renk; // Arabanın rengi
    public $marka; // Arabanın markası

    // Constructor (Yapıcı Metot): Nesne oluşturulurken çalışır
    public function __construct($renk, $marka) {
        $this->renk = $renk;  // $this-> özelliğe erişir
        $this->marka = $marka;
    }

    // Metot (Method): Arabanın bilgisini döndüren bir işlev
    public function bilgiGoster() {
        return "Bu araba bir {$this->renk} {$this->marka}.";
    }
}

// 2. Sınıftan bir nesne oluşturuyoruz
$benimArabam = new Araba("kırmızı", "Toyota");

// 3. Nesne üzerinden metoda erişiyoruz
echo $benimArabam->bilgiGoster(); // Çıktı: Bu araba bir kırmızı Toyota.

?>

11 Ocak 2025

PHP Dizin İşlemleri: Daha Derine İnelim

 

PHP Dizin İşlemleri: Daha Derine İnelim

Verdiğiniz örnekler, PHP ile dizin oluşturma ve silme işlemlerinin temelini çok güzel bir şekilde açıklıyor. Ancak, bu konuda daha da derinleşerek, bazı ek noktalara ve olası senaryolara değinmek faydalı olacaktır.

Dizin Oluşturma (mkdir)

  • İzinler (chmod): İkinci parametre olarak verilen 0777 gibi izinler, oluşturulan dizinin okuma, yazma ve yürütme izinlerini belirtir. Ancak, güvenlik açısından tüm kullanıcılar için tüm izinleri vermek her zaman önerilmez. Daha spesifik izinler belirlemek için chmod fonksiyonunu kullanabilirsiniz.
  • Çoklu Dizin Oluşturma: Tek seferde birden fazla dizin oluşturmak için mkdir fonksiyonunu iç içe kullanabilir veya recursive olarak dizin oluşturabilirsiniz.
  • Hata Kontrolü: mkdir fonksiyonu başarısız olursa, nedenini anlamak için error_get_last() fonksiyonunu kullanabilirsiniz.
  • Özel Dizinler: mkdir fonksiyonu ile özel dizinler (örneğin, . ile başlayan gizli dizinler) de oluşturabilirsiniz.

Dizin Silme (rmdir)

  • Boş Dizin Kontrolü: rmdir fonksiyonu sadece boş dizinleri silebilir. Dizin içinde dosya veya alt dizin varsa, önce bunları silmeniz gerekir.
  • Recursive Silme: İç içe dizinleri silmek için recursive olarak rmdir fonksiyonunu kullanabilir veya glob ve unlink kombinasyonuyla tüm dosyaları silerek dizini boşaltabilirsiniz.
  • Hata Kontrolü: rmdir fonksiyonu başarısız olursa, nedenini anlamak için error_get_last() fonksiyonunu kullanabilirsiniz.

Ek Fonksiyonlar ve Konular

  • file_exists: Bir dosya veya dizinin var olup olmadığını kontrol eder.
  • is_dir: Verilen yolun bir dizin olup olmadığını kontrol eder.
  • is_file: Verilen yolun bir dosya olup olmadığını kontrol eder.
  • glob: Belirli bir pattern'e uyan dosya veya dizinlerin listesini döndürür.
  • rename: Bir dosya veya dizinin adını değiştirir.
  • copy: Bir dosyayı veya dizini kopyalar.
  • scandir: Bir dizindeki tüm dosya ve alt dizinlerin listesini alır.
  • realpath: Verilen yolun mutlak yolunu döndürür.
  • dirname: Verilen yolun dizin kısmını döndürür.
  • basename: Verilen yolun dosya adını döndürür.

Güvenlik

  • Göreli Yollar: Güvenlik açıklarından kaçınmak için mutlak yollar kullanın. Göreli yollar, beklenmedik sonuçlara neden olabilir.
  • İzin Kontrolü: Kullanıcıların izinsiz dosyalara erişmesini engellemek için izinleri dikkatli bir şekilde ayarlayın.
  • Girişleri Temizleme: Kullanıcıdan alınan girişleri temizleyerek, dizin yolunda zararlı karakterlerin olmasını önleyin.

Örnek: Recursive Dizin Silme

PHP
function sil($dizin) {
    foreach (glob($dizin . '/*') as $dosya) {
        is_dir($dosya) ? sil($dosya) : unlink($dosya);
    }
    rmdir($dizin);
}

sil('dosyalar/resimler');

Örnek: Çoklu Dizin Oluşturma

PHP
function olustur($dizin, $izinler = 0755) {
    if (!is_dir($dizin)) {
        mkdir($dizin, $izinler, true); // true, recursive oluşturma
    }
}

olustur('dosyalar/resimler/2023');
olustur('dosyalar/belgeler');

Sonuç olarak, PHP ile dizin işlemleri, web uygulamalarında sıkça kullanılan önemli bir konudur. Bu işlemleri yaparken güvenlik, performans ve okunabilirlik gibi faktörleri göz önünde bulundurmak önemlidir. Verilen örnekler ve ek bilgiler, bu konuda daha iyi bir anlayış kazanmanıza yardımcı olacaktır.

Ek olarak, PHP'nin sunduğu diğer dosya ve dizin işlemleriyle ilgili daha fazla bilgi için PHP resmi dokümantasyonunu inceleyebilirsiniz.