[ カテゴリー » 開発日誌 » PHP ]

アクセス解析でドメイン毎にソート

category-icon

 こんにちは、martinです。もう師走はすぐそこですね。先日レヴィ・ストロースW氏が亡くなりました。何となく今年だろうなぁと思って、日記の方で新年の抱負Link を語っていたんですが、ちっとも進んでいません(--)

 フォーラムでアクセス解析関連のバグの報告がありました。→http://forum.p2b.jp/index.php?mode=box&UID=4592Link

 ホストごとの集計の際に、ピリオドで区切られた長いホスト名を短くする処理を入れていたんですが、ホスト名が取得できずにIPアドレスが登録されているときにも、これを適用してしまいIPアドレスが削られて表示されていました。なので正規表現部分を修正しました。

 これだけだと、1行だけの修正なんで、ついでにドメインごとの集計もする記述を加えました。
sortbydomain
こんな感じです。

 どういうドメインでソートするかは、374行目で指定しています。

 $sort_type = array('.jp', '.com', '.net', 'ne.jp', 'co.jp');
なので、例えば、or.jpad.jpなんかも追加したいということであれば、
 $sort_type = array('.jp', '.com', '.net', 'ne.jp', 'co.jp', 'ad.jp', 'or.jp');
みたいにすればOKです。自動的に認識されるかと思います。

 ファイルを添付しておきます。statディレクトリのものと入れ替えてください。

添付ファイル: view.phpattachedIcon 

— posted by martin at 09:10 pm   commentComment [5]  pingTrackBack [0]

縮小時に写真のクオリティを保持させたい

category-icon

 こんにちは。この頃のエントリーは、アップデート情報ばかりなので、たまには別の話題でも。コメントで画質のことに触れられていたので。

 ppBlogでは、ひとつの記事にいくらでも画像を貼り付けることが出来ます。その際に、サイズの大きな画像(デジカメで撮った写真など)は、アップロード時のオプション指定にもよりますが、そのままの大きさでアップロードして保存された後(これはPIXディレクトリへ)、この大きさでは表示するのに大きすぎる場合には、予め指定された大きさ(初期値は350ピクセル)に縮小され、これはPIX/s2ディレクトリへ保存されます。

 記事中に表示されるデジカメの写真などは、最初はこのPIX/s2ディレクトリにある縮小された写真が表示されている場合が多いかと思います。そして、それをクリックすると、PIXディレクトリにある元の大きさの画像を表示するという流れになっています。

 一昔前は、(コンパクト)デジカメの写真一枚のファイルサイズは、せいぜい1MB(メガバイト)程度だったんですが、この頃は、画素数の増大に伴い、3-4MBを超えることも珍しくありません。ppBlogでは、3-4MB程度のファイルサイズでもアップロード可能な処置を入れていますが、これを頻発させるとサーバーに負担をかけうるので、予めお使いのパソコンで写真のファイルサイズを小さくしてアップロードすべきでしょう。個人的には、フリーのソフトである「縮小専用。Link 」を使っています。一括処理も出来て重宝しています。Vistaであれば、標準でついているWindowsフォトギャラリーにある「修正」で、適当に修正を施した後、それを閉じれば自動的に修正されたもので上書き保存されますが、これでもそれなりにファイルサイズが小さくなります(縦横サイズはそのままで、例えば3.49MBが1.2MBになったりとか。まぁ、これでもまだアップロードするには大きいんですが)。

 さて、ここからが本題ですが、もともとファイルサイズが大きい写真をリサイズなどをしてファイルサイズを落とすと、当然ながら写真のクオリティーは低下します。更に、それをppBlogを介してサーバーにアップロードすると、そこで更にリサイズされて、画質が低下することになります。気になる方には気になる部分でしょう。

 ppBlogでは、画像のリサイズは、utils_admin.phpにあるcreate_thumbnail()関数(462行目あたり)が担っています。その中に、

  case 2 : ImageJPEG($img_out, $output); break;
という行(500行目あたり)がありますが、これはJPEG画像を出力する関数です。実は、この関数の第三引数(ひきすう)に、出力する画像の品質を指定できます。

quality はオプションであり、0(品質は最低 ですが、ファイルはより小さい)から100(品質は最高ですが、ファイルは 最大)の範囲で指定します。デフォルトは IJG 品質値(75)です。

引用元: PHP: imagejpeg - ManualLink

 現状、ppBlogでは、この部分の指定はしていないので、初期値である75というクオリティーで保存されていることになります。じゃ、他の値ではどうなるのかな?という疑問が出てきます。なので、簡単に調べてみました。Vistaに初めから付いているサンプルピクチャー(「フランジパニのクローズアップ。」by Kevin Forest氏)を元画像として、Qualityオプションを小さい方から順に10, 30, 75, 80, 85, 90, 100と指定していって、それぞれの画像を保存、そのままのファイルサイズでアップロードしたのが以下です。

 まずは元の画像です。350ピクセルにリサイズされていて(品質75)、クリックするとオリジナルのサイズで表示されます。

test0
元の画像のファイルサイズは105KBで大きさは1024x768です。

 以下、色んな品質でリサイズしていった画像を載せます。低い品質から。

test10
品質10。4.75KB。ブロックノイズが目立ち明らかに劣化している。
test30
品質30。8.4KB。ブロックノイズはだいぶ減ってはいるがモスキートノイズが。
test75
品質75。15.6KB。デフォルト値。まぁまぁ綺麗だが、目を凝らすと・・・。
test80
品質80。17.6KB。うーん。
test85
品質85。20.4KB。品質80よりノイズが減っている。
test90
品質90。25.2KB。85との違いは大きくない。
 
test100
最高品質100。ファイルサイズ70.9KB!その割りには90との違いは微妙。

 これから言えることは、JPEGの性質上、元の写真による部分もあると思うけれど、デフォルト値の75では、ノイズが少し目立ち、品質85だと明らかな改善が見られる。ファイルサイズは、15.6KBが20.4KBと約1.3倍。品質90-100は、見た目のクオリティーはほぼ変わらないにも拘わらず、品質100でのファイルサイズ増大が顕著(90で25.2KBなのが100だと70.9KB。ちなみにオリジナルは105KB)。

 なので、結論としては、初期値の75での品質が気になる方は、85-90あたりの値を指定すると、リサイズしても満足した画質が得られるんじゃないでしょうか。たった一枚のサンプル画像からの帰結ではあるけれど、まぁ妥当なところであると思います。

 というわけで縮小された写真の画質が気になる方は、utils_admin.phpの500行目あたりを、

  case 2 : ImageJPEG($img_out, $output, 85); break; // あるいは90

としてみては如何でしょうか。

 将来的には、画像アップロード時に、指定できるようにしても良いですね。


— posted by martin at 12:29 am   commentComment [9]  pingTrackBack [0]

記事アクセスランキング修正版

category-icon

 こんばんは。数個前の記事で紹介した記事アクセスランキングですが、個別記事にアクセスした際には、表示されていませんでした。これは、$RANKINGという変数のグローバル宣言をしていないためという凡ミスでした。。なので、それを修正したutils.phpを添付しておきます。また、現状では、「最近のエントリー」で表示される記事数(つまり定数RECENT_ENTRIESの同じ数がリスト表示されますが、showRanking関数のこの部分を好きな数字に変えることでリストの表示数をコントロール出来ます。

 尚、別件ですが、はてなのブックマークエントリー数を取得するAPIが変更になったLink ようで、現状ではPHPのエラーが出るかと思います。これは、ソーシャルブックマークのアイコン表示を有効にしている場合です。これの対策としては、utils.phpに記述してある$SBM_LIST変数内を修正する必要があります。具体的には、この中の'はてなブックマーク'の部分、

'b.hatena.ne.jp/entry/json/?url='
'api.b.st-hatena.com/entry.count?url='
に書き換えます。

— posted by martin at 09:35 am   commentComment [3]  pingTrackBack [0]

作成ページでPHPが通るようにしたい

category-icon

 こんばんは。昨日に引き続き。

 ppBlogでは、ブログのエントリーとは別に自由にページを作成することが出来るので、いわばCMSGのような使い方も可能です。このページ作成機能ですが、以前から改善したいなぁと思っていたことがありました。それは、作成したページの中に記述したPHPがスクリプトとしてちゃんと動作するということです。

 現状では、例えば、以下のような記述をしてページを作成してもそのまま書いた文字列が出力されてしまいます。

<?php
 echo "Bonjour à tous!"; // やぁ、みんな!
?>

上の記述は、以下のようになる。

echo "Bonjour à tous!"; // やぁ、みんな!
?>

 ページ作成画面でPHPスクリプトを自由に記述できれば、PHPに慣れた方なら色んなことが出来るようになります。なので、そうできるようにしてみましょう。ppBlogでは、作ったページは、単なるテキストファイルとして、pagesディレクトリに保存され、それをmodules/pages.inc.phpを介して、HTMLとして出力されます。なので、pages.inc.phpモジュールをいじります。具体的には、このファイルの中で定義されているoutputPage()関数に手を加えれば良いです。

 流れとしては、テキストファイル中に書かれてあるPHPタグ<?php・・・?>があれば、その中身をeval関数で評価、その結果を保持しておく。eval関数はその場ですぐに評価されるため、それがHTMLとして出力されるのを防ぐために、出力のバッファリングを有効にしておく、ということです。簡単に実装出来そうですね。以下のような記述でいけるかと思います。

if(preg_match_all('{<¥?php(.+?)¥?>}s', $page, $mt)){ // PHPタグを含むなら
  $BUFF = array(); // 評価した結果を保存する入れ物を用意しておく
  ob_start(); // 出力のバッファリングを有効に
  $length = count($mt[0]);
  for($i = 0; $i < $length; $i++){
   $php = $mt[1][$i]; // 実行させたいPHPスクリプトの中身
   if(eval($php) === FALSE){ // PHPのパースエラーなら
    $BUFF[] = "ppBlog warning: parse error!";
   } else $BUFF[] = ob_get_contents(); // きちんと評価されれば、その結果を取得
  }
  ob_end_clean();
 }

 ポイントは、ob_start関数とeval関数の組み合わせです。その際に、eval関数の返り値は、パースエラーならFALSEを返すけど、きちんと評価されれば、ob_get_contents関数で補足可能ということですかね。

 実際には、これ以外の微調整が必要ですが、それも反映させたPHP記述が有効になるpages.inc.phpを添付しておきます。既存のやつを上書きして問題ないです。

 と、これを書いている途中で思いついたのですが、ppBlogでは、[style]...[/style]の形式で、その記事だけに適用させるスタイルシートを指定出来ますが、これもページ作成画面でも指定出来るようにしました。このサイトで「人気記事ランキング」というページを作りましたが、そのソースは以下のようになってます。これをそのままページ作成画面のテキストエリアに貼り付ければOKです。

<h2>人気記事ランキング</h2>
<?php
echo '<ol>'.NL;
echo showRanking(); // utils.phpで定義している独自の関数も使える!
echo '</ol>'.NL;
?>

[style]
h2 { color: slateblue; margin: 1em auto 2em auto; }
ol li span {
 background: pink; font: bold 12px Arial; color: navy; padding: 2px 3px;
}
ol {
 list-style-type: decimal;
 width: 480px; margin: auto;
}
[/style]

 コメントにもありますが、utils.phpで定義している関数も使えるので色々と応用が利きそうです。ちなみに、上のスタイルシートの指定で、実際には以下のように、div.page-boxが自動的に付加された形で出力されます。

 <style type="text/css">
  div.page-box h2 { color: slateblue; margin: 1em auto 2em auto; }
  div.page-box ol li span {
   background: pink; font: bold 12px Arial; color: navy; padding: 2px 3px;
  }
  div.page-box ol {
   list-style-type: decimal;
   width: 480px; margin: auto;
  }
 </style>

 スタイルシート指定も有効するには、utils.phpもちょいと書き換えが必要です。これも添付しておきます。最近のバージョン(1.7-1.8)であれば、既存のを上書きしても特に動作に問題はないかと思います(いつでも元に戻せるように元のutils.phpのバックアップはとっておいて下さい)。


— posted by martin at 06:55 am   commentComment [3]  pingTrackBack [0]

各記事の閲覧数ランキングを表示させたい

category-icon

 こんばんは、久しぶりにmartinです。

 フォーラムの方で、「記事の表示回数と順位の表示は出来ないでしょうか?Link 」というエントリーがあって、ちょっとプログラミングがしたくなったのでとりあえず書いてみました。このサイトで、テーマをBasicにすれば、左側のサイドバーに「人気エントリー」というのが表示されていると思います。

 基本的には、utils.phpをいじることで実現できます。utils.phpの538行目あたりに以下の記述を追加しました。閲覧数を記録するファイル(ranking.ini.php)はownerディレクトリに作るとします。

 if(!ADMIN && $UID != ''){ // 閲覧数ランキング用
  if(is_file(($ranking = OD.'ranking.ini.php'))){
   include_once $ranking; // これで$RANKING配列をゲット
   $hit = preg_grep("/(¥d+¥t$UID¥t.+?)/", $RANKING);
   if(empty($hit)){
    array_push($RANKING, "1¥t$UID¥t$pm_link¥t$_title");
    rewrite_ini($ranking, $RANKING);
   } else {
    $ix = array_keys($hit); $ix = $ix[0];
    list($count,) = explode("¥t", $RANKING[$ix], 2);
    $RANKING[$ix] = (++$count)."¥t$UID¥t$pm_link¥t$_title"; // ヒットした数の更新
    $RANKING = array_slice($RANKING, 0, 100); // とりあえず100件も登録すればOKだろう
    rsort($RANKING, SORT_NUMERIC); // 大きい順にソート
    rewrite_ini($ranking, $RANKING);
   }
  } else rewrite_ini($ranking, '', '$RANKING'); // 記録保持ファイルがないなら作成
 }

 テーマファイルのtemplate.phpには新たな変数%_RANKING:1:人気エントリー:1_%を用意しておきます。具体的には以下のような感じ。つまりrankingという新たなIDが加わります(pprankingの方が良いかなぁ)。

<div id="ranking">%_RANKING:1:人気エントリー:1_%</div><!--#ranking-->

 そして、この変数を変換する関数を用意しておきます。

function showRanking(){
 if(is_file(($ranking = OD.'ranking.ini.php'))){
  include_once $ranking;
  if(!empty($RANKING)){
   $h = NL;
   foreach ($RANKING as $i => $r){
    if($i >= RECENT_ENTRIES) break; // 表示させる数はエントリー記事の表示数と同じ設定にしておく
    list($count, $uid, $pmlink, $title) = explode("¥t", $r, 4);
    $h .= '    <li><a href="'.$pmlink.'" title="'.date('Y年n月j日の投稿', $uid).'">'.$title.'</a> <span title="閲覧数">'.$count.'</span></li>'.NL;
   }
   return $h;
  }
 }
}

 後は、テーマファイルのCSSファイルもちょいといじって出来上がりです。とりあえず、この改造を施したutils.phpとBasicテーマのtemplate.php及びCSSファイルを添付しておきますね。

添付ファイル: template.phpattachedIcon  basic.cssattachedIcon  utils.phpattachedIcon 

— posted by martin at 05:53 am   commentComment [6]  pingTrackBack [0]

T: Y: ALL: Online:
Created in 0.0074 sec.
prev
2017.12
next
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31