<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://sonsuzus.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sonsuzus.github.io/" rel="alternate" type="text/html" /><updated>2026-08-06T07:13:33+00:00</updated><id>https://sonsuzus.github.io/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Değişkenler ve Kontrol Akışıyla Dinamik Sayfalar Tasarlamak</title><link href="https://sonsuzus.github.io/posts/degiskenler-ve-kontrol-akisiyla-dinamik-sayfalar-tasarlamak/" rel="alternate" type="text/html" title="Değişkenler ve Kontrol Akışıyla Dinamik Sayfalar Tasarlamak" /><published>2026-08-06T00:00:00+00:00</published><updated>2026-08-06T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/degiskenler-ve-kontrol-akisiyla-dinamik-sayfalar-tasarlamak</id><content type="html" xml:base="https://sonsuzus.github.io/posts/degiskenler-ve-kontrol-akisiyla-dinamik-sayfalar-tasarlamak/"><![CDATA[<p>Bir web sayfasının kullanıcıya göre farklı davranmasını sağlayan temel güç, değişkenler ve kontrol akış yapılarından gelir. Değişkenler verileri hafızada tutarken <code class="language-plaintext highlighter-rouge">if-else</code> ve <code class="language-plaintext highlighter-rouge">switch-case</code> gibi yapılar programın hangi kod yolunu izleyeceğine karar verir. Kısacası değişkenler sahnedeki oyuncuları, kontrol yapıları ise senaryoyu temsil eder.</p>

<p>``</p>

<h2 id="değişkenler-neden-gereklidir">Değişkenler Neden Gereklidir?</h2>

<p>Değişken, bir değeri program çalışırken saklayabilmek ve daha sonra kullanabilmek için verilen isimdir. Kullanıcının adı, ürün fiyatı, oturum durumu veya sepetteki ürün sayısı birer değişkende tutulabilir.</p>

<p>JavaScript’te modern değişken tanımlama işlemleri genellikle <code class="language-plaintext highlighter-rouge">let</code> ve <code class="language-plaintext highlighter-rouge">const</code> ile gerçekleştirilir:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">kullaniciAdi</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Ada</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">sepetAdedi</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">oturumAcik</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>

<span class="nx">sepetAdedi</span> <span class="o">=</span> <span class="nx">sepetAdedi</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">kullaniciAdi</span><span class="p">}</span><span class="s2"> kullanıcısının sepetinde </span><span class="p">${</span><span class="nx">sepetAdedi</span><span class="p">}</span><span class="s2"> ürün var.`</span><span class="p">);</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">const</code>, yeniden atanmayacak bir değişken oluşturur. <code class="language-plaintext highlighter-rouge">let</code> ise değeri sonradan değiştirilebilen veriler için kullanılır. Sepete yeni ürün eklendiğinde <code class="language-plaintext highlighter-rouge">sepetAdedi</code> güncellenebilir; ancak kullanıcının o işlem boyunca değişmeyen adı <code class="language-plaintext highlighter-rouge">const</code> ile tanımlanabilir.</p>

<table>
  <thead>
    <tr>
      <th>Anahtar kelime</th>
      <th style="text-align: right">Yeniden atanabilir mi?</th>
      <th>Kapsam</th>
      <th>Önerilen kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">const</code></td>
      <td style="text-align: right">Hayır</td>
      <td>Blok</td>
      <td>Varsayılan tercih</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">let</code></td>
      <td style="text-align: right">Evet</td>
      <td>Blok</td>
      <td>Değişecek değerler</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">var</code></td>
      <td style="text-align: right">Evet</td>
      <td>Fonksiyon</td>
      <td>Eski kodlarla uyumluluk</td>
    </tr>
  </tbody>
</table>

<p>Değişkenlerin hafızadaki davranışı veri türüne göre farklılaşabilir. Sayı ve boolean gibi ilkel değerler doğrudan değer mantığıyla kullanılırken nesneler referans üzerinden yönetilir. Bu nedenle bir nesneyi başka değişkene atamak her zaman bağımsız bir kopya üretmez.</p>

<h2 id="koşulların-matematiksel-mantığı">Koşulların Matematiksel Mantığı</h2>

<p>Kontrol akışının merkezinde sonucu <code class="language-plaintext highlighter-rouge">true</code> veya <code class="language-plaintext highlighter-rouge">false</code> olan ifadeler bulunur. Örneğin yaş değişkeni $y$ ise yetişkinlik koşulu $y \geq 18$ biçiminde gösterilebilir. İki şartın birlikte sağlanması gerekiyorsa mantıksal VE, alternatiflerden biri yeterliyse mantıksal VEYA kullanılır.</p>

<table>
  <thead>
    <tr>
      <th>Mantıksal işlem</th>
      <th>JavaScript</th>
      <th>Sonucun doğru olma durumu</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>VE</td>
      <td><code class="language-plaintext highlighter-rouge">A &amp;&amp; B</code></td>
      <td>İki koşul da doğruysa</td>
    </tr>
    <tr>
      <td>VEYA</td>
      <td><code class="language-plaintext highlighter-rouge">A \|\| B</code></td>
      <td>En az bir koşul doğruysa</td>
    </tr>
    <tr>
      <td>DEĞİL</td>
      <td><code class="language-plaintext highlighter-rouge">!A</code></td>
      <td>A yanlışsa</td>
    </tr>
  </tbody>
</table>

<h2 id="if-else-ile-sayfa-akışını-yönetmek"><code class="language-plaintext highlighter-rouge">if-else</code> ile Sayfa Akışını Yönetmek</h2>

<p><code class="language-plaintext highlighter-rouge">if-else</code>, farklı ve esnek koşulları değerlendirmek için idealdir. Bir üyelik sayfasının kullanıcı durumuna göre mesaj göstermesi şöyle sağlanabilir:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">yas</span> <span class="o">=</span> <span class="mi">22</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">oturumAcik</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>

<span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nx">oturumAcik</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Lütfen önce giriş yapın.</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if </span><span class="p">(</span><span class="nx">yas</span> <span class="o">&gt;=</span> <span class="mi">18</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Yetişkin içerik alanına hoş geldiniz.</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Bu bölüm için yaşınız uygun değil.</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Program koşulları yukarıdan aşağıya değerlendirir ve doğru olan ilk bloğu çalıştırır. Bu nedenle daha özel koşulları üstte, genel koşulları altta konumlandırmak hatalı yönlendirmeleri önler.</p>

<h2 id="switch-case-ne-zaman-kullanılır"><code class="language-plaintext highlighter-rouge">switch-case</code> Ne Zaman Kullanılır?</h2>

<p>Tek bir değişkenin birçok sabit değerle karşılaştırıldığı durumlarda <code class="language-plaintext highlighter-rouge">switch-case</code> daha okunaklı olabilir. Örneğin kullanıcının rolüne göre panel seçilebilir:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">rol</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">editor</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">hedefSayfa</span><span class="p">;</span>

<span class="k">switch </span><span class="p">(</span><span class="nx">rol</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">case</span> <span class="dl">'</span><span class="s1">admin</span><span class="dl">'</span><span class="p">:</span>
    <span class="nx">hedefSayfa</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">/yonetim</span><span class="dl">'</span><span class="p">;</span>
    <span class="k">break</span><span class="p">;</span>
  <span class="k">case</span> <span class="dl">'</span><span class="s1">editor</span><span class="dl">'</span><span class="p">:</span>
    <span class="nx">hedefSayfa</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">/icerikler</span><span class="dl">'</span><span class="p">;</span>
    <span class="k">break</span><span class="p">;</span>
  <span class="k">case</span> <span class="dl">'</span><span class="s1">uye</span><span class="dl">'</span><span class="p">:</span>
    <span class="nx">hedefSayfa</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">/profil</span><span class="dl">'</span><span class="p">;</span>
    <span class="k">break</span><span class="p">;</span>
  <span class="nl">default</span><span class="p">:</span>
    <span class="nx">hedefSayfa</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">/giris</span><span class="dl">'</span><span class="p">;</span>
<span class="p">}</span>

<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Yönlendirilecek adres: </span><span class="p">${</span><span class="nx">hedefSayfa</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">break</code> kullanılmazsa program sonraki <code class="language-plaintext highlighter-rouge">case</code> bloklarına da geçebilir. Bazen bilinçli olarak kullanılan bu davranış, çoğu başlangıç hatasının da kaynağıdır. <code class="language-plaintext highlighter-rouge">default</code> ise hiçbir eşleşme bulunmadığında güvenli bir varsayılan yol sağlar.</p>

<h2 id="hangisini-seçmeliyiz">Hangisini Seçmeliyiz?</h2>

<p>Aralıklar, birleşik mantıksal ifadeler ve karmaşık kurallar için <code class="language-plaintext highlighter-rouge">if-else</code>; tek bir değerin belirli seçeneklerle eşleştirilmesi için <code class="language-plaintext highlighter-rouge">switch-case</code> tercih edilmelidir. Koşullar büyüdükçe karar mantığını küçük fonksiyonlara ayırmak kodun test edilmesini kolaylaştırır. Böylece sayfa akışı bir labirente değil, tabelaları düzgün yerleştirilmiş eğlenceli bir yolculuğa dönüşür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="değişkenler" /><category term="kontrol akışı" /><category term="javascript" /><summary type="html"><![CDATA[Bir web sayfasının kullanıcıya göre farklı davranmasını sağlayan temel güç, değişkenler ve kontrol akış yapılarından gelir. Değişkenler verileri hafızada tutarken if-else ve switch-case gibi yapılar programın hangi kod yolunu izleyeceğine karar verir. Kısacası değişkenler sahnedeki oyuncuları, kontrol yapıları ise senaryoyu temsil eder.]]></summary></entry><entry><title type="html">Döngüler ve Dizilerle Dinamik HTML Üretimi</title><link href="https://sonsuzus.github.io/posts/donguler-ve-dizilerle-dinamik-html-uretimi/" rel="alternate" type="text/html" title="Döngüler ve Dizilerle Dinamik HTML Üretimi" /><published>2026-08-06T00:00:00+00:00</published><updated>2026-08-06T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/donguler-ve-dizilerle-dinamik-html-uretimi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/donguler-ve-dizilerle-dinamik-html-uretimi/"><![CDATA[<p>Bir web sayfasındaki ürün kartlarını tek tek elle yazmak, aynı şarkıyı yüz kez başa sarmaya benzer: yapılabilir ama hiç eğlenceli değildir. Diziler verileri düzenli biçimde saklarken <code class="language-plaintext highlighter-rouge">for</code> ve <code class="language-plaintext highlighter-rouge">foreach</code> döngüleri bu verileri sırayla işler. Böylece birkaç satırlık PHP koduyla onlarca HTML bloğunu dinamik, tutarlı ve kolay güncellenebilir biçimde ekrana basabiliriz.</p>

<p>``</p>

<h2 id="temel-mantık-veri-ayrı-görünüm-ayrı">Temel Mantık: Veri Ayrı, Görünüm Ayrı</h2>

<p>Dizi, birden fazla değeri tek değişken altında tutan veri yapısıdır. İndeksli dizilerde elemanlara <code class="language-plaintext highlighter-rouge">0</code>, <code class="language-plaintext highlighter-rouge">1</code>, <code class="language-plaintext highlighter-rouge">2</code> gibi konumlarla; ilişkisel dizilerde ise <code class="language-plaintext highlighter-rouge">ad</code>, <code class="language-plaintext highlighter-rouge">fiyat</code> veya <code class="language-plaintext highlighter-rouge">stok</code> gibi anlamlı anahtarlarla erişilir.</p>

<p>Bir dizide $n$ eleman varsa bütün elemanları bir kez ziyaret eden döngünün çalışma maliyeti yaklaşık olarak:</p>

\[T(n) = c \cdot n\]

<p>şeklinde ifade edilir. Buradaki $c$, her eleman için yapılan sabit miktardaki işlemdir. Bu nedenle temel listeleme işleminin zaman karmaşıklığı $O(n)$ olur. Eleman sayısı iki katına çıktığında yapılacak iş de yaklaşık iki katına çıkar.</p>

<table>
  <thead>
    <tr>
      <th>Yapı</th>
      <th>Kullanım biçimi</th>
      <th>En uygun olduğu durum</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>İndeksli dizi</td>
      <td><code class="language-plaintext highlighter-rouge">$renkler[0]</code></td>
      <td>Basit ve sıralı değer listeleri</td>
    </tr>
    <tr>
      <td>İlişkisel dizi</td>
      <td><code class="language-plaintext highlighter-rouge">$urun['ad']</code></td>
      <td>Özellikleri bulunan kayıtlar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">for</code></td>
      <td>Sayaç ve indeks kullanır</td>
      <td>Konum bilgisi gerektiğinde</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">foreach</code></td>
      <td>Elemanı doğrudan verir</td>
      <td>Koleksiyonları okunaklı biçimde dolaşırken</td>
    </tr>
  </tbody>
</table>

<h2 id="for-ile-sıralı-verileri-yazdırmak"><code class="language-plaintext highlighter-rouge">for</code> ile Sıralı Verileri Yazdırmak</h2>

<p><code class="language-plaintext highlighter-rouge">for</code> döngüsü başlangıç, koşul ve artış olmak üzere üç parçadan oluşur. Dizinin indeksine veya sıra numarasına ihtiyaç duyduğumuzda oldukça kullanışlıdır.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$diller</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'PHP'</span><span class="p">,</span> <span class="s1">'JavaScript'</span><span class="p">,</span> <span class="s1">'Python'</span><span class="p">,</span> <span class="s1">'Go'</span><span class="p">];</span>

<span class="k">for</span> <span class="p">(</span><span class="nv">$i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nv">$i</span> <span class="o">&lt;</span> <span class="nb">count</span><span class="p">(</span><span class="nv">$diller</span><span class="p">);</span> <span class="nv">$i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s1">'&lt;p&gt;'</span> <span class="mf">.</span> <span class="p">(</span><span class="nv">$i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="mf">.</span> <span class="s1">'. '</span> <span class="mf">.</span> <span class="nv">$diller</span><span class="p">[</span><span class="nv">$i</span><span class="p">]</span> <span class="mf">.</span> <span class="s1">'&lt;/p&gt;'</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">$i</code>, dizinin mevcut indeksini temsil eder. Diziler sıfırdan başladığı için kullanıcıya gösterilen sıra numarasında <code class="language-plaintext highlighter-rouge">$i + 1</code> kullanılır. Koşulun <code class="language-plaintext highlighter-rouge">$i &lt;= count($diller)</code> biçiminde yazılması, olmayan son elemana erişmeye çalışacağı için klasik bir “bir adım fazla” hatası üretir.</p>

<p>Dizi boyutu sık değişmiyorsa <code class="language-plaintext highlighter-rouge">count()</code> sonucunu önceden saklamak da mümkündür:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$toplam</span> <span class="o">=</span> <span class="nb">count</span><span class="p">(</span><span class="nv">$diller</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="nv">$i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nv">$i</span> <span class="o">&lt;</span> <span class="nv">$toplam</span><span class="p">;</span> <span class="nv">$i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s1">'&lt;li&gt;'</span> <span class="mf">.</span> <span class="nb">htmlspecialchars</span><span class="p">(</span><span class="nv">$diller</span><span class="p">[</span><span class="nv">$i</span><span class="p">])</span> <span class="mf">.</span> <span class="s1">'&lt;/li&gt;'</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">htmlspecialchars()</code> özel HTML karakterlerini dönüştürerek kullanıcı kaynaklı verilerin güvenli gösterilmesine yardımcı olur.</p>

<h2 id="foreach-ile-ürün-kartları-oluşturmak"><code class="language-plaintext highlighter-rouge">foreach</code> ile Ürün Kartları Oluşturmak</h2>

<p>İlişkisel ve çok boyutlu dizilerde <code class="language-plaintext highlighter-rouge">foreach</code>, indeks yönetme zahmetini ortadan kaldırır. Aşağıdaki veri kümesindeki her ürün bir ilişkisel dizidir:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$urunler</span> <span class="o">=</span> <span class="p">[</span>
    <span class="p">[</span><span class="s1">'ad'</span> <span class="o">=&gt;</span> <span class="s1">'Mekanik Klavye'</span><span class="p">,</span> <span class="s1">'fiyat'</span> <span class="o">=&gt;</span> <span class="mi">2450</span><span class="p">,</span> <span class="s1">'stok'</span> <span class="o">=&gt;</span> <span class="mi">8</span><span class="p">],</span>
    <span class="p">[</span><span class="s1">'ad'</span> <span class="o">=&gt;</span> <span class="s1">'Kablosuz Fare'</span><span class="p">,</span> <span class="s1">'fiyat'</span> <span class="o">=&gt;</span> <span class="mi">980</span><span class="p">,</span> <span class="s1">'stok'</span> <span class="o">=&gt;</span> <span class="mi">0</span><span class="p">],</span>
    <span class="p">[</span><span class="s1">'ad'</span> <span class="o">=&gt;</span> <span class="s1">'USB Mikrofon'</span><span class="p">,</span> <span class="s1">'fiyat'</span> <span class="o">=&gt;</span> <span class="mi">3150</span><span class="p">,</span> <span class="s1">'stok'</span> <span class="o">=&gt;</span> <span class="mi">4</span><span class="p">]</span>
<span class="p">];</span>
<span class="cp">?&gt;</span>

<span class="nt">&lt;section</span> <span class="na">class=</span><span class="s">"urun-listesi"</span><span class="nt">&gt;</span>
<span class="cp">&lt;?php</span> <span class="k">foreach</span> <span class="p">(</span><span class="nv">$urunler</span> <span class="k">as</span> <span class="nv">$urun</span><span class="p">)</span><span class="o">:</span> <span class="cp">?&gt;</span>
    <span class="nt">&lt;article</span> <span class="na">class=</span><span class="s">"urun-karti"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;h2&gt;</span><span class="cp">&lt;?=</span> <span class="nb">htmlspecialchars</span><span class="p">(</span><span class="nv">$urun</span><span class="p">[</span><span class="s1">'ad'</span><span class="p">])</span> <span class="cp">?&gt;</span><span class="nt">&lt;/h2&gt;</span>
        <span class="nt">&lt;p&gt;</span><span class="cp">&lt;?=</span> <span class="nb">number_format</span><span class="p">(</span><span class="nv">$urun</span><span class="p">[</span><span class="s1">'fiyat'</span><span class="p">],</span> <span class="mi">2</span><span class="p">,</span> <span class="s1">','</span><span class="p">,</span> <span class="s1">'.'</span><span class="p">)</span> <span class="cp">?&gt;</span> TL<span class="nt">&lt;/p&gt;</span>
        <span class="nt">&lt;strong&gt;</span>
            <span class="cp">&lt;?=</span> <span class="nv">$urun</span><span class="p">[</span><span class="s1">'stok'</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="s1">'Stokta var'</span> <span class="o">:</span> <span class="s1">'Tükendi'</span> <span class="cp">?&gt;</span>
        <span class="nt">&lt;/strong&gt;</span>
    <span class="nt">&lt;/article&gt;</span>
<span class="cp">&lt;?php</span> <span class="k">endforeach</span><span class="p">;</span> <span class="cp">?&gt;</span>
<span class="nt">&lt;/section&gt;</span>
</code></pre></div></div>

<p>Alternatif sözdizimindeki <code class="language-plaintext highlighter-rouge">foreach ... endforeach</code> yapısı, PHP ile HTML iç içeyken süslü parantezlere göre daha rahat okunur. <code class="language-plaintext highlighter-rouge">number_format()</code> fiyatı kullanıcı dostu hale getirirken üçlü koşul operatörü stok durumuna göre farklı metin üretir.</p>

<h2 id="boş-listeyi-unutmayın">Boş Listeyi Unutmayın</h2>

<p>Gerçek uygulamalarda veri kümesi her zaman dolu olmayabilir. Boş bir alan göstermek yerine kullanıcıya açıklama sunmak daha iyi bir deneyimdir:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span> <span class="k">if</span> <span class="p">(</span><span class="k">empty</span><span class="p">(</span><span class="nv">$urunler</span><span class="p">))</span><span class="o">:</span> <span class="cp">?&gt;</span>
    <span class="nt">&lt;p&gt;</span>Henüz gösterilecek ürün bulunmuyor.<span class="nt">&lt;/p&gt;</span>
<span class="cp">&lt;?php</span> <span class="k">else</span><span class="o">:</span> <span class="cp">?&gt;</span>
    <span class="cp">&lt;?php</span> <span class="k">foreach</span> <span class="p">(</span><span class="nv">$urunler</span> <span class="k">as</span> <span class="nv">$urun</span><span class="p">)</span><span class="o">:</span> <span class="cp">?&gt;</span>
        <span class="nt">&lt;div&gt;</span><span class="cp">&lt;?=</span> <span class="nb">htmlspecialchars</span><span class="p">(</span><span class="nv">$urun</span><span class="p">[</span><span class="s1">'ad'</span><span class="p">])</span> <span class="cp">?&gt;</span><span class="nt">&lt;/div&gt;</span>
    <span class="cp">&lt;?php</span> <span class="k">endforeach</span><span class="p">;</span> <span class="cp">?&gt;</span>
<span class="cp">&lt;?php</span> <span class="k">endif</span><span class="p">;</span> <span class="cp">?&gt;</span>
</code></pre></div></div>

<p>Özetle sıra numarası, belirli aralık veya indeks denetimi gerekiyorsa <code class="language-plaintext highlighter-rouge">for</code>; verileri doğrudan ve okunaklı şekilde dolaşmak gerekiyorsa <code class="language-plaintext highlighter-rouge">foreach</code> tercih edilmelidir. Veriyi dizide tutup HTML şablonunu döngüyle çoğaltmak, tekrarları azaltır ve yeni bir kayıt eklemeyi yalnızca diziye tek satır eklemek kadar kolaylaştırır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="PHP" /><category term="Diziler" /><category term="Döngüler" /><summary type="html"><![CDATA[Bir web sayfasındaki ürün kartlarını tek tek elle yazmak, aynı şarkıyı yüz kez başa sarmaya benzer: yapılabilir ama hiç eğlenceli değildir. Diziler verileri düzenli biçimde saklarken for ve foreach döngüleri bu verileri sırayla işler. Böylece birkaç satırlık PHP koduyla onlarca HTML bloğunu dinamik, tutarlı ve kolay güncellenebilir biçimde ekrana basabiliriz.]]></summary></entry><entry><title type="html">Fonksiyonlar ve Modüler Kodlama: Kopyala-Yapıştır Döngüsünden Kurtulun</title><link href="https://sonsuzus.github.io/posts/fonksiyonlar-ve-moduler-kodlama-kopyala-yapistir-dongusunden-kurtulun/" rel="alternate" type="text/html" title="Fonksiyonlar ve Modüler Kodlama: Kopyala-Yapıştır Döngüsünden Kurtulun" /><published>2026-08-06T00:00:00+00:00</published><updated>2026-08-06T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/fonksiyonlar-ve-moduler-kodlama-kopyala-yapistir-dongusunden-kurtulun</id><content type="html" xml:base="https://sonsuzus.github.io/posts/fonksiyonlar-ve-moduler-kodlama-kopyala-yapistir-dongusunden-kurtulun/"><![CDATA[<p>Bir program büyüdükçe aynı işlemleri farklı yerlerde tekrar tekrar yazmak, başlangıçta masum görünen bir alışkanlıktan ciddi bir bakım sorununa dönüşür. Fonksiyonlar ve modüler kodlama, bu tekrarları anlamlı parçalara ayırarak kodu daha okunabilir, test edilebilir ve yeniden kullanılabilir hâle getirir. Kısacası amaç, bilgisayara yalnızca ne yapacağını söylemek değil, bunu düzenli ve sürdürülebilir bir biçimde söylemektir.
``</p>
<h2 id="fonksiyon-nedir">Fonksiyon Nedir?</h2>

<p>Fonksiyon, belirli bir görevi gerçekleştiren ve gerektiğinde çağrılabilen isimlendirilmiş kod bloğudur. Bir fonksiyon girdiler alabilir, bu girdileri işleyebilir ve sonuç döndürebilir. Matematikteki fonksiyon fikriyle programlamadaki kullanım oldukça benzerdir:</p>

\[f(x) = x^2 + 2x + 1\]

<p>Burada $x$ girdi, $f(x)$ ise çıktıdır. Programlamada aynı yapı şöyle ifade edilebilir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">hesapla</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
    <span class="sh">"""</span><span class="s">x² + 2x + 1 işleminin sonucunu döndürür.</span><span class="sh">"""</span>
    <span class="k">return</span> <span class="n">x</span> <span class="o">**</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">1</span>

<span class="n">sonuc</span> <span class="o">=</span> <span class="nf">hesapla</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">sonuc</span><span class="p">)</span>  <span class="c1"># 25
</span></code></pre></div></div>

<p>Bu örnekte <code class="language-plaintext highlighter-rouge">hesapla</code> fonksiyonu işlemin nasıl yapıldığını tek bir yerde saklar. Formül değişirse fonksiyonun kullanıldığı her satırı değil, yalnızca fonksiyon gövdesini güncellemek yeterlidir.</p>

<h2 id="tekrar-neden-tehlikelidir">Tekrar Neden Tehlikelidir?</h2>

<p>Aynı kodun birden fazla yerde bulunması, hata düzeltmelerini zorlaştırır. Örneğin indirim hesaplayan formülü beş farklı noktaya kopyaladıysanız oran değiştiğinde beş yeri de bulmanız gerekir. Birini unutursanız program farklı sonuçlar üretmeye başlar.</p>

<p>Tekrarlı kod miktarını kabaca şöyle düşünebiliriz:</p>

\[T = n \times m\]

<p>Burada $n$ tekrar sayısını, $m$ ise işlemin satır sayısını temsil eder. İşlem 8 satırsa ve 6 kez tekrarlanıyorsa toplam $48$ satır yönetilir. Fonksiyon kullanıldığında mantık yalnızca 8 satırda tutulur; diğer yerlerde kısa fonksiyon çağrıları bulunur.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th style="text-align: right">Okunabilirlik</th>
      <th style="text-align: right">Değişiklik Maliyeti</th>
      <th style="text-align: right">Yeniden Kullanım</th>
      <th style="text-align: right">Hata Riski</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kopyala-yapıştır</td>
      <td style="text-align: right">Düşük</td>
      <td style="text-align: right">Yüksek</td>
      <td style="text-align: right">Düşük</td>
      <td style="text-align: right">Yüksek</td>
    </tr>
    <tr>
      <td>Tek fonksiyon</td>
      <td style="text-align: right">Yüksek</td>
      <td style="text-align: right">Düşük</td>
      <td style="text-align: right">Yüksek</td>
      <td style="text-align: right">Düşük</td>
    </tr>
    <tr>
      <td>Modüllere ayrılmış yapı</td>
      <td style="text-align: right">Çok yüksek</td>
      <td style="text-align: right">Düşük</td>
      <td style="text-align: right">Çok yüksek</td>
      <td style="text-align: right">Düşük</td>
    </tr>
  </tbody>
</table>

<h2 id="parametreler-ve-dönüş-değerleri">Parametreler ve Dönüş Değerleri</h2>

<p>İyi tasarlanmış fonksiyonlar dışarıdan parametre alır ve sonucu <code class="language-plaintext highlighter-rouge">return</code> ile döndürür. Böylece belirli değerlere bağımlı kalmazlar.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">indirimli_fiyat</span><span class="p">(</span><span class="n">fiyat</span><span class="p">,</span> <span class="n">indirim_orani</span><span class="o">=</span><span class="mf">0.10</span><span class="p">):</span>
    <span class="sh">"""</span><span class="s">Fiyata belirtilen oranda indirim uygular.</span><span class="sh">"""</span>
    <span class="k">if</span> <span class="n">fiyat</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">raise</span> <span class="nc">ValueError</span><span class="p">(</span><span class="sh">"</span><span class="s">Fiyat negatif olamaz.</span><span class="sh">"</span><span class="p">)</span>

    <span class="n">indirim</span> <span class="o">=</span> <span class="n">fiyat</span> <span class="o">*</span> <span class="n">indirim_orani</span>
    <span class="k">return</span> <span class="n">fiyat</span> <span class="o">-</span> <span class="n">indirim</span>

<span class="n">urunler</span> <span class="o">=</span> <span class="p">[</span><span class="mi">250</span><span class="p">,</span> <span class="mi">400</span><span class="p">,</span> <span class="mi">750</span><span class="p">]</span>
<span class="n">sonuclar</span> <span class="o">=</span> <span class="p">[</span><span class="nf">indirimli_fiyat</span><span class="p">(</span><span class="n">urun</span><span class="p">,</span> <span class="mf">0.20</span><span class="p">)</span> <span class="k">for</span> <span class="n">urun</span> <span class="ow">in</span> <span class="n">urunler</span><span class="p">]</span>
<span class="nf">print</span><span class="p">(</span><span class="n">sonuclar</span><span class="p">)</span>
</code></pre></div></div>

<p>Fonksiyon hem farklı ürünlerde kullanılabilir hem de varsayılan indirim oranı sayesinde esnekliğini korur. Değer doğrulamasının fonksiyon içinde yapılması, hatalı verilerin sisteme sessizce yayılmasını da önler.</p>

<h2 id="modüler-kodlama-nedir">Modüler Kodlama Nedir?</h2>

<p>Fonksiyonlar tek tek görevleri düzenlerken modüler kodlama, ilişkili fonksiyonları ayrı dosyalarda toplar. Örneğin bir e-ticaret uygulamasında fiyat işlemleri <code class="language-plaintext highlighter-rouge">fiyat.py</code>, kullanıcı işlemleri <code class="language-plaintext highlighter-rouge">kullanici.py</code>, veritabanı işlemleri ise <code class="language-plaintext highlighter-rouge">veritabani.py</code> modülünde tutulabilir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># fiyat.py
</span><span class="k">def</span> <span class="nf">vergi_ekle</span><span class="p">(</span><span class="n">fiyat</span><span class="p">,</span> <span class="n">oran</span><span class="o">=</span><span class="mf">0.20</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">fiyat</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="n">oran</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">indirim_uygula</span><span class="p">(</span><span class="n">fiyat</span><span class="p">,</span> <span class="n">oran</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">fiyat</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">oran</span><span class="p">)</span>
</code></pre></div></div>

<p>Başka bir dosyada bu modül şöyle kullanılır:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">fiyat</span> <span class="kn">import</span> <span class="n">vergi_ekle</span><span class="p">,</span> <span class="n">indirim_uygula</span>

<span class="n">ara_toplam</span> <span class="o">=</span> <span class="nf">indirim_uygula</span><span class="p">(</span><span class="mi">1000</span><span class="p">,</span> <span class="mf">0.15</span><span class="p">)</span>
<span class="n">toplam</span> <span class="o">=</span> <span class="nf">vergi_ekle</span><span class="p">(</span><span class="n">ara_toplam</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">toplam</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu ayrım, ana programın ayrıntılara boğulmasını engeller. Kod, uzun bir yapılacaklar listesi yerine anlamlı görevlerin orkestrasyonu gibi görünür.</p>

<h2 id="i̇yi-fonksiyon-yazmanın-altın-kuralları">İyi Fonksiyon Yazmanın Altın Kuralları</h2>

<ul>
  <li>Her fonksiyon mümkünse <strong>tek bir sorumluluğa</strong> sahip olmalıdır.</li>
  <li><code class="language-plaintext highlighter-rouge">islem1</code> yerine <code class="language-plaintext highlighter-rouge">siparis_toplamini_hesapla</code> gibi açıklayıcı isimler kullanılmalıdır.</li>
  <li>Gereksiz küresel değişkenlerden kaçınılmalıdır.</li>
  <li>Çok fazla parametre alan fonksiyonlar yeniden tasarlanmalıdır.</li>
  <li>Tekrarlanan mantık ortak bir fonksiyona taşınmalıdır.</li>
  <li>Fonksiyonlar küçük ve bağımsız testlerle doğrulanmalıdır.</li>
</ul>

<p>Fonksiyonlara ayırmak yalnızca satır sayısını azaltmaz; programın düşünce yapısını görünür kılar. Kodunuzda sık sık kopyala-yapıştır yapıyorsanız küçük bir alarm çalmalıdır: Orada muhtemelen keşfedilmeyi bekleyen bir fonksiyon vardır!</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="fonksiyonlar" /><category term="modüler programlama" /><category term="temiz kod" /><summary type="html"><![CDATA[Bir program büyüdükçe aynı işlemleri farklı yerlerde tekrar tekrar yazmak, başlangıçta masum görünen bir alışkanlıktan ciddi bir bakım sorununa dönüşür. Fonksiyonlar ve modüler kodlama, bu tekrarları anlamlı parçalara ayırarak kodu daha okunabilir, test edilebilir ve yeniden kullanılabilir hâle getirir. Kısacası amaç, bilgisayara yalnızca ne yapacağını söylemek değil, bunu düzenli ve sürdürülebilir bir biçimde söylemektir.]]></summary></entry><entry><title type="html">Form İşlemleri ve Güvenli Veri Doğrulama Rehberi</title><link href="https://sonsuzus.github.io/posts/form-islemleri-ve-guvenli-veri-dogrulama-rehberi/" rel="alternate" type="text/html" title="Form İşlemleri ve Güvenli Veri Doğrulama Rehberi" /><published>2026-08-06T00:00:00+00:00</published><updated>2026-08-06T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/form-islemleri-ve-guvenli-veri-dogrulama-rehberi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/form-islemleri-ve-guvenli-veri-dogrulama-rehberi/"><![CDATA[<p>Bir web formu, kullanıcı ile sunucu arasındaki dijital köprüdür. Ancak bu köprüden yalnızca isimler ve e-posta adresleri geçmez; hatalı değerler, bot istekleri ve kötü niyetli SQL parçaları da geçmeye çalışabilir. Bu nedenle veriyi doğrudan veritabanına göndermek, kapının anahtarını paspasın altına bırakmaya benzer.
``</p>

<h2 id="formdan-veritabanına-uzanan-yol">Formdan veritabanına uzanan yol</h2>

<p>Tarayıcıda doldurulan alanlar genellikle <code class="language-plaintext highlighter-rouge">GET</code> veya <code class="language-plaintext highlighter-rouge">POST</code> yöntemiyle sunucuya iletilir. <code class="language-plaintext highlighter-rouge">GET</code>, filtreleme ve arama gibi adres çubuğunda görülebilecek işlemler için uygundur. Kişisel bilgiler veya veri değiştiren işlemler ise çoğunlukla <code class="language-plaintext highlighter-rouge">POST</code> kullanmalıdır. Yine de <code class="language-plaintext highlighter-rouge">POST</code> veriyi kendiliğinden güvenli yapmaz; yalnızca URL dışında taşır. İletişimin şifrelenmesi için HTTPS gerekir.</p>

<p>Sağlıklı bir veri akışı şu aşamalardan oluşur:</p>

<ol>
  <li>İstek yöntemini ve içerik türünü kontrol etme</li>
  <li>Beklenen alanları alma</li>
  <li>Veriyi normalize etme ve gereksiz boşlukları temizleme</li>
  <li>Tür, biçim, uzunluk ve iş kuralı doğrulaması yapma</li>
  <li>Parametreli sorguyla veritabanına yazma</li>
  <li>Gösterim sırasında bağlama uygun çıktı kodlaması uygulama</li>
</ol>

<h2 id="filtreleme-ve-doğrulama-aynı-şey-değildir">Filtreleme ve doğrulama aynı şey değildir</h2>

<table>
  <thead>
    <tr>
      <th>İşlem</th>
      <th>Amacı</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Normalizasyon</td>
      <td>Veriyi standart biçime getirmek</td>
      <td>Baştaki boşlukları silmek</td>
    </tr>
    <tr>
      <td>Filtreleme</td>
      <td>İstenmeyen karakterleri ayıklamak</td>
      <td>Kontrol karakterlerini kaldırmak</td>
    </tr>
    <tr>
      <td>Doğrulama</td>
      <td>Değerin kurala uyduğunu sınamak</td>
      <td>E-posta biçimini kontrol etmek</td>
    </tr>
    <tr>
      <td>Kodlama</td>
      <td>Veriyi hedef bağlamda güvenli göstermek</td>
      <td>HTML karakterlerini dönüştürmek</td>
    </tr>
  </tbody>
</table>

<p>Bir alanın kabul koşulunu matematiksel olarak şöyle düşünebiliriz:</p>

\[V(x)=T(x) \land L_{min}\leq |x|\leq L_{max} \land B(x)\]

<table>
  <tbody>
    <tr>
      <td>Burada $T(x)$ biçim ve tür kontrolünü, $</td>
      <td>x</td>
      <td>$ uzunluğu, $B(x)$ ise uygulamanın iş kurallarını temsil eder. Koşullardan biri bile yanlışsa veri reddedilmelidir. Hatalı girdiyi sessizce değiştirmek yerine kullanıcıya anlaşılır bir mesaj göstermek çoğu zaman daha doğrudur.</td>
    </tr>
  </tbody>
</table>

<h2 id="sunucu-tarafında-güvenli-örnek">Sunucu tarafında güvenli örnek</h2>

<p>Aşağıdaki PHP örneği; adı, e-posta adresini ve yaşı doğrular. Tarayıcıdaki <code class="language-plaintext highlighter-rouge">required</code>, <code class="language-plaintext highlighter-rouge">min</code> veya <code class="language-plaintext highlighter-rouge">type="email"</code> kontrolleri kullanıcı deneyimini iyileştirir, fakat geliştirici araçlarıyla aşılabildiği için güvenlik sınırı sayılmaz.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'REQUEST_METHOD'</span><span class="p">]</span> <span class="o">!==</span> <span class="s1">'POST'</span><span class="p">)</span> <span class="p">{</span>
    <span class="nb">http_response_code</span><span class="p">(</span><span class="mi">405</span><span class="p">);</span>
    <span class="k">exit</span><span class="p">(</span><span class="s1">'Yalnızca POST kabul edilir.'</span><span class="p">);</span>
<span class="p">}</span>

<span class="nv">$name</span> <span class="o">=</span> <span class="nb">trim</span><span class="p">(</span><span class="nv">$_POST</span><span class="p">[</span><span class="s1">'name'</span><span class="p">]</span> <span class="o">??</span> <span class="s1">''</span><span class="p">);</span>
<span class="nv">$email</span> <span class="o">=</span> <span class="nb">filter_input</span><span class="p">(</span><span class="no">INPUT_POST</span><span class="p">,</span> <span class="s1">'email'</span><span class="p">,</span> <span class="no">FILTER_VALIDATE_EMAIL</span><span class="p">);</span>
<span class="nv">$age</span> <span class="o">=</span> <span class="nb">filter_input</span><span class="p">(</span><span class="no">INPUT_POST</span><span class="p">,</span> <span class="s1">'age'</span><span class="p">,</span> <span class="no">FILTER_VALIDATE_INT</span><span class="p">,</span> <span class="p">[</span>
    <span class="s1">'options'</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="s1">'min_range'</span> <span class="o">=&gt;</span> <span class="mi">18</span><span class="p">,</span> <span class="s1">'max_range'</span> <span class="o">=&gt;</span> <span class="mi">120</span><span class="p">]</span>
<span class="p">]);</span>

<span class="nv">$errors</span> <span class="o">=</span> <span class="p">[];</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$name</span> <span class="o">===</span> <span class="s1">''</span> <span class="o">||</span> <span class="nb">mb_strlen</span><span class="p">(</span><span class="nv">$name</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">80</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$errors</span><span class="p">[]</span> <span class="o">=</span> <span class="s1">'Ad alanı 1-80 karakter olmalıdır.'</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$email</span> <span class="o">===</span> <span class="kc">false</span> <span class="o">||</span> <span class="nv">$email</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$errors</span><span class="p">[]</span> <span class="o">=</span> <span class="s1">'Geçerli bir e-posta adresi girilmelidir.'</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$age</span> <span class="o">===</span> <span class="kc">false</span> <span class="o">||</span> <span class="nv">$age</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$errors</span><span class="p">[]</span> <span class="o">=</span> <span class="s1">'Yaş 18 ile 120 arasında olmalıdır.'</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$errors</span><span class="p">)</span> <span class="p">{</span>
    <span class="nb">http_response_code</span><span class="p">(</span><span class="mi">422</span><span class="p">);</span>
    <span class="k">exit</span><span class="p">(</span><span class="nb">implode</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span> <span class="nv">$errors</span><span class="p">));</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Kod, eksik alanlar için varsayılan değer kullanır ve her hatayı ayrı biçimde toplar. HTTP <code class="language-plaintext highlighter-rouge">422</code> cevabı, isteğin anlaşılmasına rağmen verilerin kurallara uymadığını belirtir.</p>

<h2 id="sql-enjeksiyonuna-kapıyı-kapatmak">SQL enjeksiyonuna kapıyı kapatmak</h2>

<p>Doğrulanan değerler bile SQL metnine birleştirilmemelidir. PDO prepared statement kullanıldığında sorgu ile veri ayrı kanallardan işlenir:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$stmt</span> <span class="o">=</span> <span class="nv">$pdo</span><span class="o">-&gt;</span><span class="nf">prepare</span><span class="p">(</span>
    <span class="s1">'INSERT INTO users (name, email, age) VALUES (:name, :email, :age)'</span>
<span class="p">);</span>

<span class="nv">$stmt</span><span class="o">-&gt;</span><span class="nf">execute</span><span class="p">([</span>
    <span class="s1">'name'</span> <span class="o">=&gt;</span> <span class="nv">$name</span><span class="p">,</span>
    <span class="s1">'email'</span> <span class="o">=&gt;</span> <span class="nv">$email</span><span class="p">,</span>
    <span class="s1">'age'</span> <span class="o">=&gt;</span> <span class="nv">$age</span>
<span class="p">]);</span>
</code></pre></div></div>

<p>Bu yaklaşım SQL enjeksiyonuna karşı temel savunmadır. Veritabanında ayrıca <code class="language-plaintext highlighter-rouge">UNIQUE</code>, <code class="language-plaintext highlighter-rouge">NOT NULL</code> ve uygun sütun türleri tanımlanmalıdır; çünkü güvenlik tek bir kontrol noktasına emanet edilmez.</p>

<p>Son olarak formlara CSRF token eklenmeli, hassas alanlar günlüklere yazılmamalı ve hata mesajlarında sorgu ayrıntıları gösterilmemelidir. Veritabanından okunan içerik HTML içinde sunulurken <code class="language-plaintext highlighter-rouge">htmlspecialchars</code> ile kodlanmalıdır. Kısacası doğru sıra şudur: istemcide kolaylaştır, sunucuda doğrula, parametreli sorguyla kaydet ve gösterirken güvenli biçimde kodla.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="form işlemleri" /><category term="veri doğrulama" /><category term="web güvenliği" /><summary type="html"><![CDATA[Bir web formu, kullanıcı ile sunucu arasındaki dijital köprüdür. Ancak bu köprüden yalnızca isimler ve e-posta adresleri geçmez; hatalı değerler, bot istekleri ve kötü niyetli SQL parçaları da geçmeye çalışabilir. Bu nedenle veriyi doğrudan veritabanına göndermek, kapının anahtarını paspasın altına bırakmaya benzer.]]></summary></entry><entry><title type="html">Geometrik Algoritmalar: Dışbükey Örtüden Tarama Doğrusuna</title><link href="https://sonsuzus.github.io/posts/geometrik-algoritmalar-disbukey-ortuden-tarama-dogrusuna/" rel="alternate" type="text/html" title="Geometrik Algoritmalar: Dışbükey Örtüden Tarama Doğrusuna" /><published>2026-08-06T00:00:00+00:00</published><updated>2026-08-06T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/geometrik-algoritmalar-disbukey-ortuden-tarama-dogrusuna</id><content type="html" xml:base="https://sonsuzus.github.io/posts/geometrik-algoritmalar-disbukey-ortuden-tarama-dogrusuna/"><![CDATA[<p>Haritadaki noktaları çevreleyen en kısa çiti bulmak, kesişen yol parçalarını tespit etmek veya bir çokgenin alanını hesaplamak… Bilgisayarlı geometrinin bu klasik problemleri, birkaç temel işlem üzerine kurulur. Nokta, doğru ve çokgenleri matematiksel olarak temsil etmeyi öğrendiğimizde dışbükey örtü ve tarama doğrusu gibi ilk bakışta ürkütücü görünen algoritmalar oldukça anlaşılır hâle gelir.
``</p>

<h2 id="geometrinin-yapı-taşları">Geometrinin yapı taşları</h2>

<p>İki boyutlu düzlemde bir noktayı $P=(x,y)$ biçiminde gösteririz. İki noktanın farkı ise bir vektördür: $AB=B-A$. Uzaklık hesabında Öklid formülü kullanılır:</p>

\[d(A,B)=\sqrt{(x_B-x_A)^2+(y_B-y_A)^2}\]

<p>Geometrik algoritmaların gizli kahramanı çapraz çarpımdır. $A$, $B$ ve $C$ noktaları için yönelim değeri şöyledir:</p>

\[cross(A,B,C)=(B_x-A_x)(C_y-A_y)-(B_y-A_y)(C_x-A_x)\]

<p>Sonucun işareti, üç noktanın dönüş yönünü söyler:</p>

<table>
  <thead>
    <tr>
      <th>Sonuç</th>
      <th>Geometrik anlam</th>
      <th>Algoritmadaki kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$cross&gt;0$</td>
      <td>Sola dönüş</td>
      <td>Saat yönünün tersinde ilerleme</td>
    </tr>
    <tr>
      <td>$cross&lt;0$</td>
      <td>Sağa dönüş</td>
      <td>Uygun olmayan noktayı çıkarma</td>
    </tr>
    <tr>
      <td>$cross=0$</td>
      <td>Noktalar doğrusal</td>
      <td>Çakışma ve sınır kontrolü</td>
    </tr>
  </tbody>
</table>

<p>Bu işlem yalnızca çarpma ve çıkarma içerdiği için açı hesaplamaktan daha hızlıdır. Tamsayı koordinatlarda kayan nokta hatalarını da önler.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="nc">Point</span> <span class="p">{</span>
    <span class="kt">long</span> <span class="kt">long</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">;</span>
<span class="p">};</span>

<span class="kt">long</span> <span class="kt">long</span> <span class="nf">cross</span><span class="p">(</span><span class="n">Point</span> <span class="n">a</span><span class="p">,</span> <span class="n">Point</span> <span class="n">b</span><span class="p">,</span> <span class="n">Point</span> <span class="n">c</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">(</span><span class="n">b</span><span class="p">.</span><span class="n">x</span> <span class="o">-</span> <span class="n">a</span><span class="p">.</span><span class="n">x</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">c</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="n">a</span><span class="p">.</span><span class="n">y</span><span class="p">)</span>
         <span class="o">-</span> <span class="p">(</span><span class="n">b</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="n">a</span><span class="p">.</span><span class="n">y</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">c</span><span class="p">.</span><span class="n">x</span> <span class="o">-</span> <span class="n">a</span><span class="p">.</span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu fonksiyon; dönüş yönü, doğru parçalarının kesişimi ve dışbükeylik kontrolü gibi birçok işlemin ortak motorudur.</p>

<h2 id="çokgen-alanı-ve-yönü">Çokgen alanı ve yönü</h2>

<p>Köşeleri sırayla verilen basit bir çokgenin alanı, ayakkabı bağı formülüyle bulunabilir:</p>

\[2A=\left|\sum_{i=0}^{n-1}(x_i y_{i+1}-y_i x_{i+1})\right|\]

<p>İndisler döngüseldir; yani son noktadan sonra yeniden ilk nokta gelir. Mutlak değer alınmadan önce toplamın işareti, köşelerin saat yönünde mi yoksa ters yönde mi sıralandığını da gösterir.</p>

<h2 id="dışbükey-örtü-noktaların-etrafına-lastik-geçirmek">Dışbükey örtü: Noktaların etrafına lastik geçirmek</h2>

<p>Dışbükey örtü, verilen bütün noktaları kapsayan en küçük dışbükey çokgendir. Sezgisel olarak noktaların çevresine bir lastik geçirip bıraktığımızda oluşan sınırdır. Monotonic Chain algoritması önce noktaları $(x,y)$ sırasına göre sıralar, ardından alt ve üst zincirleri kurar.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">vector</span><span class="o">&lt;</span><span class="n">Point</span><span class="o">&gt;</span> <span class="n">convexHull</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">Point</span><span class="o">&gt;</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sort</span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">p</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="p">[](</span><span class="n">Point</span> <span class="n">a</span><span class="p">,</span> <span class="n">Point</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="n">a</span><span class="p">.</span><span class="n">x</span> <span class="o">!=</span> <span class="n">b</span><span class="p">.</span><span class="n">x</span> <span class="o">?</span> <span class="n">a</span><span class="p">.</span><span class="n">x</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">.</span><span class="n">x</span> <span class="o">:</span> <span class="n">a</span><span class="p">.</span><span class="n">y</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>
    <span class="p">});</span>

    <span class="n">vector</span><span class="o">&lt;</span><span class="n">Point</span><span class="o">&gt;</span> <span class="n">h</span><span class="p">;</span>
    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">pass</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">pass</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">;</span> <span class="n">pass</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="kt">size_t</span> <span class="n">start</span> <span class="o">=</span> <span class="n">h</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
        <span class="k">for</span> <span class="p">(</span><span class="n">Point</span> <span class="n">q</span> <span class="o">:</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">while</span> <span class="p">(</span><span class="n">h</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="n">start</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">&amp;&amp;</span>
                   <span class="n">cross</span><span class="p">(</span><span class="n">h</span><span class="p">[</span><span class="n">h</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">2</span><span class="p">],</span> <span class="n">h</span><span class="p">.</span><span class="n">back</span><span class="p">(),</span> <span class="n">q</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span>
                <span class="n">h</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
            <span class="n">h</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">q</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="n">h</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
        <span class="n">reverse</span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">p</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">h</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Sıralama $O(n\log n)$, zincirleri oluşturma ise $O(n)$ sürer. <code class="language-plaintext highlighter-rouge">cross &lt;= 0</code> kullanımı, aynı kenar üzerindeki ara noktaları örtüden çıkarır. Bu noktalar da sonuçta isteniyorsa koşul problem tanımına göre değiştirilmelidir.</p>

<h2 id="tarama-doğrusu-olayları-sırayla-işle">Tarama doğrusu: Olayları sırayla işle</h2>

<p>Tarama doğrusu yaklaşımında hayali bir doğru düzlem boyunca hareket eder. Algoritma bütün geometrik şekilleri sürekli incelemek yerine yalnızca başlangıç, bitiş ve kesişim gibi <strong>olaylarda</strong> işlem yapar.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Temel fikir</th>
      <th>Tipik karmaşıklık</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tüm çiftleri deneme</td>
      <td>Her doğru parçasını diğerleriyle karşılaştır</td>
      <td>$O(n^2)$</td>
    </tr>
    <tr>
      <td>Tarama doğrusu</td>
      <td>Olayları sırala, aktif elemanları tut</td>
      <td>Genellikle $O(n\log n)$</td>
    </tr>
    <tr>
      <td>Dışbükey örtü</td>
      <td>Gereksiz iç noktaları ele</td>
      <td>$O(n\log n)$</td>
    </tr>
  </tbody>
</table>

<p>Örneğin yatay doğru parçalarının çakışmasını ararken başlangıç noktası aktif kümeye eklenir, bitiş noktası geldiğinde çıkarılır. Dikey bir parça işlendiğinde aktif kümede onun $y$ aralığına düşen parçalar sorgulanır. Dengeli bir arama ağacı kullanılırsa ekleme, silme ve arama işlemleri $O(\log n)$ zamanda yapılabilir.</p>

<p>Tarama doğrusu uygulamalarındaki kritik ayrıntı, aynı koordinattaki olayların sırasıdır. Bir parçanın bitişi, diğerinin başlangıcıyla çakışıyorsa kesişimin sayılıp sayılmayacağına göre olay öncelikleri belirlenmelidir. Geometride şeytan ayrıntıda, hata ise çoğunlukla eşitlik durumundadır!</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="geometri" /><category term="algoritma" /><category term="dışbükey örtü" /><summary type="html"><![CDATA[Haritadaki noktaları çevreleyen en kısa çiti bulmak, kesişen yol parçalarını tespit etmek veya bir çokgenin alanını hesaplamak… Bilgisayarlı geometrinin bu klasik problemleri, birkaç temel işlem üzerine kurulur. Nokta, doğru ve çokgenleri matematiksel olarak temsil etmeyi öğrendiğimizde dışbükey örtü ve tarama doğrusu gibi ilk bakışta ürkütücü görünen algoritmalar oldukça anlaşılır hâle gelir.]]></summary></entry><entry><title type="html">Oturum ve Çerez Yönetimi: Güvenli Login/Logout Sistemlerinin Anatomisi</title><link href="https://sonsuzus.github.io/posts/oturum-ve-cerez-yonetimi-guvenli-loginlogout-sistemlerinin-anatomisi/" rel="alternate" type="text/html" title="Oturum ve Çerez Yönetimi: Güvenli Login/Logout Sistemlerinin Anatomisi" /><published>2026-08-06T00:00:00+00:00</published><updated>2026-08-06T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/oturum-ve-cerez-yonetimi-guvenli-loginlogout-sistemlerinin-anatomisi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/oturum-ve-cerez-yonetimi-guvenli-loginlogout-sistemlerinin-anatomisi/"><![CDATA[<p>Bir kullanıcı giriş yaptığında uygulamanın onu sonraki istekte hatırlaması gerekir. HTTP ise doğası gereği durumsuzdur; yani sunucu, arka arkaya gelen iki isteğin aynı kişiye ait olduğunu kendiliğinden bilmez. Oturum ve çerez mekanizmaları bu hafıza problemini çözer. Biri bilgiyi çoğunlukla sunucuda, diğeri tarayıcıda taşır; doğru kullanıldıklarında güvenli ve akıcı bir kullanıcı deneyimi oluştururlar.</p>

<p>``</p>

<h2 id="http-neden-kullanıcıyı-hatırlamaz">HTTP Neden Kullanıcıyı Hatırlamaz?</h2>

<p>Her HTTP isteği bağımsız değerlendirilir. Kullanıcı <code class="language-plaintext highlighter-rouge">/login</code> adresinde doğru parolayı girdikten sonra <code class="language-plaintext highlighter-rouge">/profile</code> sayfasına geçtiğinde tarayıcının kimliğini yeniden kanıtlaması gerekir. Teorik olarak doğrulama maliyetini şöyle düşünebiliriz:</p>

\[T_{toplam} = n \times T_{doğrulama}\]

<p>Her istekte parola doğrulamak yerine ilk doğrulamada bir oturum oluşturulursa yaklaşık maliyet şu hâle gelir:</p>

\[T_{toplam} = T_{login} + n \times T_{sessionKontrolü}\]

<p>Oturum kontrolü, parola özeti hesaplamaktan çok daha hızlıdır. Üstelik parola her istekte ağ üzerinde dolaşmaz.</p>

<h2 id="cookie-ve-session-arasındaki-fark">Cookie ve Session Arasındaki Fark</h2>

<p>Cookie, tarayıcının sakladığı ve uygun isteklerle sunucuya gönderdiği küçük bir anahtar-değer verisidir. Session ise kullanıcıya ait geçici durumun sunucuda saklanmasıdır. Tarayıcı genellikle yalnızca tahmin edilmesi zor bir oturum kimliği taşır.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Cookie</th>
      <th>Session</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Saklama yeri</td>
      <td>Tarayıcı</td>
      <td>Sunucu, Redis veya veritabanı</td>
    </tr>
    <tr>
      <td>Veri kapasitesi</td>
      <td>Yaklaşık 4 KB</td>
      <td>Altyapıya bağlı</td>
    </tr>
    <tr>
      <td>Hassas veri</td>
      <td>Saklanmamalı</td>
      <td>Daha uygun</td>
    </tr>
    <tr>
      <td>Sunucu yükü</td>
      <td>Düşük</td>
      <td>Kullanıcı sayısıyla artar</td>
    </tr>
    <tr>
      <td>Tipik kullanım</td>
      <td>Tema, dil, session ID</td>
      <td>Kullanıcı kimliği, yetkiler</td>
    </tr>
  </tbody>
</table>

<p>Örneğin <code class="language-plaintext highlighter-rouge">theme=dark</code> doğrudan cookie içinde tutulabilir. Ancak <code class="language-plaintext highlighter-rouge">role=admin</code> değerine güvenmek tehlikelidir; kullanıcı tarayıcı araçlarıyla bunu değiştirebilir. Yetki bilgisi sunucuda doğrulanmalıdır.</p>

<h2 id="express-ile-login-ve-logout">Express ile Login ve Logout</h2>

<p>Aşağıdaki örnek, oturum verisini sunucuda tutar ve tarayıcıya yalnızca oturum kimliğini içeren cookie gönderir:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">express</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">express</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="nx">session</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">express-session</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="nx">bcrypt</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">bcrypt</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nf">express</span><span class="p">();</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nx">express</span><span class="p">.</span><span class="nf">json</span><span class="p">());</span>

<span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nf">session</span><span class="p">({</span>
  <span class="na">secret</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">SESSION_SECRET</span><span class="p">,</span>
  <span class="na">resave</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
  <span class="na">saveUninitialized</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
  <span class="na">cookie</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">httpOnly</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="na">secure</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">NODE_ENV</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">production</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">sameSite</span><span class="p">:</span> <span class="dl">"</span><span class="s2">lax</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">maxAge</span><span class="p">:</span> <span class="mi">1000</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">30</span>
  <span class="p">}</span>
<span class="p">}));</span>

<span class="nx">app</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">/login</span><span class="dl">"</span><span class="p">,</span> <span class="k">async </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">findUserByEmail</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">email</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">valid</span> <span class="o">=</span> <span class="nx">user</span> <span class="o">&amp;&amp;</span> <span class="k">await</span> <span class="nx">bcrypt</span><span class="p">.</span><span class="nf">compare</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">password</span><span class="p">,</span> <span class="nx">user</span><span class="p">.</span><span class="nx">passwordHash</span><span class="p">);</span>

  <span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nx">valid</span><span class="p">)</span> <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nf">status</span><span class="p">(</span><span class="mi">401</span><span class="p">).</span><span class="nf">json</span><span class="p">({</span> <span class="na">error</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Geçersiz bilgiler</span><span class="dl">"</span> <span class="p">});</span>

  <span class="nx">req</span><span class="p">.</span><span class="nx">session</span><span class="p">.</span><span class="nf">regenerate</span><span class="p">(</span><span class="nx">error</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nf">sendStatus</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span>
    <span class="nx">req</span><span class="p">.</span><span class="nx">session</span><span class="p">.</span><span class="nx">userId</span> <span class="o">=</span> <span class="nx">user</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span>
    <span class="nx">res</span><span class="p">.</span><span class="nf">json</span><span class="p">({</span> <span class="na">message</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Giriş başarılı</span><span class="dl">"</span> <span class="p">});</span>
  <span class="p">});</span>
<span class="p">});</span>

<span class="nx">app</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">/logout</span><span class="dl">"</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nx">req</span><span class="p">.</span><span class="nx">session</span><span class="p">.</span><span class="nf">destroy</span><span class="p">(</span><span class="nx">error</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nf">sendStatus</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span>
    <span class="nx">res</span><span class="p">.</span><span class="nf">clearCookie</span><span class="p">(</span><span class="dl">"</span><span class="s2">connect.sid</span><span class="dl">"</span><span class="p">);</span>
    <span class="nx">res</span><span class="p">.</span><span class="nf">sendStatus</span><span class="p">(</span><span class="mi">204</span><span class="p">);</span>
  <span class="p">});</span>
<span class="p">});</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">httpOnly</code>, JavaScript’in cookie değerini okumasını engelleyerek XSS saldırılarının etkisini azaltır. <code class="language-plaintext highlighter-rouge">secure</code>, cookie’nin yalnızca HTTPS üzerinden gönderilmesini sağlar. <code class="language-plaintext highlighter-rouge">sameSite</code>, başka sitelerden başlatılan istekleri sınırlayarak CSRF riskini düşürür. Login sonrasında <code class="language-plaintext highlighter-rouge">regenerate</code> kullanılması ise saldırganın önceden bildiği bir kimliği kurbana kullandırdığı session fixation saldırısına karşı önemlidir.</p>

<h2 id="tercihler-nerede-saklanmalı">Tercihler Nerede Saklanmalı?</h2>

<table>
  <thead>
    <tr>
      <th>Veri</th>
      <th>Önerilen yer</th>
      <th>Gerekçe</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tema ve dil</td>
      <td>Cookie veya localStorage</td>
      <td>Hassas değildir</td>
    </tr>
    <tr>
      <td>Sepet kimliği</td>
      <td>İmzalı cookie/session</td>
      <td>Bütünlük gerekir</td>
    </tr>
    <tr>
      <td>Kullanıcı ID</td>
      <td>Session</td>
      <td>İstemciye güvenilmez</td>
    </tr>
    <tr>
      <td>Parola</td>
      <td>Hiçbiri</td>
      <td>Yalnızca hash saklanır</td>
    </tr>
    <tr>
      <td>Erişim yetkileri</td>
      <td>Sunucu</td>
      <td>Her istekte doğrulanmalıdır</td>
    </tr>
  </tbody>
</table>

<p>Gerçek projelerde varsayılan bellek tabanlı session deposu kullanılmamalıdır; süreç yeniden başlayınca oturumlar kaybolur ve birden fazla sunucu arasında paylaşılmaz. Redis gibi süre sonu destekleyen merkezi bir depo daha uygundur.</p>

<p>Son olarak logout yalnızca arayüzde kullanıcıyı giriş sayfasına göndermek değildir. Sunucudaki oturum gerçekten yok edilmeli, cookie temizlenmeli ve hassas işlemlerde gerekirse tüm cihazlardaki oturumları iptal edebilmek için kullanıcı bazlı bir oturum listesi tutulmalıdır. Kısacası iyi bir giriş sistemi, kapıyı açmayı bildiği kadar kapatmayı da bilmelidir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="session" /><category term="cookie" /><category term="kimlik doğrulama" /><summary type="html"><![CDATA[Bir kullanıcı giriş yaptığında uygulamanın onu sonraki istekte hatırlaması gerekir. HTTP ise doğası gereği durumsuzdur; yani sunucu, arka arkaya gelen iki isteğin aynı kişiye ait olduğunu kendiliğinden bilmez. Oturum ve çerez mekanizmaları bu hafıza problemini çözer. Biri bilgiyi çoğunlukla sunucuda, diğeri tarayıcıda taşır; doğru kullanıldıklarında güvenli ve akıcı bir kullanıcı deneyimi oluştururlar.]]></summary></entry><entry><title type="html">Oyun Teorisinden Minimax’a: İki Oyunculu Oyunlarda Kazanma Stratejisi</title><link href="https://sonsuzus.github.io/posts/oyun-teorisinden-minimaxa-iki-oyunculu-oyunlarda-kazanma-stratejisi/" rel="alternate" type="text/html" title="Oyun Teorisinden Minimax’a: İki Oyunculu Oyunlarda Kazanma Stratejisi" /><published>2026-08-06T00:00:00+00:00</published><updated>2026-08-06T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/oyun-teorisinden-minimaxa-iki-oyunculu-oyunlarda-kazanma-stratejisi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/oyun-teorisinden-minimaxa-iki-oyunculu-oyunlarda-kazanma-stratejisi/"><![CDATA[<p>Satrançta rakibin vezirini tehdit ettiğinde neden hemen sevinmemelisin? Çünkü rakibin de plan yapıyor! Oyun teorisi, kararlarımızın sonucunun yalnızca bize değil, başka oyuncuların seçimlerine de bağlı olduğu durumları matematiksel olarak inceler. Minimax algoritması ise bu fikirleri bilgisayarların anlayabileceği bir oyun ağacına dönüştürerek mümkün olan en güvenli hamleyi seçmelerini sağlar.
``</p>

<h2 id="oyun-teorisinin-temel-bileşenleri">Oyun teorisinin temel bileşenleri</h2>

<p>Bir oyun; <strong>oyuncular</strong>, oyuncuların seçebileceği <strong>stratejiler</strong>, oyunun mevcut <strong>durumu</strong> ve sonuçları değerlendiren <strong>kazanç fonksiyonundan</strong> oluşur. İki oyunculu sıfır toplamlı bir oyunda bir tarafın kazancı, diğer tarafın kaybıdır. Kazançlar $u_1$ ve $u_2$ ile gösterilirse:</p>

\[u_1 + u_2 = 0\]

<p>Satranç, dama ve tic-tac-toe bu modele oldukça uygundur. Bu oyunlarda oyuncular sırayla hareket eder, oyun durumu herkes tarafından görülür ve şans faktörü bulunmaz. Böyle oyunlara <strong>deterministik, tam bilgili oyunlar</strong> denir.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Açıklama</th>
      <th>Tic-tac-toe örneği</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Durum</td>
      <td>Oyunun belirli andaki görünümü</td>
      <td>Tahtadaki X ve O işaretleri</td>
    </tr>
    <tr>
      <td>Hamle</td>
      <td>Bir durumdan diğerine geçiş</td>
      <td>Boş hücreye X koymak</td>
    </tr>
    <tr>
      <td>Terminal durum</td>
      <td>Oyunun sona erdiği durum</td>
      <td>Kazanma veya beraberlik</td>
    </tr>
    <tr>
      <td>Fayda değeri</td>
      <td>Sonucun sayısal karşılığı</td>
      <td>Kazanma: $1$, beraberlik: $0$, kayıp: $-1$</td>
    </tr>
  </tbody>
</table>

<h2 id="minimax-nasıl-düşünür">Minimax nasıl düşünür?</h2>

<p>Minimax algoritmasında bir oyuncuya <strong>MAX</strong>, diğerine <strong>MIN</strong> adı verilir. MAX en yüksek skoru seçmeye, MIN ise bu skoru mümkün olduğunca düşürmeye çalışır. Algoritma, rakibin hata yapacağını ummaz; tam tersine, rakibin her zaman en iyi hamleyi oynayacağını varsayar. Biraz karamsardır ama hazırlıksız yakalanmaz!</p>

<p>Bir $s$ durumu için minimax değeri şöyle tanımlanabilir:</p>

\[V(s) = \max V(s') \quad \text{MAX sırasındaysa}\]

\[V(s) = \min V(s') \quad \text{MIN sırasındaysa}\]

<p>Buradaki $s’$, mevcut durumdan ulaşılabilen çocuk durumlardan biridir. Terminal durumda ise değer doğrudan kazanç fonksiyonundan alınır.</p>

<h2 id="python-ile-minimax-uygulaması">Python ile minimax uygulaması</h2>

<p>Aşağıdaki fonksiyon, önceden oluşturulmuş bir oyun ağacını dolaşır. Yaprak düğümler sayısal sonuçları, listeler ise olası hamleleri temsil eder:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">minimax</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">maximizing</span><span class="p">):</span>
    <span class="c1"># Sayıya ulaştıysak oyun bitmiştir.
</span>    <span class="k">if</span> <span class="nf">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">node</span>

    <span class="n">scores</span> <span class="o">=</span> <span class="p">[</span><span class="nf">minimax</span><span class="p">(</span><span class="n">child</span><span class="p">,</span> <span class="ow">not</span> <span class="n">maximizing</span><span class="p">)</span> <span class="k">for</span> <span class="n">child</span> <span class="ow">in</span> <span class="n">node</span><span class="p">]</span>

    <span class="c1"># MAX en büyük, MIN en küçük sonucu seçer.
</span>    <span class="k">return</span> <span class="nf">max</span><span class="p">(</span><span class="n">scores</span><span class="p">)</span> <span class="k">if</span> <span class="n">maximizing</span> <span class="k">else</span> <span class="nf">min</span><span class="p">(</span><span class="n">scores</span><span class="p">)</span>

<span class="c1"># MAX oyuncusunun üç farklı hamlesi
</span> <span class="n">game_tree</span> <span class="o">=</span> <span class="p">[</span>
    <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">9</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">]</span>
<span class="p">]</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">minimax</span><span class="p">(</span><span class="n">game_tree</span><span class="p">,</span> <span class="bp">True</span><span class="p">))</span>  <span class="c1"># Çıktı: 6
</span></code></pre></div></div>

<p>MIN her dalda en düşük değeri seçeceği için dalların değerleri sırasıyla $2$, $1$ ve $6$ olur. MAX da bunların en büyüğü olan $6$ değerli üçüncü hamleyi tercih eder. Böylece karar formülü $\max(2,1,6)=6$ olur.</p>

<h2 id="kazanma-stratejisi-nasıl-hesaplanır">Kazanma stratejisi nasıl hesaplanır?</h2>

<p>Öncelikle geçerli tüm hamleler üretilir ve her hamle için oluşacak durum hesaplanır. Oyun sonuna ulaşılabiliyorsa gerçek fayda değeri kullanılır. Satranç gibi ağacı devasa olan oyunlarda ise belirli bir derinlikte durularak taş üstünlüğü, hareketlilik ve şah güvenliği gibi ölçütlerden oluşan bir <strong>sezgisel değerlendirme fonksiyonu</strong> çalıştırılır.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Avantaj</th>
      <th>Dezavantaj</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tam minimax</td>
      <td>Kesin sonucu bulabilir</td>
      <td>Büyük ağaçlarda çok yavaştır</td>
    </tr>
    <tr>
      <td>Derinlik sınırlı minimax</td>
      <td>Daha hızlıdır</td>
      <td>Değerlendirme hatası yapabilir</td>
    </tr>
    <tr>
      <td>Alfa-beta budama</td>
      <td>Gereksiz dalları atlar</td>
      <td>Hamle sıralamasına duyarlıdır</td>
    </tr>
  </tbody>
</table>

<p>Alfa-beta budama, sonucu değiştirmeyeceği kesinleşen dalları incelemez. İyi bir hamle sıralamasıyla minimax’ın pratik performansını ciddi biçimde artırır. Sonuç olarak kazanma stratejisi; rakibin en güçlü cevabını hesaba katmak, en kötü sonucu güvenceye almak ve hesaplama sınırları varsa durumları doğru değerlendirmek üzerine kuruludur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="oyun teorisi" /><category term="minimax" /><category term="algoritma" /><summary type="html"><![CDATA[Satrançta rakibin vezirini tehdit ettiğinde neden hemen sevinmemelisin? Çünkü rakibin de plan yapıyor! Oyun teorisi, kararlarımızın sonucunun yalnızca bize değil, başka oyuncuların seçimlerine de bağlı olduğu durumları matematiksel olarak inceler. Minimax algoritması ise bu fikirleri bilgisayarların anlayabileceği bir oyun ağacına dönüştürerek mümkün olan en güvenli hamleyi seçmelerini sağlar.]]></summary></entry><entry><title type="html">PHP Kurulumu ve XAMPP/MAMP ile Yerel Sunucu Ortamı</title><link href="https://sonsuzus.github.io/posts/php-kurulumu-ve-xamppmamp-ile-yerel-sunucu-ortami/" rel="alternate" type="text/html" title="PHP Kurulumu ve XAMPP/MAMP ile Yerel Sunucu Ortamı" /><published>2026-08-06T00:00:00+00:00</published><updated>2026-08-06T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/php-kurulumu-ve-xamppmamp-ile-yerel-sunucu-ortami</id><content type="html" xml:base="https://sonsuzus.github.io/posts/php-kurulumu-ve-xamppmamp-ile-yerel-sunucu-ortami/"><![CDATA[<p>PHP ile dinamik bir web uygulaması geliştirirken dosyaya çift tıklamak yeterli değildir. Tarayıcı PHP kodunu doğrudan çalıştıramaz; isteğin bir web sunucusuna ulaşması, PHP yorumlayıcısından geçmesi ve gerekiyorsa veritabanıyla konuşması gerekir. XAMPP ve MAMP, bu parçaları tek pakette sunarak bilgisayarımızı internete açmadan küçük bir geliştirme sunucusuna dönüştürür.</p>

<p>``</p>

<h2 id="yerel-sunucu-neden-gereklidir">Yerel sunucu neden gereklidir?</h2>

<p>HTML, CSS ve JavaScript çoğunlukla tarayıcı tarafında çalışır. PHP ise sunucu taraflı bir dildir. Teknik olarak PHP kodları klasik anlamda doğrudan makine koduna derlenmek yerine PHP motoru tarafından işlenir; modern PHP sürümleri opcode ve JIT gibi optimizasyonlardan da yararlanabilir.</p>

<p>Tipik bir isteğin yolu şöyledir:</p>

<ol>
  <li>Tarayıcı <code class="language-plaintext highlighter-rouge">http://localhost/proje</code> adresine istek gönderir.</li>
  <li>Apache isteği karşılar ve ilgili PHP dosyasını bulur.</li>
  <li>PHP motoru kodu çalıştırır.</li>
  <li>Gerekirse MySQL veya MariaDB sunucusuna sorgu gönderilir.</li>
  <li>Üretilen HTML tarayıcıya döndürülür.</li>
</ol>

<p>Toplam yanıt süresini basitçe şu şekilde düşünebiliriz:</p>

\[T_{toplam} = T_{sunucu} + T_{PHP} + T_{veritabani} + T_{ag}\]

<p>Yerel geliştirmede ağ gecikmesi çok düşük olduğundan kod ve veritabanı performansını daha rahat gözlemleyebiliriz.</p>

<h2 id="xampp-ve-mamp-karşılaştırması">XAMPP ve MAMP karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>XAMPP</th>
      <th>MAMP</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>İşletim sistemleri</td>
      <td>Windows, macOS, Linux</td>
      <td>macOS ve Windows</td>
    </tr>
    <tr>
      <td>Web sunucusu</td>
      <td>Apache</td>
      <td>Apache veya Nginx seçenekleri</td>
    </tr>
    <tr>
      <td>Veritabanı</td>
      <td>MariaDB</td>
      <td>MySQL</td>
    </tr>
    <tr>
      <td>Yönetim biçimi</td>
      <td>Kontrol paneli</td>
      <td>Masaüstü uygulaması</td>
    </tr>
    <tr>
      <td>Kullanım yaklaşımı</td>
      <td>Esnek ve yaygın</td>
      <td>Özellikle macOS’ta sade</td>
    </tr>
  </tbody>
</table>

<p>Her iki araç da başlangıç için uygundur. Windows kullanıcıları genellikle XAMPP’ı, macOS kullanıcıları ise MAMP’ı tercih eder. Seçim yaparken projenin kullanacağı PHP sürümünü kontrol etmek önemlidir.</p>

<h2 id="kurulum-ve-servislerin-başlatılması">Kurulum ve servislerin başlatılması</h2>

<p>Paketi yalnızca resmi XAMPP veya MAMP sitesinden indirin. Kurulum sırasında en az Apache, PHP ve MySQL/MariaDB bileşenlerini seçin. XAMPP kullanıyorsanız kontrol panelinden <strong>Apache</strong> ve <strong>MySQL</strong> servislerini <code class="language-plaintext highlighter-rouge">Start</code> düğmesiyle çalıştırın. MAMP’ta ise <strong>Start Servers</strong> düğmesi aynı görevi üstlenir.</p>

<p>Tarayıcıda <code class="language-plaintext highlighter-rouge">http://localhost</code> adresini açtığınızda karşılama sayfasını görüyorsanız web sunucusu hazırdır. Apache başlamıyorsa çoğunlukla 80 veya 443 numaralı port başka bir uygulama tarafından kullanılıyordur. Bu durumda ilgili uygulamayı kapatabilir ya da Apache yapılandırmasında portu örneğin <code class="language-plaintext highlighter-rouge">8080</code> yapabilirsiniz. Yeni adresiniz <code class="language-plaintext highlighter-rouge">http://localhost:8080</code> olur.</p>

<h2 id="i̇lk-php-dosyasını-çalıştırmak">İlk PHP dosyasını çalıştırmak</h2>

<p>XAMPP’ta proje dosyaları genellikle <code class="language-plaintext highlighter-rouge">htdocs</code>, MAMP’ta ise <code class="language-plaintext highlighter-rouge">htdocs</code> veya ayarlanan belge kökü içine yerleştirilir. <code class="language-plaintext highlighter-rouge">php-deneme</code> adlı klasörde <code class="language-plaintext highlighter-rouge">index.php</code> oluşturun:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$uygulama</span> <span class="o">=</span> <span class="s2">"Yerel PHP Sunucusu"</span><span class="p">;</span>
<span class="nv">$saat</span> <span class="o">=</span> <span class="nb">date</span><span class="p">(</span><span class="s2">"H:i:s"</span><span class="p">);</span>

 <span class="k">echo</span> <span class="s2">"&lt;h1&gt;</span><span class="si">{</span><span class="nv">$uygulama</span><span class="si">}</span><span class="s2">&lt;/h1&gt;"</span><span class="p">;</span>
 <span class="k">echo</span> <span class="s2">"&lt;p&gt;Sunucu saati: </span><span class="si">{</span><span class="nv">$saat</span><span class="si">}</span><span class="s2">&lt;/p&gt;"</span><span class="p">;</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>

<p>Bu kod bir değişken tanımlar, sunucu saatini hesaplar ve dinamik HTML üretir. Dosyayı doğrudan açmak yerine <code class="language-plaintext highlighter-rouge">http://localhost/php-deneme</code> adresine gidin. Kodun kendisi değil, oluşturduğu başlık ve saat görünmelidir.</p>

<p>Kurulu PHP sürümünü terminalden denetlemek için şu komutu kullanabilirsiniz:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>php <span class="nt">-v</span>
</code></pre></div></div>

<p>Ancak terminaldeki PHP sürümüyle Apache’nin kullandığı sürüm farklı olabilir. Web tarafını kesin olarak kontrol etmek için geçici bir dosyada <code class="language-plaintext highlighter-rouge">phpinfo();</code> çalıştırabilirsiniz. Bu sayfa ayrıntılı sistem bilgileri gösterdiğinden inceleme sonrasında mutlaka silinmelidir.</p>

<h2 id="veritabanını-doğrulamak">Veritabanını doğrulamak</h2>

<p>XAMPP ve MAMP genellikle phpMyAdmin arayüzü sağlar. Buradan <code class="language-plaintext highlighter-rouge">deneme_db</code> adlı bir veritabanı oluşturabilir, tablo ve kullanıcıları yönetebilirsiniz. Geliştirme sırasında varsayılan yönetici hesabı pratik görünse de gerçek projelerde ayrı kullanıcı ve güçlü parola kullanın.</p>

<p>Yerel ortam artık hazırdır: Apache istekleri karşılar, PHP uygulama mantığını yürütür, MySQL veya MariaDB verileri saklar. Böylece internetteki sunucuya her değişiklikte dosya göndermek yerine hızlı, güvenli ve kahve dökülmesine dayanıklı sayılabilecek bir geliştirme döngüsü elde edersiniz.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="PHP" /><category term="XAMPP" /><category term="MAMP" /><summary type="html"><![CDATA[PHP ile dinamik bir web uygulaması geliştirirken dosyaya çift tıklamak yeterli değildir. Tarayıcı PHP kodunu doğrudan çalıştıramaz; isteğin bir web sunucusuna ulaşması, PHP yorumlayıcısından geçmesi ve gerekiyorsa veritabanıyla konuşması gerekir. XAMPP ve MAMP, bu parçaları tek pakette sunarak bilgisayarımızı internete açmadan küçük bir geliştirme sunucusuna dönüştürür.]]></summary></entry><entry><title type="html">PHP Temelleri: Sunucudan HTML’e Uzanan Yolculuk</title><link href="https://sonsuzus.github.io/posts/php-temelleri-sunucudan-htmle-uzanan-yolculuk/" rel="alternate" type="text/html" title="PHP Temelleri: Sunucudan HTML’e Uzanan Yolculuk" /><published>2026-08-06T00:00:00+00:00</published><updated>2026-08-06T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/php-temelleri-sunucudan-htmle-uzanan-yolculuk</id><content type="html" xml:base="https://sonsuzus.github.io/posts/php-temelleri-sunucudan-htmle-uzanan-yolculuk/"><![CDATA[<p>Bir web sayfasındaki kullanıcı adı, ürün listesi veya sepet tutarı kendiliğinden ortaya çıkmaz. Perdenin arkasında çalışan PHP; isteği karşılar, verileri işler ve tarayıcıya gönderilecek HTML çıktısını üretir. Tarayıcı PHP kodunu görmez; yalnızca onun hazırladığı sonucu görür. Gelin bu mutfağa girip PHP’nin çalışma mantığını, sözdizimini ve veri tiplerini inceleyelim.
``</p>
<h2 id="php-nasıl-çalışır">PHP nasıl çalışır?</h2>

<p>PHP, <strong>sunucu tarafında</strong> çalışan yorumlanan bir programlama dilidir. Kullanıcı <code class="language-plaintext highlighter-rouge">profil.php</code> adresini açtığında süreç kabaca şöyledir:</p>

<ol>
  <li>Tarayıcı sunucuya HTTP isteği gönderir.</li>
  <li>Web sunucusu <code class="language-plaintext highlighter-rouge">.php</code> dosyasını PHP yorumlayıcısına iletir.</li>
  <li>PHP kodu çalışır; gerekirse veritabanı veya dosyalarla iletişim kurar.</li>
  <li>Üretilen HTML istemciye gönderilir.</li>
  <li>Tarayıcı gelen HTML’yi ekranda gösterir.</li>
</ol>

<p>Toplam yanıt süresini basitçe şöyle düşünebiliriz:</p>

\[T_{yanıt}=T_{ağ}+T_{PHP}+T_{veritabanı}\]

<p>PHP kodunun tarayıcıya gönderilmemesi hem uygulama mantığını gizler hem de sunucuda güvenli işlemler yapılabilmesini sağlar. Ancak bu durum kodun otomatik olarak güvenli olduğu anlamına gelmez; kullanıcı girdileri yine doğrulanmalıdır.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>PHP</th>
      <th>JavaScript (tarayıcıda)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Çalıştığı yer</td>
      <td>Sunucu</td>
      <td>İstemci</td>
    </tr>
    <tr>
      <td>Veritabanına doğrudan erişim</td>
      <td>Yapabilir</td>
      <td>Genellikle yapamaz</td>
    </tr>
    <tr>
      <td>Kaynak kodunu kullanıcı görür mü?</td>
      <td>Hayır</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Temel görevi</td>
      <td>Dinamik çıktı ve veri işlemleri</td>
      <td>Arayüz ve kullanıcı etkileşimi</td>
    </tr>
  </tbody>
</table>

<h2 id="temel-sözdizimi">Temel sözdizimi</h2>

<p>PHP kodu <code class="language-plaintext highlighter-rouge">&lt;?php</code> etiketiyle başlar. Komutların çoğu noktalı virgülle biter ve değişken adlarının önünde <code class="language-plaintext highlighter-rouge">$</code> bulunur.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$isim</span> <span class="o">=</span> <span class="s2">"Ada"</span><span class="p">;</span>
<span class="nv">$yas</span> <span class="o">=</span> <span class="mi">28</span><span class="p">;</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$yas</span> <span class="o">&gt;=</span> <span class="mi">18</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">"Merhaba, "</span> <span class="mf">.</span> <span class="nv">$isim</span> <span class="mf">.</span> <span class="s2">"!"</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">"Erişim için yaşınız yeterli değil."</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">.</code> operatörü metinleri birleştirir. <code class="language-plaintext highlighter-rouge">echo</code>, oluşturulan metni HTTP çıktısına ekler. Değişkenin tipi ayrıca belirtilmemiştir; PHP, atanan değere bakarak türü çalışma anında belirler.</p>

<p>PHP değişken adları büyük-küçük harfe duyarlıdır. Dolayısıyla <code class="language-plaintext highlighter-rouge">$isim</code> ile <code class="language-plaintext highlighter-rouge">$Isim</code> aynı değişken değildir. Açıklamalar <code class="language-plaintext highlighter-rouge">//</code>, <code class="language-plaintext highlighter-rouge">#</code> veya çok satırlı içerikler için <code class="language-plaintext highlighter-rouge">/* ... */</code> kullanılarak yazılabilir.</p>

<h2 id="veri-tipleri">Veri tipleri</h2>

<p>PHP’nin sık kullanılan veri tipleri aşağıdaki gibidir:</p>

<table>
  <thead>
    <tr>
      <th>Veri tipi</th>
      <th>Örnek</th>
      <th>Kullanım amacı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">string</code></td>
      <td><code class="language-plaintext highlighter-rouge">"Merhaba"</code></td>
      <td>Metin saklamak</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">int</code></td>
      <td><code class="language-plaintext highlighter-rouge">42</code></td>
      <td>Tam sayılar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">float</code></td>
      <td><code class="language-plaintext highlighter-rouge">19.95</code></td>
      <td>Ondalıklı sayılar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">bool</code></td>
      <td><code class="language-plaintext highlighter-rouge">true</code></td>
      <td>Mantıksal durumlar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">array</code></td>
      <td><code class="language-plaintext highlighter-rouge">["PHP", "HTML"]</code></td>
      <td>Birden fazla değer</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">null</code></td>
      <td><code class="language-plaintext highlighter-rouge">null</code></td>
      <td>Değer bulunmadığını belirtmek</td>
    </tr>
  </tbody>
</table>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$urun</span> <span class="o">=</span> <span class="s2">"Klavye"</span><span class="p">;</span>
<span class="nv">$fiyat</span> <span class="o">=</span> <span class="mf">850.50</span><span class="p">;</span>
<span class="nv">$stoktaMi</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nv">$etiketler</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"donanım"</span><span class="p">,</span> <span class="s2">"aksesuar"</span><span class="p">];</span>

<span class="nv">$kdvliFiyat</span> <span class="o">=</span> <span class="nv">$fiyat</span> <span class="o">*</span> <span class="mf">1.20</span><span class="p">;</span>
<span class="k">echo</span> <span class="nv">$kdvliFiyat</span><span class="p">;</span>
</code></pre></div></div>

<p>Bu örnek ürün bilgilerini farklı veri tipleriyle saklar ve yüzde 20 KDV ekler. Matematiksel karşılığı $F_{son}=F_{ilk}\times1.20$ biçimindedir. Bir değişkenin tipini görmek için <code class="language-plaintext highlighter-rouge">gettype($fiyat)</code>, ayrıntılı içeriğini incelemek için <code class="language-plaintext highlighter-rouge">var_dump($fiyat)</code> kullanılabilir.</p>

<h2 id="phpyi-html-içine-gömmek">PHP’yi HTML içine gömmek</h2>

<p>PHP’nin güçlü yanlarından biri, HTML arasında yalnızca ihtiyaç duyulan bölgelerde kullanılabilmesidir:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$kullanici</span> <span class="o">=</span> <span class="s2">"Deniz"</span><span class="p">;</span>
<span class="nv">$dersler</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"PHP"</span><span class="p">,</span> <span class="s2">"MySQL"</span><span class="p">,</span> <span class="s2">"HTML"</span><span class="p">];</span>
<span class="cp">?&gt;</span>

<span class="nt">&lt;h2&gt;</span>Hoş geldin, <span class="cp">&lt;?=</span> <span class="nb">htmlspecialchars</span><span class="p">(</span><span class="nv">$kullanici</span><span class="p">)</span> <span class="cp">?&gt;</span><span class="nt">&lt;/h2&gt;</span>
<span class="nt">&lt;ul&gt;</span>
    <span class="cp">&lt;?php</span> <span class="k">foreach</span> <span class="p">(</span><span class="nv">$dersler</span> <span class="k">as</span> <span class="nv">$ders</span><span class="p">)</span><span class="o">:</span> <span class="cp">?&gt;</span>
        <span class="nt">&lt;li&gt;</span><span class="cp">&lt;?=</span> <span class="nb">htmlspecialchars</span><span class="p">(</span><span class="nv">$ders</span><span class="p">)</span> <span class="cp">?&gt;</span><span class="nt">&lt;/li&gt;</span>
    <span class="cp">&lt;?php</span> <span class="k">endforeach</span><span class="p">;</span> <span class="cp">?&gt;</span>
<span class="nt">&lt;/ul&gt;</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">&lt;?= ... ?&gt;</code>, bir değeri kısa yoldan ekrana yazdırır. <code class="language-plaintext highlighter-rouge">foreach</code> dizideki her ders için bir <code class="language-plaintext highlighter-rouge">&lt;li&gt;</code> üretir. <code class="language-plaintext highlighter-rouge">htmlspecialchars()</code> ise özel HTML karakterlerini dönüştürerek zararlı içeriklerin sayfaya kod olarak basılmasını önlemeye yardımcı olur.</p>

<p>Özetle PHP, sunucuda hesap yapan ve sonuç olarak HTML üreten bir mutfak şefidir. Değişkenleri, koşulları, dizileri ve döngüleri öğrendiğinizde statik sayfaları kullanıcıya ve veriye göre değişen gerçek web uygulamalarına dönüştürebilirsiniz.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="PHP" /><category term="Web Programlama" /><category term="Sunucu Tarafı" /><summary type="html"><![CDATA[Bir web sayfasındaki kullanıcı adı, ürün listesi veya sepet tutarı kendiliğinden ortaya çıkmaz. Perdenin arkasında çalışan PHP; isteği karşılar, verileri işler ve tarayıcıya gönderilecek HTML çıktısını üretir. Tarayıcı PHP kodunu görmez; yalnızca onun hazırladığı sonucu görür. Gelin bu mutfağa girip PHP’nin çalışma mantığını, sözdizimini ve veri tiplerini inceleyelim.]]></summary></entry><entry><title type="html">PHP’de Süper Global Değişkenler: $_GET ve $_POST Nasıl Çalışır?</title><link href="https://sonsuzus.github.io/posts/phpde-super-global-degiskenler-_get-ve-_post-nasil-calisir/" rel="alternate" type="text/html" title="PHP’de Süper Global Değişkenler: $_GET ve $_POST Nasıl Çalışır?" /><published>2026-08-06T00:00:00+00:00</published><updated>2026-08-06T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/phpde-super-global-degiskenler-_get-ve-_post-nasil-calisir</id><content type="html" xml:base="https://sonsuzus.github.io/posts/phpde-super-global-degiskenler-_get-ve-_post-nasil-calisir/"><![CDATA[<p>Bir kullanıcı arama kutusuna kelime yazdığında, giriş formunu doldurduğunda veya bir bağlantıya tıkladığında tarayıcı ile sunucu arasında veri alışverişi gerçekleşir. PHP, gelen bu verilere erişebilmemiz için <code class="language-plaintext highlighter-rouge">$_GET</code> ve <code class="language-plaintext highlighter-rouge">$_POST</code> adlı süper global değişkenleri sunar. Adlarındaki “süper” ifadesi boşuna değildir; bu değişkenlere fonksiyonların içinden bile doğrudan erişilebilir.
``</p>
<h2 id="i̇stek-ve-yanıt-döngüsü">İstek ve yanıt döngüsü</h2>

<p>Web iletişimi temel olarak <strong>istemci–sunucu modeline</strong> dayanır. Tarayıcı istemci olarak bir HTTP isteği gönderir, sunucu isteği işler ve bir HTTP yanıtı üretir. Basitleştirilmiş süreç şöyledir:</p>

<ol>
  <li>Kullanıcı bir bağlantıya tıklar veya form gönderir.</li>
  <li>Tarayıcı GET ya da POST isteği oluşturur.</li>
  <li>Web sunucusu isteği PHP dosyasına yönlendirir.</li>
  <li>PHP, verileri ilgili süper global diziye yerleştirir.</li>
  <li>Uygulama veriyi işler ve tarayıcıya yanıt döndürür.</li>
</ol>

<p>İletişim süresini kabaca $T_{toplam} = T_{istek} + T_{işleme} + T_{yanıt}$ biçiminde düşünebiliriz. Ağ gecikmesi ve sunucudaki işlem yükü arttıkça kullanıcının bekleme süresi de artar.</p>

<h2 id="get-metodu-ve-_get">GET metodu ve <code class="language-plaintext highlighter-rouge">$_GET</code></h2>

<p>GET, verileri URL’nin <strong>sorgu dizesine</strong> ekler. Örneğin aşağıdaki adres, <code class="language-plaintext highlighter-rouge">kategori</code> ve <code class="language-plaintext highlighter-rouge">sayfa</code> isimli iki değer taşır:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>urunler.php?kategori=kitap&amp;sayfa=2
</code></pre></div></div>

<p>Soru işaretinden sonraki bölüm sorgu dizesidir. Parametreler <code class="language-plaintext highlighter-rouge">&amp;</code> karakteriyle ayrılır ve her biri <code class="language-plaintext highlighter-rouge">anahtar=değer</code> biçimindedir. PHP bunları ilişkisel bir dizi olan <code class="language-plaintext highlighter-rouge">$_GET</code> içine aktarır:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$kategori</span> <span class="o">=</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">'kategori'</span><span class="p">]</span> <span class="o">??</span> <span class="s1">'tumu'</span><span class="p">;</span>
<span class="nv">$sayfa</span> <span class="o">=</span> <span class="nb">filter_input</span><span class="p">(</span><span class="no">INPUT_GET</span><span class="p">,</span> <span class="s1">'sayfa'</span><span class="p">,</span> <span class="no">FILTER_VALIDATE_INT</span><span class="p">)</span> <span class="o">?:</span> <span class="mi">1</span><span class="p">;</span>

<span class="k">echo</span> <span class="s2">"Kategori: "</span> <span class="mf">.</span> <span class="nb">htmlspecialchars</span><span class="p">(</span><span class="nv">$kategori</span><span class="p">,</span> <span class="no">ENT_QUOTES</span><span class="p">,</span> <span class="s1">'UTF-8'</span><span class="p">);</span>
<span class="k">echo</span> <span class="s2">" | Sayfa: "</span> <span class="mf">.</span> <span class="nv">$sayfa</span><span class="p">;</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">??</code> operatörü parametre gönderilmediyse varsayılan değer sağlar. <code class="language-plaintext highlighter-rouge">filter_input</code> sayfanın gerçekten tam sayı olup olmadığını denetler. <code class="language-plaintext highlighter-rouge">htmlspecialchars</code> ise çıktıyı HTML içinde güvenli göstererek XSS riskini azaltır.</p>

<p>GET; arama, filtreleme, sıralama ve sayfalama için idealdir. URL paylaşılabilir, yer imlerine eklenebilir ve tarayıcı geçmişinde tutulabilir. Bu nedenle parola gibi hassas bilgiler GET ile gönderilmemelidir.</p>

<h2 id="post-metodu-ve-_post">POST metodu ve <code class="language-plaintext highlighter-rouge">$_POST</code></h2>

<p>POST verileri URL’ye değil, HTTP isteğinin gövdesine yerleştirir. Genellikle kayıt, giriş, yorum ekleme veya veri güncelleme işlemlerinde kullanılır:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;form</span> <span class="na">action=</span><span class="s">"kaydet.php"</span> <span class="na">method=</span><span class="s">"post"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"kullanici"</span> <span class="na">required</span><span class="nt">&gt;</span>
  <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"password"</span> <span class="na">name=</span><span class="s">"parola"</span> <span class="na">required</span><span class="nt">&gt;</span>
  <span class="nt">&lt;button</span> <span class="na">type=</span><span class="s">"submit"</span><span class="nt">&gt;</span>Gönder<span class="nt">&lt;/button&gt;</span>
<span class="nt">&lt;/form&gt;</span>
</code></pre></div></div>

<p>Form gönderildiğinde PHP alanlara <code class="language-plaintext highlighter-rouge">$_POST</code> üzerinden erişir:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$kullanici</span> <span class="o">=</span> <span class="nb">trim</span><span class="p">(</span><span class="nv">$_POST</span><span class="p">[</span><span class="s1">'kullanici'</span><span class="p">]</span> <span class="o">??</span> <span class="s1">''</span><span class="p">);</span>
<span class="nv">$parola</span> <span class="o">=</span> <span class="nv">$_POST</span><span class="p">[</span><span class="s1">'parola'</span><span class="p">]</span> <span class="o">??</span> <span class="s1">''</span><span class="p">;</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$kullanici</span> <span class="o">===</span> <span class="s1">''</span> <span class="o">||</span> <span class="nv">$parola</span> <span class="o">===</span> <span class="s1">''</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">exit</span><span class="p">(</span><span class="s1">'Tüm alanları doldurun.'</span><span class="p">);</span>
<span class="p">}</span>

<span class="nv">$parolaOzeti</span> <span class="o">=</span> <span class="nb">password_hash</span><span class="p">(</span><span class="nv">$parola</span><span class="p">,</span> <span class="no">PASSWORD_DEFAULT</span><span class="p">);</span>
<span class="k">echo</span> <span class="s1">'Veriler işlenmeye hazır.'</span><span class="p">;</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">trim</code> gereksiz boşlukları temizler, <code class="language-plaintext highlighter-rouge">password_hash</code> ise parolayı düz metin olarak saklamak yerine güvenli bir özet üretir. Ancak POST tek başına şifreleme sağlamaz; gerçek gizlilik için mutlaka <strong>HTTPS</strong> kullanılmalıdır.</p>

<h2 id="get-ve-post-karşılaştırması">GET ve POST karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>GET</th>
      <th>POST</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Veri konumu</td>
      <td>URL sorgu dizesi</td>
      <td>İstek gövdesi</td>
    </tr>
    <tr>
      <td>Görünürlük</td>
      <td>Adres çubuğunda görünür</td>
      <td>URL’de görünmez</td>
    </tr>
    <tr>
      <td>Paylaşılabilirlik</td>
      <td>Kolaydır</td>
      <td>Doğrudan mümkün değildir</td>
    </tr>
    <tr>
      <td>Tipik kullanım</td>
      <td>Arama ve filtreleme</td>
      <td>Kayıt ve güncelleme</td>
    </tr>
    <tr>
      <td>Veri miktarı</td>
      <td>URL sınırlarına bağlı</td>
      <td>Sunucu ayarlarına bağlı</td>
    </tr>
    <tr>
      <td>Güvenlik</td>
      <td>Hassas veriye uygun değil</td>
      <td>HTTPS ile daha uygundur</td>
    </tr>
  </tbody>
</table>

<h2 id="güvenlik-altın-kuralı">Güvenlik altın kuralı</h2>

<p>İstemciden gelen hiçbir veri güvenilir kabul edilmemelidir. Kullanıcı sayı beklenen yere metin, HTML veya kötü niyetli SQL gönderebilir. Bu yüzden verileri <strong>doğrulamak</strong>, uygun biçime dönüştürmek ve veritabanı işlemlerinde prepared statement kullanmak gerekir.</p>

<p>Ayrıca isteğin metodunu kontrol etmek kodun niyetini belirginleştirir:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'REQUEST_METHOD'</span><span class="p">]</span> <span class="o">===</span> <span class="s1">'POST'</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Yalnızca POST ile gelen form burada işlenir.</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Özetle GET okunabilir ve paylaşılabilir sorguların, POST ise sunucuda değişiklik oluşturan form işlemlerinin doğal tercihidir. <code class="language-plaintext highlighter-rouge">$_GET</code> ve <code class="language-plaintext highlighter-rouge">$_POST</code> yalnızca veri taşıyan diziler değildir; doğru doğrulama, HTTPS ve güvenli çıktı yöntemleriyle birlikte sağlam PHP uygulamalarının temelini oluştururlar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="PHP" /><category term="GET ve POST" /><category term="Web Programlama" /><summary type="html"><![CDATA[Bir kullanıcı arama kutusuna kelime yazdığında, giriş formunu doldurduğunda veya bir bağlantıya tıkladığında tarayıcı ile sunucu arasında veri alışverişi gerçekleşir. PHP, gelen bu verilere erişebilmemiz için $_GET ve $_POST adlı süper global değişkenleri sunar. Adlarındaki “süper” ifadesi boşuna değildir; bu değişkenlere fonksiyonların içinden bile doğrudan erişilebilir.]]></summary></entry></feed>