蛇田.jp ~開発ブログ~

2009 年 4 月 2 日

Oracleの環境変数

カテゴリー: 未分類 — admin @ 12:44 AM

Oracleの環境変数の意味やメモ

ORACLE_BASE(OFA推奨)
directory_path
Optimal Flexible Architecture(OFA) というガイドラインにおいてインストールのディレクトリ構造のベース(基点)

ORACLE_HOME (必須)
directory_path
Oracle ソフトウェアのホーム。マルチホーム(マルチバージョン)などにも使用される。

ORACLE_SID (必須)
oracle_sid
インスタンス識別子、接続するインスタンスを設定する。

TNS_ADMIN (任意)
directory_path
Net Service 関連構成ファイルを格納しているディレクトリ。(TNSNAME.ORA、LISTENER.ORA、SQLNET.ORA など)
テスト運用などでデフォルトディレクトリはパーミッションなどから変更が面倒な場合などにも利用できる。

PATH(必須)
$ORACLE_HOME/bin を追加

LD_LIBRARY_PATH(任意)
$ORACLE_HOME/lib を追加
ORACLEのライブラリ検索パスを追加

NLS_LANG (任意)
language_territory.characterset
NLS_LANG=言語_地域.文字コードセット
データベースへ接続する端末の言語、テリトリ、キャラクタセットを一度に設定するための環境変数

Oracleの文字コードを取得するSQL

SELECT VALUE
  FROM NLS_DATABASE_PARAMETERS
 WHERE PARAMETER='NLS_CHARACTERSET'
;

参照サイト
Oracle [環境変数]
Olacle 文字コード

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

2009 年 3 月 29 日

投票システムの構築

カテゴリー: 未分類 — admin @ 1:05 AM

石巻市長選挙をキッカケに投票システムを構築してみました。

石巻投票

「投票」となると、個人の特定がキーになるのですが。
今回のこのシステムは、連続投稿を防ぐ最低限のことしかしていません。

やっていることは
IPによる連続投稿の不許可
ぐらいです。

ポイントとなるのは

  1. DBへの投票データの入れ込み
  2. DBでのIPの引き当て
  3. 画像の作成

です。

1.DBへの投票データの入れ込み

投票したデータをDBに溜めるためにテーブルを作成します。

create table research_election(
research_id int(8) NOT NULL AUTO_INCREMENT,
ip int(20) unsigned NOT NULL default '0',
vote int(8) NOT NULL,
PRIMARY KEY (research_id)
)type=InnoDB;

「投票ID」と「IP」と「票」のカラムを作成します。

これは市長選挙のみの場合を考慮しています。
例えば、このテーブルに市長選挙以外のものも入れようとするには、「市長選挙」としてグルーピングが可能となるカラムをもう一つ作成すれば良いです。

2.DBでのIPの引き当て

DBでのIPを引き当てます。
まぁーIPが変わってしまったら話しにならないのですが・・・

PHPで次のようにしてIPを取得し、DBで引き当てています

$ip = $_SERVER["REMOTE_ADDR"];
$ip = sprintf('%u', ip2long($ip));

これで$ipにIPアドレスが格納されます。

関数の詳細はip2longを参照してください。

この$ipがDBに存在しない場合は投票可能とみなし、存在する場合には投票済みとみなします。
※現在の仕様だとIPが変更された場合には投票が可能となります。
本来であれば、+Cookieを発行するなどして管理を強化する必要があります。

3.画像の作成

画像はPHPのGDライブラリで作成しています。
上記のIPの判断で投票が可能であった場合にはDBへデータをINSERTした後に画像生成プログラムをキックします。

以下のサイトを参照しました。
円グラフの生成 – PHP/データベース

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

2009 年 3 月 26 日

PHPでOracleに接続

カテゴリー: 未分類 — admin @ 1:40 AM

PHPでOracleに接続する方法のメモです

PHPの公式ドキュメント
PHP: Oracle 関数 – Manual

PHPのextentionとしてOracle接続用のドライバをインストールします。
これを動かすためにはOracleのクライアントライブラリが必要となります。

Oracle コールインターフェース (OCI)

この拡張モジュールを使用する前に Web デーモンのユーザでもある Oracle ユーザに対する Oracle 用環境変数が正しく設定されていることを 確認してください。これらの変数は Web サーバを起動する 前に 設定されていなければなりません。 設定されている必要がある変数を以下に示します。

  • ORACLE_HOME
  • ORACLE_SID
  • LD_PRELOAD
  • LD_LIBRARY_PATH
  • NLS_LANG

Web サーバーのユーザ用に環境変数を設定した後、Web サーバーのユーザ (nobody, www) をグループ oracle に追加してください。

実行時設定

名称 デフォルト 変更可否 変更履歴
oci8.privileged_connect “0″ PHP_INI_SYSTEM PHP 5.1.2 以降で使用可能
oci8.max_persistent “-1″ PHP_INI_SYSTEM PHP 5.1.2 以降で使用可能
oci8.persistent_timeout “-1″ PHP_INI_SYSTEM PHP 5.1.2 以降で使用可能
oci8.ping_interval “60″ PHP_INI_SYSTEM PHP 5.1.2 以降で使用可能
oci8.statement_cache_size “20″ PHP_INI_SYSTEM PHP 5.1.2 以降で使用可能
oci8.default_prefetch “10″ PHP_INI_SYSTEM PHP 5.1.2 以降で使用可能
oci8.old_oci_close_semantics “0″ PHP_INI_SYSTEM PHP 5.1.2 以降で使用可能

以下に設定ディレクティブに関する簡単な説明を示します。
oci8.privileged_connect boolean
このオプションは外部の信用 (OCI_SYSOPER, OCI_SYSDBA) を利用して権限付きの接続を有効にします。
oci8.max_persistent int
プロセスあたりの永続的な OCI8 接続の最大値を指定します。 このオプションを -1 に設定することは、制限なしを意味します。
oci8.persistent_timeout int
与えられたプロセスがアイドル状態の永続的接続を維持する最大時間 (秒単位) を指定します。 このオプションを -1 に設定することは、 アイドル状態の永続的接続は永久に維持されることを意味します。
oci8.ping_interval int
oci_pconnect() の間、ping を発行するまでに経過させる時間 (秒単位) を指定します。 0 に設定した場合、永続的接続は再利用される度に ping を発行します。 ping を完全に無効にするためには、このオプションを -1 に設定します。
注意: ping を無効にすることで oci_pconnect() は最高の効率で処理をコールしますが、ネットワークが分断された場合や PHP が接続した後に Oracle サーバがダウンし、 その後に実行されるスクリプト中において PHP が接続の失敗を検知しなくなります。 詳細な情報は oci_pconnect() を参照ください。
oci8.statement_cache_size int
このオプションはステートメントキャッシュを有効にします。 また、キャッシュするステートメントの数を指定します。 ステートメントキャッシュを無効にする場合、このオプションを 0 に設定してください。
注意: より大きなキャッシュは、メモリ使用量の増加と引き替えに パフォーマンスの改善をもたらします。
oci8.default_prefetch int
このオプションはステートメントのプリフェッチを有効にし、 ステートメントの実行後自動的にフェッチされるデフォルトの行数を 設定します。
注意: より大きなプリフェッチは、メモリ使用量の増加と引き替えに パフォーマンスの改善をもたらします。
oci8.old_oci_close_semantics boolean
このオプションは oci_close() の動作を制御します。有効にすると、oci_close() は何も行いません。接続はスクリプトの終了まで閉じられません。 これは後方互換性のためのみに存在しています。 この設定を有効にする必要があると判明した場合、 このオプションを有効にする代わりに、 oci_close() をアプリケーションから削除することが 強く推奨されます。

接続のハンドリング

Oracleのコネクションのプーリングについて。
これでDBのハンドルのキャッシュ(プーリング)できているのだろうか・・・

oci8 拡張モジュールは Oracle に接続するための 3 つの異なる関数を提供しています。 アプリケーションに最適な関数を使用するのはあなた次第です。 また、このセクションにある情報は、 インフォームド・チョイス (十分な説明を受けよく考えた上での選択) を行う助けになることを目的としています。

Oracle サーバへの接続は、完了まで要する時間という点から見ると、 かなりコストのかかる操作です。oci_pconnect() 関数は、 異なるスクリプトリクエスト間で接続の再利用が可能な 持続的キャッシュを使用します。 これは、PHP プロセス (もしくは Apache の子プロセス) 毎の接続に関するオーバーヘッドを一度のみ負うということを意味しています。

もしアプリケーションが信用された異なる Web ユーザー毎に Oracle に接続する場合、oci_pconnect() による持続的キャッシュは、 同時ユーザー数の増加と共に有効ではなくなるでしょう。 これは、多くのアイドル状態の接続が維持されることが原因で、 Oracle サーバ全体のパフォーマンスに不利な影響を与え始めるためです。 もしアプリケーションがこの方法で構成されている場合、 oci8.max_persistent や oci8.persistent_timeout (持続的接続のキャッシュサイズや生存期間の制御が可能になります) を使用してアプリケーションをチューニングする、もしくは代わりに oci_connect() を使用することが推奨されます。

oci_connect() と oci_pconnect() の両者とも接続キャッシュを使用します。もし、同一パラメータと共に oci_connect() を複数回コールする場合、 2 番目以降は既存の接続ハンドルを返します。oci_connect() によって使用されるキャッシュは、スクリプト実行終了時、 もしくは明示的に接続ハンドルを閉じた時にクリアされます。 oci_pconnect() も同様の動作をしますが、 キャッシュは独立して維持され、リクエスト間で残存します。

このキャッシュ機能は忘れてはならないほど重要です。 それは、2 つのハンドルがトランザクション的に独立していない (実際には同じ接続なので、どのような種類の独立もありません) ためです。もしアプリケーションが 2 つの別々でトランザクション的に独立した接続を必要とする場合、 oci_new_connect() を使用すべきです。

oci_new_connect() は、他の既存の接続が存在したとしても 常に Oracle サーバへの新規接続を生成します。 特にアプリケーションの最も負荷が高い部分など、 高トラフィックな Web アプリケーションに対しては oci_new_connect() の使用を避けてください。

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

2009 年 3 月 7 日

WWW::Mixiを使ってmixiをハック

カテゴリー: 未分類 — admin @ 10:44 PM

WWW::MixiというPerlのモジュールを使用してmixiの情報を取り出してみました。

WWW::MixiはCPANで公開されています。
http://search.cpan.org/~tsukamoto/WWW-Mixi/
ドキュメントはこちら

ですが、更新がだいぶ昔でとまっており、今では使える機能が限定されてしまっています。
ただ、ログイン周りは引き続き使用できるので、ログインはこのモジュールを使用できます。

また、このモジュールを使用して当サイトでは
石巻市関連のmixiのコミュニティ一覧の更新情報をRSSとして提供しています。
石巻市コミュ更新情報ページ

これをどのように作成したかをご紹介します。

まず、CPANからモジュールを落とします。
サーバでの管理の問題などなどから、CPANから直接落としてファイルを配置しました。
こんな感じです↓

/home/hebita/perl/cpan/lib/WWW/
              ┠ MIXI.pm
              └ MIXI/
               ┠Cookbook.pod
               └Mixi.pod

これで準備は完了
WWW以下を好きな場所に置いてください。

宣言の仕方などは以下の通り
use lib でライブラリの位置を読み込みます。
これで配置したWWW::Mixiを使用することが出来るようになります。

 #!/usr/bin/perl

use lib '/home/hebita/perl/cpan/lib';

use WWW::Mixi;
use HTTP::Cookies;
use HTTP::Request::Common;
use CGI;
use Data::Dumper;
use Jcode;

WWW::Mixiの大体の使い方

インスタンスします。

my $mixi = WWW::Mixi->new($MIXI_EMAIL, $MIXI_PASSWORD);

$MIXI_EMAIL:mixiにログインする際に使用しているメールアドレス
$MIXI_PASSWORD:mixiにログインするときのパスワード

my $sData = $mixi->login;

ログインを実行します。

$sData = $mixi->get($sMixiURL);
$_ = $sData->content;

$sMixiURL:必要とするmixi上のURL
$_にコンテンツの内容が入ることとなります。

このあと$_を好きなようなデータに加工することで、mixiの情報を外部に持ち出すことが可能となります。

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

WebAPIの処理を簡単にするクラスの作成

カテゴリー: 未分類 — admin @ 7:10 PM

個人でサイトを作成する際に、欲しくなるのがWebAPIで提供されているデータです。
これらのWebAPIは大枠で使用方法が同じなので、共通している部分はある程度、クラスとして使いまわすことができます。

当サイトにおいても、PHPでクラスを作成し、そのクラスを継承した子クラスで処理を行っています。

まず、WebAPIを使用する際にはどんな機能が必要なのか。
だいたい以下の機能が必要だと思われます。

WebAPIで共通使用できる機能

文字コードのエンコード機能

使用している文字コードにもよりますが、WebAPIはUTF-8でのリクエスト&XMLを受け取ることとなるので、エンコード機能が必要となります。
EUC-JP UTF-8 の双方の変換機能は欲しいです。
また、日本語でのリクエストを実現する場合にはURLエンコードをかける場合が多いので、これも必要です。

リクエストURLをセット

クラスで作成することを前提としていますので、継承した子クラスをインスタンスした際にconstructにURLをセットすることとします。
WebAPIを叩く専用クラスとなれば、リクエストURLを明示的にしておいた方がいいですね。
また、クラスのメンバ変数にリクエストURLのパラメータと値をセットできるメソッドも欲しいです。

リクエストの発行

リクエストを投げるメソッドが欲しいです。
file_get_contentsが使用できるなら、それを使う関数を呼び、さらに文章をXMLとしてセットすることとします。

WebAPIクラスの作成

こんな感じでどうでしょうか

<?php

// API 共通で使えるクラス

class API{

  // 本クラスのコンストラクタ
  function __construct(){

  }

  // 渡された変数をEUC-JPからUTF-8にして返す
  function E2U($sStr){
    return mb_convert_encoding($sStr,'UTF-8','EUC-JP');
  }

  // 渡された変数をUTF-8からEUC-JPにして返す
  function U2E($sStr){
    return mb_convert_encoding($sStr,'EUC-JP','UTF-8');
  }

  // 渡された変数をURLエンコードして返す
  function URLenc($sStr){
    return urlencode($sStr);
  }

  // リクエストURLに対してパラメータをセットする
  // 1:パラメータ
  // 2:値
  function SetQuery($sParameter,$sQuery){
    $this->sRequestURL .= '&' . $sParameter . '=' . $sQuery;
  }

  // リクエストURLに対してHTTPアクセスし値を得る
  function GetData(){
    $this->XML = file_get_contents($this->sRequestURL);
    // ここにXMLが入る
    $this->oXML = simplexml_load_string($this->XML);

  }

}
?>

上記ソースをコピペしてファイルとして保存します。
api.phpとでもしてください。

使い方は簡単です。
同ディレクトリにapi.phpを置いた場合
別の場所にapi.phpを配置した場合にはrequire_onceの指定を変えてください。
単純にAPIのリクエスト結果を得たい場合、対応する子クラスを記述します。
今回は食べログAPIを叩いてコンテンツを作った例で紹介します。

食べログAPIを使用する例

<?php
// 食べログAPIを叩く
// API共通APIをrequire
require_once('./api.php');

// APIキーのセット
define('TABE_LOG_API','*************');

// APIクラスを継承する
Class TBL extends API{

  var $sRequestURL = NULL;
  function __construct(){
    // 親クラスのコンストラクタを叩く
    parent::__construct();
  }

  // 必須キーのセット
  // TABE_LOG_API はdefineで記述
  function SetRequest(){
    $this->sRequestURL =
          $this->sRequestURL . '?' .
          'Key=' . TABE_LOG_API;
  }

  // リクエストページを指定することで、取得結果を変える
  function SetSearch($nPageNum){
    // レストラン検索
    $this->sRequestURL = 'http://api.tabelog.com/Ver2/RestaurantSearch/';
    $this->SetRequest();
    $this->SetQuery('Datum','tokyo');
    $this->SetQuery('SearchRange','large');
    $this->SetQuery('Prefecture','miyagi');
    $this->SetQuery('ResultSet','large');
    $this->SetQuery('SortOrder','totalscore');
    $this->SetQuery('PageNum',$nPageNum);
    $this->SetQuery('ResultDatum','tokyo');
  }

  // レストランコードを指定
  function SetReview($nRcd){
    // クチコミ検索
    $this->sRequestURL = 'http://api.tabelog.com/Ver1/ReviewSearch/';
    $this->SetRequest();
    $this->sRequestURL .= '&Rcd=' . $nRcd;
  }

  // レストランコードを指定
  function SetImage($nRcd){
    // レストランの画像検索
    $this->sRequestURL = 'http://api.tabelog.com/Ver1/ReviewImageSearch/';
    $this->SetRequest();
    $this->sRequestURL .= '&Rcd=' . $nRcd;
  }

}

?>

このファイルをさらに、TabeLog.phpとして保存します。

TabeLog.phpをrequireしインスタンスすることで食べログへのリクエストを簡単に実行することができます。

こんな感じで完成です。

<?php
require_once('./TabeLog.php');

// 子クラスのインスタンス
$oTBL = new TBL;

// 1ページ目のレストラン検索
$oTBL->SetSearch(1);

// レストランコードを指定し口コミ検索
$oTBL->SetReview(4001728);

// レストランコードを指定し画像検索
$oTBL->SetImage(4001728);

?>

これで、ソースコード上は非常に見やすくなります。
上記ソースコードを保存し、アクセスすることで、情報を得ることができます。

あとは、その情報を、自分の好きなように加工し表示してあげれば、OKです。

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

2009 年 3 月 3 日

石巻ニュース

カテゴリー: 未分類 — admin @ 12:57 AM

石巻のニュースを紹介をフィードして表示しているのが
http://hebita.jp/news/
になります。

技術的には簡単なことしかしていなくて、

をクロールして記事を集めているだけです。

記事を集めたいページを解析してスクレイピングしています。

具体例を少しだけ。

石巻かほくのメインフレームを正規表現で切り刻む方法

とりあえず、このファイルの取得の仕方ですが、PHPであれば簡単にできます。

<php?
// 目的URL
$URL = 'http://www.sanriku-kahoku.com/main.html';

// file_get_contents関数の仕様
$HTML = file_get_contents($url);
?>

これだけ。
詳しくはWebスクレイピングを参照してください。

これでソースが取得できます。

まず、記事のリンク先のURLを取得するために見出し部分を切り刻みます。
ターゲットとするHTMLは

<TABLE border="0" cellspacing="5" cellpadding="0">
      <TR>
        <TD width="286" height="681">
                 ・
            (見出しが入っています)
                 ・
    </TD>
      </TR>
    </TABLE>

といった感じにします。
tableで組んだ中にtableを入れ子でいれているようです。
どうやら石巻かほくさんはheight=”681″の記述部分を手動で変更しているらしく、自動でクロールしているクローラーがときどきパースでエラーを起こしていました。

まず、このTDタグの中身を取得します。
PHPだとpreg_match関数を使用し以下のように書けば取得できます。

preg_match("/(.+?)<\/TD>/s", $HTML, $Kiji);

$HTML  ソース
$Kiji[0] TD入りの切り刻んだ記事が入ります
$Kiji[1] TDを除いた切り刻んだ記事が入ります

この場合にはTDが必要ないので$Kiji[1]を使用します。
データをキレイにします。

$main_kiji = str_replace("
","",$Kiji[1]); $Kiji = str_replace("\n","",$Kiji);

これで、BRタグと改行を取り除きます。

キレイになったところで、preg_match_all関数を使用して、変数中に存在するaタグを全て取り出し、配列に格納します。

preg_match_all("/<A href\=\"news(.+?)\">(.+?)<\/A>/s", $Kiji, $Midashi);

これで$Midashi配列に全ての記事のリンクが入ることになります。

それで、これをHTMLとしてジェネレートして好きな形で吐き出すことでデータの生成は終了です。

また当サイトではニュースの更新データをRSSとして吐き出しています。

これらのデータを生成する際にはリンクを更に細かく切り刻みURLとテキストに分けます。
そこからUTF-8にエンコードをして、XMLの形にして、ジェネレートして吐き出してあげます。

ジェネレートのタイミングは3時間おきで、指定のプログラムをcronでキックし定期的に生成しています。

記事の見出しを勝手に拝借している形なので、注意があった際には公開を停止しようと考えています。

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

2009 年 3 月 1 日

dp.SyntaxHighlighterでソースコードを表示

カテゴリー: 未分類 — admin @ 11:15 PM

ソースコードを表示する際に、見た目をキレイに表示してくれるJavascriptライブラリが「dp.SyntaxHighlighter」です。

SyntaxHighlighter のすすめを参考にして実装してみました。

実装の仕方を以下に記述します。

1.ソースの入手
ソースのダウンロードを行います。
以下のGoogleCodeで入手できます。
http://code.google.com/p/syntaxhighlighter/

また、ツールバーの表示が日本語化される改造版のパッチを当てます。
パッチはこちらからダウンロードします。
パッチファイルを解凍後にSyntaxHighlighter.css と shCore.jsを上書きします。

2.アップロード
ファイルをアップロードします。
当サイトでは。以下のように配置しました。

/home/hebita/www/css/sh/SyntaxHighlighter.css
/home/hebita/www/css/sh/clipboard.swf
/home/hebita/www/js/sh/shBrush****.js

これでファイルの準備は完了。

3.テンプレートの修正
ブログで表示するためには、テンプレートの修正作業が必要となります。

3-1.HeadタグにJSとCSSの埋め込み
サーバへアップロードしたJavascriptとCSSを読み込むように設定します。

<head>


    
    
    
    
    
    

    
</head>

3-2.エントリー部分の後ろにJSタグ挿入

<script type="text/javascript">
dp.SyntaxHighlighter.ClipboardSwf = "http://hebita.jp/css/sh/clipboard.swf";
dp.SyntaxHighlighter.HighlightAll("code");
</script>

このタグを入れることで該当する<pre>タグに変換をかけます。

これで準備は完了です。

4.記述の仕方
実際の書き方です。
ブログには以下のように記述します。
PHPのソースコードの場合。

<pre name="code" class="php:firstline[1]">
ここに記述
</pre>

これでブログにソースコードを記述することができます。

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

2009 年 1 月 27 日

PHPでのフレームワーク作成 その1

カテゴリー: 未分類 — admin @ 1:12 AM

当サイトはPHPで作成しています。

多少、フレームワークっぽくしてサイトの構成を実現しています。
ホームページ作成において、最も重要となるのが

HTMLファイルをどのように扱うか」

ということになります。

PHPでページを表示することになるので、出来る限り、「ロジック」と「テンプレート」は分けたいものです。
そうすることによって、PHPのソースコードがとても見やすくなり、メンテナンスしやすくなります。

ですが、フレームワークチックにするとやはり、デメリットもあります。
それは、フレームワークを理解するためのコストが掛かるということです。

一般的なフレームワークを使うのであれば、上記のようなデメリットも発生しますが、一からフレームワークを作成すれば、そんな苦労はなくなりますし、なにより、手が入れやすいです。

まず、ロジックとテンプレートの切り分け方法を考えます。

プログラムロジックは各ページのindex.phpに任せます。

サーバーのrewriteruleを調整して一箇所のindex.phpにアクセスを集めて、パラメータで処理ワケをするという手もありますが、それ程大規模なサイトでなければガチガチに、アクセスを集めるよりも柔軟な対応ができる方がいいと思います。

rewriteruleはこまかくいじれない場合が多いですからね。

ですので。

Document Root
/home/hebita/www/

/home/hebita/www/index.php
/home/hebita/www/news/index.php
/home/hebita/www/weather/index.php
/home/hebita/www/tv/index.php

これらのindex.phpにロジックを持たせています。

それから、対となるテンプレートは

/home/hebita/www/template

以下に分かりやすく配置してあげます。

当サイトでは共通するテンプレートをcommonとして扱い、各ページで使用するテンプレートをpartsとして扱っています。
ですので、以下のようなテンプレート配置としています。

/home/hebita/www/template/common
/home/hebita/www/template/parts
/home/hebita/www/template/AD
/home/hebita/www/template/gen
/home/hebita/www/template/Base.html

こんな感じで配置しています。

ADディレクトリ
広告パーツを配置しています。
GoogleAdsenseやYahoo!IMやAmazonの広告配信用のJavascriptとなっているHTMLを置いておくことで、どの場所からも呼び出せるようにしています。

genディレクトリ
HTMLをジェネレートする際に読み込むエレメントパーツを配置しておきます。
HTMLパーツのジェネレートプログラムからエレメントを呼び出して静的HTMLを作成するパーツとなります。

Base.html
全てのページを表示する際に読み込まれる大元のHTMLとなります。
実際にアクセスすると分かるのですが。
http://hebita.jp/template/Base.html
中身は

<!-- HEADER -->
<!-- CONTENTS -->
<!-- FOOTER -->

こんな内容になっています。

大元のファイルはこれだけで、一つの画面を構成させることができます。

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

2009 年 1 月 20 日

Webスクレイピング

カテゴリー: 未分類 — タグ: , , — admin @ 11:24 PM

Webスクレイピングとは
はてなでは

英語で”scrape”とは「削ること」。
特に、ウェブサイトのデータを必要な部分だけ抽出して利用すること。

なんて紹介されています。
個人でホームページを作る場合に欲しくてたまらなくなるものが、「データ」ですね。
つまり、Webスクレイピングとは
欲しいデータを掲載しているサイトそのものをプログラムでダウンロードし、欲しいデータだけを取得し加工しましょうというものです。
それ程難しいものではなく、PHPであれば簡単に実行できてしまいます。
プログラムの大まかな流れは

  1. HTTP通信でデータ(HTMLページ)を取得(ダウンロード)
  2. 取得したHTMLを変数として扱い「正規表現」で欲しいデータだけを取得
  3. データを加工し、(可能であれば)HTMLとしてジェネレートし出力する

といった流れになります。
可能であればHTMLとしてジェネレートするというのには理由があります。
自サイトにアクセスが発生する際にいちいち、PHPによって他のサイトまでHTTPの通信を行うと、非常にコストがかかりますし、他のサイトさんにも迷惑をかけます。
(Webスクレイピングをしている時点で迷惑をかけている感はありますが・・・)
ですので、可能であればcronでキックされるジェネレート方式にした方がいいかと思います。
今回は、Webスクレイピングで簡単にいろいろなデータを取得したいと思い、クラスを作成してみました。
スクレイピングするために以下のようなクラスを作ってみました。

<?php
// WebScrapingをするツール
Class WebScraping{
function __construct($sURL){
// ターゲットURL
$this->sURL = $sURL;
// Get
ini_set('user_agent', 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');
$this->sSrc = @file_get_contents($sURL);
$this->aHtml = $this->sSrc;
}
////////////////////////////////////////////////
// 正規表現をセットし
// 切り取ったデータを返す
// 2: 正規表現分なし = 1
//		正規表現分あり = 0
////////////////////////////////////////////////
function RegexAllGet($regex,$sReturn){
preg_match_all("/$regex/s",$this->sSrc,$this->aHtml);
if($sReturn){
$this->aHtml = $this->aHtml[1];
}else{
$this->aHtml = $this->aHtml[0];
}
return $this->aHtml;
}
////////////////////////////////////////////////
// もらった配列をメンバ変数としてセットしなおす
////////////////////////////////////////////////
function SetHtml($aHtml){
$this->aHtml = $aHtml;
}
////////////////////////////////////////////////
// 1: 正規表現
// 2: 正規表現分なし = 1
//		正規表現分あり = 0
// 3: オプション
//		指定があった場合にはその配列を正規表現で切り刻む
////////////////////////////////////////////////
function RegexGet($regex,$sReturn,$aHtml = NULL){
if(!isset($aHtml)){
$aHtml = $this->aHtml;
}
if(is_array($aHtml)){
$nRow = count($aHtml);
$i = 0;
$aResult = array();
while($nRow > $i){
preg_match("/$regex/s",$aHtml[$i],$aResult);
$aResult_0[$i] = $aResult[0];
$aResult_1[$i] = $aResult[1];
$i++;
}
if($sReturn){
$this->aHtml = $aResult_1;
}else{
$this->aHtml = $aResult_0;
}
return $this->aHtml;
}else{
preg_match("/$regex/s",$aHtml,$aResult);
if(empty($aResult)){
return 1;
}
if($sReturn){
$this->aHtml = $aResult[1];
}else{
$this->aHtml = $aResult[0];
}
return $this->aHtml;
}
}
}
?>

使い方はこんな感じ

  <?php
require_once('WebScraping.php');
$sURL = 'http://dailynews.yahoo.co.jp/fc/';
$oWS = new WebScraping($sURL);
$regex = '
    (.*?)
'; $aHtml = $oWS->RegexAllGet($regex,1); // $aHtmlにヤフートピックスの見出しが配列として入ります。 ?>

ただ、ここで注意するのはHTTPでファイルを取得しに行く際にPHPの標準関数である

file_get_contents

を使用しています。
これはセキュリティ上サーバによっては許可されていない場合もあります。
php.iniファイルをいじることができるのであれば、

allow_url_fopen = On

とします。
当サイトにおいては、とあるサイトからデータを取得する際には上で紹介したようなclassを用いてページをジェネレートしています。
例えば、トップページで言えば

  • ニュース記事の見出し
  • 仙台放送女子アナブログ
  • イオン ショップ情報
  • ワーナー・マイカル・シネマズ 新石巻

等の情報を定期的にクロールをして取得しています。
やり方はいろいろあると思うのですが、機会があったらチャレンジしてみてください!

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

2009 年 1 月 1 日

プロフィール 164

カテゴリー: 未分類 — admin @ 11:33 PM

プロフィールを書いて個人ブログをスタートしようと思います。

管理人名 164(ひろし)
性別
年齢 23
出身 宮城県石巻市
住んでいるとこ 東京都練馬区
職業 Webエンジニア
PHP、Perl、Ruby
(HTML、CSS、Javascript)
好きなテレビ 大河ドラマ
趣味 サッカー
ホームページ作成

当ブログは管理人のメモとして使おうと思っています。
お問い合わせがございましたら書きURLの入力フォームよりよろしくお願いいたします。

お問い合わせ

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加 古い投稿 »