<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>ロックオン開発チームブログ -Lockon Knowledge Repositories-</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/" />
   <link rel="self" type="application/atom+xml" href="http://www.lockon.co.jp/blog/atom.xml" />
   <id>tag:www.lockon.co.jp,2010:/blog//1</id>
   <updated>2010-02-05T11:36:01Z</updated>
   
   <generator uri="http://www.sixapart.com/movabletype/">Movable Type 3.31-ja</generator>

<entry>
   <title>FirefoxのアドオンJetPackを試す</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/firefoxjetpack_1.html" />
   <id>tag:www.lockon.co.jp,2009:/blog//1.1169</id>
   
   <published>2009-05-30T07:02:00Z</published>
   <updated>2010-02-05T11:36:01Z</updated>
   
   <summary>どうも、ソリューションチームの中西です。 Firefoxのアドオンとして発表され...</summary>
   <author>
      <name>ぼーだー</name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[どうも、ソリューションチームの中西です。<br />
Firefoxのアドオンとして発表されたJetpackが話題になっているようですのでちょっと遊んでみます。<br />
JetpackはFirefoxのアドオンを作りやすくするアドオンです。<br />
JavaScriptライブラリの<a href="http://jquery.com/">JQuery</a>で作成することができます。
とりあえずJetpackをインストールします。
下記サイトのGetStartedをクリックしてからFirefoxを再起動してください。<br />
<a href="https://jetpack.mozillalabs.com/">https://jetpack.mozillalabs.com/</a>
<img src="http://www.lockon.co.jp/blog/dcnjfm9c_83dnprqsdn_b.png" alt="dcnjfm9c_83dnprqsdn_b.png" width="400" height="300" />
インストールされたらさっそく試してみましょう。<br />
ロケーションバーに　about:jetpack　と入力してください。<br />
Jetpackの設定画面が表示されます。<br />
ここではJetpack開発のチュートリアルやらインストールされているJetpackスクリプトの管理、そして開発が行えます。<br />
<img src="http://www.lockon.co.jp/blog/dcnjfm9c_85ggzcr9cz_b.png" alt="dcnjfm9c_85ggzcr9cz_b.png" width="400" height="300" />
Developタブを押すとエディタ上で開発が行えます。<br />
「try out this code」の部分を押せばすぐに動作確認できます。<br />
<img src="http://www.lockon.co.jp/blog/dcnjfm9c_86gfmbqfcb_b.png" alt="dcnjfm9c_86gfmbqfcb_b.png" width="400" height="300" />
開発する場合はFirebugがあった方が良いです。<br />
<br />
では、そろそろ開発を。<br />
まずはお約束Hello,Worldから。<br />
----------------------------------<br />
<pre>
$(function(){<br />
&nbsp; jetpack.statusBar.append({<br />
&nbsp; onReady: function(doc){<br />
&nbsp; jetpack.notifications.show(&quot;Hello , Jetpack&quot;);<br />
}<br />
&nbsp;});<br />
});<br />
</pre>
----------------------------------<br />
実行するとお約束な文字列が表示されます。<br />
<br />
もうちょっと色々さわってみます。<br />
ステータスバーにロックオンが誇る<a href="http://www.ebis.ne.jp/">Ebis</a>のマスコットのエビス君のアイコンを表示させてみましょう。<br />
そしてエビス君をクリックするとHello,Ebisと表示させるようにします。<br />
<br />
----------------------------------<br />
<pre>
$(function(){<br />
jetpack.statusBar.append({<br />
//エビス君のアイコンを表示させる。<br />
html: &#39;&lt; img src=&quot;http://www.ebis.ne.jp/favicon.ico&quot; alt=&quot;&quot; width=&quot;20&quot; height=&quot;20&quot; /&gt;&#39;,<br />
width: 20 ,<br />
//クリックするとメッセージを表示させる。<br />
onReady: function(doc){<br />
$(doc).find(&quot;img&quot;).click(function(){<br />
jetpack.notifications.show(&quot;Hello ,Jetpack&quot;);<br />
});<br />
}<br />
});<br />
});<br />
</pre>
----------------------------------<br />
<br />
と、まあ、こんな感じで比較的簡単にFirefoxに機能を追加することができます。<br />
かなりお気軽に拡張機能が作れるようになっていますので皆様もアドオン開発にじゃんじゃんチャレンジしてください。
&nbsp;
じつは恥ずかしながらJQueryを触った事が無かったのでJQueryで戸惑いました&hellip;<br />
ついでにJQueryも勉強します。
]]>
      
   </content>
</entry>
<entry>
   <title>Boots C++でspiritを利用しての構文解析</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/boots_cspirit_1.html" />
   <id>tag:www.lockon.co.jp,2008:/blog//1.940</id>
   
   <published>2008-12-05T05:00:50Z</published>
   <updated>2008-12-05T04:50:30Z</updated>
   
   <summary>こんにちは、にゃんです。 　 今回は構文解析について少しだけお話ししたいと思いま...</summary>
   <author>
      <name>たけにゃん</name>
      <uri>dev</uri>
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[こんにちは、にゃんです。
　
今回は構文解析について少しだけお話ししたいと思います。
　
構文解析というと、難しくとらえがちですが
ライブラリやツールを使用することで簡単に実装ができます。
　
実際の利用に近いソースを記述するとわかりにくくなるので
構文解析の手法を学ぶための単純なソースを記述します。
　
少し改造を行うだけでもcsv解析などはすぐに作成できるでしょう。
機会があれば、そのあたりも紹介したいと思います。
　
使用する言語はC++です。
今回はboostライブラリーを使用して構文解析を行います。
　
boostライブラリについては多くのサイトで紹介されていますが
その中で今回は「spirit」についてです。
　
どのようなライブラリかと言うと文字列解析(構文解析)等に用いられます。
一般的にはyaccなどで作成したファイルを流用することが多いのですが
設定が面倒なので　にゃんは、boostライブラリで解析を行っています。
　
さっそく簡単な構文解析をおこなってみましょう。
スペース区切りでデータを分解してくれるプログラムです。
　
-----------------------------------------------------
<PRE style="font-size:14px;"><FONT COLOR="#000099">#include &lt;string&gt;
#include&lt;boost/spirit.hpp&gt;
</FONT><FONT COLOR="#990000">
using namespace</FONT> std<B><FONT COLOR="#663300">;</FONT></B><FONT COLOR="#990000">
using namespace</FONT> boost<B><FONT COLOR="#663300">::</FONT></B>spirit<B><FONT COLOR="#663300">;</FONT></B><FONT COLOR="#FF6633">

void</FONT> out<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#FF6633">char</FONT><FONT COLOR="#990000"> const</FONT><B><FONT COLOR="#663300">*</FONT></B>p1<B><FONT COLOR="#663300">,</FONT></B><FONT COLOR="#FF6633"> char</FONT><FONT COLOR="#990000"> const</FONT><B><FONT COLOR="#663300">*</FONT></B>p2<B><FONT COLOR="#663300">) {</FONT></B>
        cout<B><FONT COLOR="#663300"> &lt;&lt;</FONT></B> p1<B><FONT COLOR="#663300"> &lt;&lt;</FONT></B> endl<B><FONT COLOR="#663300">;
}</FONT></B><FONT COLOR="#990000">

struct</FONT> Test<B><FONT COLOR="#663300"> :</FONT></B><FONT COLOR="#990000">public</FONT> grammar<B><FONT COLOR="#663300">&lt;</FONT></B>Test<B><FONT COLOR="#663300">&gt;{</FONT></B><FONT COLOR="#990000">
        template</FONT><B><FONT COLOR="#663300">&lt;</FONT></B><FONT COLOR="#990000">typename</FONT> T<B><FONT COLOR="#663300">&gt;</FONT></B><FONT COLOR="#990000">
        struct</FONT> definition<B><FONT COLOR="#663300">{</FONT></B>
                rule<B><FONT COLOR="#663300">&lt;</FONT></B>T<B><FONT COLOR="#663300">&gt;</FONT></B> expr<B><FONT COLOR="#663300">,</FONT></B> data<B><FONT COLOR="#663300">;</FONT></B>
                definition<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#990000">const</FONT> Test<B><FONT COLOR="#663300">&amp;</FONT></B> self<B><FONT COLOR="#663300">){</FONT></B>
                        expr<B><FONT COLOR="#663300"> =</FONT></B> data<B><FONT COLOR="#663300"> |</FONT></B> ch_p<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#009900">'\n'</FONT><B><FONT COLOR="#663300">);</FONT></B>
                        data<B><FONT COLOR="#663300"> = (*</FONT></B>alnum_p<B><FONT COLOR="#663300">)[&amp;</FONT></B>out<B><FONT COLOR="#663300">];
                }</FONT></B><FONT COLOR="#990000">
                const</FONT> rule<B><FONT COLOR="#663300">&lt;</FONT></B>T<B><FONT COLOR="#663300">&gt;&amp;</FONT></B> start<B><FONT COLOR="#663300">()</FONT></B><FONT COLOR="#990000"> const</FONT><B><FONT COLOR="#663300">{</FONT></B><FONT COLOR="#FF0000">
                        return</FONT> expr<B><FONT COLOR="#663300">;
                }
        };
        
};</FONT></B><FONT COLOR="#FF6633">

int</FONT><FONT COLOR="#990000"> main</FONT><B><FONT COLOR="#663300">(){</FONT></B>
        Test test<B><FONT COLOR="#663300">;</FONT></B>
        string str<B><FONT COLOR="#663300"> =</FONT></B><FONT COLOR="#009900"> "表示 用文 字列"</FONT><B><FONT COLOR="#663300">;</FONT></B>
        parse<B><FONT COLOR="#663300">(</FONT></B>str<B><FONT COLOR="#663300">.</FONT></B>c_str<B><FONT COLOR="#663300">(),</FONT></B>test<B><FONT COLOR="#663300">,</FONT></B>space_p<B><FONT COLOR="#663300"> |</FONT></B> ch_p<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#009900">'\n'</FONT><B><FONT COLOR="#663300">));</FONT></B><FONT COLOR="#FF0000">
        return</FONT><FONT COLOR="#999900"> 0</FONT><B><FONT COLOR="#663300">;
}</FONT></B></PRE>
-----------------------------------------------------
　
簡単に解説を行いますと、boostで定義されているgrammarクラスをTestクラスが継承し、
その中に解析ルールを記述します。
　
expr = data | ch_p('\n');
data = (*alnum_p)[&out];
　
こちらが解析ルールとなります。
　
BNF等で解析ルールを説明するのが良いのですが、今回はスペース区切りで
解析を行うので必要ないでしょう。
　
exprはdataか改行というルールとなります。
dataは「alnum_p」が英数字と数値を意味し「*alnum_p」で*をつけることにより複数の文字を意味します。
(*alnum_p)[&out];で解析結果をout関数へ送ることができます。
　
Boostライブラリーはこのように、扱いさえ覚えれば非常に有効なものですので
皆様もぜひ触ってみてください。
]]>
      
   </content>
</entry>
<entry>
   <title>C++のnew,deleteのオーバーライド</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/cnewdelete_1.html" />
   <id>tag:www.lockon.co.jp,2008:/blog//1.856</id>
   
   <published>2008-09-23T23:36:58Z</published>
   <updated>2008-09-30T01:15:35Z</updated>
   
   <summary>こんにちは。 にゃん と申します。 今までの開発ブログではないネタを書きます。 ...</summary>
   <author>
      <name>たけにゃん</name>
      <uri>dev</uri>
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[こんにちは。
にゃん と申します。

今までの開発ブログではないネタを書きます。
いまさらC++です！

もともと、にゃんはC言語,C++系でDirectX等を学んでいましたので
このようなネタが中心となります。

皆様はC++にはnewとdeleteをオーバーライドができるのをご存知でしょうか？
余り使用されていませんが今回はnewとdeleteのオーバーライドの一例を
ご紹介させていただきたいと思います。
先にソースを記述します。
//////////ここからソース//////////
<pre　style='padding-top:0xp;text-indent:10px;
'><font color="#c0c0c0">     1 :</font>	#include &lt;stdio.h&gt;
<font color="#c0c0c0">     2 :</font>	
<font color="#c0c0c0">     3 :</font>	<font color="green">// 確保する配列の個数</font>
<font color="#c0c0c0">     4 :</font>	#define MEMORY_ERIA 10
<font color="#c0c0c0">     5 :</font>	
<font color="#c0c0c0">     6 :</font>	
<font color="#c0c0c0">     7 :</font>	<font color="blue">class</font> Test{
<font color="#c0c0c0">     8 :</font>	<font color="blue">private</font>:
<font color="#c0c0c0">     9 :</font>	    <font color="green">// newで使用されるメモリー領域</font>
<font color="#c0c0c0">    10 :</font>	    <font color="blue">static</font> Test gm_Memory[MEMORY_ERIA];
<font color="#c0c0c0">    11 :</font>	    <font color="green">// 使用されている個数</font>
<font color="#c0c0c0">    12 :</font>	    <font color="blue">static</font> <font color="blue">unsigned</font> <font color="blue">int</font> gm_useMemory;
<font color="#c0c0c0">    13 :</font>	    <font color="green">// 使用フラグ</font>
<font color="#c0c0c0">    14 :</font>	    <font color="blue">bool</font> m_use;
<font color="#c0c0c0">    15 :</font>	<font color="blue">public</font>:
<font color="#c0c0c0">    16 :</font>	    <font color="green">// コンストラクタ</font>
<font color="#c0c0c0">    17 :</font>	    Test(){
<font color="#c0c0c0">    18 :</font>	    }
<font color="#c0c0c0">    19 :</font>	    <font color="green">// デストラクタ</font>
<font color="#c0c0c0">    20 :</font>	    ~Test(){
<font color="#c0c0c0">    21 :</font>	    }
<font color="#c0c0c0">    22 :</font>	    <font color="green">// newのオーバーライド</font>
<font color="#c0c0c0">    23 :</font>	    <font color="blue">void</font>* <font color="blue">operator</font> <font color="blue">new</font>(size_t t){
<font color="#c0c0c0">    24 :</font>	        gm_useMemory++;
<font color="#c0c0c0">    25 :</font>	        <font color="blue">for</font>( <font color="blue">int</font> i = 0; i &lt; MEMORY_ERIA; i++ ){
<font color="#c0c0c0">    26 :</font>	            <font color="blue">if</font>( !gm_Memory[ i ].m_use ){
<font color="#c0c0c0">    27 :</font>	                gm_Memory[ i ].m_use = <font color="blue">true</font>;
<font color="#c0c0c0">    28 :</font>	                <font color="blue">return</font> &amp;gm_Memory[ i ];
<font color="#c0c0c0">    29 :</font>	            }
<font color="#c0c0c0">    30 :</font>	        }
<font color="#c0c0c0">    31 :</font>	        <font color="blue">return</font> NULL;
<font color="#c0c0c0">    32 :</font>	    }
<font color="#c0c0c0">    33 :</font>	    <font color="green">// deleteのオーバーライド</font>
<font color="#c0c0c0">    34 :</font>	    <font color="blue">void</font> <font color="blue">operator</font> <font color="blue">delete</font>(<font color="blue">void</font>* test){
<font color="#c0c0c0">    35 :</font>	        ((Test*)test)-&gt;m_use = <font color="blue">false</font>;
<font color="#c0c0c0">    36 :</font>	        gm_useMemory--;
<font color="#c0c0c0">    37 :</font>	    }
<font color="#c0c0c0">    38 :</font>	};
<font color="#c0c0c0">    39 :</font>	
<font color="#c0c0c0">    40 :</font>	<font color="green">// newで使用されるメモリー領域</font>
<font color="#c0c0c0">    41 :</font>	Test Test::gm_Memory[MEMORY_ERIA] = {};
<font color="#c0c0c0">    42 :</font>	<font color="green">// 使用されている個数</font>
<font color="#c0c0c0">    43 :</font>	<font color="blue">unsigned</font> <font color="blue">int</font> Test::gm_useMemory = 0;
<font color="#c0c0c0">    44 :</font>	 
<font color="#c0c0c0">    45 :</font>	<font color="blue">int</font> main(){
<font color="#c0c0c0">    46 :</font>	    <font color="green">// データを確保</font>
<font color="#c0c0c0">    47 :</font>	    Test* data[MEMORY_ERIA];
<font color="#c0c0c0">    48 :</font>	    <font color="green">// 初期化</font>
<font color="#c0c0c0">    49 :</font>	    <font color="blue">for</font>(<font color="blue">int</font> i=0;i&lt;MEMORY_ERIA;i++){
<font color="#c0c0c0">    50 :</font>	        data[i]=<font color="blue">new</font> Test();
<font color="#c0c0c0">    51 :</font>	    }
<font color="#c0c0c0">    52 :</font>	    <font color="green">// 偶数番目を削除</font>
<font color="#c0c0c0">    53 :</font>	    <font color="blue">for</font>(<font color="blue">int</font> i=0;i&lt;MEMORY_ERIA;i++){
<font color="#c0c0c0">    54 :</font>	        <font color="blue">if</font>( i % 2 == 0 ){
<font color="#c0c0c0">    55 :</font>	            <font color="blue">delete</font> data[i];
<font color="#c0c0c0">    56 :</font>	            data[i] = NULL;
<font color="#c0c0c0">    57 :</font>	        }
<font color="#c0c0c0">    58 :</font>	    }    
<font color="#c0c0c0">    59 :</font>	     <font color="blue">return</font> 0;
<font color="#c0c0c0">    60 :</font>	}</pre>
//////////ここまでソース//////////
以上がソースとなりますがこのプログラムの特徴は
　　newを行っていても不特定のメモリーが確保されない。
　　newを行える最大領域が決定している。
　　operatorを駆使することで配列アクセスを可能となる。
　　deleteでの解放処理が簡易であるため構想に動作する。
　　メモリーマップを見るデバッグが容易である。
その他にもさまざまですが主な特徴となります。

ソースコードの量に対し説明する項目が少ないですが
１０、１２行目でグローバル変数を定義しています。
これらがnew,delete時に使用される配列となります。
defineで「MEMORY_ERIA」を定義し最大確保数を決定しています。
１４行目の「m_use」で現在のメモリーが使用されているかの判定を行います。
newを置こうと「m_use」が「true」になりdeleteを行うと「false」になります。
したがってprivate宣言となっていますがこれは各内部関数からでも不用意に変更してはダメな
ローカル変数となります。

23行目からのnewのオーバーライド部分ですがgm_Memory変数配列からm_use
が使用されていない部分を探しポインターを返しているだけとなります。
34行目のdeleteはさらに単純で「void*」が引数に存在するのでこれをクラス名で
キャストを行い、m_useのフラグを「false」に変更するだけです。
これらがnew,deleteのオーバーライドに対する説明となります。

では、どのようなシステムに流用できるかですが、
今回のソースはnew,deleteのオーバーライドを実装するためだけのソースですが
これらを改良し、にゃんは主にタスクリスト(連結リスト)に使用しています。
その他に配列数が固定のスタック等にも応用可能かもしれません。

機会があれば応用編も行いたいと思います。
ソースコードの量が肥大化しすぎるため苦しいかもしれませんが
では、またお会いしましょう
にゃんでした。
]]>
      
   </content>
</entry>
<entry>
   <title>PHPでopenSSLが有効でないとハマるとき</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/php/phpopenssl.html" />
   <id>tag:www.lockon.co.jp,2008:/blog//1.831</id>
   
   <published>2008-09-08T01:32:24Z</published>
   <updated>2008-09-08T01:59:39Z</updated>
   
   <summary>PEARのHTTP_RequestやHTTP_Clientで、通常のHTTPなら...</summary>
   <author>
      <name>ふく</name>
      
   </author>
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      PEARのHTTP_RequestやHTTP_Clientで、通常のHTTPなら返ってくるのですが、SSLサイトを取りに行こうとすると、中身が返ってこないという現象に遭遇しました。
　
　
ブラウザで叩くとしっかり存在します。

試しにfopenやfile_get_contetnsで開こうと思ってもダメ。

というところまできて、php.iniの設定を洗ってみたところ、やっぱPHPのインストール時にミスっていてopenSSLが有効になっていないことに気づきました。

--with-openssl=[dir]
が通っていないときは、無言で返ってくるようです。
　
　
ってことで、PHPでSSLが？ってときは、OpenSSLが組み込まれているか、真っ先に確認すると幸せになれそうです。(・∀・)
      
   </content>
</entry>
<entry>
   <title>Rubyで顔認識</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/ruby_1.html" />
   <id>tag:www.lockon.co.jp,2008:/blog//1.631</id>
   
   <published>2008-04-22T01:00:00Z</published>
   <updated>2008-04-23T05:13:43Z</updated>
   
   <summary>こんにちは。 ロックオンの中西です。 久しぶりに開発ブログを書きます。 今回はR...</summary>
   <author>
      <name>ぼーだー</name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[こんにちは。
ロックオンの中西です。<br />
久しぶりに開発ブログを書きます。<br />
今回はRubyで画像内の人物の顔の認識を行いたいと思います。<br />
最近、社内で「攻殻機動隊」がちょっと流行っているので「笑い男」にならってやってみました。<br />
でも、人気があるのかネットで検索したら同じ様な事してる人はかなり多いですね。<br />
Rubyと画像処理ライブラリの<a href="http://sourceforge.net/projects/opencvlibrary/">OpenCV</a>を利用します。
こちら各環境に合わせてインストールしてください。また、Ruby画像処理の画像処理ライブラリのRMagickと
RubyのOpenCVを利用したの物体認識ライブラリのObjectdetectも用います。
これらはgemでインストールできます。<br />
<br />
以下は顔を認識して四角形を描画するプログラムです。<br />
require &#39;rubygems&#39;<br />
require &#39;RMagick&#39;<strong><br />
require &#39;objectdetect&#39;</strong>

<strong>#OpenCVのインストールディレクトリの中の顔認識のxmlを利用する
model_path = &#39;OpenCVのディレクトリ/opencv/haarcascades/haarcascade_frontalface_alt2.xml&#39; # 要変更</strong>

#読み込むファイル名、実行時にファイル名を引数として与える<br />
<strong>file = ARGV[0]</strong>

<strong>#顔の位置を検出<br />
array_face_position = ObjectDetect::detect(model_path, file)
original_img = Magick::ImageList.new(file)</strong>

<strong>#四角形を書くための設定<br />
square = Magick::Draw.new
square.stroke(&#39;green&#39;)
square.fill_opacity(0)
square.stroke_width(1)</strong>

<strong>#顔を検出するごとに四角形を描画する<br />
array_face_position.each do |position|<br />
x, y, width, height = position square.polyline(x,y,x+width,y,x+width,y+height,x,y+height,x,y)
square.draw(original_img)<br />
end</strong>

#画像を出力、実行時に引数２として与える。固定でもいいけど。
original_img.write(ARGV[1]+&#39;.jpg&#39;)

以下は顔認識の結果になります。
画像は採用ブログより引用しました。
<img src="http://www.lockon.co.jp/blog/lena_out.jpg" alt="lena_out.jpg" width="256" height="256" />
<br />
まずは画像処理といえばlenaさん。<br />
問題なく検出できています。

<img src="http://www.lockon.co.jp/blog/test_out3.jpg" alt="test_out3.jpg" width="240" height="180" />
<br />
ひょうきんになった愛弟子。
おもしろ眼鏡着用でも問題ありません。

<img src="http://www.lockon.co.jp/blog/test_out6.jpg" alt="test_out6.jpg" width="240" height="427" />
<br />
ゲシュタルトの限界に迫った表情でも問題なく検出できます。<br />
高性能。

<img src="http://www.lockon.co.jp/blog/test_out1.jpg" alt="test_out1.jpg" width="240" height="400" />
<br />
セクシーな表情は検出できず。。。<br />
残念です。

とまあ、検出能力はこんな感じです。
目と口の位置が検出のポイントだと思います。<br />
顔は複数あっても検出できます。<br />
<br />
下にあるのは指定した画像を検出した顔に貼付けるプログラムです。<br />
貼付けてるのは<a href="http://images.google.co.jp/images?q=%E7%AC%91%E3%81%84%E7%94%B7%E3%83%9E%E3%83%BC%E3%82%AF&amp;lr=lang_ja&amp;ie=UTF-8&amp;oe=utf-8&amp;rls=org.mozilla:ja:official&amp;client=firefox-a&amp;um=1&amp;sa=N&amp;tab=wi">「笑い男マーク」</a>じゃなく弊社のキャラクターの<a href="http://www.ebis.ne.jp/">エビス</a>君。
<img src="http://www.lockon.co.jp/blog/out_ebis.jpg" alt="out_ebis.jpg" width="448" height="300" />

<strong>require&#39;rubygems&#39;<br />
require &#39;RMagick&#39;<br />
require &#39;objectdetect&#39;</strong>

<strong>model_path = &#39;OpenCVのディレクトリ/opencv/haarcascades/haarcascade_frontalface_alt2.xml&#39; # 要変更</strong>

<strong>file = &quot;test.jpg&quot;
array_face_position = ObjectDetect::detect(model_path, file)
original_img = Magick::ImageList.new(file)</strong>

<strong>#合成する画像を読み込み<br />
src_image = Magick::Image.read(&quot;ebis.png&quot;)[0]</strong>

<strong>#Drawインスタンス生成<br />
draw_instance = Magick::Draw.new<br />
<br />
#顔を検出したら画像を上書きする<br />
array_face_position.each do |position|<br />
x, y, width, height = position
draw_instance.composite(x-10,y-10,width+20,height+20,src_image,Magick::OverCompositeOp)
draw_instance.draw(original_img)<br />
end<br />
<br />
#画像を出力<br />
original_img.write(&#39;out.jpg&#39;)</strong><br />
<br />
まだまだ本物には遠い感じですがプログラムってこういうこともできるよって事で。<br />
<br />
参考：<a href="http://d.hatena.ne.jp/darashi/20070223/1172232765">dara日記 「OpenCVで物体認識を行うRuby拡張ライブラリのソース」</a>]]>
      
   </content>
</entry>
<entry>
   <title>Postgresql8.3のチューニングの合宿</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/postgresql83.html" />
   <id>tag:www.lockon.co.jp,2008:/blog//1.602</id>
   
   <published>2008-03-12T12:16:20Z</published>
   <updated>2008-03-12T12:51:45Z</updated>
   
   <summary>みなさん、こんにちわ。 ロックオンの高橋です。 2月23日(土曜日)から2月24...</summary>
   <author>
      <name>takahashi</name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[みなさん、こんにちわ。
ロックオンの高橋です。
<p>
2月23日(土曜日)から2月24日(日曜日)に佐賀県で開かれたPostgresql8.3のチューニングの合宿に<p>行って参りました。<p>
僕の所属するSaaSチームでも、Postgresql8.3が、今までのPostgresql8.2よりも圧倒的に速い！！<p>
と言うことを聞いていまして、Bata版から試しており、その速さには驚いておりました。<p>

ただ、Postgresql8.3では、postgresql8.2の頃で利用していた設定のパラメータを変えなくても
速くて、逆に、どこをチューニングしたらよいかを悩んでおりましたので、
今回の合宿は勉強になりました。
<p>
合宿で行ったチューニング内容や結果は、Postgresqlのメーリングリストで、
詳しい内容が流れていますので、僕がここで記載するよりも、
そちらをご覧になられた方が良いと思います。<p>
どうも、今回のチューニングは、非同期コミットとかが肝になりそうですね。<p>

あと、今回の合宿では、チューニングあまり、話には出ませんでしたが、
Postgresql8.3からサポートされた機能で、個人的に興味があるものが2点あります。
<p>
まず、1点目は、XML対応です。
以前から、XMLDBというものに興味はありましたが、
忙しかったということもあって、試す機会がありませんでした。

ただ、ロックオンでは、個人で興味があることを研究開発をする時間がありますので、
そちらの時間を用いて、色々と試してみて、結果については、そのうち、
ロックオンの開発ブログなどで公開をしていきたく思いますので、
生暖かい目で見守ってやってください。
<p>
そして、2点目は、Postgresql8.3から、全文検索が日本語で、できるように
なったみたいですので、それが、どれくらいの精度とパフォーマンスが出るのかに興味があります。
多分、そこらへんは、一緒に今回の合宿に参加した松村が所属する、
ロックオンが誇る人工知能の研究開発班の皆さんがやってくれることでしょう。
<p>
最後になりますが、今回の合宿で、関西から参加したメンバーは、
僕と同じチームの松村の2名だけでした。(九州が遠い事が原因かもしれませんが・・)
<p>
PostgreSQLユーザ会理事長の片岡さんのお話では、北海道と九州では、ユーザ会の活動は
活発にあるけど、関西はそうでもない、だけど、東京から見て関西のPostgresqlの開発者が
少ないとは感じない、いう事を仰っていました。
<p>
僕は、関西の活動が少ないのは、関西圏の開発者の絶対数が少ないからだと
思っていたのですが、まわりから見るとそうでもないみたいです。
<p>
僕自身、PostgreSQLユーザ会のような活動に参加したのは、今回が初めてだったのですが、
関西の技術者が、この手の活動にあまり参加していないと思われるのは、
関西住民として寂しいことですので、関西でPostgresqlを使って開発をされている、
エンジニアの方々にも、カンファレンスに参加して頂ければ良いなぁ、と思っております。
<p>
エンジニアでなくても、Postgresqlを盛りあげよう！と思う方ならエンジニアでなくても
オッケーということです。
実際、今回の合宿でも、『Postgresqlってよう分からんのですわ！！でも、
こうゆう活動を盛り上げたいのですわ！』と言われている方が
参加されていて、むっちゃ感動しました。
<p>
ちなみに、次のPostgresqlのカンファレンスは、今週末の3月14日に大阪で開催されます。
もちろん、ロックオンからは、僕と松村は、参加する予定です。
あと、恐ろしい事に、なんか僕と松村が、講演で話すという洒落にならないプランが
進んでいます。
((（ ;ﾟДﾟ)))ｶﾞｸｶﾞｸﾌﾞﾙﾌﾞﾙ
<p>
関西でPostgreqlに自信があるエンジニアの方、マジで参加してください。
僕は盛り上げる方でがんばろうと思いますので・・・(笑)。




<img alt="P1000490.JPG" src="http://www.lockon.co.jp/blog/P1000490.JPG" width="512" height="384" />
<br />
<strong>Postgressql sが多いやん！！</strong>

]]>
      
   </content>
</entry>
<entry>
   <title>圧縮したファイルを添付して、メールで送信</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/post_12.html" />
   <id>tag:www.lockon.co.jp,2007:/blog//1.395</id>
   
   <published>2007-11-22T02:15:58Z</published>
   <updated>2007-11-22T03:05:54Z</updated>
   
   <summary>皆さんこんにちは、まつもとと申します。 「あんなこといいな、出来たらいいな」を合...</summary>
   <author>
      <name>まつけん</name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[皆さんこんにちは、まつもとと申します。
「あんなこといいな、出来たらいいな」を合言葉に、今回は「圧縮したファイルを添付して、メールで送信」する方法を探ってみたいと思います。


▼ファイルを圧縮しよう
さて、ファイルを圧縮する方法ですが、PEARを使うのが一番です。今回は下記を使わせて頂きます。


PEAR::Archive_Zip
http://pear.php.net/package/Archive_Zip


Archive_Zipがインストールされていない場合は、下記でインストールします。
# pear install -f Archive_Zip


圧縮の仕方自体は簡単です。

<pre>
require_once("Archive/Zip.php");

$zip_file = example.zip;               //圧縮した後のファイル名を名付ける
$objZip = new Archive_Zip($zip_file);
$fileName = example.jpg;            //圧縮したいファイル・画像を代入
$objZip->create($fileName);
</pre>

これだけでOKです。ただし、僕も最初はステンと躓いたのですが、ファイルを圧縮する場合はディレクトリの位置に気を付けないといけません（この辺は、試しにテストしてみて下さい）。
このソースを実行するカレントディレクトリ、画像を置いているディレクトリ、圧縮ファイルを置いていたいディレクトリが同じなら問題ありませんが、大抵の場合は違うと思うので、書き直すとするなら……。

<pre>
//--- カレントディレクトリ変更（画像を置いているディレクトリに変更する） ⇒ ファイル圧縮 ⇒ 完成
chdir('/../../../XXX/XXX/example.net/XXX/XXX/XXX');
$zip_file = XXX/XXX/XXX/XXX/XXX/example.zip;        //圧縮した後のファイル名をディレクトリ形式で名付ける
$objZip = new Archive_Zip($zip_file);
$fileName = example.jpg;
$objZip->create($fileName);
</pre>

これでダイジョーブだと思います。予め、

<pre>
echo getcwd();
chdir('/../../../XXX/XXX/example.net/XXX/XXX/XXX');
echo getcwd();
</pre>

など、テストしておけば良いのではないか、と思います。
ちなみに"$fileName"を圧縮する時、ディレクトリまで入れてしまうと、それまで圧縮されてしまいます。つまり、下記のようにソースを書いた場合は、圧縮ファイルを解凍してみると、fooというフォルダの中のbarというフォルダの中にexample.jpgという画像が入ってしまうようです。

<pre>
require_once("Archive/Zip.php");
$zip_file = XXX/XXX/XXX/XXX/XXX/example.zip;   //ディレクトリの指定
$objZip = new Archive_Zip($zip_file);
$fileName = foo/bar/example.jpg;               //ディレクトリの指定
$objZip->create($fileName);
</pre>

検索してみると、どうもここで「えっ？　なんで？」と迷われている方がおられるみたいなので、もし宜しければ「他にも、こんなやり方あるよ！」という声を戴けたらと思います。


▼添付してメール形式で送信しよう
さて、先ほど圧縮したzipファイルを添付して送信する訳ですが、ここは皆さんにとってもお馴染みであろうPEARのMail_Mimeを使います。


PEAR::Mail_Mime
http://pear.php.net/package/Mail_Mime/


これでメールの送信が可能になるはずです。メール送信に関しては、色んなやり方があるかと思います。下記は如何でしょう？

<pre>
//PEAR::Mail_Mime
require_once('Mail/mime.php');
// 送信先メールアドレス
$to = "hoge@example.com";
// 送信元メールアドレス
$from = "hoge@example.co.jp";
// エラー送信先
$returnpath = "hoge@example.co.jp";
// 題名
$subject = "foo";
$subject = mb_encode_mimeheader($subject,"ISO-2022-JP" );
// 本文
$body = "bar";
$body = mb_convert_encoding($body, "ISO-2022-JP" );
// ファイル（パス指定）
$file_path = "XXX/XXX/XXX/XXX/XXX/example.zip";

$headers['From'] = $from;
$headers['X-Mailer'] = "PHP/".phpversion();

$mime = new Mail_mime("\r\n");
$mime->_build_params['text_charset'] = 'iso-2022-jp';
$mime->setTXTBody($body);

//添付ファイルの指定
$mime->addAttachment($file_path, '','',true);

//メールボディの取得
$body = $mime->get();
//メールヘッダの取得
$headers = $mime->headers($headers);

//ヘッダの組立
foreach ($headers as $key => $val) {
    $header .= $key.": ".$val."\n";
}
$header = trim($header);

//送信
$send_flag = mail($to, $subject, $body, $header, "-f".$returnpath);
</pre>

送信先や本文、題名などは操作し易いように先に書いてみました。これだと、DBから情報を取ってきて、それぞれに当てはめることも可能かもしれません。
あとは送信出来たか否かを確認するために、"$send_flag"に値を持たせてみました。
また、添付ファイルの指定ですが調べてみると第５引数の存在が確認出来ました。エンコード方式を指定出来るようです（"base64"など）。この辺りは調べれば調べるほど情報が出そうですね。奥が深いです。]]>
      
   </content>
</entry>
<entry>
   <title>RSSを使ったブログパーツ風のもの</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/php/rss.html" />
   <id>tag:www.lockon.co.jp,2007:/blog//1.326</id>
   
   <published>2007-11-09T06:37:51Z</published>
   <updated>2007-11-09T12:44:55Z</updated>
   
   <summary>技術開発部の松村です。 今日はPHPでRSS解析したものををJavascript...</summary>
   <author>
      <name>まつむら</name>
      
   </author>
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[<p>技術開発部の松村です。<br />
今日はPHPでRSS解析したものををJavascriptのタグで読み込んで表示させる、というのをやってみたいと思います。<br />
よくブログパーツとしてあるようなものを想像して頂いたらよいかと思います。</p>

<p>今回は、PEARのXML_RSSを使ってXMLを解析しています。<br />
よって、<p/>

<p># pear install -a XML_RSS</p>

<p>というふうにインストールしてください。XM_PARSERが入っていない場合は、こちらもインストールをする必要があるようです。</p>

<p>以下のようなJavascriptで表示させます。</p>
<pre>
&lt;script type="text/javascript">
&lt;!--
var url = 'http://www.example.com/rss_parse.php?url=http://q.hatena.ne.jp/list/computer?mode=rss';
document.write("&lt;scr" + "ipt type=\"text\/javascript\" src=\"" + url + "\">&lt;\/scr" + "ipt>");
// -->
&lt;/script>
</pre>
<p>次に実際にRSSを解析して、表示させるPHPのソースです。<br />
RSSを解析し、その中からランダムな記事を取ってくるようにしています。<br />
Javacriptで読ませるURLが非常にダサいんですが、一応いろいろなサイトのRSSを取ってこれるので、この方法にしました。（確認はあまりしていませんが。。。）
</p>

<pre>
&lt;?php
require_once("XML/RSS.php");

// $_GETの引数が２つ以上のときは、その引数も付けてあげる
if(count($_GET) > 1 ) {
    foreach($_GET as $key => $val) {
        if(empty($rssUrl)) {
            $rssUrl = $val;
        } else {
            $rssUrl .= "&" . $key . "=" . $val;
        }
    }
} else {
    $rssUrl = $_GET['url'];
}
//RSSファイルへのURIをコンストラクタの引数に渡す
$rss =& new XML_RSS($rssUrl);
// RSSファイルをパースする
$rss->parse();

// RSSの説明情報取得
$arrChannelInfo = $rss->getChannelInfo();
$big_title = mb_convert_encoding(ereg_replace("\n", "", $arrChannelInfo['title']), mb_internal_encoding(), 'auto');

// getItemsメソッドを使用して全item要素を取得し、表示する
$arrItems = $rss->getItems();
$count = count($arrItems);
// ランダムな値を取得
$i = rand(0, $count-1);

// リンクURL
$link = $arrItems[$i]['link'];

// タイトル
$title = $arrItems[$i]['title'];
//エスケープ処理
$title = ereg_replace("\"", "\\\"", $title);
$title = ereg_replace("'", "\\'", $title);
$title = mb_convert_encoding(ereg_replace("\n", "", $title), mb_internal_encoding(), 'auto');

// 空の場合は注意書きを代入
if(!empty($arrItems[$i]['description'])) {
    $description = $arrItems[$i]['description'];
    //エスケープ処理
    $description = ereg_replace("\"", "\\\"", $description);
    $description = ereg_replace("'", "\\'", $description);
    $description = mb_convert_encoding(ereg_replace("\n", "", $description), mb_internal_encoding(), 'auto');
} else {
    $description = "詳細情報登録なし！！";
}
// 実際に表示される
$disp = "&lt;div id=\\\"rss_body\\\">&lt;ul id=\\\"in_rss_body\\\">&lt;li id=\\\"big_title\\\">" . $big_title . "&lt;/li>&lt;li id=\\\"title\\\">&lt;a href='" . $link . "' target=\\\"_blank\\\">&lt;span>" . $title . "&lt;/span>&lt;/a>&lt;/li>&lt;/ul>&lt;/div>";

?>

document.write("&lt;link rel=\"stylesheet\" type=\"text/css\" href=\"rss.css\">");
document.write("&lt;?print($disp);?>");
document.write("&lt;div id=\"popup\">&lt;p>&lt;? print($description);?>&lt;/p>&lt;/div>");
document.write("&lt;scr" + "ipt type=\"text\/javascript\" src=\"popup.js\">&lt;\/scr" + "ipt>");

</pre>

<p>下記は、詳細内容をPOPUPで表示させるJavascriptのファイル、popup.jsです。</p>

<pre>
init_popup();

function init_popup() {
	if(!document.createAttribute) return;
	
	var div = document.getElementById("popup");
	var span = document.getElementsByTagName("SPAN");

	setHandler(span[0], div);
}

function setHandler(elem, div) {
	elem.onmouseover = function(evt) {
		if(!evt) evt = window.event;

		div.style.left = (evt.clientX + 4) + "px";
		div.style.top = (evt.clientY + 4) + "px";
		div.style.display = "block";
	}
	elem.onmouseout = function(evt) {
		div.style.display = "none";
	}
}
</pre>

<p>最後にCSSのファイルのrss.cssです。<br />
文字だけというのも悲しいので、CSSを知らないなりにちょっとしたデザインも入れてみました。<br />
また、POPUPで出てくるウィンドウを半透明にしています。
</p>

<pre>
div#rss_body{
	width: 140;
	background-color: black;
}
ul#in_rss_body{
	padding:9px;
	margin:1px;
	width: 120;
	background-color: white;
}
li#big_title {
	margin:1px;
	list-style-type: none;
	list-style-position:outside;
	font-size: 12px;
	width: 120;
	left: 0;
}
li#title {
	list-style-type: none;
	font-size: 13px;
	width: 120px;
	left: 0;
}
div#popup {
	position:absolute; left: 0; top: 0;
	font-size: 10px;
	width: 300px; height:100px;
	display: none;
	filter:alpha(opacity=75); /*IE*/
		   -moz-opacity:0.75; /*FireFox*/
	background-image: url(back.gif);
	padding: 8px;
}
</pre>

<p>これが実際どういうふうに表示されるかは、本当に申し訳ありませんが、自分のサーバでやって頂けると幸いです。<br />
セキュリティ上どうしても自社サーバに置くことができませんでした。<br />
リロードすると、ランダムに取ってきていることがわかったりします。</p>

<p>余談ですが、IEとFireFoxで表示のされ方が違うようですね。<br />
あと、たまにPOPUP文字列がはみ出すことがあります。<br .>
Javascriptでがんばって制御しようと思ったのですが、無理でした。。。<br />]]>
      
   </content>
</entry>
<entry>
   <title>CACHE_LITE</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/cache_lite_1.html" />
   <id>tag:www.lockon.co.jp,2007:/blog//1.315</id>
   
   <published>2007-11-07T08:26:25Z</published>
   <updated>2007-11-20T08:45:41Z</updated>
   
   <summary>技術開発部の岸田です。今回は、PEARライブラリーのCACHE_LITEを使って...</summary>
   <author>
      <name>kansai_ningen</name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[技術開発部の岸田です。今回は、PEARライブラリーのCACHE_LITEを使ってキャッシュをお手軽に活用としてみたいと思います。<br />
<br />
<b>[CACHE_LITEを使用する前準備]</b><br />
pear install Cache_Lite<br />
<br />
今回の流れとしまして、一意なIDによって紐づけられている商品情報を取得し、その情報をキャッシュし、その商品情報に変更が生じた際にキャッシュを破棄し、新しくキャッシュを生成するです。<br />
<br />
そんなこんなでこんな感じです。↓<br />
<pre>
// 接続情報
define ('DB_TYPE', 'pgsql');
define ('DB_USER', 'admin');
define ('DB_PASSWORD', '********');
define ('DB_SERVER', '127.0.0.1');
define ('DB_NAME', '********_db');
define ('DB_PORT', '5432');

if(defined('DB_TYPE') && defined('DB_USER') && defined('DB_PASSWORD') && defined('DB_SERVER') && defined('DB_PORT') && defined('DB_NAME')) {
    // サイト用DB
    define ("DEFAULT_DSN", DB_TYPE . "://" . DB_USER . ":" . DB_PASSWORD . "@" . DB_SERVER . ":" .DB_PORT . "/" . DB_NAME);
}

// キャッシュ用情報
$cache_option = array(
                // キャッシュを保存するフォルダ
                'cacheDir' => '../cache/tmp/',
                // キャッシュの有効/無効
                'caching' => "true",
                // 自動シリアライズの有効/無効
                'automaticSerialization' => "true",
                // キャッシュ生存期間を秒単位で指定します
                'lifeTime' => 100
);

require_once("MDB2.php");
require_once('cache/lite.php');
$mdb2 =& MDB2::factory(DEFAULT_DSN);
$cache = new Cache_Lite($cache_option);

if (PEAR::isError($mdb2)) {
    // 接続エラー
    die($mdb2->getMessage());
}else{
/*  本来ならばこっちのID使用
    if(sfIsInt($_GET['product_id'])){
        処理継続
    }else{
        echo '商品IDが不正です';
    }
*/
    // 今回は決め打ちで商品IDを固定する
    $product_id = "3";
    // キャッシュファイルがあれば、キャッシュファイル内の情報を表示
　　// [product_id3⇒商品情報]
    if($cache_data = $cache->get('product_id'.$product_id)){
        // 商品情報表示
        print_r($cache_data);
    // キャッシュファイルがなければ、キャッシュファイルを生成
    }else{
        // 商品IDから商品情報を取得
        $product_info = lfGetProductInfo($product_id);
        
        if($product_info == false){
            // エラー処理
            echo '商品がありません';
        }else{
            echo 'キャッシュ成功'."<br>";
            // キャッシュファイル[product_id商品ID⇒商品情報]として生成
            $cache->save($product_info, 'product_id'.$product_id);
            print_r($product_info);
        }
        
    }
   
}
// 商品情報の在庫が一個減る
//lfCustomerBuy($product_id);

// 商品IDで紐付いてる商品情報されているキャッシュを削除
$cache->remove('product_id'.$product_id);
    


// お客様が商品を購入された場合
/**
 * lfBuyProduct
 * 
 */
function lfCustomerBuy($product_id){
    global $cache;
    /* 在庫用のテーブルから、在庫を一つ減らす処理 */
    省略
}

/**
 * lfGetProductInfo
 * 商品情報を配列に格納し、returnしてくれる
 * @param  $date array(integer) 商品IDを格納した配列
 * @return $
 */
function lfGetProductInfo($product_id){
    global $mdb2;
    
    $tmp_product_id = array($product_id);
    // プレースホルダー用SQL作成
    $prepare = $mdb2->prepare('SELECT * FROM dtb_products WHERE product_id = ?', NULL, MDB2_PREPARE_RESULT );
    // SQL実行
    $exe = $prepare->execute($tmp_product_id);
    // 取得結果を配列の形にして取得
    $product_info = $exe->fetchAll(MDB2_FETCHMODE_ASSOC);
    
    if(!is_array($product_info) AND "0" < count($product_info)){
        // 商品情報が配列に格納されていなかったら、例外処理
        return false;
    }else{
        // 商品情報をreturn
        return $product_info;
    }
}

// INT型の数値チェック
function sfIsInt($value) {
    if($value != "" && strlen($value) <= INT_LEN && is_numeric($value)) {
        return true;
    }
    return false;
}
</pre>
<br />
こんな感じでお手軽にキャッシュを生成し、その情報に変更があれば最新の情報をキャッシュとして保存させる事が出来ます。
]]>
      
   </content>
</entry>
<entry>
   <title>SimpleTestでWebブラウジング</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/simpletestweb_1.html" />
   <id>tag:www.lockon.co.jp,2007:/blog//1.313</id>
   
   <published>2007-10-05T10:47:22Z</published>
   <updated>2007-10-16T05:07:04Z</updated>
   
   <summary>こんにちは、足立です。 本日はSimpleTestというユニットテストライブラリ...</summary>
   <author>
      <name>adachi</name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[こんにちは、足立です。

本日はSimpleTestというユニットテストライブラリをご紹介したいと思います。


SimpleTest
<a href="http://simpletest.org/">http://simpletest.org/</a>


PHPでユニットテストといえば、PHPUnitが有名かと思いますが、
現在メンテナンスされているPHPUnit3ではPHP4をサポートしておらず、
PHP4で開発を行う場合、PHPUnitのかなり古いバージョンを使わなければなりません。


SimpleTestはPHP4対応であり、
ドキュメントも(英語ですが)チュートリアルやAPIドキュメントが充実していてわかりやすいです。
また、Symfonyやethnaでも、SimpleTestが使われています。


インストール方法や通常のユニットテストのやり方は、google先生に聞けば教えてくれると思いますので、今回はsimpletestでwebサイトのテストをしてみましょう。


simpletestには仮想的なブラウザ機能があり、
テストプログラムからwebサイトを巡回していくようなことができます。


ではEC-CUBEのdemoサイトを対象にサンプルコードを書いてみます。
<pre>
require_once 'simpletest/web_tester.php';
require_once 'simpletest/reporter.php';

define('SITE_URL', 'http://demo.ec-cube.net/');
define('TITLE',    'みんなのサンプルショッピング/'); // タイトルは変わる可能性があるので、demoサイトにあわせましょう。

class WebTest_Of_Eccube extends WebTestCase {

    function testTop() {
        $this->assertTrue($this->get(SITE_URL));
        $this->assertTitle(TITLE . 'TOPページ');
    }

    function testMypageLogin() {
        $this->assertTrue($this->get(SITE_URL . 'mypage/login.php'));
        $this->assertTitle(TITLE . 'MYページ(ログイン)');

        $this->post(
            SITE_URL . 'mypage/login_check.php',
            array(
                'mode' => 'login',
                'mypage_login_email' => '*****@lockon.co.jp',
                'mypage_login_pass' => 'password',
            )
        );

        $this->assertResponse(array(200));

        $this->assertTrue($this->get(SITE_URL . 'mypage/index.php'));
        $this->assertTitle(TITLE . 'MYページ/購入履歴一覧');
    }
}

$test = new WebTest_Of_Eccube('EC-CUBE WEB TEST');
$test->run(new HTMLReporter('EUC-JP'));
</pre>


これをドキュメントルートに適当なファイル名で保存します。
そして保存先へブラウザからアクセスしてみましょう。


緑のラインで結果が表示されればOKです！赤色であればどこかでテストが失敗しています。


testTop()は単にトップページを表示できるかどうかをテストしているだけなのですが、
testMypageLogin()では実際にマイページへのログイン処理を行っています。


今回の場合だと、login_check.phpへ直接POSTしていますが、
SubmitFormById()などのようなメソッドもあり、フォームに値をセットして
submitする処理などもやってくれるみたいです。


最後のnew HTMLReporterをnew TextReporterに変えれば、
シェルからも実行できますので試してみてください。


また、HTMLReporterの表示がしょぼくて気に入らない！といった場合は、
Reporterクラスなどを継承して自分用にカスタマイズすることも可能です。
]]>
      
   </content>
</entry>
<entry>
   <title>モーショントゥイーン風なjavascriptのライブラリ</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/javascript/javascript_1.html" />
   <id>tag:www.lockon.co.jp,2007:/blog//1.312</id>
   
   <published>2007-09-28T14:11:02Z</published>
   <updated>2007-09-28T14:35:41Z</updated>
   
   <summary>お久しぶりです。開発部の上原です。 今日はFlashのモーショントゥイーン風な動...</summary>
   <author>
      <name>ゴーヤ</name>
      
   </author>
         <category term="JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[お久しぶりです。開発部の上原です。
今日はFlashのモーショントゥイーン風な動きを実現させる高機能で軽量なjavascriptライブラリ「JSTween」をご紹介いたします。


単純な動きなら簡単に実現できるのでFlashは苦手だけどWEBサイトに動きを持たせたいって方にはおすすめです。


まずはライブラリを配布している<a href="http://jstween.blogspot.com/#TweenMethodsEx" target="_brank">こちらのサイト</a>からjavascriptソースコードをダウンロードして下さい。
全部で6種類ありますが今回は「Tween.js」と「ColorTween.js」というライブラリを使用してみます。


■まずhead部分にダウンロードしたファイルを読み込み準備します。
<pre>
&lt;script type="text/javascript" src="Tween.js"&gt;&lt;/script>
&lt;script type="text/javascript" src="ColorTween.js">&lt;/script>
</pre>



■まずはdivで囲まれたスペースを動かすサンプルです。
<pre>
&lt;div id="position" style="width:150px;height:50px;position:relative;left:0px;"&gt;★ここが動きます★&lt;/div&gt;
&lt;input type="button" value="動かします" onclick="
// (要素ID, 現在位置, イベント, 始点, 終点, 実行時間(大きければ大きいほど遅くなる),)
tween = new Tween(document.getElementById('position').style,'left',Tween.elasticEaseOut,10,300,10,'px');
// 移動実行
tween.start();"&gt;
&lt;input type="button" onclick="tween.rewind();" value="戻します"&gt;
</pre>

tween = new Tween(document.getElementById('要素ID').style,'現在位置',イベント,始点,終点,実行時間,'px');
tween.start();

divのonclick部分に上記2行加えるだけですので数値をかえたり色々お試し下さい。




■アルファ効果で徐々に色を変えるサンプルです。

<pre>
&lt;div id="font" style="font-color:#FF0000;"&gt;フォントカラーの変更&lt;/div&gt;
&lt;input type="button" value="フォントカラーの変更" onclick="
// (要素ID, 処理タイプ, イベント, 始点の色, 終点の色, 実行時間(大きければ大きいほど遅くなる))
bgColorTween=new ColorTween(document.getElementById('font').style,'color',Tween.bounceEaseOut,'333333','FFFFFF',3);
// 実行
bgColorTween.start();"&gt;
</pre>

bgColorTween=new ColorTween(document.getElementById('要素ID').style,'処理タイプ',イベント,'始点の色','終点の色',実行時間);

こちらも先ほどのサンプル同様に上記部分を指定してやれば動きます。




■バックグランドカラーの変更を行うサンプルです。
<pre>
&lt;input type="button" value="バックグラウンドを変更します" onclick="
// (要素ID, 処理タイプ, イベント, 始点の色, 終点の色, 実行時間(大きければ大きいほど遅くなる))
bgTween = new ColorTween(document.body.style, 'backgroundColor', Tween.bounceEaseOut,'FFFFFF','000000',2);
// 実行
bgTween.onMotionFinished = function(){
   this.yoyo();
   this.onMotionFinished = undefined;
};
bgTween.start();"&gt;
</pre>

こちらは先ほどのサンプルの応用例です。


bgTween.onMotionFinished = function(){
   this.yoyo();
   this.onMotionFinished = undefined;
};


こちらの記述で終了したあと更にもとに戻るという動きをyoyo();とう関数で実現しています。


今回紹介したサンプルの動作確認は<a href="http://www.lockon.co.jp/blog/Tween.html" target="_blank">こちら</a>から


他にも沢山の機能がございますので、興味をもった方は<a href="http://jstween.blogspot.com/" target="_brank">本家サイト</a>の方で詳しい使い方を参照して見てください。


次はポストprototypeと噂される高機能なjQueryなども使ってみようと思います。]]>
      
   </content>
</entry>
<entry>
   <title>EC-CUBEのDB接続をmdb2に変更</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/php/eccubedbmdb2.html" />
   <id>tag:www.lockon.co.jp,2007:/blog//1.311</id>
   
   <published>2007-09-24T04:37:39Z</published>
   <updated>2007-09-26T04:16:54Z</updated>
   
   <summary> ITproの記事にもありましたが、PHPでDB接続にPEAR::DBを使ってい...</summary>
   <author>
      <name>カッキー</name>
      
   </author>
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[<p>
ITproの記事にもありましたが、PHPでDB接続にPEAR::DBを使っている場合にはPEAR::MDB2への移行を推奨するとのことです。
</p>
<p>
<a href="http://itpro.nikkeibp.co.jp/article/COLUMN/20070827/280396/">http://itpro.nikkeibp.co.jp/article/COLUMN/20070827/280396/</a>
</p>
<p>&nbsp;</p>
<p>
現在、EC-CUBEではDB接続にPEAR::DBを用いていますので、移行できるか試して見ました。
</p>
<p>
まず、MDB2のパッケージをダウンロードし、解凍したものを data/module 配下に置きます。
</p>
<p>
今回はPostgreSQLで以降の検証を行いたいと思います。
</p>
<p>
<a href="http://pear.php.net/package/MDB2/download/2.4.0">http://pear.php.net/package/MDB2/download/2.4.0</a>
<a href="http://pear.php.net/package/MDB2_Driver_pgsql/download">http://pear.php.net/package/MDB2_Driver_pgsql/download</a>
</p>
<p>&nbsp;</p>
<p>
次にMDB2を用いてDB接続を行うようにプログラムを改造します。 
</p>
<p>&nbsp;</p>
<p>
変更ファイル：data/class/SC_DbConn.php
<pre>
class SC_DbConn{    
    var $conn;
    var $conn_mdb2;　// MDB2の接続オブジェクト    
    var $result; 
    var $includePath;
    var $error_mail_to;
    var $error_mail_title;        
    var $dsn;        
    var $err_disp = true;

    // コンストラクタ        
    function SC_DbConn($dsn = "", $err_disp = true, $new = false){        
        global $objDbConn;    
        global $objDbConnMDB2;
        // Debugモード指定    
        $options['debug'] = PEAR_DB_DEBUG;    
        // 既に接続されていないか、新規接続要望の場合は接続する。    
        if(!isset($objDbConn->connection) || $new) {    
            if($dsn != "") {
                $objDbConn = DB::connect($dsn, $options);    
                $objDbConnMDB2 = MDB2::factory($dsn, $options);  // MDB2で接続を行う    
                $objDbConnMDB2->loadModule('Extended', null, false);  // getAllなどのPEAR::DBで使用していた関数をそのまま使えるようにするためのモジュール                    
                $this->dsn = $dsn;    
            } else {        
                if(defined('DEFAULT_DSN')) {    
                    $objDbConn = DB::connect(DEFAULT_DSN, $options);
                    $objDbConnMDB2 = MDB2::factory(DEFAULT_DSN, $options);  // MDB2で接続を行う
                    $objDbConnMDB2->loadModule('Extended', null, false); // getAllなどのPEAR::DBで使用していた関数をそのまま使えるようにするためのモジュール                    
                    $this->dsn = DEFAULT_DSN;
                } else {    
                    return;
                }    
            }        
        }            

        $this->conn = $objDbConn;
        $this->conn_mdb2 = $objDbConnMDB2; // MDB2で接続を行ったオブジェクト
        $this->error_mail_to = DB_ERROR_MAIL_TO;
        $this->error_mail_title = DB_ERROR_MAIL_SUBJECT;
        $this->err_disp = $err_disp;
    }    

*** 中略 ***

    // SELECT文の実行結果を全て取得    
    function getAll($n, $arr = ""){    
        // mysqlの場合にはビュー表を変換する
        if (DB_TYPE == "mysql") $n = sfChangeMySQL($n);

        if(PEAR::isError($this->conn)) {        
            sfErrorHeader("DBへの接続に失敗しました。");            
            gfPrintLog("couldn't connect : " . $this->dsn);            
            return 0;            
        }            

        if ( $arr ){    
            //$result = $this->conn->getAll($n, $arr, DB_FETCHMODE_ASSOC);
            $result = $this->conn_mdb2->extended->getAll($n, null, $arr, null,DB_FETCHMODE_ASSOC, false);  // MDB2で実行            
        } else {    
            //$result = $this->conn->getAll($n, DB_FETCHMODE_ASSOC);
            $result = $this->conn_mdb2->extended->getAll($n, null, null, null,DB_FETCHMODE_ASSOC, false);  // MDB2で実行            
        }    
        if ($this->conn->isError($result)){    
            $this->send_err_mail ($result, $n);
        }    
        $this->result = $result;

        return $this->result;
    }

</pre>
</p>
<p>&nbsp;</p>
<p>
他に、MDB2モジュールのパスを正しく設定してあげれば終了です。
</p>
<p>&nbsp;</p>
<p>
今回は検証ということで、getAllのみをMDB2で取得するようにしております。
</p>
<p>
そのため、無駄に2回DB接続を行ったりしていますので、正式に移行する場合にはPEAR::DBは削除するようにしてください。        
</p>
<p>
また、まだデータ更新部分は検証していなかったり、色々やることはあるのですが、
移行自体は思ったより簡単に行うことが出来そうです。</p>
<p>
（なんとなくですみません。。。）
</p>
<p>&nbsp;</p>
<p>
今回は移行できるかの検証をさせていただきまが、MDB2の方が速いといったメリットもあるようですので、次回くらいには速度面からも検証していければと思います。
</p>]]>
      
   </content>
</entry>
<entry>
   <title>pgpoolについて</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/database/postgresql/pgpool_1.html" />
   <id>tag:www.lockon.co.jp,2007:/blog//1.310</id>
   
   <published>2007-09-03T10:31:14Z</published>
   <updated>2007-09-03T11:43:56Z</updated>
   
   <summary>こんにちは。 PostgreSQL専用のコネクションプーリング・ソフトウェアであ...</summary>
   <author>
      <name>たおる</name>
      
   </author>
         <category term="PostgreSQL" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[こんにちは。

PostgreSQL専用のコネクションプーリング・ソフトウェアであるpgpoolですが、やっかいな問題があります。

それは、「クライアントから接続を中断されたときに、そのコネクションが残り続けること」です。

その状態が連続すると、pgpoolがハングアップし、pgpoolのポートへの接続ができなくなります。
例えば、5433番ポートでpgpoolを動かしているとすると、

<pre>
$ psql -l -p 5433
</pre>

と入力しても、応答が全く帰ってきません。

また、この時

<pre>
$ psql -l
</pre>

は、応答がかえってきます。<br/>
postgresには直接接続できるということです。<br/><br/>

特に高負荷時、クライアント側でコネクションタイムアウト処理が行われるときに発生しやすいように思います。<br/><br/>

この問題は、pgpoolのパラメータであるconnection_life_timeを使うことで、アイドル状態のコネクションを解放できることは確認できましたが、高負荷な場合には意味をなさないようです。<br/><br/>

また、pgpool3.3を使用していた頃、3.4がリリースされてChangeLogを見たところ、そのあたりに関係しそうなことが記載されていて、pgpool3.4にアップデートしましたが状況は変わらずでした。<br/><br/>

クライアント側のコネクションタイムアウト処理は変えずに、pgpoolの設定のみで対応する方法としましては、実メモリとpostgresql.confのmax_connection値の範囲内で、num_init_childrenを増やせば、同現象が起こる可能性は低くなります。
（理論的にはその分max_pool値は低く設定しなければパフォーマンスは低下するので、高負荷にはなりますが、要は、ある親プロセスに紐づく子プロセスを使い切らないようにすることがポイントかと）<br/><br/>

話は変わって、パラメータのlogdirですが、/tmp以外に変更されることをお勧めします。<br/>
pidファイルもここに格納されるようになっていますが、Linuxはtmpwatchなどで/tmp以下を自動で削除する仕組みになっていますので。<br/><br/>

もし万が一pidファイルを消失してしまった場合は、pgpoolの起動、停止ができません。<br/>
その場合、親プロセスからプロセスIDを調べて、noeolバイナリーでpgpool.pidファイルを作成します。<br/>
viモードで「:set bin noeol」で、保存します。<br/><br/><br/>

おそらくpgpoolを使用されている方も多いと思い、いろいろと気になる現象を挙げてみました。<br/>
同様の現象に心当たりのある方はおられますでしょうか。
]]>
      
   </content>
</entry>
<entry>
   <title>ローカル環境の Apache で複数のサイトを平行して開発する</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/_apache.html" />
   <id>tag:www.lockon.co.jp,2007:/blog//1.309</id>
   
   <published>2007-09-03T01:00:02Z</published>
   <updated>2007-09-03T01:08:58Z</updated>
   
   <summary>EC-CUBE 開発チームの大河内です. 僕は普段, FreeBSD や Mac...</summary>
   <author>
      <name>nanasess</name>
      
   </author>
         <category term="Apache" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[<p>EC-CUBE 開発チームの大河内です.</p>


<p>
僕は普段, FreeBSD や Mac OS X といった PC-UNIX をクライアントにして開発をしています.
自機がサーバーになってしまうので, EC-CUBE などの開発は非常に楽なのですが, PHP4 と, PHP5 の動作確認を行ったり, 複数の EC-CUBE を同時にテストしようと思うと, 少々工夫が必要です.
</p>

<p>
DNS サーバーを自前で管理できれば, サブドメインを作って, ネームベースの VirtualHost で複数のドメインを動作させることができるので楽なのですが, 現在の開発環境では, localhost のみで何とかしなければならないのです.
</p>

<p>
そこで, 以下の方法を考えました.
</p>
<ul>
  <li>Apache は ネームベースの VirtualHost ではなく, 複数のポートで動かす.</li>
  <li>PHP4 と PHP5 の Apache module をインストールしておき, httpd.conf の簡単な修正で変更できるようにする.</li>
</ul>

<h3>設定方法</h3>
<ol>
  <li><strong>Apache と PHP5 をインストール.</strong>
      <p>まずは特に特殊な設定は不要なので, ports から入れてしまいました.<br>
         Linux なら rpm や apt-get でも大丈夫だと思います.</p>
      <pre># portinstall -Ccr www/apache20
# portinstall -Ccr lang/php5
# portinstall -Ccr lang/php5-extensions</pre>
  </li>
  <li><strong>PHP4 のインストール.</strong>
      <p>PHP5 と PHP4 を簡単に切り変えるために PHP4 もインストールします.<br>
         単純には共存できないため, こちらはソースからビルドします.</p>
	 <pre>$ tar xvjf php-4.4.7.tar.bz2
$ cd php-4.4.7
$ './configure' \
'--with-layout=GNU' \
'--with-config-file-scan-dir=/usr/local/etc/php' \
'--with-apxs2=/usr/local/sbin/apxs' \
'--with-regex=php' \
'--enable-zend-multibyte' \
'--prefix=/usr/local' \
'--without-pear' \
'--disable-cgi' \
'--disable-cli' \
'--with-gd' \
'--enable-gd-native-ttf' \
'--enable-gd-jis-conv' \
'--with-iconv' \
'--enable-mbstring' \
'--with-mysql' \
'--with-pgsql=/usr/local/pgsql/8.2.4' \
'--with-zlib-dir=/usr/local' \
'--with-jpeg-dir=/usr/local' \
'--with-png-dir=/usr/local'
$ make
$ sudo make install
</pre>
<p>configure オプションは各環境に合わせて調節して下さい.<br>
僕の場合は, Apache2 モジュール版の PHP4 のみをインストールするようにし, PostgreSQL は幾つかのバージョンを同居させているので, 8.2.4 のライブラリを読むようにしました<br>
  </li>
  <li><strong>PHP の共存設定</strong>
      <p>PHP4 と PHP5 はインストールできたので, どちらのモジュールを有効にするかは, httpd.conf で行います.<br>
      下記のように, LoadModule 行のどちらかをコメントアウトしてやれば良いです.(Apache2.0系の場合)</p>
<pre>
#LoadModule php4_module        libexec/apache2/libphp4.so
LoadModule php5_module        libexec/apache2/libphp5.so
</pre>
<p>PHP4 を有効にしたければ, php5_module の行をコメントアウトして, Apache を再起動しましょう.
  </li>
  <li><strong>複数ホスト同居させる</strong>
      <p>複数のホストを同居させるには, VirtualHost を使えば良いのですが, localhost のみではサブドメインが使えないため, Apache を複数のポートで立ち上げて対応するようにします.<br>
      僕は, httpd.conf に VirtualHost の設定をたくさん書くのはいやなので, httpd.conf の最終行付近に下記のような設定を追加しました.</p>
      <pre>Include etc/apache2/Includes/*.conf</pre>
      <p>こうすると, $PREFIX/etc/apache2/Includes 以下の *.conf ファイルは, すべて httpd.conf が 読み込んでくれます.</p>
      <p>あとは, ホストごとに, *.conf ファイルを作っていけば良いです.</p>
      <pre>##--------------------------------------------------------------------
# EC-CUBE module-update 開発用
##--------------------------------------------------------------------
Listen 15000
NameVirtualHost *:15000
&lt;VirtualHost *:15000&gt;
    ServerAdmin     root@loop-az.jp
    DocumentRoot    /home/foo-user/workspace/eccube-branches/feature-module-update/html
    DirectoryIndex  index.php
    ServerName       127.0.0.1
    ErrorLog        /var/log/15000-httpd-error.log
    CustomLog       /var/log/15000-httpd-access.log combined
    AddType application/x-httpd-php .php
    php_value include_path .:/usr/local/share/pear
    &lt;Directory /home/foo-user/workspace/eccube-branches/feature-module-update/html&gt;
        AllowOverride All
        Options All
        &lt;Limit GET POST OPTIONS PROPFIND&gt;
            Order allow,deny
            Allow from all
        &lt;/Limit&gt;
        &lt;LimitExcept GET POST OPTIONS PROPFIND&gt;
            Order deny,allow
            Deny from all
        &lt;/LimitExcept&gt;
    &lt;/Directory&gt;
&lt;/VirtualHost&gt;
##--------------------------------------------------------------------
# EC-CUBE comu-utf8 用
##--------------------------------------------------------------------
Listen 16000
NameVirtualHost *:16000
&lt;VirtualHost *:16000&gt;
    ServerAdmin     root@example.jp
    DocumentRoot    /home/foo-user/workspace/eccube-branches/comu-utf8/html
    DirectoryIndex  index.php
    ServerName       127.0.0.1
    ErrorLog        /var/log/16000-httpd-error.log
    CustomLog       /var/log/16000-httpd-access.log combined
    AddType application/x-httpd-php .php
    php_value include_path .:/usr/local/share/pear
    &lt;Directory /home/foo-user/workspace/eccube-branches/comu-utf8/html&gt;
        AllowOverride All
        Options All
        &lt;Limit GET POST OPTIONS PROPFIND&gt;
            Order allow,deny
            Allow from all
        &lt;/Limit&gt;
        &lt;LimitExcept GET POST OPTIONS PROPFIND&gt;
            Order deny,allow
            Deny from all
        &lt;/LimitExcept&gt;
    &lt;/Directory&gt;
&lt;/VirtualHost&gt;
</pre>
<p><strong>ポイントは, VirtualHost ごとに, Listen するポートを分けることです.</strong> こうすることで, 定義したポートごとに VirtualHost の作成ができます.<br>
Listen させるポートは, 1024 番以降の空いているポートを使用するようにしましょう.<br>
ドメイン名は localhost のみなので, NameVirtualHost と, VirtualHost ディレクティブは, <strong>*:ポート番号</strong> と指定すると良いです.<br>
上記の設定だと, ブラウザから, http://localhost:15000 及び, http://localhost:16000 にアクセスすることで, 各 VirtualHost へのアクセスが確認できると思います.</p>
  </li>
</ol>

<p>上記サンプルは, あくまでもローカル環境でのテスト用なので, AllowOverride All なんてしてありますが, VPS 等の外部サーバーでテストする場合は, 的確な設定をした方が良いでしょう...</p>]]>
      
   </content>
</entry>
<entry>
   <title>ログローテーション</title>
   <link rel="alternate" type="text/html" href="http://www.lockon.co.jp/blog/cat10/post_10.html" />
   <id>tag:www.lockon.co.jp,2007:/blog//1.308</id>
   
   <published>2007-08-31T03:41:01Z</published>
   <updated>2007-08-31T03:57:33Z</updated>
   
   <summary>どうもこんにちは中川です。 Linux付属のログローテーション機能が、プロセスに...</summary>
   <author>
      <name>naka</name>
      
   </author>
         <category term="サーバ" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.lockon.co.jp/blog/">
      <![CDATA[どうもこんにちは中川です。<br>
<br>
Linux付属のログローテーション機能が、プロセスにシグナルを送らないと、<br>
うまく動作しなかったりと挙動が気になったので、<br>
ログローテーションスクリプトを自作しました。<br>
<br>
logrotate.sh /var/log/php.log 10<br>
のような感じで、ローテンションしたいログファイル名と、世代数を指定して、<br>
定期的に実行するとgz圧縮されたログが蓄積していきます。<br>
<pre>
#!/bin/sh

if [ $# -lt 2 ]; then
        echo "Usage: $0 logfile maxcnt"
        exit 1
fi 

# initial
LOGFILE=$1
OUTDIR=`dirname $LOGFILE`
MAXCNT=$2
FILENAME=`basename $LOGFILE`
OUTPATH=${OUTDIR}/${FILENAME}

# move old log
rm -rf $OUTPATH.$MAXCNT.gz
CNT=$MAXCNT
while [ $CNT -gt 0 ]; do
        CNT=`expr $CNT - 1`
        if [ -f $OUTPATH.$CNT.gz ]; then
                mv $OUTPATH.$CNT.gz $OUTPATH.`expr $CNT + 1`.gz
        fi
done

# copy new log
cp $LOGFILE $OUTPATH.0  
gzip $OUTPATH.0

# clear new log
if [ -f $OUTPATH.0.gz ]; then
        echo -n "" > $LOGFILE
fi
</pre>
]]>
      
   </content>
</entry>

</feed>
