<hr/>

<h2>
    <a name="use-case-8-ddns-updater-script-cli" href="#use-case-8-ddns-updater-script-cli"></a>
    Kullanım Durumu 8 — DDNS güncelleyici script (CLI)
</h2>

<p>Sunucunun public IP'sinin değişip değişmediğini kontrol eden ve Cloudflare DNS kaydını güncelleyen bir PHP CLI scripti:<br/></p>

<div class="highlight js-code-highlight">
    <pre class="highlight php"><code><span class="cp"><?php </span?>

// Çalıştırmak için: php ddns_updater.php

<span class=”nb>define(<span class=”s1>’CF_API_TOKEN’, <span class=”nb>getenv(<span class=”s1>’CF_API_TOKEN’));
<span class=”nb>define(<span class=”s1>’CF_ZONE_ID’, <span class=”nb>getenv(<span class=”s1>’CF_ZONE_ID’));
<span class=”nb>define(<span class=”s1>’CF_RECORD_ID’, <span class=”nb>getenv(<span class=”s1>’CF_RECORD_ID’));
<span class=”nb>define(<span class=”s1>’RECORD_NAME’, <span class=”s1>’home.yourdomain.com’);
<span class=”nb>define(<span class=”s1>’CACHE_FILE’, <span class=”s1>’/tmp/ddns_last_ip.txt’);

function <span class=”n>getCurrentIP(): ?string $ch = <span class=”nb>curl_init(<span class=”s1>’https://ipv4.ippubblico.org/);
<span class=”nb>curl_setopt_array(<span class=”nv>$ch, [
<span class=”no>CURLOPT_RETURNTRANSFER => <span class=”kc>true,
<span class=”no>CURLOPT_TIMEOUT => <span class=”mi>10,
]);
<span class=”nv>$ip = <span class=”nb>trim((<span class=”nv>$ch));
<span class=”nv>$ok = (<span class=”nv>$ch, <span class=”no>CURLOPT_HTTP_CODE) === <span class=”mi>200;
(<span class=”nv>$ch);
return <span class=”nv>$ok ? <span class=”nv>$ip : <span class=”kc>null;
}

function <span class=”n>getLastKnownIP(): ?string <span class=”p>{
return (<span class=”no>CACHE_FILE) ? ((<span class=”no>CACHE_FILE)) : <span class=”kc>null;
}

function <span class=”n>updateCloudflare(string <span class=”nv>$ip): bool $payload = <span class=”nb>json_encode([
<span class=”s1>’type’ => <span class=”s1>’A’,
<span class=”s1>’name’ => <span class=”no>RECORD_NAME,
<span class=”s1>’content’ => <span class=”nv>$ip,
<span class=”s1>’ttl’ => <span class=”mi>60,
]);

<span class="nv>$ch</span> <span class="o">=</span> <span class="nb>curl_init</span><span class="p">(</span><span class="nb>sprintf</span><span class="p">(</span>
    <span class="s1>'https://api.cloudflare.com/client/v4/zones/%s/dns_records/%s'</span><span class="p">,</span>
    <span class="no>CF_ZONE_ID</span><span class="p">,</span> <span class="no>CF_RECORD_ID</span>
<span class="p">));</span>
<span class="nb>curl_setopt_array</span><span class="p">(</span><span class="nv>$ch</span><span class="p">,</span> <span class="p">[</span>
    <span class="no>CURLOPT_RETURNTRANSFER</span> <span class="o">=&gt;</span> <span class="kc>true</span><span class="p">,</span>
    <span class="no>CURLOPT_CUSTOMREQUEST</span>  <span class="o">=&gt;</span> <span class="s1>'PUT'</span><span class="p">,</span>
    <span class="no>CURLOPT_POSTFIELDS</span>     <span class="o">=&gt;</span> <span class="nv>$payload</span><span class="p">,</span>
    <span class="no>CURLOPT_HTTPHEADER</span>     <span class="o">=&gt;</span> <span class="p">[</span>
        <span class="s1>'Authorization: Bearer '</span> <span class="mf">.</span> <span class="no>CF_API_TOKEN</span><span class="p">,</span>
        <span class="s1>'Content-Type: application/json'</span><span class="p">,</span>
    <span class="p">],</span>
    <span class="no>CURLOPT_TIMEOUT</span>        <span class="o">=&gt;</span> <span class="mi>10</span><span class="p">,</span>
<span class="p">]);</span>
<span class="nv>$response</span> <span class="o">=</span> <span class="nb>json_decode</span><span class="p>(</span><span class="nb>curl_exec</span><span class="p>(</span><span class="nv>$ch</span><span class="p">),</span> <span class="kc>true</span><span class="p">);</span>
<span class="nb>curl_close</span><span class="p>(</span><span class="nv>$ch</span><span class="p">);</span>

<span class="k">return</span> <span class="nv>$response</span><span class="p">[</span><span class="s1>'success'</span><span class="p">]</span> <span class="o">??</span> <span class="kc>false</span><span class="p">;</span>

}

// Ana
<span class=”nv>$current = <span class=”nf>getCurrentIP();
if (<span class=”nv>$current === <span class=”kc>null) {
echo <span class=”s1>'[ERROR] Public IP alınamadı’ . <span class=”kc>PHP_EOL;
exit1);
}

<span class=”nv>$last = <span class=”nf>getLastKnownIP();

if (<span class=”nv>$current === <span class=”nv>$last) {
echo {<span class=”nv>$current‘” . <span class=”kc>PHP_EOL;
exit0);
}

echo {<span class=”nv>$last‘ → ‘$current‘” . <span class=”kc>PHP_EOL;

if ((<span class=”nv>$current)) {
(<span class=”no>CACHE_FILE, <span class=”nv>$current);
echo {<span class=”nv>$current‘” . <span class=”kc>PHP_EOL;
} else {
echo <span class=”s1>'[HATA] DNS güncelleme başarısız’ . <span class=”kc>PHP_EOL;
exit1);
}

<p>Crontab'a ekleme:<br/></p>

<div class="highlight js-code-highlight">
    <pre class="highlight shell"><code><span class="k">*</span>/5 <span class="k">*</span> <span class="k">*</span> <span class="k">*</span> <span class="k">*</span> /usr/bin/php /usr/local/bin/ddns_updater.php <span class="o">&gt;&gt;</span> /var/log/ddns.log 2&gt;&amp;1

<hr/>

<h2>
    <a name="handling-rate-limits" href="#handling-rate-limits"></a>
    Rate Limit Yönetimi
</h2>

<p>API, aynı IP'den kısa bir süre içinde çok fazla istek gelirse <code>429 Too Many Requests</code> ve <code>Retry-After</code> başlığı ile geri döner:<br/></p>

<div class="highlight js-code-highlight">
    <pre class="highlight php"><code><span class="cp"><?php </span?>

function getPublicIPWithRetry(int <span class=”nv>$maxRetries = <span class=”mi>2): ?string <span class=”p>{
for (<span class=”nv>$attempt = <span class=”mi>0; <span class=”nv>$attempt <span class=”nv>$maxRetries; <span class=”nv>$attempt++) {
<span class=”nv>$ch = <span class=”nb>curl_init(<span class=”s1>’https://ipv4.ippubblico.org/);
<span class=”nb>curl_setopt_array(<span class=”nv>$ch, [
<span class=”no>CURLOPT_RETURNTRANSFER => <span class=”kc>true,
<span class=”no>CURLOPT_TIMEOUT => <span class=”mi>5,
<span class=”no>CURLOPT_HEADER => <span class=”kc>true,
]);
<span class=”nv>$response = (<span class=”nv>$ch);
<span class=”nv>$httpCode = (<span class=”nv>$ch, <span class=”no>CURLOPT_HTTP_CODE);
<span class=”nv>$headerSize = (<span class=”nv>$ch, <span class=”no>CURLOPT_HEADER_SIZE);
(<span class=”nv>$ch);

    <span class="k">if</span> <span class="p">(</span><span class="nv>$httpCode</span> <span class="o">===</span> <span class="mi>200</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nb>trim</span><span class="p">(</span><span class="nb>substr</span><span class="p>(</span><span class="nv>$response</span><span class="p">,</span> <span class="nv>$headerSize</span><span class="p">));</span>
    <span class="p">}</span>

    <span class="k">if</span> <span class="p">(</span><span class="nv>$httpCode</span> <span class="o">===</span> <span class="mi>429</span> <span class="o>&amp;&amp;</span> <span class="nv>$attempt</span> <span class="o"> <span class="nv>$maxRetries</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv>$headers</span> <span class="o">=</span> <span class="nb>substr</span><span class="p>(</span><span class="nv>$response</span><span class="p">,</span> <span class="mi>0</span><span class="p">,</span> <span class="nv>$headerSize</span><span class="p">);</span>
        <span class="nb>preg_match</span><span class="p>(</span><span class="s1>'/Retry-After:\s*(\d+)/i'</span><span class="p">,</span> <span class="nv>$headers</span><span class="p">,</span> <span class="nv>$matches</span><span class="p">);</span>
        <span class="nv>$wait</span> <span class="o">=</span> <span class="p">(</span><span class="n>int</span><span class="p">)(</span><span class="nv>$matches</span><span class="p">[</span><span class="mi>1</span><span class="p">]</span> <span class="o">??</span> <span class="mi>10</span><span class="p">);</span>
        <span class="nb>sleep</span><span class="p>(</span><span class="nv>$wait</span><span class="p">);</span>
        <span class="k">continue</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="kc>null</span><span class="p">;</span>

}

<hr/>

<h2>
    <a name="quick-reference" href="#quick-reference"></a>
    Hızlı Referans
</h2>

<div class="table-wrapper-paragraph">
    <table>
        <thead>
            <tr>
                <th>İhtiyaç</th>
                <th>Uç Nokta</th>
                <th>Yanıt</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Yalnızca IPv4</td>
                <td><code>https://ipv4.ippubblico.org/</code></td>
                <td><code>203.0.113.42</code></td>
            </tr>
            <tr>
                <td>Yalnızca IPv6</td>
                <td><code>https://ipv6.ippubblico.org/</code></td>
                <td><code>2001:db8::1</code> veya <code>NONE</code></td>
            </tr>
            <tr>
                <td>Her iki protokol</td>
                <td><code>https://ippubblico.org/?text=1</code></td>
                <td><code>IPv4: x\nIPv6: x</code></td>
            </tr>
            <tr>
                <td>Tam coğrafi konum</td>
                <td><code>https://ippubblico.org/?api=1</code></td>
                <td>Ülke, şehir, ISP ile JSON</td>
            </tr>
            <tr>
                <td>Yerelleştirilmiş coğrafi</td>
                <td><code>https://ippubblico.org/?api=1&amp;lang=ja</code></td>
                <td>Japonca şehir/ülke</td>
            </tr>
        </tbody>
    </table>
</div>

<p>Tam dokümantasyon: <a href="https://ippubblico.org/docs.html" target="_blank" rel="noopener noreferrer">ippubblico.org/docs.html</a><br/>Kod örnekleri: <a href="https://github.com/ippubblico/examples" target="_blank" rel="noopener noreferrer">github.com/ippubblico/examples</a></p>

<hr/>

<h2>
    <a name="conclusion" href="#conclusion"></a>
    Sonuç
</h2>

<p>PHP'nin cURL uzantısı, her kullanım durumunu temiz bir şekilde karşılıyor — skriptler ve DDNS araçları için düz metin, web uygulamaları için JSON ve birkaç düzine satır içinde gerekli olan tüm önbellekleme ve yeniden deneme mantığı. Laravel middleware'leri ve WordPress kod parçaları, her istekte API'yi çarpmamak için sonuçları doğru bir şekilde önbelleğe alarak üretim için hazır başlangıç noktalarıdır.</p>

<hr/>

<p><em>Bir PHP projesinde IPPubblico kullanıyor musunuz? Kullanım durumunuzu yorumlarda paylaşın.</em></p>

Kaynak: Orijinal Makale

Bu Makaleyi Paylaş