Ben nasıl bu basit bir PHP komut dosyası optimize edebilirsiniz?

5 Cevap php

Bu ilk senaryom bir AJAX isteği üzerinden her kullanıcı için birkaç kez çağrılır. Bu bir metin dosyasının son satırı almak için farklı bir sunucu üzerinde başka bir komut dosyası çağırır. Gayet iyi çalışıyor, ama ben iyileştirilmesi için oda bir sürü olduğunu düşünüyorum ama ben çok iyi bir PHP coder değilim, ben hız ve verimlilik için bu optimize edebilirsiniz toplumun yardımıyla umuyorum:

AJAX POST Request made to this script

<?php session_start();
$fileName = $_POST['textFile'];
$result = file_get_contents($_SESSION['serverURL']."fileReader.php?textFile=$fileName");
echo $result;
?>

It makes a GET request to this external script which reads a text file

<?php
$fileName = $_GET['textFile'];
if (file_exists('text/'.$fileName.'.txt')) {
    $lines = file('text/'.$fileName.'.txt');
    echo $lines[sizeof($lines)-1];
}
else{
    echo 0;
}
?>

Ben herhangi bir yardım takdir ediyorum. Ben ilk komut yapılabilir daha fazla gelişme olduğunu düşünüyorum. Bu iyi en azından ben kendi pahalı düşünüyorum, pahalı bir işlev çağrısı (? Izle) yapar!

5 Cevap

Bu komut dosyası geri gidiyor konumları ve dosya türlerini sınırlamak gerekir.

Bu çalışırken birileri düşünün:

http://www.yoursite.com/yourscript.php?textFile=../../../etc/passwd (veya benzeri)

.. Gecikmeler meydana nerede bulmaya çalışın HTTP istek uzun sürer, ya da okuma uzun sürüyor o kadar büyük dosya bulunmamaktadır.

Isteği yavaş ise, yerel sonuçları önbelleğe deneyin.

Dosya çok büyük ise, o zaman düzenli aralıklarla (ya da her değişiminde) dosyanın son satırını ayıklayan bir cron işi kurmak ve diğer komut doğrudan erişebileceğiniz bir dosyaya o kurtarabilir.

readfile is your friend here it reads a file on disk and streams it to the client.

script 1:

<?php
  session_start();
  // added basic argument filtering
  $fileName = preg_replace('/[^A-Za-z0-9_]/', '', $_POST['textFile']);

  $fileName = $_SESSION['serverURL'].'text/'.$fileName.'.txt';
  if (file_exists($fileName)) {

      // script 2 could be pasted here

      //for the entire file
      //readfile($fileName);

      //for just the last line
      $lines = file($fileName);
      echo $lines[count($lines)-1];


      exit(0);
  }

  echo 0;
?>

This script could further be improved by adding caching to it. But that is more complicated. The very basic caching could be.

komut 2:

<?php

  $lastModifiedTimeStamp filemtime($fileName);

  if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
      $browserCachedCopyTimestamp = strtotime(preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']));
      if ($browserCachedCopyTimestamp >= $lastModifiedTimeStamp) {
          header("HTTP/1.0 304 Not Modified");
          exit(0);
      }
  }

  header('Content-Length: '.filesize($fileName));
  header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + 604800)); // (3600 * 24 * 7)
  header('Last-Modified: '.date('D, d M Y H:i:s \G\M\T', $lastModifiedTimeStamp));
?>

İlk şeyler ilk: Eğer gerçekten optimize etmek gerekir mi? Bu kullanımı durumda yavaş parçası mı? Eğer xdebug doğrulamak için kullanılır mı? Bunu yaptıysanız, okumaya:

Gerçekten yararlı ilk komut optimize olamaz: Bir http-istek ihtiyacınız varsa, bir http-istek gerekir. (Ilk komut ikinci komut üzerinde faaliyet aynı dosyaları erişebilirsiniz yani) mümkün olduğu takdirde http isteği atlanıyor olsa da, bir performans artışı olabilir.

İkinci komut gelince: belleğe dosyanın tamamını okuma bazı havai gibi görünüyor ama dosyalar küçük eğer, neglibable olduğunu. Bu durumda olduğu gibi kod çok okunabilir görünüyor, onu bırakacaktı.

Dosyaları büyük iseniz, ancak, kullanmak isteyebilirsiniz fopen() and its friends fseek() and fread()

# Do not forget to sanitize the file name here!
# An attacker could demand the last line of your password
# file or similar! ($fileName = '../../passwords.txt')
$filePointer = fopen($fileName, 'r');
$i = 1;
$chunkSize = 200;
# Read 200 byte chunks from the file and check if the chunk
# contains a newline
do {
    fseek($filePointer, -($i * $chunkSize), SEEK_END);
    $line = fread($filePointer, $i++ * $chunkSize);
} while (($pos = strrpos($line, "\n")) === false);
return substr($line, $pos + 1);

Dosyaları değişmeyen iseniz, son satırı önbelleğe gerekir.

Dosyalar değişiyor ve onlar üretilen şekilde kontrol ederse, o ya da sipariş satırları bir satır ömrü boyunca okumak ne sıklıkta bağlı olarak, yazılı tersine bir gelişme olmayabilir olabilir.

Edit:

Sizin sunucu, kendi günlüğüne yazmak memcache koymak ve o günlüğüne yazmak istediğini anlamaya olabilir. Son satır için istek yerine dosya okuma memcache fulfulled olabilir.

Gecikme en olası kaynağı olduğunu çapraz sunucu HTTP isteği olduğunu. Dosyaları küçük iseniz, fopen / fread / fclose maliyeti tüm HTTP isteğine göre bir şey değildir.

(Bir süre önce ben dinamically görüntü-tabanlı menüler oluşturmak için görüntüleri almak için kullanılan HTTP. Saniyenin onda biri kadar saniye gecikme azaltılmış yerel bir dosya okuma ile HTTP isteği değiştirilmesi.)

Ben dosya sunucusu dosya sistemi erişim bariz çözüm, doğrudan söz konusu olduğunu varsayalım. Değilse, o zaman en iyi ve en basit seçenektir.

Eğer değilse, önbelleğe kullanabilirsiniz. Bunun yerine tüm dosyayı alma, sadece bir HEAD isteği yayınlama ve yerel bir kopya damgası karşılaştırın.

Eğer aynı dosyalara dayalı müşterilerine bir çok ajax-güncelliyoruz Ayrıca, eğer (örneğin, meteor) kuyrukluyıldız kullanılarak bakarak düşünebilirsiniz. Tek bir değişiklik birkaç müşterilerine yayınlanacak olan sohbetler, gibi şeyler için kullanılır.