hello world

Мое знакомство с программированием под web началось в далеком 2001 году, за достоверность описываемых событий я уже ручаться не могу, очень многое успело наложиться на память с тех времен. Но исписаны были килобайты кода, некрасивого, нерабочего, и просто опасного. Но любовь к моей первой веб hello world я сохраняю до сих пор.

#!/usr/bin/perl
print "Hello world\n\n";

кэширование запросов

Есть сайт, который состоит из элементов контент которых дергается из бд.
Для снижения нагрузки на сервер БД, можно результат запросов писать в кэш, при этом здесь мы рассмотрим реализацию файлового кэша.

логика работы такова.
прежде чем обратиться к базе с очередным селектом, смотрим, есть ли в специально отведенной папке под это дело файла, отвечающего за конкретно этот запрос. Если файл есть, то прочитать его, если нет, то послать запрос, и результат записать в кэш, чтобы не изобретать велосипед, данные в кеш пишутся сериализоваными.

в идеале это сводится к следующему:

$query='SELECT * FROM `table` ORDER BY id DESC LIMIT 1';
$rez=$cache->get('GET_LAST_POST',$query);

но, это требует от класса еще научится работать с БД, что непременно его усложнит.
поэтому вот модель попроще:

$query='SELECT * FROM `table` ORDER BY id DESC LIMIT 1';
$rez=$cache->is('GET_LAST_POST') ? $cache->get('GET_LAST_POST') : mysql_query($query);
$cache->put($rez);

Уже не так красиво, как в первом варианте, зато не требует от будущего класса функций сверх необходимых.

Теперь остановимся подробнее, на структуре класса занимающегося кэшированием.
Наш класс должен знать куда писать, он дожен уметь создавать перезаписывать и удалять файлы, подготавливать данные к помещению и изъятию из кэша.
вот так он выглядит у меня:

class Cache {
    
    private $path=''; # путь до папки с кэшем
    private $str='';   # имя файла кэша
    private $isStr=false; #есть ли имя
    private $isCache=false; #есть ли файл по этому имени

# устанавливаем путь
    public function setPath($path){
        $this->path=$path;
    }
# передаем имя
    public function setStr($str){
        $str=trim($str);
        if (strlen($str)<=2){
            return false;
        }else{
            $this->str=$this->prepareStr($str);
            $this->isStr=true;
            $this->isCache=($this->isFile($this->str))?true:false;            
            return true;
        }
    }
# возвращаем сгенерированое имя, имя конкретного файла кэша
    public function getStr(){
        return $this->str;
    }
# возвращаем кэш, если есть что
    public function getCache(){
        if ($this->isCache==true){
            return file_get_contents($this->path.'/'.$this->str);
        }else{
            return '';
        }
    }
# есть ли кэш
    public function isCache(){
        return $this->isCache;
    }
# записать в кэш
    public function putToCache($str){
        if ($this->isStr){
            $file = fopen ($this->path.'/'.$this->str,'w');

              if ( !$file )
              {
                $this->isCache=false;
                return false;
              }
              else
              {
                fputs ( $file, $str);
              }
              fclose ($file);
              if ($this->isFile($this->str)==true){
                  $this->isCache=true;
                  return true;
              }else{
                  return false;
              }
        }else{
            return false;
        }
    }
#очстить папку кэша
    public function clearCache(){
        if (empty($this->path) || !file_exists($this->path.'/')){return false;}
        $dir = opendir ($this->path.'/');
          while ( $file = readdir ($dir)){
            if (( $file != ".") && ($file != "..") && strlen($file)==32)
            {
                if (is_file($this->path.'/'.$file)){$this->deleteFile($this->path.'/'.$file);}
            }
          }
          closedir ($dir);
          return true;
    }
#физическое удаление файла
    private function deleteFile($file){
        //print $file;
        unlink($file);
    }
#есть ли файл кэша
    private function isFile($file){
        return (!empty($file) && file_exists($this->path.'/'.$file))?true:false;
    }
#подготавливаем имя файла из переданных параметров
    private function prepareStr($str){        
        return md5(strtolower($str));
    }
}

вроде бы все возможные косяки были учтены, и код работает.

Живой пример использования класса:

include_once('/class/Cache.php');
$cache=new Cache;
$cache->setPath('/www/cache');
#cache_code
    if(isset($cache) && $cache->setStr('GET_NEWS_'.$_GET['id']) && $cache->isCache()){
        $aNews=unserialize($cache->getCache());
    }
    else{
        $aNews=mysql_query('SELECT * FROM `news` WHERE `id`='.$_GET['id'].' LIMIT 1;');
        if (isset($cache)){$cache->putToCache(serialize($aNews));}
    }
#

SQL, удалить все данные старше 2х дней

В качестве условия в этом запросе служит параметр времени. Тип поля, по которому осуществляется выборка — DATETIME.
Вид запроса:


DELETE FROM `table` WHERE `date` < DATE_ADD( NOW( ) , INTERVAL -2 DAY ); [/sql]

SQL запрос, выборка данных в промежутках между датами

Понадобилось мне выбрать данные, что находится между 2-мя промежутками времени.
Конкретно эти промежутки были описаны так, крайняя левая — самая ранняя запись, крайняя правая — текущий момент.


SELECT *
FROM `base`.`table`
WHERE YEAR( `date` ) >= (
SELECT YEAR( MIN( `date` ) )
FROM `base`.`table`
WHERE 1
LIMIT 1 )
AND MONTH( `date` ) >= (
SELECT MONTH( MIN( `date` ) )
FROM `customer`.`table`
WHERE 1
LIMIT 1 )
AND DAYOFMONTH( `date` ) >= (
SELECT DAYOFMONTH( MIN( `date` ) )
FROM `customer`.`table`
WHERE 1
LIMIT 1 )
AND YEAR( `date` ) <= YEAR( NOW( ) ) AND MONTH( `date` ) <= MONTH( NOW( ) ) AND DAYOFMONTH( `date` ) <= DAYOFMONTH( NOW( ) ) ORDER BY `date` DESC ; [/sql] что делает запрос: он выполняет 3 подзапроса, для выборки минимального года, месяца и числа, в качестве левого условия, и с правой стороны ставит текущие значения даты. Такой вид запроса удобен если параметры как левой части запроса так и правой могут быть заданы.