[PHP-users 2260] Re: 1 -> 1st, 2 -> 2nd ...

Osamu Shigematsu php-users@php.gr.jp
Wed, 26 Sep 2001 14:40:55 +0900


重松です。こんにちは。

>> date() とかじゃダメですか?
> $day = date("F jS", mktime(0,0,0,10,1,2001));

とのことですが、いわゆる、あなたは n 番目のお客様です、というのを表示したい
のです。

というわけで、きしださんのをほとんどそのまま拝領して、以下のような感じで、そ
れっぽくは動いております。。。

あと、便乗質問で恐縮なのですが、排他制御を行いつつ、

(1) 最初の行 (だけ) を素早く読む方法
    とりあえず、1000 バイトを超えることはないので、固定しています。
(2) ファイルのサイズを切りつめる方法
    ANSI C のファイル関数でも切りつめられないですよね?
    といういうことは PHP でもできないのでしょうか?

がわかりません。アドバイスいただければ幸いです。

<?php
class simple_counter{
    var $enable_flock = true;
    var $log = 'log.txt';
    
    var $total = -1;
    var $today,$yesterday,$timestamp;
    
    function lock(&$fp){
        if($fp){
            if(!$this->enable_flock) return true;
            for($i = 0; $i < 10; ++$i){
                if(flock($fp,2)) // LOCK_EX
                    return true;
                sleep(1);
            }
            fclose($fp);
            $fp = 0;
        }
        return false;
    }
    
    function unlock(&$fp){
        if($fp){
            if(!$this->enable_flock) return true;
            return flock($fp,3); // LOCK_UN
        }
        return false;
    }
    
    function simple_counter(){
        $fp = @fopen($this->log,'r+');
        if($this->lock($fp)){
            $d = date('Ymd');
            $buf = fgets($fp,1000);
            if($buf){
                list(
                    $this->total,
                    $this->today,
                    $this->yesterday,
                    $this->timestamp
                ) = explode(',',$buf);
            }else{
                $this->total = 0;
                $this->today = 0;
                $this->yesterday = 0;
                $this->timestamp = $d;
            }
            ++$this->total;
            if($d==$this->timestamp){
                ++$this->today;
            }else{
                $this->yesterday = $this->today;
                $this->today = 1;
                $this->timestamp = $d;
            }
            rewind($fp);
            fputs($fp,
                $this->total.','.
                $this->today.','.
                $this->yesterday.','.
                $this->timestamp.',');
            $this->unlock($fp);
            fclose($fp);
        }
    }
    
    function ordinal($a){
        $a = (int)$a;
        if((($a / 10) % 10) == 1) return $a . 'th';
        switch($a % 10){
        case 1: return $a . 'st';
        case 2: return $a . 'nd';
        case 3: return $a . 'rd';
        }
        return $a . 'th';
    }
    
    function format(){
        return
            sprintf(
                'Welcome! '.
                'You are the %s visitor! '.
                '(today: %d, yesteday %d)',
                    $this->ordinal($this->total),
                    $this->today,
                    $this->yesterday);
    }
}

$counter = new simple_counter;
print $counter->format();
?>

-- 
Osamu Shigematsu

http://www.ravi.ne.jp/%7eshige/
mailto:shige@ravi.ne.jp