Web Hosting & cPanel

    PHP Dosyası Açılmıyor, İndiriliyor veya Kod Olarak Görünüyor: Çözümü

    PHP dosyalarının çalışmak yerine indirilmesinin veya kaynak kod olarak görünmesinin altı sebebini teşhis sırasıyla anlatır.

    12 dk okuma Güncellendi: 18 Ağustos 2026

    Dosyaları FTP ile yüklediniz, tarayıcıda siteadi.com/index.php adresini açtınız ve sayfa gelmedi. Bunun yerine Chrome'un alt köşesinde bir indirme çubuğu belirdi: index.php. Ya da daha kötüsü, sayfa açıldı ama ekranda sitenizin kendisi değil, <?php require_once 'config.php'; $db = new mysqli(... satırları duruyor. Her iki durumda da olan şey aynı: web sunucusu o dosyayı PHP yorumlayıcısına hiç vermedi, ham dosyayı olduğu gibi tarayıcıya yolladı.

    Bu semptom Türkçe forumlarda sürekli sorulur ve verilen cevap genellikle tek satırlıktır: ".htaccess'i sil" ya da "PHP sürümünü değiştir". İkisi de bazen işe yarar, ama neden işe yaradığını bilmeden yapıldığında ya sorun geri gelir ya da bu sefer siteniz 500 hatası verir. Oysa altı farklı sebep var ve hangisi olduğunu bulmak beş dakika sürüyor.

    Aşağıda önce iki semptomu birbirinden ayıracağız — çünkü kaynak kodun ekranda görünmesi acil bir güvenlik olayıdır, indirilmesi ise sadece bir yapılandırma hatasıdır. Sonra bir tek testle sorunu dosyanızdan mı yoksa sunucudan mı kaynaklandığını netleştirecek, ardından altı sebebi teşhis sırasıyla tek tek eleyeceğiz.

    Kod Ekranda Görünüyorsa Önce Erişimi Kesin#

    Bu bölüm sırasıyla en sonda olmalıydı ama en başa aldım, çünkü zaman baskısı var. Eğer tarayıcıda PHP kodunuzun kendisini okuyabiliyorsanız, sizin okuduğunuzu herkes okuyabiliyor demektir. WordPress kullanıyorsanız wp-config.php dosyasında veritabanı kullanıcı adı, şifresi ve tuz anahtarları düz metin olarak durur. Özel yazılım kullanıyorsanız API anahtarları, SMTP şifreleri ve ödeme sağlayıcı bilgileri aynı dosyalardadır.

    Sıra şudur: önce kapat, sonra düzelt. Site yayında kalırken hata ayıklamaya çalışmak, arama motoru botlarının o kodu indekslemesine ve tarayıcı önbelleklerine yerleşmesine yeterli süreyi verir.

    # public_html/.htaccess dosyasının EN ÜSTÜNE geçici olarak ekleyin
    # Yalnızca kendi IP'nizden erişime izin verir
    Require ip 203.0.113.45
    

    Kendi IP adresinizi bir arama motoruna "ip adresim" yazarak öğrenebilirsiniz. Apache 2.2 kullanan çok eski bir sunucudaysanız Require yerine Order deny,allow sözdizimi gerekir; sunucunuz hangisini kabul ediyorsa onu kullanın.

    Erişimi kestikten sonra ikinci adım, ifşa olan sırları değiştirmektir. Sorunu çözüp siteyi geri açmak sızan şifreyi geri getirmez:

    1. Veritabanı kullanıcısının şifresini değiştirin ve yeni şifreyi wp-config.php veya yapılandırma dosyanıza yazın.
    2. Yapılandırmada duran tüm API/SMTP anahtarlarını ilgili panellerden yenileyin.
    3. WordPress'te wp-config.php içindeki sekiz AUTH_KEY/SALT satırını yenileriyle değiştirin — bu, açık kalmış tüm oturumları düşürür.
    4. Sunucu erişim günlüklerinde o dosyaya kimlerin istek attığına bakın: grep 'wp-config' ~/access-logs/siteadi.com

    Ne kadar süre açıkta kaldığını bilmiyorsanız, en kötü senaryoyu varsayın. Kodun görünmesi sadece bir görüntü hatası değildir.

    İki Farklı Semptom, İki Farklı Sebep#

    Bu iki davranış aynı kök nedene (PHP çalışmıyor) dayansa da sunucunun gönderdiği Content-Type başlığı farklıdır ve bu fark size teşhiste yol gösterir.

    GördüğünüzSunucunun gönderdiği Content-TypeAnlamı
    Dosya indiriliyorapplication/x-httpd-php veya application/octet-streamSunucu uzantıyı tanıyor ama işleyecek bir modül yok
    Kod ham metin olarak ekrandatext/plainBir yerde .php düz metne eşlenmiş
    Sayfa boş, kaynağa bakınca kod vartext/htmlTarayıcı <?php ... ?> bloğunu bilinmeyen HTML etiketi sanıp gizliyor

    Üçüncü satır özellikle kafa karıştırıcıdır: sayfa bomboş açılır, insanlar "beyaz ekran hatası" sanır ve PHP hata günlüklerini kurcalamaya başlar. Oysa Ctrl+U ile kaynağı görüntülediğinizde kodun tamamı oradadır. Gerçek beyaz ekran hatasında ise kaynak da boştur; ikisini karıştırmayın.

    Hangi başlığın geldiğini tahmin etmek yerine sorun:

    curl -sI https://siteadi.com/index.php | grep -i 'content-type\|HTTP/'
    

    Beklenen sağlıklı çıktı Content-Type: text/html; charset=UTF-8 olmalıdır. Yukarıdaki tablodan başka bir şey gördüyseniz teşhis doğrulanmıştır: PHP işlenmiyor.

    Ayırt Edici Test: Boş Bir test.php Dosyası#

    Sorunun kendi kodunuzdan mı yoksa sunucu yapılandırmasından mı geldiğini anlamanın en hızlı yolu, hiçbir bağımlılığı olmayan tek satırlık bir dosya denemektir. Karmaşık bir uygulamanın hangi satırında takıldığını aramadan önce bunu yapın.

    public_html içine phptest.php adında bir dosya oluşturun ve içine yalnızca şunu yazın:

    <?php
    phpinfo();
    

    Sonra https://siteadi.com/phptest.php adresini açın. Üç olası sonuç var ve her biri sizi farklı bir bölüme gönderir:

    • Mavi-mor tablolu PHP bilgi sayfası geldi: Sunucuda PHP çalışıyor. Sorun bu dizine ya da bu dosyaya özgüdür — doğrudan .htaccess ve dizin bölümlerine gidin.
    • Bu dosya da indirildi veya kodu göründü: PHP hesap genelinde çalışmıyor. Sürüm ataması ve handler bölümlerine bakın.
    • 404 Not Found aldınız: Dosyayı yanlış dizine koydunuz. Alan adının kök dizinini teyit edin; public_html nedir yazısı hangi alan adının hangi klasöre bağlandığını anlatıyor.

    Test bittiğinde phptest.php dosyasını mutlaka silin. phpinfo() çıktısı sunucunun tam yolunu, açık modülleri, PHP sürümünü ve yapılandırma yollarını listeler; bu bilgi bir saldırgan için hazır keşif raporudur.

    Sebep 1: .htaccess'teki Yanlış AddHandler veya AddType Satırı#

    Bu, listedeki en yaygın sebeptir ve neredeyse her zaman aynı hikâyeden çıkar: siteyi başka bir hosting firmasından taşıdınız, eski sunucudaki .htaccess dosyasını olduğu gibi kopyaladınız. O dosyada eski sunucunun PHP kurulumuna özgü bir satır vardı ve yeni sunucuda o handler adı diye bir şey yok.

    Klasik suçlular şunlardır:

    # Eski cPanel sunucularından taşınan satırlar — yeni sunucuda karşılığı yok
    AddHandler application/x-httpd-php5 .php
    AddType application/x-httpd-php .php .php5
    AddHandler x-httpd-php53 .php
    

    Apache bu satırı okuduğunda .php uzantısını application/x-httpd-php5 adlı bir işleyiciye bağlar. Yeni sunucuda o isimde bir işleyici tanımlı değilse Apache bunu bir handler değil, bir MIME türü gibi ele alır ve dosyayı o içerik tipiyle olduğu gibi gönderir. Tarayıcı application/x-httpd-php5 türünü nasıl göstereceğini bilemez, indirir. Handler ile MIME türü arasındaki bu ayrım cPanel Apache Handlers yazısında ayrıntılı anlatılıyor.

    Çözüm, bu satırları silmektir. Modern cPanel sunucularında PHP eşlemesini panel kendisi yönetir; .htaccess içine elle handler yazmanız gerekmez.

    1. Dosya Yöneticisi'nde public_html/.htaccess dosyasını açın. Görünmüyorsa gizli dosyaları gösterme adımları burada.
    2. Düzenlemeden önce .htaccess.yedek adıyla bir kopya alın.
    3. İçinde AddHandler veya AddType geçen ve php kelimesi içeren tüm satırları silin.
    4. cPanel'in kendi ürettiği blok varsa ona dokunmayın — o blok şu yorumla başlar ve panel tarafından yönetilir:
    # php -- BEGIN cPanel-generated handler, do not edit
    AddHandler application/x-httpd-ea-php83 .php .php8 .phtml
    # php -- END cPanel-generated handler, do not edit
    

    Buradaki ea-php83 adı EasyApache 4'ün kurduğu PHP 8.3 paketini gösterir. Sunucuda o sürüm kurulu değilse bu blok da aynı sorunu üretir — bir sonraki bölüm tam olarak bunu çözüyor.

    Dosyayı kaydettikten sonra tarayıcıyı Ctrl+F5 ile yenileyin. Hâlâ indiriliyorsa .htaccess dosyasını geçici olarak .htaccess.kapali adına çevirip tekrar deneyin: sorun kalkıyorsa suçlu kesinlikle bu dosyadadır ve satırları tek tek geri ekleyerek hangisi olduğunu bulabilirsiniz.

    Sebep 2: Hesaba PHP Sürümü Atanmamış Olması#

    Paylaşımlı hosting hesaplarında sık görülen ikinci senaryo: hesap yeni açılmış ya da sunucuda bir PHP sürümü kaldırılmış, alan adı da "inherit" (devral) durumunda kalmış ve devralacağı bir varsayılan yok. Sonuç, .php uzantısı için hiçbir işleyicinin tanımlı olmamasıdır.

    cPanel'de kontrol etmek için:

    1. Software → MultiPHP Manager menüsünü açın.
    2. Alan adınızın satırındaki PHP Version sütununa bakın. inherit yazıyorsa ya da boşsa sorun budur.
    3. Alan adının solundaki kutuyu işaretleyin, sağ üstteki açılır menüden somut bir sürüm seçin (ea-php82 veya ea-php83 gibi) ve Apply deyin.

    CloudLinux çalıştıran sunucularda ikinci bir katman daha vardır: Select PHP Version (PHP Selector). MultiPHP'de sürüm atanmış olsa bile Selector tarafında "native" seçiliyken sunucudaki native sürüm kaldırılmışsa aynı sonucu alırsınız. İki aracın nasıl örtüştüğünü CloudLinux PHP Selector yazısı açıklıyor.

    Panelsiz bir sunucudaysanız durum farklıdır. Apache'de mod_php ya da php-fpm modülünün gerçekten yüklü olduğunu doğrulayın:

    # Apache'de PHP ile ilgili modüller yüklü mü?
    apachectl -M 2>/dev/null | grep -i php
    
    # PHP-FPM servisi çalışıyor mu?
    systemctl status php8.3-fpm --no-pager
    
    # Apache'nin PHP yapılandırması etkin mi (Debian/Ubuntu)
    ls -l /etc/apache2/mods-enabled/ | grep php
    

    grep -i php hiçbir şey döndürmüyorsa Apache PHP'yi tanımıyor demektir. Debian/Ubuntu'da a2enmod proxy_fcgi setenvif && a2enconf php8.3-fpm && systemctl reload apache2 komutu tipik çözümdür; kurulu sürüm numarasını kendi sisteminize göre değiştirin. Sürüm seçiminin genel mantığı için PHP sürüm yönetimi yazısına bakabilirsiniz.

    Sebep 3: Dosya Adı Gerçekte .php Değil#

    Bu sebep basit göründüğü için genelde en son akla gelir, oysa özellikle Windows'tan dosya yükleyenlerde çok sık çıkar. Windows Gezgini varsayılan olarak "bilinen dosya türlerinin uzantılarını gizle" ayarıyla gelir. Not Defteri ile bir dosya oluşturup index.php adını verdiğinizde Windows arka planda .txt ekler ve gerçek ad index.php.txt olur. Gezgin size yine index.php gösterir.

    Sunucuda gerçek adı doğrulayın. cPanel Dosya Yöneticisi listesi de bazen yanıltır; SSH'ınız varsa kesin cevabı şu verir:

    ls -la public_html/ | grep -i php
    

    Çıktıda index.php.txt, index.php.html ya da sondaki boşluk gibi bir anormallik varsa yeniden adlandırın:

    mv 'public_html/index.php.txt' public_html/index.php
    

    Aynı aileden ikinci bir tuzak, uzantının büyük harfli olmasıdır. Linux dosya sistemleri büyük-küçük harfe duyarlıdır ve Apache'nin .php eşlemesi varsayılan olarak .PHP uzantısını kapsamaz. Bir Windows makinesinden taşınan Index.PHP dosyası bu yüzden işlenmez. Uzantıları küçük harfe çevirin.

    Sebep 4: Dosya, PHP Çalıştırılmayan Bir Dizinde#

    Bazen dosyanın kendisinde de sunucu genelinde de sorun yoktur; sorun dosyanın nerede durduğudur. En sık karşılaşılan üç durum:

    Statik olarak yapılandırılmış bir alt alan adı. Bir alt alan adını bir CDN'e ya da statik dosya barındırmaya ayırdıysanız, o sanal konak için PHP işleme kapatılmış olabilir. Alt alan adları farklı sunuculara da yönlendirilebilir; alt alan adını farklı sunucuda barındırma bu ayrımı anlatıyor.

    Bir güvenlik kuralıyla PHP'si kapatılmış yükleme klasörü. WordPress güvenlik eklentileri wp-content/uploads içine şu içerikte bir .htaccess bırakır:

    <Files "*.php">
        Require all denied
    </Files>
    php_flag engine off
    

    Bu kural bilinçli ve doğrudur — yüklenen bir dosyanın çalıştırılmasını engeller. Ama meşru bir PHP dosyasını yanlışlıkla o klasöre koyduysanız, kod ham olarak servis edilir. Bu tür bir dosyayı klasörün dışına taşıyın, kuralı gevşetmeyin.

    Kök dizin sandığınız yerin aslında kök olmaması. Alan adı public_html/siteadi klasörüne bağlıyken dosyayı public_html içine koyduysanız, gördüğünüz sayfa hiç beklediğiniz dosya olmayabilir.

    Hangi dizinde olduğunuzu kesinleştirmek için test dosyanızın içeriğini geçici olarak şu satırla değiştirip çalıştırın:

    <?php
    echo __FILE__;
    

    Ekrana basılan tam yol, sunucunun gerçekten hangi dosyayı okuduğunu gösterir. Beklediğiniz yol değilse aradığınız sorun PHP değil, dizin eşlemesidir.

    Sebep 5: Nginx'te .php location Bloğu Yok#

    Nginx, Apache'den yapısal olarak farklı davranır ve bu fark tam olarak burada acı verir. Apache'de PHP eşlemesi çoğunlukla sunucu geneline kurulur ve .htaccess ile ince ayar yapılır. Nginx'te ise .htaccess diye bir şey yoktur ve PHP eşlemesi her sanal konakta ayrı ayrı yazılmak zorundadır. Bloğu yazmayı unuttuysanız Nginx .php dosyasını sıradan bir statik dosya sayar ve default_type ne ise onunla gönderir — varsayılan application/octet-stream olduğu için tarayıcı dosyayı indirir.

    Eksik olan blok tipik olarak şudur:

    server {
        listen 443 ssl;
        server_name siteadi.com;
        root /var/www/siteadi/public;
        index index.php index.html;
    
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
    
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        }
    }
    

    Değişikliği yaptıktan sonra yapılandırmayı doğrulamadan yeniden yüklemeyin:

    nginx -t && systemctl reload nginx
    

    Soket yolunun doğru olduğundan emin olun; ls /run/php/ komutu sunucudaki gerçek soket adını gösterir. Blok var ama hâlâ indiriliyorsa iki şeye bakın: fastcgi_pass hedefi ayakta mı (systemctl status php8.3-fpm), ve daha spesifik bir location bloğu isteği önce yakalayıp statik olarak sunuyor mu. Nginx ile PHP-FPM ilişkisinin ayrıntıları için Nginx PHP-FPM yapılandırması yazısına bakın.

    Sebep 6: Handler Çakışması ve Ardından Gelen 500 Hatası#

    Son sebep, aslında birinci sebebi "çözmeye" çalışırken üretilen bir yan etkidir. İnternette bulunan çözümlerin çoğu .htaccess dosyasına elle bir handler satırı eklemenizi söyler. Sunucu suPHP, FCGId ya da PHP-FPM ile çalışıyorsa bu satır izinsiz kabul edilir ve dosya artık indirilmez — bunun yerine 500 Internal Server Error verir.

    Belirti şudur: bir satır eklediniz, sorun görünüşte değişti ama düzelmedi. Sunucunun hata günlüğü kesin cevabı verir:

    tail -n 30 ~/logs/siteadi.com.error.log
    tail -n 30 /var/log/apache2/error.log
    

    .htaccess: AddHandler not allowed here benzeri bir satır görüyorsanız, o yönergeyi kullanma yetkiniz yok demektir. Doğru hamle satırı silmek ve sürüm atamasını panelden yapmaktır. 500 hatasının diğer nedenleri için 500 Internal Server Error çözümü yazısı ayrı bir kontrol listesi sunuyor.

    Aynı bölümde işinize yarayacak bir ayrım daha var: sorun düzeldikten sonra sayfa gelmeye başladıysa ama içerik eksikse, artık PHP çalışıyor ve karşınızda sıradan bir uygulama hatası var demektir. O aşamada hataları ekrana basmak yerine günlüğe yazdırmak için PHP hata raporlama ayarlarını kullanın.

    Sorunu Kalıcı Kapatmak İçin Son Kontroller#

    Site düzeldiğinde bitmiş saymadan önce üç şeyi doğrulayın. Bu üç kontrol, aynı sorunun bir hafta sonra başka bir dizinde geri gelmesini engeller.

    • Tüm dizinleri tarayın. Kök dizindeki .htaccess düzeldi diye alt klasörlerdekiler düzelmez: grep -rn 'AddHandler\|AddType' public_html/ --include='.htaccess'
    • Alan adı ve alt alan adlarını ayrı ayrı test edin. MultiPHP Manager'da her giriş bağımsızdır; siteadi.com düzelmişken blog.siteadi.com hâlâ inherit durumunda kalabilir.
    • Sertifika ve yönlendirme sonrası tekrar bakın. HTTPS yönlendirmesi devredeyse curl -sI testini https:// üzerinden yapın; HTTP üzerinden gelen yanıt yalnızca 301 yönlendirmesini gösterir ve gerçek Content-Type başlığını gizler.

    Son olarak test dosyalarınızı temizleyin. phptest.php, info.php, .htaccess.yedek gibi dosyalar sunucuda kalırsa hem bilgi sızdırır hem de bir sonraki sorun gidermede sizi yanıltır.

    Sıkça Sorulan Sorular#

    PHP dosyam indiriliyor, sunucuda arıza mı var?#

    Neredeyse hiçbir zaman. Bu belirti sunucunun çöktüğünü değil, .php uzantısını PHP yorumlayıcısına bağlayan eşlemenin eksik ya da hatalı olduğunu gösterir. Sunucu tamamen sağlıklıdır ve dosyayı size sadık şekilde teslim eder; yanlış olan, onu teslim etmeden önce çalıştırması gerektiğini bilmemesidir. Bu yüzden çözüm de sunucuyu yeniden başlatmak değil, handler veya sürüm atamasını düzeltmektir.

    phpinfo çalışıyor ama sitem hâlâ indiriliyor, neden?#

    Bu, sorunun sunucu genelinde değil dizin ya da dosya düzeyinde olduğunun kanıtıdır. Üç yere bakın: sitenizin bulunduğu klasördeki .htaccess dosyasına, dosya adının gerçekten .php ile bitip bitmediğine ve alan adının hangi klasöre bağlı olduğuna. phptest.php dosyasını sorunlu dosyayla aynı klasöre koyup tekrar deneyin; orada da indiriliyorsa suçlu o klasörün .htaccess dosyasıdır.

    .htaccess dosyasını tamamen silmek güvenli mi?#

    Test amacıyla silmek yerine adını değiştirin: .htaccess.kapali gibi. Silmek geri dönüşü olmayan bir işlemdir ve o dosyada WordPress kalıcı bağlantı kuralları, HTTPS yönlendirmesi, hata sayfaları ve IP engellemeleri duruyor olabilir. Adını değiştirdiğinizde Apache dosyayı görmez ama içerik korunur; sorun kalkarsa satırları tek tek geri ekleyerek suçluyu bulabilirsiniz.

    Kodum göründüğüne göre veritabanı şifremi değiştirmem şart mı?#

    Evet. Kodun tarayıcıda görünebildiği süre boyunca herkes aynı içeriği okuyabiliyordu ve arama motoru botları da o sayfayı çekmiş olabilir. Şifreyi değiştirmek maliyetsizdir; değiştirmemek ise gelecekteki bir sızıntının hazır anahtarını sunucuda bırakmak demektir. Aynı işlemi API anahtarları, SMTP şifresi ve WordPress kullanıyorsanız oturum tuz anahtarları için de tekrarlayın.

    Sadece bazı sayfalarda oluyorsa sebep ne olabilir?#

    Bu durumda genelde tek bir dosya ya da tek bir klasör hedefli bir kural vardır. Yükleme klasörlerine güvenlik eklentilerinin bıraktığı php_flag engine off satırı en yaygın örnektir. İkinci ihtimal, o dosyanın adının gerçekte farklı olmasıdır — büyük harfli .PHP uzantısı ya da sonda gizli bir .txt. Sorunlu URL'nin tam yolunu alıp o dizindeki .htaccess dosyasına ve ls -la çıktısına bakmak ikisini de birkaç saniyede ayırır.

    Kaynak kodunun görünmesiyle beyaz ekran hatası aynı şey mi?#

    Hayır ve karıştırmak sizi yanlış yöne götürür. Beyaz ekran hatasında PHP çalışır, bir yerde ölümcül hata alır ve hiçbir çıktı üretmez; sayfanın kaynağı da boştur. Kod görünmesi durumunda ise PHP hiç çalışmamıştır ve Ctrl+U ile bakıldığında dosyanın tamamı kaynak içinde durur. Ayrımı yapmanın en hızlı yolu kaynağı görüntülemektir: boşsa uygulama hatası, doluysa yapılandırma hatası arıyorsunuz.

    PHPSorun GidermeApache

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.