Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Счётчик

2.2K
28 апреля 2006 года
Фауст
29 / / 08.02.2004
Всем привет!
Есть проблема, надеюсь, вы поможете её решить!
Написал, счётчик для страниц, а точнее, сколько раз прочитали. В коде, используется функция flock (запирание файла), записывается и считывается информация, из одного файла. Всё работает нормально, одно время, а потом, файл просто обнуляется, а точнее, в нём, остаётся, всего один символ “|”. Суппорт хостинга, говорит, что это, логическая ошибка скрипта!

Плизззз, гляньте, есть ли в коде ошибка! Я уже, 3 недели парюсь!

Вот код:
Код:
<?
if (@$_REQUEST['id'])
{
        $file_counter = "base/counter.dat";
        $data='';
        if (file_exists($file_counter))
        {
                $fp = fopen($file_counter, "r+");
            while (!feof($fp))
            {                          
                list($change1,$change2)=explode("|", fgets($fp));
                if (@$_REQUEST['id']==$change1)
                {                                                                              
                        $counter=$change2;
                                        $counter=$counter+1;                                    
                    if (!feof($fp))
                                        {
                                                $data=$data.$change1.'|'.$counter."\n";
                                        }
                                        else
                                        {
                                                $data=$data.$change1.'|'.$counter;
                                        }
                }
                else
                {                                                      
                        $data=$data.$change1.'|'.$change2;
                }                
            }
        }

        fclose($fp);
       
        $fp = fopen($file_counter, "a");
        flock($fp,LOCK_EX);
        if(flock($fp,LOCK_EX)){
        ftruncate($fp,0);
        fputs($fp, $data);
        flock($fp,LOCK_UN);
        fclose($fp);
        }
}
?>
8
29 апреля 2006 года
mfender
3.5K / / 15.06.2005
Всо правильно. Достаточно один раз попасться пустой строке - всё подчистится.
Попытайся сделать лог на эти движения. огда поймёшь причину.
И ещё: откуда в 15й строке берётся $counter?

И вообще, вспоминаю 1998 год, когда я был не очень хорошо ознакомлен с базами данных и порывался написать всё на куче файлов (писал ещё на Perl-3). Именно так, как ты: сидел и сочинял конструкции с делимитерами "|", расчитывал концы строк... Короче - морока.

Мой тебе совет: присмотрись к функции serialize/unserialize. Не так давно уже такого рода простейший счётчик уже обсасывали тут , и там я предложил конструкцию, которая тебя может заинтересовать. Весь твой счётчик уместится в восемь строк и не надо париться три месяца с флоками.
2.2K
29 апреля 2006 года
Фауст
29 / / 08.02.2004
Спасибо! Попробую разобраться с serialize/unserialize.
База, мне не подходят, так как, на сервере есть пхп, но нет мускула!
А могли бы Вы, привести пример, как реализовать мой код при помощи serialize/unserialize?
Так как поиск, ничего не дал!
2.2K
29 апреля 2006 года
Фауст
29 / / 08.02.2004
Плиззззз, помогите, очень нужно!!!! Проблему никак не решить!
Сегодня опять всё слитело!!!
15
29 апреля 2006 года
shaelf
2.7K / / 04.05.2005
Цитата:
Originally posted by Фауст
Спасибо! Попробую разобраться с serialize/unserialize.
База, мне не подходят, так как, на сервере есть пхп, но нет мускула!
А могли бы Вы, привести пример, как реализовать мой код при помощи serialize/unserialize?
Так как поиск, ничего не дал!


Обратитесь пожалуйста к документации и впредь не нужно кричать

Цитата:
Плиззззз, помогите, очень нужно!!!! Проблему никак не решить! Сегодня опять всё слитело!!!

. Как сочтут нужным, Вам ответят.

8
30 апреля 2006 года
mfender
3.5K / / 15.06.2005
Цитата:
Originally posted by Фауст
Плиззззз, помогите, очень нужно!!!! Проблему никак не решить!
Сегодня опять всё слитело!!!



Что ж так кричать-то? Мы же тоже человеки, мы же тоже в выходные дни и ночи ходим с дитями в зоопарк и пьём пиво... :D

Вот, на скорую руку набросал:

Код:
class PhaustClickCounter
{
    /*Основной класс, определяющий свойства и методы счётчиков*/

    /*Определим некоторые константы, необходимые просто для работы
    и удобства работы*/


    /**
     * Этот префикс будем ставить в идентификтор счётчиков,
     * чтобы PHP понимал, что мы обращаемся к хэшу, а не к
     * нумерованному массиву.
     */

    const COUNT_PREFIX              = "PAGE_";
   
    /** Имя поля, в котором храним время последнего обновления */
    const COUNTERS_LASTUPDATE_FIELD = "LAST_UPDATE";
   
    /**
     * Имя поля, в которое впишем имя счётчика
     * Зачем это нужно? Ну, например для удобства визуальной
     * идентификации при просмотре списка счётчиков
     */

    const COUNTER_NAME              = "COUNTER_NAME";
   
    /** Имя хэша, в котором собраны показания счётчиков для одного OID */
    const COUNTERS_HASH_FIELD       = "COUNTERS";
   
    /**
     * Имена полей счётчиков
     */

    const COUNTER_TOTAL         =   "Total";
    const COUNTER_TODAY         =   "Today";
    const COUNTER_MONTH         =   "Month";
    const COUNTER_YEAR          =   "Year";

    /**
     * Хэш, с которым мы работаем
     * @var Array
     */

    protected $countersHash;
   
    /**
     * Сюда мы положим содержимое актуального счётчика
     * @var Array
     */

    public $actualCounter;
   
    /**
     * Текущее время, его засекаем в конструкторе
     * @var Integer
     */

    protected $actualTime;
   
    /**
     * По ссылке установим содержимое массива счётчика
     *
     * @param $arr Array Ссылка на весь массив из файла
     * @param String $index Индекс хэша актуального счётчика
     */

    protected function SetActualCounter(&$arr, $index){
        if(!isset($arr[$index])) $arr[$index] = $this->InitCounter($index);
        $this->actualCounter =& $arr[$index];
    }
   
    /**
     * Инициализация счётчика
     * Используем её, если счётчика ещё нет
     *
     * @param String $index Имя хэша
     * @return Array Инициализированный счётчик
     */

    private function InitCounter($index){
        return array(
                    self::COUNTER_NAME  => "Страница без названия",
                    self::COUNTERS_LASTUPDATE_FIELD => $this->actualTime,
                    self::COUNTERS_HASH_FIELD => array(
                        self::COUNTER_TOTAL     =>  0,
                        self::COUNTER_TODAY     =>  0,
                        self::COUNTER_MONTH     =>  0,
                        self::COUNTER_YEAR      =>  0  
                    )
                );
    }
   
    /* Небольшой агрегатор методов */
    protected function CalculateCounters(){
        /*Просто увеличиваем общий счётчик*/
        ++$this->actualCounter[self::COUNTERS_HASH_FIELD][self::COUNTER_TOTAL];
        $this->AnyDay($this->actualTime, $this->actualCounter[self::COUNTERS_LASTUPDATE_FIELD]);
        $this->AnyMonth($this->actualTime, $this->actualCounter[self::COUNTERS_LASTUPDATE_FIELD]);
        $this->AnyYear($this->actualTime, $this->actualCounter[self::COUNTERS_LASTUPDATE_FIELD]);
        $this->actualCounter[self::COUNTERS_LASTUPDATE_FIELD] = $this->actualTime;
    }
   
    /*Методы для вычисления переменных счётчикв*/
    private function AnyDay($actualTime, $lastTime){
        $endOfDay = mktime(23, 59, 59, date("n", $lastTime), date("j", $lastTime), date("Y", $lastTime));
        if($actualTime > $endOfDay) $this->actualCounter[self::COUNTERS_HASH_FIELD][self::COUNTER_TODAY] = 0;
        ++$this->actualCounter[self::COUNTERS_HASH_FIELD][self::COUNTER_TODAY];
    }
   
    private function AnyMonth($actualTime, $lastTime){
        $endOfMonth = mktime(23, 59, 59, date("n", $lastTime), date("t", $lastTime), date("Y", $lastTime));
        if($actualTime > $endOfMonth) $this->actualCounter[self::COUNTERS_HASH_FIELD][self::COUNTER_MONTH] = 0;
        ++$this->actualCounter[self::COUNTERS_HASH_FIELD][self::COUNTER_MONTH];
    }
   
    private function AnyYear($actualTime, $lastTime){
        $endOfYear = mktime(23, 59, 59, 12, 31, date("Y", $lastTime));
        if($actualTime > $endOfYear) $this->actualCounter[self::COUNTERS_HASH_FIELD][self::COUNTER_YEAR] = 0;
        ++$this->actualCounter[self::COUNTERS_HASH_FIELD][self::COUNTER_YEAR];
    }
}

class PhaustFileClickCounter extends PhaustClickCounter
{
    /**
     * Собственно, это и есть файл, в котором храним показания счётчиков.
     * @var String
     */

    private $cFile;

    public function __construct($countersFile, $counterOID){
        $this->actualTime = time();
        $this->cFile = $countersFile;
        $this->GetCounters($this->countersHash);
        $this->SetActualCounter($this->countersHash, self::COUNT_PREFIX . $counterOID);
        $this->CalculateCounters();
        $this->SetCounters();
    }

    /*Определим методы для работы с файлом данных*/
    /**
     * Метод записывает массив в переменную $countersHash из файла
     */

    private function GetCounters(&$arr){
        $arr = unserialize($this->IsArrayFile($this->cFile));
        if(!is_array($arr)) $arr = array();
    }

    /**
     * Метод записывает массив из переменной $countersHash в файл
     */
   
    private function SetCounters(){
        file_put_contents($this->cFile, serialize($this->countersHash));
    }

    private function IsArrayFile($fileName){
        if(!is_file($fileName)){
            file_put_contents($fileName, serialize(array()));
        }
        return file_get_contents($fileName);
    }
}

define("COUNTERS_FILE", $_SERVER['DOCUMENT_ROOT']."/cntrs.dat");

if(isset($_GET['cnt'])){
    $cnt = new PhaustFileClickCounter(COUNTERS_FILE, $_GET['cnt']);
    echo "
        <div>Всего: {$cnt->actualCounter[PhaustClickCounter::COUNTERS_HASH_FIELD][PhaustClickCounter::COUNTER_TOTAL]}</div>
        <div>Сегодня: {$cnt->actualCounter[PhaustClickCounter::COUNTERS_HASH_FIELD][PhaustClickCounter::COUNTER_TODAY]}</div>
        <div>В этом месяце: {$cnt->actualCounter[PhaustClickCounter::COUNTERS_HASH_FIELD][PhaustClickCounter::COUNTER_MONTH]}</div>
        <div>В этом году: {$cnt->actualCounter[PhaustClickCounter::COUNTERS_HASH_FIELD][PhaustClickCounter::COUNTER_YEAR]}</div>
    "
;
}


Как мог прокомментировал. Думаю, будет понятно.
8
30 апреля 2006 года
mfender
3.5K / / 15.06.2005
Немного поразмыслив, добавил ещё просмотр всех счётчиков в таблице:
Код:
if(isset($_GET['cnt'])){
    $cnt = new PhaustFileClickCounter(COUNTERS_FILE, $_GET['cnt']);
    echo "
        <div>Всего: {$cnt->actualCounter[PhaustClickCounter::COUNTERS_HASH_FIELD][PhaustClickCounter::COUNTER_TOTAL]}</div>
        <div>Сегодня: {$cnt->actualCounter[PhaustClickCounter::COUNTERS_HASH_FIELD][PhaustClickCounter::COUNTER_TODAY]}</div>
        <div>В этом месяце: {$cnt->actualCounter[PhaustClickCounter::COUNTERS_HASH_FIELD][PhaustClickCounter::COUNTER_MONTH]}</div>
        <div>В этом году: {$cnt->actualCounter[PhaustClickCounter::COUNTERS_HASH_FIELD][PhaustClickCounter::COUNTER_YEAR]}</div>
    "
;
    prer($cnt->countersHash);
}
elseif (isset($_GET['showCounters'])){
    $cntArray = unserialize(file_get_contents(COUNTERS_FILE));
    echo "
    <style>
    BODY{
        font-family:        sans-serif;
        font-size:          11px;
    }
   
    .headerTD{
        background-color:   #CCC;
        font-weight:        bold;
        text-align:         center;
    }
   
    .dataTD{
        background-color:   #FFF;
        font-weight:        normal;
        text-align:         right;
    }    
    </style>
    "
;
    echo "<table border=0 cellpadding=0 cellspacing=0 align=center width=600><tr><td bgcolor=#000000>";
    echo "<table border=0 cellpadding=3 cellspacing=1 width=100%>";
    echo "<tr>
<td class=headerTD>OID</td>
<td class=headerTD>Счётчик</td>
<td class=headerTD>За сегодня</td>
<td class=headerTD>За месяц</td>
<td class=headerTD>За год</td>
<td class=headerTD>Всего</td>
</tr>"
;
    foreach($cntArray as $key=>$row){
        echo "
        <tr>
            <td class=dataTD>$key</td>
            <td class=dataTD>{$row[PhaustClickCounter::COUNTER_NAME]}</td>
            <td class=dataTD> {$row[PhaustClickCounter::COUNTERS_HASH_FIELD][PhaustClickCounter::COUNTER_TODAY]}</td>
            <td class=dataTD> {$row[PhaustClickCounter::COUNTERS_HASH_FIELD][PhaustClickCounter::COUNTER_MONTH]}</td>
            <td class=dataTD> {$row[PhaustClickCounter::COUNTERS_HASH_FIELD][PhaustClickCounter::COUNTER_YEAR]}</td>
            <td class=dataTD> {$row[PhaustClickCounter::COUNTERS_HASH_FIELD][PhaustClickCounter::COUNTER_TOTAL]}</td>
        </tr>            
            "
;
    }
    echo "</table>";
    echo "</td></tr></table>";
}


Вобщем, к счётчику обращаемся, как http://domain.name/script.php?cnt=<номер счётчика>, а для просмотра всех - http://domain.name/script.php?showCounters
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог