<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>スイナシア(PHP)</title>
<link>http://suin.asia/tag/PHP</link>
<description>「PHP」なエントリー</description>
<language>ja</language>
<lastBuildDate>Sat, 31 Jul 2010 18:56:40 +0900</lastBuildDate>
<docs>http://backend.userland.com/rss/</docs>
<category>PHP</category>
<item>
<title>Cometを実装していて竜ヶ峰帝人のウェブ技術に脱帽した</title>
<link>http://suin.asia/2010/04/01/i_had_to_take_my_hat_off_to_ryugamine_for_his_web_skill</link>
<description><![CDATA[<p>注：ネタバレがあります。</p>
<p>私が、デュラララ!!のチャットを再現する道のりは、竜ヶ峰帝人がダラーズのサイトを立ち上げたものを後から追っていくようなものだ。</p>
<p>竜ヶ峰帝人は、池袋でオフ会をしてあれだけのメンバーが集まるようなコミュニティサイトを立ち上げたんだから、きっとチャットもCometを実装したに違いない。彼の足跡を辿るようにして、私もCometの実装にとりかかった。Cometの実装パターンはいろいろあるが、その中でも一番修正が少なくて済みそうなXHR long-pollingという方法をとることにした。</p>
<p>この方法をPHPでやるとすると、AjaxでPHPにリクエスト → 新しい発言があるまでPHPが無限ループ → 発言が見つかるとデータレスポンスを返す → クライアントがデータを料理して表示 → 最初に戻る という流れになる。</p>
<p>PHPで無限ループするところでは、sleep(1)をかませるのが王道。一秒ごとに新しい発言がないかチェックするわけだ。しかし、このsleep()関数が第一の鬼門だった。チャットアプリは当然ログインしているわけで、セッションを張った状態になっている。このセッションが張られた状態で、sleep()の無限ループがつづいていると、その後に別のスクリプトに出したリクエストが帰ってこない。これは、どうしたものかと調べてみると、sleep()はスクリプト単位ではなく、セッション単位で機能するということ。とりあえず、sleep()に入る直前にsession_write_close()することで解決できた。</p>
<p>そして、Cometにおいて最大の難関にさしかかる。それはIEの対応。Cometは少なくても2コネクションを同時に使う。ひとつは発言のPOST、もうひとつは無限ループしてるスクリプトへのGET。IEだと、同時に2コネクションしか使うことができない。2個もあれば十分じゃないかと思ったら、チャット中に他のページに行くこと（3つ目のコネクションを作ること）ができないことが分かった。これはたぶんTCPの仕様じゃなかったかと思う。だからIEは間違ってない。FFやChromeが寛大なだけだ。</p>
<p>調べてみると、Cometではこの対策として複数のドメインをたらいまわす方法がとられているらしい。Ajaxではドメインを超えて通信できなので、IFRAMEの出番になる……。</p>
<p>ここまでのことを竜ヶ峰帝人は、高校生にしてやりとげたというのか！私が高校生だったころなんて、オブジェクト指向はおろか参照渡しもわからなかったと言うのに。帝人のウェブ技術に脱帽。</p>]]></description>
<pubDate>Thu, 01 Apr 2010 01:25:12 +0900</pubDate>
<guid>http://suin.asia/2010/04/01/i_had_to_take_my_hat_off_to_ryugamine_for_his_web_skill</guid>
<category domain="http://suin.asia/tag/%E3%83%87%E3%83%A5%E3%83%A9%E3%83%A9%E3%83%A9">デュラララ</category>
<category domain="http://suin.asia/tag/PHP">PHP</category>
</item>
<item>
<title>gettext的な多言語対応方法での文法数の実装をPHPで考える</title>
<link>http://suin.asia/2010/03/19/treat_grammatical_number_in_php</link>
<description><![CDATA[<p>勉強がてら、gettextの<a href="http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html">ngettext()</a>関数を参考に、PHPで文法数(grammatical number)の切り替え機能を書いてみます。関数<code class="php">number()</code>を作り、に整数を入れると、数量にあった形式(0 ~ 3)を導く処理を作ります。形式は主に単数・複数・双数(dual)ですが、拡張性(新たなパターンの言語の対応)を考えて、形式には0~3の抽象的な値を割り振っておきます。例えば、0は単数形・1は複数形の場合、0は単数形・1は双数形・2は複数形の場合などがあります。</p>

<ul>
<li>0 :  形式 A</li>
<li>1 :  形式 B</li>
<li>2 :  形式 C</li>
<li>3 :  形式 D</li>
</ul>

<p>言語によって、使い分ける形式の数が異なります。少ない言語で1つの形式を、多い言語で4つの形式を使い分けます。また、形式の数が同じでも、先行する数字によって、形式の使い分け方が言語によって異なります。この点を総括すると、11パターンが考えられます。</p>

<ol>
<li>パターン1 : 形式が1つ</li>
<li>パターン2.1 : 形式が2つ » 単数形が1に使われる</li>
<li>パターン2.2 : 形式が2つ » 単数形が0と1に使われる</li>
<li>パターン3.1 : 形式が3つ » 0が特別</li>
<li>パターン3.2 : 形式が3つ » 1と2が特別</li>
<li>パターン3.3 : 形式が3つ » <code class="regex">/00$/</code>と<code class="regex">/[2-9][0-9]$/</code>が特別</li>
<li>パターン3.4 : 形式が3つ » <code class="regex">/1[2-9]$/</code>が特別</li>
<li>パターン3.5 : 形式が3つ » <code class="regex">/1$/</code>と<code class="regex">/[2-4]$/</code>が特別 (<code class="regex">/1[1-4]$/</code>以外)</li>
<li>パターン3.6 : 形式が3つ » 1と2, 3, 4が特別</li>
<li>パターン3.7 : 形式が3つ » <code class="regex">/[2-4]$/</code>が特別</li>
<li>パターン4.1 : 形式が4つ » <code class="regex">/0*[2]$/</code>と<code class="regex">/0*[3-4]$/</code>が特別</li>
</ol>

<p>それでは、以上の順にしたがって、それぞれのパターンの実装を書いていきます。もし、誤りがあれば教えてください m(_ _ )m</p>

<h3>パターン1 : 形式が1つ</h3>

<p>数の文法カテゴリがなく、ひとつの形式で表す言語です。アジア型の言語に多いです。日本人にとっては一番身近なパターンです。</p>
<dl>
<dt>対象言語</dt>
<dd>日本語・韓国語・ベトナム語・トルコ語など</dd>
</dl>

<pre class="php" name="code">
&lt;php
function number($int)
{
	return 0;
}
?&gt;
</pre>

<h3>パターン2 : 形式が2つ</h3>

<p>数を表すのに2つの形式を使い分ける言語です。ヨーロッパ型の言語の中でも西ヨーロッパに多いです。日本人にとって、このパターンも理解しやすいほうだと思います。</p>

<h4>パターン2.1 : 単数形が1に使われる</h4>

<dl>
<dt>対象言語</dt>
<dd>英語・オランダ語・ドイツ語・エストニア語・フィンランド語・ギリシャ語・イタリア語・ポルトガル語・スペイン語・エスペラント語など</dd>
</dl>

<pre class="php" name="code">
&lt;php
function number($int)
{
	if ( $int == 1 )
	{
		return 0; // 1
	}

	return 1;
}
?&gt;
</pre>

<h4>パターン2.2 : 単数形が0と1に使われる</h4>

<dl>
<dt>対象言語</dt>
<dd>フランス語・ブラジルポルトガル語など</dd>
</dl>

<pre class="php" name="code">
&lt;php
function number($int)
{
	if ( $int &lt;= 1 )
	{
		return 0;
	}

	return 1;
}
?&gt;
</pre>

<h3>パターン3 : 形式が3つ</h3>

<p>数を表すのに3つの形式を使い分ける言語です。ヨーロッパ型の言語の中でも東ヨーロッパに多いです。これらの言語の中には、単数・複数に加え、双数の概念があります。この言語では、基本的には、双数が2で、複数は3以上です。極端なことを言うと、英語などが「1, いっぱい」と数えるのに対して、「1, 2, いっぱい」という数え方をする言語ということになります。</p>
<p>また、ヨーロッパ型の言語では、1~19まで数えて20以降は数字を組み合わせるといった20進法的な面があり、そのため1~19に関わる数字が不規則になることがあるようです。</p>

<h4>パターン3.1 : 0が特別</h4>

<dl>
<dt>対象言語</dt>
<dd>ラトビア語</dd>
</dl>

<pre class="php" name="code">
&lt;php
function number($int)
{
	// 1, 21, 31, 41, 51, 61, 71, 81, 91, 
	// 101, 121, 131, 141, 151, 161, 171, 181, 191, 
	// 201, 221, 231, 241, 251, ...
	if ( $int % 10 == 1 and $int % 100 != 11 )
	{
		return 0;
	}
	// 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
	// 12, 13, 14, 15, 16, 17, 18, 19, 20, 
	// 22, 23, 24, 25, 26, 27, 28, 29, 30, ...
	elseif ( $int != 0 )
	{
		return 1;
	}

	// 0 [特別]
	return 2;
}
?&gt;
</pre>

<h4>パターン3.2 : 1と2が特別</h4>

<dl>
<dt>対象言語</dt>
<dd>アイルランド語</dd>
</dl>

<pre class="php" name="code">
&lt;?php
function number($int)
{
	// 1 [特別]
	if ( $int == 1 )
	{
		return 0;
	}
	// 2 [特別]
	elseif ( $int == 2 )
	{
		return 1;
	}

	//  0, 3, 4, 5, 6, 7, 8, 9, 
	// 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, ...
	return 2;
}
?&gt;
</pre>

<h4>パターン3.3 : /00$/と/[2-9][0-9]$/が特別</h4>

<dl>
<dt>対象言語</dt>
<dd>ルーマニア語</dd>
</dl>

<p>つまり、ルーマニア語では、2から19までは形式1になります。</p>

<pre class="php" name="code">
&lt;?php 
function number($int)
{
	// 1
	if ( $int == 1 )
	{
		return 0;
	}
	// 0, 2, 3, 4, 5, 6, 7, 8, 9, 
	// 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 
	// 101, 102, 103, 104, 105, 106, 107, 108, 109, 
	// 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, ...
	elseif ( $int == 0 or ( $int % 100 &gt; 0 and $int % 100 &lt; 20 ) )
	{
		return 1;
	}

	// 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,  [特別]
	// 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, ...
	// 100, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, ...
	return 2;
}
?&gt;
</pre>

<h4>パターン3.4 : /1[2-9]$/が特別</h4>

<dl>
<dt>対象言語</dt>
<dd>リトアニア語</dd>
</dl>

<p>うーん、これであってるか心配。</p>

<pre class="php" name="code">
&lt;?php
function number($int)
{
	// 1, 21, 31, 41, 51, 61, 71, 81, 91, 101, 121, ...
	if ( $int % 10 == 1 and $int % 100 != 11 )
	{
		return 0;
	}
	// 2, 3, 4, 5, 6, 7, 8, 9, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, ...
	elseif ( $int % 10 &gt;= 2 and ( $int % 100 &lt; 10 or $int % 100 &gt;= 20 ) )
	{
		return 1;
	}

	// 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, [特別]
	// 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 110,
	// 111, 112, 113, 114, 115, 116, 117, 118, 119 120, ...
	return 2;
}
?&gt;
</pre>

<h4>パターン3.5 : /1$/と/[2-4]$/が特別 (/1[1-4]$/以外)</h4>

<dl>
<dt>対象言語</dt>
<dd>クロアチア語・セルビア語・ロシア語・ウクライナ語</dd>
</dl>

<pre class="php" name="code">
&lt;?php
function number($int)
{
	// 1, 21, 31, 41, 51, 61, 71, 81, 91,  [特別]
	// 101, 121, 131, 141, 151, 161, 171, 181, 191, 
	// 201, 221, 231, 241, 251, ...
	if ( $int %10 == 1 and $int % 100 != 11 )
	{
		return 0;
	}
	// 2, 3, 4, 22, 23, 24, 32, 33, 34, 42, 43, 44,  [特別]
	// 52, 53, 54, 62, 63, 64, 72, 73, 74, 82, 83, 84, 
	// 92, 93, 94, 102, 103, 104, 122, 123, 124, ...
	elseif ( $int % 10 &gt;= 2 and $int % 10 &lt;= 4 and ( $int % 100 &lt; 10 or $int % 100 &gt;= 20 ) )
	{
		return 1;
	}

	// 0, 5, 6, 7, 8, 9, 10, 
	// 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
	// 25, 26, 27, 28, 29, 30, 35, 36, 37, 38, 39, ...
	return 2;
}
?&gt;
</pre>

<h4>パターン3.6 : 1と2, 3, 4が特別</h4>

<dl>
<dt>対象言語</dt>
<dd>スロバキア語・チェコ語</dd>
</dl>

<pre class="php" name="code">
&lt;?php
function number($int)
{
	// 1 [特別]
	if ( $int == 1 )
	{
		return 0;
	}
	// 2, 3, 4 [特別]
	elseif ( $int &gt;= 2 and $int &lt;= 4 )
	{
		return 1;
	}

	// 0, 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, ...
	return 2;
}
?&gt;
</pre>

<h4>パターン3.7 : /[2-4]$/が特別</h4>

<dl>
<dt>対象言語</dt>
<dd>ポーランド語</dd>
</dl>

<pre class="php" name="code">
&lt;?php
function number($int)
{
	// 1
	if ( $int == 1 )
	{
		return 0;
	}
	// 2, 3, 4, 22, 23, 24, 32, 33, 34,  [特別]
	// 42, 43, 44, 52, 53, 54, 62, 63, 64, 
	// 72, 73, 74, 82, 83, 84, 92, 93, 94, ...
	elseif ( $int % 10 &gt;= 2 and $int % 10 &lt;= 4 and ( $int % 100 &lt; 10 or $int % 100 &gt;= 20 ) )
	{
		return 1;
	}

	// 0, 5, 6, 7, 8, 9, 10, 
	// 11, 12, 13, 14, 15, 16, 17, 18, 19, 
	// 20, 21, 25, 26, 27, 28, 29, 
	// 30, 31, 35, 36, 37, 38, 39, ...
	return 2;
}
?&gt;
</pre>

<h3>パターン4 : 形式が4つ</h3>

<p>数を表すのに4つの形式を使い分ける言語です。</p>

<h4>パターン4 .1 : /0*[2]$/と/0*[3-4]$/が特別</h4>

<dl>
<dt>対象言語</dt>
<dd>スロベニア語</dd>
</dl>

<pre class="php" name="code">
&lt;?php
function number($int)
{
	// 1, 101, 201, ...
	if ( $int % 100 == 1 )
	{
		return 0;
	}
	// 2, 102, 202, ... [特別]
	elseif ( $int % 100 == 2 )
	{
		return 1;

	}
	// 3, 4, 103, 104, 203, 204, ... [特別]
	elseif ( $int % 100 == 3 or $int % 100 == 4 )
	{
		return 2;
	}

	// 0, 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, ...
	return 3;
}
?&gt;
</pre>]]></description>
<pubDate>Fri, 19 Mar 2010 16:59:04 +0900</pubDate>
<guid>http://suin.asia/2010/03/19/treat_grammatical_number_in_php</guid>
<category domain="http://suin.asia/tag/PHP">PHP</category>
<category domain="http://suin.asia/tag/gettext">gettext</category>
<category domain="http://suin.asia/tag/%E6%96%87%E6%B3%95">文法</category>
</item>
<item>
<title>言語コード(ISO-639)と言語名と現地語表記</title>
<link>http://suin.asia/2010/03/13/langcode_language_names_list</link>
<description><![CDATA[<p>ISO-639で決められている言語コード2文字と、言語の英語表記、言語の現地語表記をリスト化しました。クリエティブコモンズやWikipediaの言語選択のようなインターフェイスを作るときに使えるかも。間違いがあれば教えてください。なお、PHPerのために配列もこしらえました。</p>
<table>
<tr>
<th>ISO-639</th>
<th>現地語表記</th>
<th>英語表記</th>
</tr>
<tr>
<td>aa</td>
<td>Qafár af</td>
<td>Afar</td>
</tr>
<tr>
<td>ab</td>
<td>Аҧсуа</td>
<td>Abkhazian</td>
</tr>
<tr>
<td>af</td>
<td>Afrikaans</td>
<td>Afrikaans</td>
</tr>
<tr>
<td>am</td>
<td>አማርኛ</td>
<td>Amharic</td>
</tr>
<tr>
<td>ar</td>
<td>اللغة العربية</td>
<td>Arabic</td>
</tr>
<tr>
<td>as</td>
<td>অসমীয়া</td>
<td>Assamese</td>
</tr>
<tr>
<td>ay</td>
<td>Aymara</td>
<td>Aymara</td>
</tr>
<tr>
<td>az</td>
<td>azərbaycanca</td>
<td>Azerbaijani</td>
</tr>
<tr>
<td>ba</td>
<td>Башҡорт теле</td>
<td>Bashkir</td>
</tr>
<tr>
<td>be</td>
<td>беларуская мова</td>
<td>Byelorussian</td>
</tr>
<tr>
<td>bg</td>
<td>Български език</td>
<td>Bulgarian</td>
</tr>
<tr>
<td>bh</td>
<td>भोजपुरी</td>
<td>Bihari</td>
</tr>
<tr>
<td>bi</td>
<td>Bislama</td>
<td>Bislama</td>
</tr>
<tr>
<td>bn</td>
<td>বাংলা</td>
<td>Bengali</td>
</tr>
<tr>
<td>bo</td>
<td>བོད་སྐད་</td>
<td>Tibetan</td>
</tr>
<tr>
<td>br</td>
<td>Brezhoneg</td>
<td>Breton</td>
</tr>
<tr>
<td>ca</td>
<td>Català</td>
<td>Catalan</td>
</tr>
<tr>
<td>co</td>
<td>Corsu</td>
<td>Corsican</td>
</tr>
<tr>
<td>cs</td>
<td>čeština</td>
<td>Czech</td>
</tr>
<tr>
<td>cy</td>
<td>Cymraeg</td>
<td>Welsh</td>
</tr>
<tr>
<td>da</td>
<td>dansk</td>
<td>Danish</td>
</tr>
<tr>
<td>de</td>
<td>Deutsch</td>
<td>German</td>
</tr>
<tr>
<td>dz</td>
<td>རྫོང་ཁ</td>
<td>Bhutani</td>
</tr>
<tr>
<td>el</td>
<td>Ελληνικά</td>
<td>Greek</td>
</tr>
<tr>
<td>en</td>
<td>English</td>
<td>English</td>
</tr>
<tr>
<td>eo</td>
<td>Esperanto</td>
<td>Esperanto</td>
</tr>
<tr>
<td>es</td>
<td>Español</td>
<td>Spanish</td>
</tr>
<tr>
<td>et</td>
<td>Eesti keel</td>
<td>Estonian</td>
</tr>
<tr>
<td>eu</td>
<td>Euskara</td>
<td>Basque</td>
</tr>
<tr>
<td>fa</td>
<td>فارسى‎</td>
<td>Persian</td>
</tr>
<tr>
<td>fi</td>
<td>Suomi</td>
<td>Finnish</td>
</tr>
<tr>
<td>fj</td>
<td>Na vosa vaka-Viti</td>
<td>Fiji</td>
</tr>
<tr>
<td>fo</td>
<td>Føroyskt</td>
<td>Faeroese</td>
</tr>
<tr>
<td>fr</td>
<td>Français</td>
<td>French</td>
</tr>
<tr>
<td>fy</td>
<td>Frysk</td>
<td>Frisian</td>
</tr>
<tr>
<td>ga</td>
<td>Gaeilge</td>
<td>Irish</td>
</tr>
<tr>
<td>gd</td>
<td>Gàidhlig na h-Alba</td>
<td>Gaelic</td>
</tr>
<tr>
<td>gl</td>
<td>galego</td>
<td>Galician</td>
</tr>
<tr>
<td>gn</td>
<td>avañe'ẽ</td>
<td>Guarani</td>
</tr>
<tr>
<td>gu</td>
<td>ગુજરાતી</td>
<td>Gujarati</td>
</tr>
<tr>
<td>ha</td>
<td>هَوُسَ</td>
<td>Hausa</td>
</tr>
<tr>
<td>hi</td>
<td>हिन्दी</td>
<td>Hindi</td>
</tr>
<tr>
<td>hr</td>
<td>Hrvatski</td>
<td>Croatian</td>
</tr>
<tr>
<td>hu</td>
<td>Magyar nyelv</td>
<td>Hungarian</td>
</tr>
<tr>
<td>hy</td>
<td>Հայերեն</td>
<td>Armenian</td>
</tr>
<tr>
<td>ia</td>
<td>Interlingua</td>
<td>Interlingua</td>
</tr>
<tr>
<td>ie</td>
<td>Interlingue</td>
<td>Interlingue</td>
</tr>
<tr>
<td>ik</td>
<td>Inupiatun</td>
<td>Inupiak</td>
</tr>
<tr>
<td>id</td>
<td>Bahasa Indonesia</td>
<td>Indonesian</td>
</tr>
<tr>
<td>is</td>
<td>íslenska</td>
<td>Icelandic</td>
</tr>
<tr>
<td>it</td>
<td>Italiano</td>
<td>Italian</td>
</tr>
<tr>
<td>he</td>
<td>עברית‎</td>
<td>Hebrew</td>
</tr>
<tr>
<td>ja</td>
<td>日本語</td>
<td>Japanese</td>
</tr>
<tr>
<td>yi</td>
<td>ייִדיש</td>
<td>Yidish</td>
</tr>
<tr>
<td>jv</td>
<td>Basa Jawa</td>
<td>Javanese</td>
</tr>
<tr>
<td>ka</td>
<td>ქართული</td>
<td>Georgian</td>
</tr>
<tr>
<td>kk</td>
<td>Қазақ тілі</td>
<td>Kazakh</td>
</tr>
<tr>
<td>kl</td>
<td>Kalaallisut</td>
<td>Greenlandic</td>
</tr>
<tr>
<td>km</td>
<td>ភាសាខ្មែរ</td>
<td>Cambodian</td>
</tr>
<tr>
<td>kn</td>
<td>ಕನ್ನಡ</td>
<td>Kannada</td>
</tr>
<tr>
<td>ko</td>
<td>한국어</td>
<td>Korean</td>
</tr>
<tr>
<td>ks</td>
<td>कॉशुर</td>
<td>Kashmiri</td>
</tr>
<tr>
<td>ku</td>
<td>كوردی</td>
<td>Kurdish</td>
</tr>
<tr>
<td>ky</td>
<td>Кыргыз тили</td>
<td>Kirghiz</td>
</tr>
<tr>
<td>la</td>
<td>Lingua Latina</td>
<td>Latin</td>
</tr>
<tr>
<td>ln</td>
<td>Lingála</td>
<td>Lingala</td>
</tr>
<tr>
<td>lo</td>
<td>ພາສາລາວ</td>
<td>Laothian</td>
</tr>
<tr>
<td>lt</td>
<td>Lietuvių kalba</td>
<td>Lithuanian</td>
</tr>
<tr>
<td>lv</td>
<td>Latviešu</td>
<td>Latvian</td>
</tr>
<tr>
<td>mg</td>
<td>Malagasy</td>
<td>Malagasy</td>
</tr>
<tr>
<td>mi</td>
<td>Te Reo Māori</td>
<td>Maori</td>
</tr>
<tr>
<td>mk</td>
<td>македонски</td>
<td>Macedonian</td>
</tr>
<tr>
<td>ml</td>
<td>മലയാളം</td>
<td>Malayalam</td>
</tr>
<tr>
<td>mn</td>
<td>Монгол хэл</td>
<td>Mongolian</td>
</tr>
<tr>
<td>mo</td>
<td>limba moldovenească</td>
<td>Moldavian</td>
</tr>
<tr>
<td>mr</td>
<td>मराठी</td>
<td>Marathi</td>
</tr>
<tr>
<td>ms</td>
<td>Bahasa Melayu</td>
<td>Malay</td>
</tr>
<tr>
<td>mt</td>
<td>Malti</td>
<td>Maltese</td>
</tr>
<tr>
<td>my</td>
<td>မြန်မာဘာသာ</td>
<td>Burmese</td>
</tr>
<tr>
<td>na</td>
<td>Ekaiairũ Naoero</td>
<td>Nauru</td>
</tr>
<tr>
<td>ne</td>
<td>नेपाली भाषा</td>
<td>Nepali</td>
</tr>
<tr>
<td>nl</td>
<td>Nederlands</td>
<td>Dutch</td>
</tr>
<tr>
<td>no</td>
<td>Norsk</td>
<td>Norwegian</td>
</tr>
<tr>
<td>oc</td>
<td>Lenga d'òc</td>
<td>Occitan</td>
</tr>
<tr>
<td>om</td>
<td>Afaan Oromoo</td>
<td>Oromo</td>
</tr>
<tr>
<td>or</td>
<td>ଓଡ଼ିଆ</td>
<td>Oriya</td>
</tr>
<tr>
<td>pa</td>
<td>ਪੰਜਾਬੀ</td>
<td>Punjabi</td>
</tr>
<tr>
<td>pl</td>
<td>język polski</td>
<td>Polish</td>
</tr>
<tr>
<td>ps</td>
<td>پښتو</td>
<td>Pashto</td>
</tr>
<tr>
<td>pt</td>
<td>Português</td>
<td>Portuguese</td>
</tr>
<tr>
<td>qu</td>
<td>Runa Simi</td>
<td>Quechua</td>
</tr>
<tr>
<td>rm</td>
<td>Rhaeto-Romance</td>
<td>Rhaeto-Romance</td>
</tr>
<tr>
<td>rn</td>
<td>Kirundi</td>
<td>Kirundi</td>
</tr>
<tr>
<td>ro</td>
<td>limba română</td>
<td>Romanian</td>
</tr>
<tr>
<td>ru</td>
<td>Русский язык</td>
<td>Russian</td>
</tr>
<tr>
<td>rw</td>
<td>Kinyarwanda</td>
<td>Kinyarwanda</td>
</tr>
<tr>
<td>sa</td>
<td>संस्कृतम्</td>
<td>Sanskrit</td>
</tr>
<tr>
<td>sd</td>
<td>سنڌي ٻولي</td>
<td>Sindhi</td>
</tr>
<tr>
<td>sg</td>
<td>Sängö</td>
<td>Sangro</td>
</tr>
<tr>
<td>sh</td>
<td>Srpskohrvatski jezik</td>
<td>Serbo-Croatian</td>
</tr>
<tr>
<td>si</td>
<td>සිංහල භාෂාව</td>
<td>Singhalese</td>
</tr>
<tr>
<td>sk</td>
<td>Slovenčina</td>
<td>Slovak</td>
</tr>
<tr>
<td>sl</td>
<td>Slovenščina</td>
<td>Slovenian</td>
</tr>
<tr>
<td>sm</td>
<td>Gagana fa'a Sāmoa</td>
<td>Samoan</td>
</tr>
<tr>
<td>sn</td>
<td>chiShona</td>
<td>Shona</td>
</tr>
<tr>
<td>so</td>
<td>Soomaaliga</td>
<td>Somali</td>
</tr>
<tr>
<td>sq</td>
<td>Shqip</td>
<td>Albanian</td>
</tr>
<tr>
<td>sr</td>
<td>Српски/Srpski</td>
<td>Serbian</td>
</tr>
<tr>
<td>ss</td>
<td>SiSwati</td>
<td>Siswati</td>
</tr>
<tr>
<td>st</td>
<td>Sesotho</td>
<td>Sesotho</td>
</tr>
<tr>
<td>su</td>
<td>Basa Sunda</td>
<td>Sudanese</td>
</tr>
<tr>
<td>sv</td>
<td>Svenska</td>
<td>Swedish</td>
</tr>
<tr>
<td>sw</td>
<td>Kiswahili</td>
<td>Swahili</td>
</tr>
<tr>
<td>ta</td>
<td>தமிழ்</td>
<td>Tamil</td>
</tr>
<tr>
<td>te</td>
<td>తెలుగు</td>
<td>Tegulu</td>
</tr>
<tr>
<td>tg</td>
<td>Тоҷикӣ</td>
<td>Tajik</td>
</tr>
<tr>
<td>th</td>
<td>ไทย</td>
<td>Thai</td>
</tr>
<tr>
<td>ti</td>
<td>ትግርኛ</td>
<td>Tigrinya</td>
</tr>
<tr>
<td>tk</td>
<td>Türkmençe</td>
<td>Turkmen</td>
</tr>
<tr>
<td>tl</td>
<td>Tagalog</td>
<td>Tagalog</td>
</tr>
<tr>
<td>tn</td>
<td>Setswana</td>
<td>Setswana</td>
</tr>
<tr>
<td>to</td>
<td>lea faka-Tonga</td>
<td>Tonga</td>
</tr>
<tr>
<td>tr</td>
<td>Türkçe</td>
<td>Turkish</td>
</tr>
<tr>
<td>ts</td>
<td>Xitsonga</td>
<td>Tsonga</td>
</tr>
<tr>
<td>tt</td>
<td>Татарча/Tatarça</td>
<td>Tatar</td>
</tr>
<tr>
<td>tw</td>
<td>Twi</td>
<td>Twi</td>
</tr>
<tr>
<td>uk</td>
<td>Українська</td>
<td>Ukrainian</td>
</tr>
<tr>
<td>ur</td>
<td>اردو</td>
<td>Urdu</td>
</tr>
<tr>
<td>uz</td>
<td>O'zbek</td>
<td>Uzbek</td>
</tr>
<tr>
<td>vi</td>
<td>Tiếng Việt</td>
<td>Vietnamese</td>
</tr>
<tr>
<td>vo</td>
<td>Volapük</td>
<td>Volapuk</td>
</tr>
<tr>
<td>wo</td>
<td>Wolof</td>
<td>Wolof</td>
</tr>
<tr>
<td>xh</td>
<td>isiXhosa</td>
<td>Xhosa</td>
</tr>
<tr>
<td>yo</td>
<td>Yorùbá</td>
<td>Yoruba</td>
</tr>
<tr>
<td>zh</td>
<td>中文</td>
<td>Chinese</td>
</tr>
<tr>
<td>zu</td>
<td>isiZulu</td>
<td>Zulu</td>
</tr>
</table>

<pre class="php" name="code">
array(
	'aa' => array('Qafár af', 'Afar'),
	'ab' => array('Аҧсуа', 'Abkhazian'),
	'af' => array('Afrikaans', 'Afrikaans'),
	'am' => array('አማርኛ', 'Amharic'),
	'ar' => array('اللغة العربية', 'Arabic'),
	'as' => array('অসমীয়া', 'Assamese'),
	'ay' => array('Aymara', 'Aymara'),
	'az' => array('azərbaycanca', 'Azerbaijani'),
	'ba' => array('Башҡорт теле', 'Bashkir'),
	'be' => array('беларуская мова', 'Byelorussian'),
	'bg' => array('Български език', 'Bulgarian'),
	'bh' => array('भोजपुरी', 'Bihari'),
	'bi' => array('Bislama', 'Bislama'),
	'bn' => array('বাংলা', 'Bengali'),
	'bo' => array('བོད་སྐད་', 'Tibetan'),
	'br' => array('Brezhoneg', 'Breton'),
	'ca' => array('Català', 'Catalan'),
	'co' => array('Corsu', 'Corsican'),
	'cs' => array('čeština', 'Czech'),
	'cy' => array('Cymraeg', 'Welsh'),
	'da' => array('dansk', 'Danish'),
	'de' => array('Deutsch', 'German'),
	'dz' => array('རྫོང་ཁ', 'Bhutani'),
	'el' => array('Ελληνικά', 'Greek'),
	'en' => array('English', 'English'),
	'eo' => array('Esperanto', 'Esperanto'),
	'es' => array('Español', 'Spanish'),
	'et' => array('Eesti keel', 'Estonian'),
	'eu' => array('Euskara', 'Basque'),
	'fa' => array('فارسى‎', 'Persian'),
	'fi' => array('Suomi', 'Finnish'),
	'fj' => array('Na vosa vaka-Viti', 'Fiji'),
	'fo' => array('Føroyskt', 'Faeroese'),
	'fr' => array('Français', 'French'),
	'fy' => array('Frysk', 'Frisian'),
	'ga' => array('Gaeilge', 'Irish'),
	'gd' => array('Gàidhlig na h-Alba', 'Gaelic'),
	'gl' => array('galego', 'Galician'),
	'gn' => array("avañe'ẽ", 'Guarani'),
	'gu' => array('ગુજરાતી', 'Gujarati'),
	'ha' => array('هَوُسَ', 'Hausa'),
	'hi' => array('हिन्दी', 'Hindi'),
	'hr' => array('Hrvatski', 'Croatian'),
	'hu' => array('Magyar nyelv', 'Hungarian'),
	'hy' => array('Հայերեն', 'Armenian'),
	'ia' => array('Interlingua', 'Interlingua'),
	'ie' => array('Interlingue', 'Interlingue'),
	'ik' => array('Inupiatun', 'Inupiak'),
	'id' => array('Bahasa Indonesia', 'Indonesian'),
	'is' => array('íslenska', 'Icelandic'),
	'it' => array('Italiano', 'Italian'),
	'he' => array('עברית‎', 'Hebrew'),
	'ja' => array('日本語', 'Japanese'),
	'yi' => array('ייִדיש', 'Yidish'),
	'jv' => array('Basa Jawa', 'Javanese'),
	'ka' => array('ქართული', 'Georgian'),
	'kk' => array('Қазақ тілі', 'Kazakh'),
	'kl' => array('Kalaallisut', 'Greenlandic'),
	'km' => array('ភាសាខ្មែរ', 'Cambodian'),
	'kn' => array('ಕನ್ನಡ', 'Kannada'),
	'ko' => array('한국어', 'Korean'),
	'ks' => array('कॉशुर', 'Kashmiri'),
	'ku' => array('كوردی', 'Kurdish'),
	'ky' => array('Кыргыз тили', 'Kirghiz'),
	'la' => array('Lingua Latina', 'Latin'),
	'ln' => array('Lingála', 'Lingala'),
	'lo' => array('ພາສາລາວ', 'Laothian'),
	'lt' => array('Lietuvių kalba', 'Lithuanian'),
	'lv' => array('Latviešu', 'Latvian'),
	'mg' => array('Malagasy', 'Malagasy'),
	'mi' => array('Te Reo Māori', 'Maori'),
	'mk' => array('македонски', 'Macedonian'),
	'ml' => array('മലയാളം', 'Malayalam'),
	'mn' => array('Монгол хэл', 'Mongolian'),
	'mo' => array('limba moldovenească', 'Moldavian'),
	'mr' => array('मराठी', 'Marathi'),
	'ms' => array('Bahasa Melayu', 'Malay'),
	'mt' => array('Malti', 'Maltese'),
	'my' => array('မြန်မာဘာသာ', 'Burmese'),
	'na' => array('Ekaiairũ Naoero', 'Nauru'),
	'ne' => array('नेपाली भाषा', 'Nepali'),
	'nl' => array('Nederlands', 'Dutch'),
	'no' => array('Norsk', 'Norwegian'),
	'oc' => array("Lenga d'òc", 'Occitan'),
	'om' => array('Afaan Oromoo', 'Oromo'),
	'or' => array('ଓଡ଼ିଆ', 'Oriya'),
	'pa' => array('ਪੰਜਾਬੀ', 'Punjabi'),
	'pl' => array('język polski', 'Polish'),
	'ps' => array('پښتو', 'Pashto'),
	'pt' => array('Português', 'Portuguese'),
	'qu' => array('Runa Simi', 'Quechua'),
	'rm' => array('Rhaeto-Romance', 'Rhaeto-Romance'),
	'rn' => array('Kirundi', 'Kirundi'),
	'ro' => array('limba română', 'Romanian'),
	'ru' => array('Русский язык', 'Russian'),
	'rw' => array('Kinyarwanda', 'Kinyarwanda'),
	'sa' => array('संस्कृतम्', 'Sanskrit'),
	'sd' => array('سنڌي ٻولي', 'Sindhi'),
	'sg' => array('Sängö', 'Sangro'),
	'sh' => array('Srpskohrvatski jezik', 'Serbo-Croatian'),
	'si' => array('සිංහල භාෂාව', 'Singhalese'),
	'sk' => array('Slovenčina', 'Slovak'),
	'sl' => array('Slovenščina', 'Slovenian'),
	'sm' => array("Gagana fa'a Sāmoa", 'Samoan'),
	'sn' => array('chiShona', 'Shona'),
	'so' => array('Soomaaliga', 'Somali'),
	'sq' => array('Shqip', 'Albanian'),
	'sr' => array('Српски/Srpski', 'Serbian'),
	'ss' => array('SiSwati', 'Siswati'),
	'st' => array('Sesotho', 'Sesotho'),
	'su' => array('Basa Sunda', 'Sudanese'),
	'sv' => array('Svenska', 'Swedish'),
	'sw' => array('Kiswahili', 'Swahili'),
	'ta' => array('தமிழ்', 'Tamil'),
	'te' => array('తెలుగు', 'Tegulu'),
	'tg' => array('Тоҷикӣ', 'Tajik'),
	'th' => array('ไทย', 'Thai'),
	'ti' => array('ትግርኛ', 'Tigrinya'),
	'tk' => array('Türkmençe', 'Turkmen'),
	'tl' => array('Tagalog', 'Tagalog'),
	'tn' => array('Setswana', 'Setswana'),
	'to' => array('lea faka-Tonga', 'Tonga'),
	'tr' => array('Türkçe', 'Turkish'),
	'ts' => array('Xitsonga', 'Tsonga'),
	'tt' => array('Татарча/Tatarça', 'Tatar'),
	'tw' => array('Twi', 'Twi'),
	'uk' => array('Українська', 'Ukrainian'),
	'ur' => array('اردو', 'Urdu'),
	'uz' => array("O'zbek", 'Uzbek'),
	'vi' => array('Tiếng Việt', 'Vietnamese'),
	'vo' => array('Volapük', 'Volapuk'),
	'wo' => array('Wolof', 'Wolof'),
	'xh' => array('isiXhosa', 'Xhosa'),
	'yo' => array('Yorùbá', 'Yoruba'),
	'zh' => array('中文', 'Chinese'),
	'zu' => array('isiZulu', 'Zulu'),
	);
</pre>]]></description>
<pubDate>Sat, 13 Mar 2010 23:09:44 +0900</pubDate>
<guid>http://suin.asia/2010/03/13/langcode_language_names_list</guid>
<category domain="http://suin.asia/tag/%E8%A8%80%E8%AA%9E">言語</category>
<category domain="http://suin.asia/tag/PHP">PHP</category>
</item>
<item>
<title>Smarty2.0からSmarty3.0への変更点</title>
<link>http://suin.asia/2010/03/06/smarty_3.0</link>
<description><![CDATA[<p>Smarty3.0のパッケージに入っている、SMARTY2_BC_NOTESを和訳してみた。</p>

<h3>分かっているSmarty2との非互換性</h3>

<h4>シンタクス</h4>

<p>Smarty 3 APIはシンタクスが新しくなりました。Smarty2のシンタクスはサポートしますが、将来サポートが保証されない可能性があります。</p>

<h4>PHPのバージョン</h4>

<p>Smarty3はPHP5のみ対応します。PHP4では動きません。</p>

<h4>{php}タグ</h4>

<p><code>{php}</code>タグはデフォルトでは無効になりました。<code>{php}</code>タグを使うことは非推奨です。<code>$smarty->allow_php_tag=true;</code>で<code>{php}</code>タグを有効にすることができます。</p>
<p>しかし、複数の<code>{php}</code>タグにまたがるPHPコードは、これ以上は動かないでしょう。</p>

<h4>デリミタとホワイトスペース</h4>

<p>ホワイトスペースに囲まれたデリミタは今後、Smartyのタグとして扱われません。したがって、<code>{ foo }</code>はタグとしてコンパイルされません。この場合、コンパイルするには<code>{foo}</code>とする必要があります。この変更により、<code>{literal}</code>が必要とならないので、Javascript/CSSが扱いやすくなります。なお、<code>$smarty->auto_literal = false;</code>でこの設定を無効化できます。</p>

<h4>クォートされなかった文字列</h4>

<p>Smarty2は、パラメータにクォートしていない文字列が現れたとき、大雑把で曖昧な面がありました。一方、Smarty3はより厳密です。といっても、特別な文字(A-Za-z0-9_以外)を含まない限り、今でもクォーテーションなしの文字列を使うことはできます。</p>

<p>例えば、ファイル名の文字列はクォートしなければなりません。</p>

<pre class="smarty" name="code">
{include file='path/foo.tpl'}
</pre>

<h4>Smartyクラスの拡張</h4>

<p>Smarty3は初期化するのに、<code>__construct</code>メソッドを使います。Smartyクラスを拡張するとき、もし、小クラスが独自のコンストラクタを定義すると、Smartyのコンストラクタは実行されません。Smartyのコンストラクタを実行する必要があれば、小クラスのコンストラクタで<code>parent::__construct()</code>を実行してください。</p>

<pre class="php" name="code">
class MySmarty extends Smarty {
   function __construct() {
       parent::__construct();
    
       // your initialization code goes here

   }
}
</pre>

<h4>オートローダー</h4>

<p>Smarty3は<code>spl_autoload_register</code>で独自のオートローダーを登録します。もしあなたのコード中に<code>__autoload</code>関数が存在するのなら、 それを明示的に<code>__autoload</code>スタックに登録しなければなりません。 詳しくは、http://us3.php.net/manual/en/function.spl-autoload-register.php を御覧下さい。</p>

<h4>プラグインファイル名</h4>

<p>Smarty3ではPHP <code>spl_autoloader</code>をサポートしています。このオートローダーは、ファイル名を小文字にすることを要求しています。したがって、Smartyプラグインのファイル名は小文字である必要があります。Smarty2では、大文字小文字が混在したファイル名でも動作しました。</p>

<h4>特別なSmarty変数のスコープ</h4>

<p>Smarty2では特別なSmarty変数(例えば、<code>$smarty.section...</code>や<code>$smarty.foreach</code>)がグローバルスコープでした。もし、同じ名前のループがサブテンプレートにあると、親テンプレートの変数を上書きしていまします。<p>

<p>Smarty3では特別なSmarty変数は、ループがあるテンプレートのローカルスコープになります。もし、親テンプレートの変数をサブテンプレートに渡す場合は、パラメータにする必要があります。</p>

<pre class="smarty" name="code">
{include file='path/foo.tpl' index=$smarty.section.foo.index}
</pre>

<h4>SMARTY_RESOURCE_CHAR_SET</h4>

<p>Smarty3はutf-8をデフォルトcharsetとして、定数<code>SMARTY_RESOURCE_CHAR_SET</code>に定義します。これは、escapeのような修飾子のデフォルトcharsetとして使われるようになります。もし、utf-8以外のcharsetをテンプレートで使う場合、適宜に<code>SMARTY_RESOURCE_CHAR_SET</code>を定義することに注意してください。そうしなければ、なにも出力されない可能性があります。</p>

<h4>改行での{if}タグ</h4>

<p>テンプレートのソースに予期される改行の出力を得るために、<code>{if}</code>,<code>{else}</code>,<code>{elseif}</code>,<code>{/if}</code>タグのコンパイル後コードに¥nが追加されました。もし、<code>{if}</code>タグなどが行末にある場合、HTMLの出力結果が改行されます。</p>]]></description>
<pubDate>Sat, 06 Mar 2010 22:20:42 +0900</pubDate>
<guid>http://suin.asia/2010/03/06/smarty_3.0</guid>
<category domain="http://suin.asia/tag/smarty">smarty</category>
<category domain="http://suin.asia/tag/php">php</category>
</item>
<item>
<title>XOOPS 一般設定しかない管理画面は一般設定に転送する</title>
<link>http://suin.asia/2010/01/28/xoops_redirect_to_preference</link>
<description><![CDATA[<p>モジュールを作っていると、管理画面に一般設定しかないというケースがあります。この場合、管理画面のトップ(/admin/index.php)は空白のページになってしまい、なんとも不格好です。見た目もそうですが、操作性をあげるためにも、管理画面のトップが空白の場合は一般設定に転送してあげましょう。</p>

<p>そして下がそのコード。</p>

<pre name="code" class="php">
require "../../../mainfile.php";

$mid = $xoopsModule->mid();

if ( defined('XOOPS_CUBE_LEGACY') )
{
	$url = sprintf('%s/modules/legacy/admin/index.php?action=PreferenceEdit&confmod_id=%u', XOOPS_URL, $mid);
}
else
{
	$url = sprintf('%s/modules/system/admin.php?fct=preferences&op=showmod&mod=%u', XOOPS_URL, $mid);
}

header('Location: '.$url);
</pre>]]></description>
<pubDate>Thu, 28 Jan 2010 00:54:23 +0900</pubDate>
<guid>http://suin.asia/2010/01/28/xoops_redirect_to_preference</guid>
<category domain="http://suin.asia/tag/XOOPS">XOOPS</category>
<category domain="http://suin.asia/tag/Tips">Tips</category>
<category domain="http://suin.asia/tag/PHP">PHP</category>
</item>
<item>
<title>『PHPポケットリファレンス』のいいところ</title>
<link>http://suin.asia/2009/10/27/php_pocket_reference</link>
<description><![CDATA[<p>高校生1年のときに、初めて買ったPHPの本は『<a href="http://www.amazon.co.jp/gp/product/4774125024?ie=UTF8&tag=suinyeze-22&linkCode=as2&camp=247&creative=1211&creativeASIN=4774125024">PHP ポケットリファレンス</a><img src="http://www.assoc-amazon.jp/e/ir?t=suinyeze-22&l=as2&o=9&a=4774125024" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />』だった。初心者のころかなり使い込んだ。それで、手あかがついたり、ページが破けたりしてしまった。私にとって、とても思い出の深い本だ。</p>
<p class="photo"><a href="http://picasaweb.google.co.jp/lh/photo/yY4Y2ugSu3NNk5Nz_xAglg?feat=embedwebsite"><img src="http://lh5.ggpht.com/_dG0BBWAhWis/Sub1zWilwXI/AAAAAAAAAtE/WnwADdXQp30/s400/DSCF3231.JPG" /></a></p>
<p class="photo"><a href="http://picasaweb.google.co.jp/lh/photo/IlmeDrzLFOiaVlRUzDIIqg?feat=embedwebsite"><img src="http://lh3.ggpht.com/_dG0BBWAhWis/Sub1zvrmJ0I/AAAAAAAAAtI/Mz-Y0n1CQOM/s400/DSCF3233.JPG" /></a></p>
<p>残念なことに、初版のポケットリファレンスはPHP4までにしか対応していない。最近はPHP5が前提の開発が多いので、改訂版のポケットリファレンスを買った。今はそれを使っている。まだ使ってからそれほどたっていないし、初心者のころと比べてリファレンスを引くことも少なくなった。それで、本にはまだ新品の香りが残っている。</p>
<p class="photo"><a href="http://picasaweb.google.co.jp/lh/photo/N6aKGNRye97PlVScXx1ePA?feat=embedwebsite"><img src="http://lh4.ggpht.com/_dG0BBWAhWis/Sub1z0u-xzI/AAAAAAAAAtM/1oE4o7rpBgc/s400/DSCF3234.JPG" /></a></p>
<p>私がなんでそんなにポケットリファレンスが好きかというと、これが本である点がある。</p>
<p>まず、場所を覚えられる点がある。使い慣れるとどこに書いてあったか分かるので、すっと引くことができる。これが一番大きい理由だと思う。よく開くページは本に癖がついて、すっと開けるようになる。下手したら検索するよりも早いってこともある。</p>
<p>次に、情報がシンプルにまとめてある点がある。ネット上のPHPリファレンスもいいと思うし、よく使う。でも、情報が多すぎて単に引数が何かを知りたいときにはかえって不便だ。ポケットリファレンスはいわば、本でできたPHPチートシートのようなものだと思う。</p>
<p>最後に、紙なので書き込める点がある。ネットで「この関数はこういうときに使うのがいい」などを知ることがある。そうした場合、私はポケットリファレンスに簡単にメモする。メモすることで覚えるし、うっかり忘れても本を開けば書いてあるというわけだ。これは電子媒体ではそう簡単じゃない。自分と共に成長する PHPリファレンスなんて素敵じゃないだろうか。</p>
<p class="photo"><a href="http://picasaweb.google.co.jp/lh/photo/jSx5TBEhQdosAEspm8dlpg?feat=embedwebsite"><img src="http://lh6.ggpht.com/_dG0BBWAhWis/Sub10JdrfRI/AAAAAAAAAtQ/G5EzAg_GmXU/s400/DSCF3238.JPG" /></a></p>
<p class="photo"><a href="http://picasaweb.google.co.jp/lh/photo/oQKHcvzY5pxV3XNDzFrOHQ?feat=embedwebsite"><img src="http://lh5.ggpht.com/_dG0BBWAhWis/Sub10SAd4sI/AAAAAAAAAtU/lIqPHQhyGWk/s400/DSCF3239.JPG" /></a></p>
<p>『PHPポケットリファレンス』は、持っていて損はないと思う。PHPをこれから始める人にも、ばりばりやってる人にもおすすめの一冊だ。</p>]]></description>
<pubDate>Tue, 27 Oct 2009 23:14:31 +0900</pubDate>
<guid>http://suin.asia/2009/10/27/php_pocket_reference</guid>
<category domain="http://suin.asia/tag/PHP">PHP</category>
<category domain="http://suin.asia/tag/%E3%81%8A%E3%81%99%E3%81%99%E3%82%81">おすすめ</category>
</item>
<item>
<title>USBに入れられるAMPサーバーアプリ</title>
<link>http://suin.asia/2009/10/24/usb_amp_server_application</link>
<description><![CDATA[<p>USBに入れられるAMP(Appache + MySQL + PHP)アプリは次のような利点がある。</p>
<ul>
<li>USBに入れられるし、USBから起動できる。</li>
<li>DropBoxに入れて、複数のパソコンでひとつのサーバを共有できる。</li>
<li>インストールしなくていい。</li>
<li>コンパクトさを生かして、簡易的な開発環境が作れる。</li>
</ul>
<p>USBに入れられるAMPアプリには次のようなものがある。個人的には、小ささとデザインの点でUSB WebServerがお気に入り。</p>
<ul>
<li><a href="http://www.uniformserver.com/">Uniform Server</a></li>
<li><a href="http://portableapps.com/apps/development/xampp">Xampp portable</a></li>
<li><a href="http://www.usbwebserver.com/">USB WebServer</a></li>
<li><a href="http://www.chsoftware.net/en">MoWeS</a></li>
</ul>]]></description>
<pubDate>Sat, 24 Oct 2009 00:06:17 +0900</pubDate>
<guid>http://suin.asia/2009/10/24/usb_amp_server_application</guid>
<category domain="http://suin.asia/tag/USB">USB</category>
<category domain="http://suin.asia/tag/PHP">PHP</category>
</item>
<item>
<title>preg_match_allのお供にarray_combine</title>
<link>http://suin.asia/2009/09/10/preg_match_all_with_array_combine</link>
<description><![CDATA[<p>preg_match_all()でマッチしたものは配列で返される。なので、その配列を整理するのにforeach()をつかったりしてひと仕事することも多い。しかし、もし、キーと値の関係にあるデータなら、array_combine()を使うと、手軽に連想配列にすることができる。覚えておくといいかもしれない。</p>

<pre name="code" class="php">
$html = '
<dl>
<dt>Apple</dt><dd>りんご</dd>
<dt>Orange</dt><dd>みかん</dd>
<dt>Strawberry</dt><dd>いちご</dd>
</dl>
';

preg_match_all('/<dt>(.+)<\/dt><dd>(.+)<\/dd>/U', $html, $matches);

var_dump($matches);

/*
array(3) {
  [0]=>
  array(3) {
    [0]=>
    string(32) "<dt>Apple</dt><dd>りんご</dd>"
    [1]=>
    string(33) "<dt>Orange</dt><dd>みかん</dd>"
    [2]=>
    string(37) "<dt>Strawberry</dt><dd>いちご</dd>"
  }
  [1]=>
  array(3) {
    [0]=>
    string(5) "Apple"
    [1]=>
    string(6) "Orange"
    [2]=>
    string(10) "Strawberry"
  }
  [2]=>
  array(3) {
    [0]=>
    string(9) "りんご"
    [1]=>
    string(9) "みかん"
    [2]=>
    string(9) "いちご"
  }
}
*/

$keys   = $matches[1];
$values = $matches[2];

$words = array_combine($keys, $values); // ここがみそ

var_dump($words);
/*
array(3) {
  ["Apple"]=>
  string(9) "りんご"
  ["Orange"]=>
  string(9) "みかん"
  ["Strawberry"]=>
  string(9) "いちご"
}
*/
</pre>]]></description>
<pubDate>Thu, 10 Sep 2009 13:34:47 +0900</pubDate>
<guid>http://suin.asia/2009/09/10/preg_match_all_with_array_combine</guid>
<category domain="http://suin.asia/tag/PHP">PHP</category>
<category domain="http://suin.asia/tag/Tips">Tips</category>
</item>
<item>
<title>PHPで自分のURLを取得する方法</title>
<link>http://suin.asia/2009/09/06/how_to_get_current_url_by_php</link>
<description><![CDATA[<p>忘れやすいのでメモする。</p>
<p>PHPで現在のURLを取得するには、$_SERVERの変数をもとにすればいい。以下のコードが具体的に、URLを取得する方法。この方法が一番シンプルで汎用性があると思う。</p>

<pre name="code" class="php">
if ( isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on' )
{
	$protocol = 'https://';
}
else
{
	$protocol = 'http://';
}

$url  = $protocol.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
</pre>]]></description>
<pubDate>Sun, 06 Sep 2009 18:22:07 +0900</pubDate>
<guid>http://suin.asia/2009/09/06/how_to_get_current_url_by_php</guid>
<category domain="http://suin.asia/tag/PHP">PHP</category>
<category domain="http://suin.asia/tag/Tips">Tips</category>
</item>
<item>
<title>PHPで配列の空白要素を一括除去したい</title>
<link>http://suin.asia/2009/03/13/array-filter.html</link>
<description><![CDATA[<p>explode()やsplit()で文字列を配列に分割したとき、空白の要素が混ざってしまうことがあります。</p>

<p>たとえば、「aaa, bbb, ccc」というような文字列をスペースかカンマで分割して配列にする場合、表記のゆれを防止するために、次のようなコードが想定されます。</p>
<pre name="code" class="php">&lt;?php
$tags = "aaa, bbb, ccc ddd,eee";

$tags = split(' |,', $tags); // スペースでもカンマでも分割する。

?&gt;</pre>
<p>取り出したかった配列の要素は5つだけのはずでしたが、空白の要素がノイズとして紛れ込んでしまいます。</p>
<pre>array(7) {
  [0]=&gt;
  string(3) "aaa"
  [1]=&gt;
  string(0) ""
  [2]=&gt;
  string(3) "bbb"
  [3]=&gt;

  string(0) ""
  [4]=&gt;
  string(3) "ccc"
  [5]=&gt;
  string(3) "ddd"
  [6]=&gt;
  string(3) "eee"
}
</pre>
<p>空白を取り除く処理は特に難しくありません。一番単純な発想でいけば、foreachで一通りチェックして、空白ならunset()するという手段を思いつくでしょう。</p>
<pre name="code" class="php">foreach ( $tags as $k =&gt; $v ) if ( empty($v) ) unset($tags[$k]);</pre>

<p>これでも十分に、空白を取り除くことができますが、もっとシンプルに書く方法があります。array_filter()を使うやりかたです。この方法だと、一行にすっきり納めることができます。</p>
<pre name="code" class="php">$tags = array_filter($tags, 'strlen');</pre>
<p>さっきのノイズ混じりの配列もこれで、必要な要素だけに絞り込むことができます。</p>
<pre>array(5) {
  [0]=&gt;
  string(3) "aaa"
  [2]=&gt;
  string(3) "bbb"
  [4]=&gt;
  string(3) "ccc"
  [5]=&gt;

  string(3) "ddd"
  [6]=&gt;
  string(3) "eee"
}
</pre>]]></description>
<pubDate>Fri, 13 Mar 2009 17:22:45 +0900</pubDate>
<guid>http://suin.asia/2009/03/13/array-filter.html</guid>
<category domain="http://suin.asia/tag/PHP">PHP</category>
<category domain="http://suin.asia/tag/php">php</category>
</item>
<item>
<title>Object→Arrayにキャストする ～多次元配列編～</title>
<link>http://suin.asia/2009/03/09/cast-object-to-array.html</link>
<description><![CDATA[<p>PHPではオブジェクト型のメンバ変数を連想配列型にキャストすることができます。(See <a href="http://d.hatena.ne.jp/shimooka/20071116/1195176801">オブジェクトをarrayにキャストする - Do You PHP はてな:</a>) </p>
<pre name="code" class="php">
$fruit = new stdClass;
$fruit-&gt;apple = '150yen';
$fruit-&gt;orange = '170yen';</pre>
<p>上の$fruitを(array)すると、</p>
<pre name="code" class="php">echo 'An apple costs '.$fruit['apple'].'.';</pre>
<p>というかんじで、普通に配列として振る舞えます。</p>
<p>stdClassでオブジェクトを作って、後で連想配列にするという手は意外と便利です。ちなみにstdClassはPHPの標準クラスです。なんの断りもなしにnewして使うことができます。</p>
<p>PHPでのオブジェクトは短い演算子（-&gt;）でメンバ変数を指定できるので、連想配列にするよりもコードがすっきりして個人的には好きです。逆に、Smartyの場合では、連想配列のキーをドット(.)で指し示すことができるので、オブジェクトで持つよりも連想配列で持った方がコードがきれいになります。</p>
<p>なので、PHPではオブジェクトにしておいて、Smartyに渡すところで連想配列にキャストするなんてことを たまにしたりします。</p>
<p>$fruitの例のように1次元の配列だと、(array)をかけるだけで、まるまる配列になりますが、階層が2段以上になるオブジェクトの場合は、(array)だと思うように多次元配列になりません。</p>
<p>アジアの都市の人口のデータのオブジェクトを例にあげて考えます。</p>
<pre name="code" class="php">$asia = new stdClass; // アジア都市の人口
$asia-&gt;japan-&gt;tokyo&nbsp;&nbsp;&nbsp; = '12,909,940';
$asia-&gt;japan-&gt;osaka&nbsp;&nbsp;&nbsp; = '8,834,433';
$asia-&gt;korea-&gt;seoul&nbsp;&nbsp;&nbsp; = '10,421,782';
$asia-&gt;korea-&gt;busan&nbsp;&nbsp;&nbsp; = '3,711,268';
$asia-&gt;china-&gt;beijing&nbsp; = '17,430,000';
$asia-&gt;china-&gt;hongkong = '6,963,100';
</pre>
<p>単純にこれを var_dump($asia); すると、当たり前のように $asia も、その子の $japan, $korea, $china
もオブジェクト型になっています。</p>
<pre>object(stdClass)#4 (3) {
  [&quot;japan&quot;]=&gt;
  object(stdClass)#5 (2) {
    [&quot;tokyo&quot;]=&gt;
    string(10) &quot;12,909,940&quot;
    [&quot;osaka&quot;]=&gt;
    string(9) &quot;8,834,433&quot;
  }
  [&quot;korea&quot;]=&gt;
  object(stdClass)#6 (2) {
    [&quot;seoul&quot;]=&gt;
    string(10) &quot;10,421,782&quot;
    [&quot;busan&quot;]=&gt;
    string(9) &quot;3,711,268&quot;
  }
  [&quot;china&quot;]=&gt;
  object(stdClass)#7 (2) {
    [&quot;beijing&quot;]=&gt;
    string(10) &quot;17,430,000&quot;
    [&quot;hongkong&quot;]=&gt;
    string(9) &quot;6,963,100&quot;
  }
}</pre>
<p>次に、 var_dump((array)$asia); を試してみます。すると、$asia だけが配列になり、 $japan などはオブジェクトのままです。</p>
<pre>array(3) {
  [&quot;japan&quot;]=&gt;
  object(stdClass)#5 (2) {
    [&quot;tokyo&quot;]=&gt;
    string(10) &quot;12,909,940&quot;
    [&quot;osaka&quot;]=&gt;
    string(9) &quot;8,834,433&quot;
  }
  [&quot;korea&quot;]=&gt;
  object(stdClass)#6 (2) {
    [&quot;seoul&quot;]=&gt;
    string(10) &quot;10,421,782&quot;
    [&quot;busan&quot;]=&gt;
    string(9) &quot;3,711,268&quot;
  }
  [&quot;china&quot;]=&gt;
  object(stdClass)#7 (2) {
    [&quot;beijing&quot;]=&gt;
    string(10) &quot;17,430,000&quot;
    [&quot;hongkong&quot;]=&gt;
    string(9) &quot;6,963,100&quot;
  }
}</pre>
<p>オブジェクトにオブジェクト内オブジェクトが...といりこ状になっているオブジェクトの場合は、再帰的に (array) をかける必要があります。便宜的に次のような関数を定義すると楽です。</p>
<pre name="code" class="php">function obj2arr($obj)
{
&nbsp;&nbsp;&nbsp; if ( !is_object($obj) ) return $obj;

&nbsp;&nbsp;&nbsp; $arr = (array) $obj;

&nbsp;&nbsp;&nbsp; foreach ( $arr as &amp;$a )
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $a = obj2arr($a);
&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp; return $arr;
}</pre>
<p>最後に、var_dump(obj2arr($asia)); を実行してみると、みごとにオブジェクトが多次元連想配列に置き換わります。</p>
<pre id="line1">array(3) {
  [&quot;japan&quot;]=&gt;
  array(2) {
    [&quot;tokyo&quot;]=&gt;
    string(10) &quot;12,909,940&quot;
    [&quot;osaka&quot;]=&gt;
    string(9) &quot;8,834,433&quot;
  }
  [&quot;korea&quot;]=&gt;
  array(2) {
    [&quot;seoul&quot;]=&gt;
    string(10) &quot;10,421,782&quot;
    [&quot;busan&quot;]=&gt;
    string(9) &quot;3,711,268&quot;
  }
  [&quot;china&quot;]=&gt;
  array(2) {
    [&quot;beijing&quot;]=&gt;
    string(10) &quot;17,430,000&quot;
    [&quot;hongkong&quot;]=&gt;
    string(9) &quot;6,963,100&quot;
  }
}</pre>]]></description>
<pubDate>Mon, 09 Mar 2009 14:16:12 +0900</pubDate>
<guid>http://suin.asia/2009/03/09/cast-object-to-array.html</guid>
<category domain="http://suin.asia/tag/PHP">PHP</category>
</item>
<item>
<title>getcwd()とdirname(__FILE__)は違う結果になるときがある</title>
<link>http://suin.asia/2009/02/18/getcwddirname-file.html</link>
<description><![CDATA[<p>phpでの話です。</p>
<p>getcwd()とdirname(__FILE__)はカレントディレクトリのパスを取得するという点で同じように説明されますが、require(_once)やinclude(_once)が絡むと、全く異なった結果を返します。</p>
<p>実験として、次のようなファイルを作成しました。<br />
C:/UsbWebServer/Root/phptest/getcwd.php<br />
C:/UsbWebServer/Root/phptest/getcwd/dir/ect/ory/include.php</p>
<p>getcwd.phpはindex.phpをrequireしています。</p>
<p>getcwd.php</p>
<pre name="code" class="php">&lt;?php

require 'getcwd/dir/ect/ory/include.php';

?&gt;</pre>
<p>include.phpには、getcwd()とdirname(__FILE__)の結果を出力する処理を書きました。</p>
<pre name="code" class="php">&lt;?php

echo 'getcwd() : ';
var_dump(getcwd());
echo '&lt;br /&gt;dirname(__FILE__) : ';
var_dump(dirname(__FILE__));

?&gt;</pre>
<p>以上の前提でgetcwd.phpを実行(ブラウザでアクセス)したところ、次のような結果になりました。</p>
<p>getcwd() : string(28) &quot;C:\UsbWebServer\Root\phptest&quot;<br />
dirname(__FILE__) : string(47) &quot;C:\UsbWebServer\Root\phptest\getcwd\dir\ect\ory&quot;
</p>
<p>上の結果をまとめると次のようになります。</p>
<p>getcwd()はアクセス中のファイルがあるディレクトリ<br />
dirname(__FILE__) はそれが書かれているファイルがあるディレクトリ</p>]]></description>
<pubDate>Wed, 18 Feb 2009 17:12:17 +0900</pubDate>
<guid>http://suin.asia/2009/02/18/getcwddirname-file.html</guid>
<category domain="http://suin.asia/tag/PHP">PHP</category>
<category domain="http://suin.asia/tag/getcwd">getcwd</category>
</item>
</channel>
</rss>