İyinet'e Hoşgeldiniz!

Türkiye'nin En Eski Webmaster Forum'una Hemen Kayıt Olun!

Kayıt Ol!

Php Optimizasyon İçin İpuçları

...::LorD::...

0
İyinet Üyesi
Katılım
27 Aralık 2007
Mesajlar
2,109
Reaction score
2
Konum
cHeteM
merhabalar

php optimizasyonu için ipuçlarını hep birlikte makale haline getirerek arkadaşlara yardımcı olalım ve bilgilerimizi tazeleyelim istedim. bildiğim bir kaç bilgiyi paylaşayım.

1. php kasılmaması için scriptinizde <?php ?> az açıp kapayın.

2. tablodan veri çekerken SELECT id,konu FROM table

şeklinde size lazım olan sütunları çekin

3. sürekli tablodan veri çekmek yerine bu işi biraz da cookie ve sessionlara atayın mesela üyeye

Hoşgeldin Ad Soyad

yazdırılacak Ad Soyad verisini sürekli tablodan çekeceğimize tablodan bir kere çekeriz ve COOKIE oluştururuz böylece sorgu sayımız azalır

aklıma şimdilik gelenler bunlar geldikçe yazarım arkadaşlarda eklerlerse yararlı olurlar teşekkürler
 

Angelo

0
İyinet Üyesi
Katılım
13 Aralık 2004
Mesajlar
9,603
Reaction score
111
Konum
AZ
Çok temel bir cache sistemi örneği verelim o halde.

Bu örnekte, herhangi bir kaynaktan çeşitli işlemlerden geçirilip sunulan verilerin, her sayfa çağrılışında işlem yapmak yerine, kayıt ederek, kayıttan kullanıcıya sunulmasını hedefliyoruz.

Örnekte düz kod olarak örnek vereceğim, kendi uygulamanıza göre fonksiyon yazıp nerede/nasıl uygulayacağınız kendi tasarrufunuzda. Örnekte yer alan kullanıcı girdilerini güvenlik gereği filtrelemek hususlarına da değinmeyeceğim.

1. Adım: Cache dosyasını ve süresini tanımlamak.

Örnek:
PHP:
$cachefile = 'cache/benimsayfam.dat';
$cachetime = 60 * 60 * 24  // 24 saat

Tabii her sayfa için örnekteki gibi bir isim belirtmek zor olacaktır. Bir kategori sayfanız olduğunu düşünelim. Bu kategori sayfası URL'den kategori ID'sini alıyor olsun. (kategori.php?katid=12 gibi)

PHP:
$cachefile = 'cache/kategori-'.$_GET['katid'].'.dat';
$cachetime = 60 * 60 * 24  // 24 saat

Burada her bir kategori icin cache dosyasi tanimlamis olacak script. Cagirdiniz kategori 25 ise, kategori-25.dat dosyasını tanımlamış olduk script içinde.

24 saatlik bir cache süresi tanımladık. Herhangi bir zorunlu hal olmadığı takdirde, 24 saat sürece cache'den dosya okutulacak, database'den değil. Bu isteğinize, veri yapınızın güncellenme süresine göre değişebilir.

2. Adım: Cache dosyasını kontrol etmek

PHP:
       if (file_exists($cachefile)) {
       // cache dosyasi mevcut.
       $mtime = filemtime($cachefile);   // dosyanın son değiştirilme zamani 
            
              if (time() - $cachetime < $mtime) {
              // dosya cache suresi limitinden daha once degistirildiyse uygun
              $data = file_get_contents($cachefile);
              echo $data;
              echo '<!-- Cached kopya. Yaratilis zamani: '.date ("F d Y H:i:s.", $mtime).' -->';
              exit;
              }
        }

Bu script, oncelikle dosyanın varlığını kontrol edecek, daha sonra son değiştirilme zamanı belirttiğimiz cache süresinden sonra ise, dosyayı kayıttan okuyup scriptin geri kalan kismini (database islemleri vb) bu kullanici icin tekrar tekrar calistirmayacaktir.

3. Adım: Cache dosyasının hazırlanması

Eğer sistemde oluşmuş bir cache kayıt yoksa, tabi doğal olarak yukarıdaki kod daki if döngüsü yanlış sonuçlanıp, sizin scriptinizin normal işleyiş kısmına geçecektir. Yapmamız gereken bu adımlar bittikten sonra kayıt altına alınmasını istediğimiz kısımın en sonuna cache dosyasını hazırlatmaktır. Veriyi kaydetmek için kayıt altına alınacak kısmın en tepesine de çıktı kontrol fonksiyonlarından birini yerleştiriyoruz.

PHP:
ob_start();  //output buffer i aciyoruz, kayit icin

// normal islemleriniz

// script ve database okumalari vs..

// kayit altina alinacak kismin sonuna gelindiginde

$icerik = ob_get_contents();   // ob_start() ile basladigimiz alandan bu ana kadar ki ciktiyi degiskene aldik.

ob_end_flush();  // sifonu cek. ciktiyi ekrana bosalt. 

if ($cachefile) {
$f = fopen($cachefile,'w+');  // dosyayı yazmak icin ac, icerigi sifirla.
fwrite($f,$icerik);
fclose($f);
// dosyaya kayit ettigimiz icerigi yazdik.
}


Icerik yazilip dosya kapatilinca (cache dizininin chmod ayarı yazılabilir olmalı), tepede belirttigimiz cache dosyasi kaydedilmis oldu, bir sonraki refresh'te db islemleri yapilmayacak, dosya kayittan okunup kullaniciya sunulacaktir.


Birlestirince

PHP:
// script basi islemleriniz

// kayit edilmesini istediginiz alanin basi.

$cachefile = 'cache/kategori-'.$_GET['id'].'.dat';
$cachetime = 60 * 60 * 24  // 24 saat

       if (file_exists($cachefile)) {
       // cache dosyasi mevcut.
       $mtime = filemtime($cachefile);   // dosyanın son değiştirilme zamani 
            
              if (time() - $cachetime < $mtime) {
              // dosya cache suresi limitinden daha once degistirildiyse uygun
              $data = file_get_contents($cachefile);
              echo $data;
              echo '<!-- Cached kopya. Yaratilis zamani: '.date ("F d Y H:i:s.", $mtime).' -->';
              exit;
              }
        }


ob_start();

// DATABASE ISLEMLERI VB. KAYIT ALTINA ALINACAK ISLEMLER..

$icerik = ob_get_contents();   // ob_start() ile basladigimiz alandan bu ana kadar ki ciktiyi degiskene aldik.

ob_end_flush();  // sifonu cek. ciktiyi ekrana bosalt. 

if ($cachefile) {
$f = fopen($cachefile,'w+');  // dosyayı yazmak icin ac, icerigi sifirla.
fwrite($f,$icerik);
fclose($f);
// dosyaya kayit ettigimiz icerigi yazdik.
}

// kayit edilmesini istediginiz alanin sonu


// script sonu islemleriniz


Olasi sorun: 24 saat olarak tarif edilmis bir cache dosyasinda bazen kullanicilar icerige mudahale ediyorlar, bu durumda cache eskimis olacak, kullanici belki de yaptigi update islemini goremeyecek. Ornegin scriptinizde yorumlar kismi var, cache'e almak istediniz. Ancak bir kisi yeni yorum postaladi. Cache'den okursa goremeyecek yeni yorumu.

Bu gibi durumlar icin farkli cozumler kullanilabilir. Update islemini yapan script parcacigina, update yapildigina dair bir session bilgisi atabiliriz.

PHP:
// cache dosyasindaki verilere direk mudahele edecek
// kullanici islemleri
// update vs..

$_SESSION['forcecache']['bolge'] = 1;

"Bolge" isimli alanin cache bilgisini update edin diye session bilgisi atadik. Dinamik olarak bolge adini degistirebilirsiniz.

Daha sonra cache dosyasinin kontrol edildigi bolgeye bir sart daha ekleriz. Bolge alani forcecache olarak tanimlanmis mi diye. Bu durumda bolgeye 1 atadiginiz icin if sarti false donecek ve script cache'i okuyamayacak, mecburen db islemleri yapilip, cache script sonunda yeniden fwrite() ile guncellenecektir.

PHP:
if (file_exists($cachefile) AND $_SESSION['forcecache']['bolge'] != '1') {
//
}

Bunu yaptiginizda fwrite() isleminden sonra SESSION bilgisini tekrar sifirlayiniz. Aksi takdirde, session bilgisi sayesinde her refresh'de cache'i force eder.

PHP:
fwrite($f,$icerik);
fclose($f);
unset($_SESSION['forcecache']['bolge']);   // cache'i bir kere guncelledik, cache zorlama bilgisini kapat.

Ek olarak Unix dosya sisteminde diskte, bellekten sanal bir alan yaratıp disk olarak mount edebiliyorsunuz. Bu durumda cache dosyalarını isterseniz bellekte de tutma şansınız var. Okuma/yazma hızı fark ediyor.

100K hitli bir e-store'da çok basit bu tarz bir uygulama kullanarak, Apache'ye gelen hitler saniye başı ortalama 600 iken, SQL server'a gelen hiti saniye başı 10'lara kadar düşürmüştük. Server load'unda muazzam bir farkedilirlik ortaya çıktı.

Kaynak gostererek yayinlayabilirsiniz.
 

...::LorD::...

0
İyinet Üyesi
Katılım
27 Aralık 2007
Mesajlar
2,109
Reaction score
2
Konum
cHeteM
çok güzel bir makale emek döküp bu makaleyi hazırladığınız için teşekkürler muhakkak işime yarayacaktır tekrar teşekkürler
 

CMYLMZ

0
İyinet Üyesi
Katılım
8 Aralık 2006
Mesajlar
1,775
Reaction score
0
Konum
Forumdan ayrıld
oldukça yararlı bir paylaşım olmuş
yazan tüm arkadaşları kutluyorum.
şirketteki Coder arkadaşlarla paylaştım.

gelen sorulardan birisi şu oldu;
bir kullanıcının ikinci bir sayfa açması nasıl engellenebilir ?
yani Crtl+N yaparak ikinci bi sayfa açarsa ya onu dışarı atmak yada boş bir sayfaya düşürmek için neler yapılabilir ?

Teşekkürler
 

...::LorD::...

0
İyinet Üyesi
Katılım
27 Aralık 2007
Mesajlar
2,109
Reaction score
2
Konum
cHeteM
bence şöyle bir şey yapılabilir sorduğunu bende merak ediyordum şimdi aklıma bir şey geldi

her sayfada session oluşturulur ve tablo da üyenin session sütunu her sayfada güncellenir kişinin sessionu ile tablodaki session'u uyuşmadığı takdirde bir yere yönlendirirsiniz veya sessionları sıfırlarsınız haliyle son açtığı sayfa aktif olacak ilk açtığı sayfa düşecektir.

kıdemlı arkadaşlar daha iyi bir şekilde izah edebilirler veya daha iyi bir yöntem tavsiye ederler diye düşünüyorum
 

...::LorD::...

0
İyinet Üyesi
Katılım
27 Aralık 2007
Mesajlar
2,109
Reaction score
2
Konum
cHeteM
arkadaşlar aklına başka ipucu gelen arkadaşlar var mı burdaki ipuçlarını göz önünde bulundurarak yeni bir script yazacağım.
 

*siber*

0
İyinet Üyesi
Katılım
20 Temmuz 2005
Mesajlar
2,014
Reaction score
1
Konum
about:blank
echo kullanırken tek tırnak, çift tırnak kullanmaktan daha hızlıdır. Tek tırnak kullanarak değişkeni

PHP:
echo "$değişken Hello"; /// yavaş
echo $degisken.', Hello'; //hızlı

daha çok performans sağlar.


Mysql den çekilen tek verilerde kesinlikle LIMIT 1 kullanın.


mysql_num_rows kullanırken değişkene atamadan if içinde kullanın

PHP:
if(mysql_num_rows($sayi)<1){kodlar}

PHP:
Hızlı:

< ?
...
...
?>

Yavaş
< ? ... ?>
< ? ... ?>
Tek kod genelde 1. de daha hızlı çalışır.

for döngüleri için üst limit daha önceden bir değişkene atanmalıdır.

PHP:
Hızlı
$ust = 100/10;
for($i=0; $i<$ust; $i++){

}

Yavaş
for($i=0; $i<100/10; $i++){

}
 

Türkiye’nin ilk webmaster forum sitesi iyinet.com'da forum üyeleri tarafından yapılan tüm paylaşımlardan; Türk Ceza Kanunu’nun 20. Maddesinin, 5651 Sayılı Kanununun 4. maddesinin 2. fıkrasına göre, paylaşım yapan üyeler sorumludur.

Üst