<?xml version="1.0" encoding="euc-jp"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>WEBプログラム覚書</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/" />
   <link rel="self" type="application/atom+xml" href="http://www.kantenna.com/pg/atom.xml" />
   <id>tag:www.kantenna.com,2008:/pg//2</id>
   <updated>2008-09-08T11:32:37Z</updated>
   <subtitle>PHP、MySQL、JavaScript、XMLに関する覚書。自分用メモなど</subtitle>
   <generator uri="http://www.sixapart.com/movabletype/">Movable Type 3.33-ja</generator>

<entry>
   <title>sprintf()メモ</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/09/sprintf.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.237</id>
   
   <published>2008-09-08T11:29:44Z</published>
   <updated>2008-09-08T11:32:37Z</updated>
   
   <summary>文字列のフォーマット</summary>
   <author>
      <name></name>
      
   </author>
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="2" label="PHP" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="11" label="関数" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p>慣れないとなかなか使おうと思わない<a href="http://jp.php.net/manual/ja/function.sprintf.php">printf()</a>。使いこなせばかなり便利なのは間違いない。</p>]]>
      <![CDATA[<h3>型指定子</h3>
<h4>数値関係</h4>

<p>右は</p>
<pre><code>
$y = 2008;
$m = 9;
$d = 1;
printf('%型指定子-%型指定子-%型指定子', $y, $m, $d);

</code></pre>
<p>の結果</p>
<?
$y = 2008;
$m = 9;
$d = 1;
?>
<table class="btType1">
<tr>
<th>b - 引数を整数として扱い、 バイナリの数値として表現します。</th>
<td><? printf('%b-%b-%b', $y, $m, $d); ?></td>
</tr>

<tr>
<th>c - 引数を整数として扱い、その ASCII 値の文字として表現します。</th>
<td><? printf('%c-%c-%c', $y, $m, $d); ?></td>
</tr>

<tr>
<th>d - 引数を整数として扱い、 10 進数として表現します。</th>
<td><? printf('%d-%d-%d', $y, $m, $d); ?></td>
</tr>

<tr>
<th>e - 引数を科学記法として扱います (例 1.2e+2)。 精度の指定子は、PHP 5.2.1 以降では小数点以下の桁数を表します。 それより前のバージョンでは、有効数字の桁数 (ひとつ小さい値) を意味していました。</th>
<td><? printf('%e-%e-%e', $y, $m, $d); ?></td>
</tr>

<tr>
<th>u - 引数を整数として扱い、符号無しの 10 進数として表現します。</th>
<td><? printf('%u-%u-%u', $y, $m, $d); ?></td>
</tr>

<tr>
<th>f - 引数を double として扱い、 浮動小数点数として表現します。</th>
<td><? printf('%f-%f-%f', $y, $m, $d); ?></td>
</tr>

<tr>
<th>F - 引数を float として扱い、 浮動小数点数として表現します (ロケールに依存しません)。 PHP 4.3.10 および PHP 5.0.3 以降で使用可能です。</th>
<td><? printf('%F-%F-%F', $y, $m, $d); ?></td>
</tr>

<tr>
<th>o - 引数を整数として扱い、 8 進数として表現します。</th>
<td><? printf('%o-%o-%o', $y, $m, $d); ?></td>
</tr>

<tr>
<th>x - 引数を整数として扱い、16 進数として (小文字で)表現します。</th>
<td><? printf('%x-%x-%x', $y, $m, $d); ?></td>
</tr>

<tr>
<th>X - 引数を整数として扱い、16 進数として (大文字で)表現します。</th>
<td><? printf('%X-%X-%X', $y, $m, $d); ?></td>
</tr>
</table>

<h4>文字列</h4>
<p>右は</p>
<pre><code>
$string = 'abc';
printf('%s', $string);

</code></pre>
<p>の結果</p>
<?
$string = 'abc';
?>
<table class="btType1">
<tr>
<th>s - 引数を文字列として扱い、表現します。</th>
<td><? printf('%s', $string); ?></td>
</tr>
</table>

<h3>引数の番号付け/交換</h3>
<p>4.0.6以降はフォーマット文字列における引数の番号付け/交換をサポートしている。</p>

<h4>サンプル</h4>
<p>下記について考える。</p>
<pre><code>
$name = 'KANTENNA';
$year = 2004;

$format = 'copyright %s since %d';
printf($format, $name, $year);

</code></pre>

<h4>実行結果</h4>
<div class="result">
<?
$name = 'KANTENNA';
$year = 2004;

$format = 'copyright %s since %d';
printf($format, $name, $year);
?>
</div>

<p>
基本的に置換指示子の順番は、引数の順番と一致させる必要があるので
フォーマット文字列が下記の感じだとアウト。
</p>

<pre><code>
$format = 'copyright %d since %s';
printf($format, $name, $year);

</code></pre>

<h4>実行結果</h4>
<div class="result">
<?
$format = 'copyright %d since %s';
printf($format, $name, $year);
?>
</div>

<p>
この場合、引数の順序を入れ替えるのではなくフォーマット文字列で
順序を指定してあげるのが望ましいとのこと。
</p>

<pre><code>
$format = 'copyright %2$d since %1$s';
printf($format, $name, $year);

</code></pre>

<h4>実行結果</h4>
<div class="result">
<?
$format = 'copyright %2$d since %1$s';
printf($format, $name, $year);
?>
</div>

<p>同じ置換指示子を複数回使用する際に引数を増やすこと無く利用できるので便利</p>
<pre><code>
$format = 'copyright %s since %d -%sは%dにスタートしました-';
printf($format, $name, $year, $name, $year);

echo '&lt;br /&gt;';

$format = 'copyright %1$s since %2$d -%1$sは%2$dにスタートしました-';
printf($format, $name, $year);
</code></pre>

<h4>実行結果</h4>
<div class="result">
<?
$format = 'copyright %s since %d -%sは%dにスタートしました-';
printf($format, $name, $year, $name, $year);

echo '<br />';

$format = 'copyright %1$s since %2$d -%1$sは%2$dにスタートしました-';
printf($format, $name, $year);

?>
</div>

<h3>符号指定子</h3>
<p>符号指定子は+-を付与します。これを利用すると正の数にも強制的に + 符号をつけることが出来る。</p>
<pre><code>
$plus = 1500;
$minus = -1500;
printf('%+d', $plus);
echo '&lt;br /&gt;'
printf('%+d', $minus);
</code></pre>

<h4>実行結果</h4>
<div class="result">
<?
$plus = 1500;
$minus = -1500;
printf('%+d', $plus);
echo '<br />';
printf('%+d', $minus);
?>
</div>

<h3>パディング指定子</h3>
<p>
文字列が指定の長さになるまで指定文字で埋める。
デフォルトは空白右詰め。空白、0以外で埋める場合はシングルクォーテーション + 指定文字。
</p>

<pre><code>
$padding = 'abc';

printf('[%s]&lt;br /&gt;', $padding);
printf('[%10s]&lt;br /&gt;', $padding);// 空白右詰め
printf('[%-10s]&lt;br /&gt;', $padding);// 空白左詰め
printf('[%010s]&lt;br /&gt;', $padding);//0で右詰め
printf("[%'#10s]&lt;br /&gt;", $padding);//#で右詰め

</code></pre>

<div class="result">
<pre><code>
<?
$padding = 'abc';

printf('[%s]<br />', $padding);
printf('[%10s]<br />', $padding);// 空白右詰め
printf('[%-10s]<br />', $padding);// 空白左詰め
printf('[%010s]<br />', $padding);//0で右詰め
printf("[%'#10s]<br />", $padding);//#で右詰め
?>
</code></pre>
</div>
]]>
   </content>
</entry>
<entry>
   <title>一定時間でsession終了メモ</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/09/session.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.236</id>
   
   <published>2008-09-05T12:09:25Z</published>
   <updated>2008-09-05T12:12:16Z</updated>
   
   <summary>時間の計算はUnix時間が便利</summary>
   <author>
      <name></name>
      
   </author>
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="2" label="PHP" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="320" label="session" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p>一定時間経過したらログアウトとかに利用。時間の計算はUnix時間が便利。</p>]]>
      <![CDATA[<h3>サンプルコード</h3>
<pre><code>
$keep_time = 60;

session_start();

if (!isset($_SESSION['time'])) {
    $_SESSION['time'] = time();
}

$keep_time = 60;

session_start();

if (!isset($_SESSION['time'])) {
    $_SESSION['time'] = time();
}
if (time() &gt; $_SESSION['time'] + $keep_time) {
    echo '終了';
	session_unset($_SESSION['time']);
} else {
    // 再セット
    $_SESSION['time'] = time();
    echo '継続します。' . '&lt;br /&gt;';
    echo '開始 or 更新時間 : ' . $_SESSION['time'] . '&lt;br /&gt;';
    echo '終了時間 : ' . ($_SESSION['time'] + $keep_time);
}
</code></pre>
<ul>
<li><a href="/sample/php/pg/session.html" target="_blank">動作確認</a></li>
</ul>]]>
   </content>
</entry>
<entry>
   <title>PHP ファイルのオープンと読み込み</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/07/php_4.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.233</id>
   
   <published>2008-07-09T11:48:01Z</published>
   <updated>2008-07-09T11:49:16Z</updated>
   
   <summary>ファイルのオープンと読み込み</summary>
   <author>
      <name></name>
      
   </author>
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="2" label="PHP" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="313" label="ファイル操作" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p>めっさ基本的なことだけど、ファイル操作ってやってなかったんでやってみる。</p>]]>
      <![CDATA[<h4>ファイルのオープンと読み込みサンプル</h4>
<pre><code>
$uid = '000008';
$passwd = 'hhhhhh';

$handle = fopen('passwd.txt', 'r');
while (!feof($handle)) {
    $line = fgets($handle);
    if (preg_match(&quot;/^$uid,$passwd/&quot;, $line)) {
        $user = split(',', $line);
    }
}
fclose($handle);
echo &quot;こんにちわ $uid さん。&lt;br /&gt;&quot;;
echo &quot;年齢 : $user[2]&lt;br /&gt;&quot;;
echo &quot;誕生日 : $user[3]&lt;br /&gt;&quot;;

-----------------------------------------
passwd.txt
-----------------------------------------
uid,passwd,old,birthday
000001,aaaaaa,18,2001/05/26
000002,bbbbbb,20,2001/05/26
000003,cccccc,56,2001/05/26
000004,dddddd,2,1985/12/26
000005,eeeeee,85,2081/05/26
000006,ffffff,66,2001/05/26
000007,gggggg,15,1192/07/20
000008,hhhhhh,88,2001/05/26
000009,iiiiii,59,2001/05/26

</code></pre>

<h4>実行結果</h4>
<div class="result">
<?
$uid = '000008';
$passwd = 'hhhhhh';

$handle = fopen(LIB_SAMPLE . 'text' . DS . 'passwd.txt', 'r');
while (!feof($handle)) {
	$line = fgets($handle);
	if (preg_match("/^$uid,$passwd/", $line)) {
		$user = split(',', $line);
	}
}
fclose($handle);

echo "こんにちわ $uid さん。<br />";
echo "年齢 : $user[2]<br />";
echo "誕生日 : $user[3]<br />";
?>
</div>

<p>ファイル内容全て読み込むにはfread()を利用する。</p>

<h4>fread()サンプル</h4>
<pre><code>
$handle = fopen('passwd.txt', 'r');
$conts = fread($handle, 1024);
fclose($handle);

var_dump($conts);

</code></pre>

<h4>実行結果</h4>
<div class="result">
<?
$handle = fopen(LIB_SAMPLE . 'text' . DS . 'passwd.txt', 'r');
$conts = fread($handle, 1024);
fclose($handle);
$KT->myDump($conts);
?>
</div>

<? $KT->getGroupBook('php'); ?>]]>
   </content>
</entry>
<entry>
   <title>jQueryによる表示、非表示切り替え</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/06/jquery.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.230</id>
   
   <published>2008-06-30T11:28:16Z</published>
   <updated>2008-06-30T19:44:50Z</updated>
   
   <summary>jQueryによるDiv要素の表示、非表示切り替え</summary>
   <author>
      <name></name>
      
   </author>
         <category term="JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="13" label="Javascript" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="310" label="jQuery" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p>今さらながらjQueryをお勉強。日本語のリファレンスも充分すぎるくらい充実してますんで、勉強しやすいですねよく使いそうなDivの表示、非表示切り替えをjQueryでやると・・・</p>]]>
      <![CDATA[<script language="javascript" type="text/javascript">
$(function(){    
    // id="jQuerySample" 内のdivを非表示
    $('#jQuerySample div').css('display', 'none');
    
    // id="jQuerySample"内のi番目のh5がクリックされた時、
    // i番目のdivの表示、非表示切り替え
    $('#jQuerySample h5').each(function(i){
        $(this).click(function(){
            $('#jQuerySample div').eq(i).toggle();
        });
    });
	
     // id="jQuerySample" を親要素に持つdivを非表示
    $('#jQuerySample2 > div').css('display', 'none');
    
    // id="jQuerySample"を親要素に持つi番目のh5が
    // クリックされた時、i番目のdivの表示、非表示切り替え
    $('#jQuerySample2 > h5').each(function(i){
        $(this).click(function(){
            $('#jQuerySample2 > div').eq(i).toggle();
        });
    });
});
</script>

<h3>jQueryによる表示、非表示サンプル</h3>
<pre><code>
-----------------------------------------------------
Javascript
-----------------------------------------------------
$(function(){    
    // id=&quot;jQuerySample&quot; 内のdivを非表示
    $('#jQuerySample').css('display', 'none');
    
    // id=&quot;jQuerySample&quot;内のi番目のh5がクリックされた時、
    // i番目のdivの表示、非表示切り替え
    $('#jQuerySample').each(function(i){
        $(this).click(function(){
            $('#jQuerySample').eq(i).toggle();
        });
    });
});

-----------------------------------------------------
HTML
-----------------------------------------------------
&lt;div id=&quot;jQuerySample&quot;&gt;
    &lt;h5&gt;jQueryサンプル1&lt;/h5&gt;
    &lt;div&gt;
    &lt;p&gt;これはjQueryのサンプル1です。&lt;/p&gt;
    &lt;/div&gt;
	
    &lt;h5&gt;jQueryサンプル2&lt;/h5&gt;
    &lt;div&gt;
    &lt;p&gt;これはjQueryのサンプル2です。&lt;/p&gt;
    &lt;/div&gt;
    
    &lt;h5&gt;jQueryサンプル3&lt;/h5&gt;
    &lt;div&gt;
    &lt;p&gt;これはjQueryのサンプル3です。&lt;/p&gt;
    &lt;/div&gt;
&lt;/div&gt;

</code></pre>

<h4>実行結果</h4>
<div class="result">
<div id="jQuerySample">
    <h5>jQueryサンプル1</h5>
    <div>
    <p>これはjQueryのサンプル1です。</p>
    </div>

    <h5>jQueryサンプル2</h5>
    <div>
    <p>これはjQueryのサンプル2です。</p>
    </div>

    <h5>jQueryサンプル3</h5>
    <div>
    <p>これはjQueryのサンプル3です。</p>
    </div>
</div>
</div>

<p>たったこれだけ。自分の場合jQuery使わないと下記のようにわけわからんことになってしまいました。もう吐きそうです。</p>

<h3>jQueryを利用しない表示、非表示サンプル</h3>
<pre><code>
onload = function() {
    obj = document.getElementById(&quot;jQuerySample&quot;);
    h5 = getEreaObj(obj,&quot;h5&quot;);
    div = getEreaObj(obj, &quot;div&quot;);
    
    for (i=0; i&lt;h5.length; i++) {
        div[i].style.display = &quot;none&quot;;
        showhide(h5[i], i);
    }
}

function getEreaObj(obj, tag){
  objs = obj.getElementsByTagName(tag);
  return objs;
}

function showhide(obj, num){
    myFunc = function(){
        if(div[num].style.display == &quot;none&quot;){
          div[num].style.display = &quot;block&quot;;
        }else{
          div[num].style.display = &quot;none&quot;;
        }
    }
    obj.onclick = myFunc;
}

</code></pre>

<p>
表示、非表示の切り替えでもこんな面倒です。さらにdivの中にdivが入ってる入れ子の状態の場合、
通常もっと厄介になりますが、jQuery利用すれば選択部分を変更するだけです。
</p>

<h3>jQueryを利用した子要素のみの表示、非表示サンプル</h3>
<pre><code>
-----------------------------------------------------
Javascript
-----------------------------------------------------
$(function(){    
    // id=&quot;jQuerySample2&quot; を親要素に持つdivを非表示
    $('#jQuerySample2 &gt; div').css('display', 'none');
    
    // id=&quot;jQuerySample2&quot;を親要素に持つi番目のh5が
    // クリックされた時、i番目のdivの表示、非表示切り替え
    $('#jQuerySample2 &gt; h5').each(function(i){
        $(this).click(function(){
            $('#jQuerySample2 &gt; div').eq(i).toggle();
        });
    });
});

-----------------------------------------------------
HTML
-----------------------------------------------------
&lt;div id=&quot;jQuerySample&quot;&gt;
    &lt;h5&gt;jQueryサンプル1&lt;/h5&gt;
    &lt;div&gt;
    &lt;p&gt;これはjQueryのサンプル1です。&lt;/p&gt;
        &lt;div&gt;
        &lt;p&gt;これはjQueryのサンプル1の中のdiv内です。&lt;/p&gt;
        &lt;/div&gt;
    &lt;/div&gt;
	
    &lt;h5&gt;jQueryサンプル2&lt;/h5&gt;
    &lt;div&gt;
    &lt;p&gt;これはjQueryのサンプル2です。&lt;/p&gt;
    &lt;/div&gt;
    
    &lt;h5&gt;jQueryサンプル3&lt;/h5&gt;
    &lt;div&gt;
    &lt;p&gt;これはjQueryのサンプル3です。&lt;/p&gt;
	    &lt;div&gt;
        &lt;p&gt;これはjQueryのサンプル3の中のdiv内です。&lt;/p&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
</code></pre>

<h4>実行結果</h4>
<div class="result">
<div id="jQuerySample2">
    <h5>jQueryサンプル1</h5>
    <div>
    <p>これはjQueryのサンプル1です。</p>
		<div>
		<p>これはjQueryのサンプル1の中のdiv内です。</p>
		</div>
    </div>

    <h5>jQueryサンプル2</h5>
    <div>
    <p>これはjQueryのサンプル2です。</p>
    </div>

    <h5>jQueryサンプル3</h5>
    <div>
    <p>これはjQueryのサンプル3です。</p>
		<div>
		<p>これはjQueryのサンプル3の中のdiv内です。</p>
		</div>
    </div>
</div>
</div>
<p>実際書き比べてみると便利さがよくわかります・・・</p>
<? $KT->getGroupBook('jquery'); ?>]]>
   </content>
</entry>
<entry>
   <title>MySQLユーザ発行</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/06/mysql_5.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.229</id>
   
   <published>2008-06-28T19:50:08Z</published>
   <updated>2008-06-28T19:51:58Z</updated>
   
   <summary>いっつも忘れるGRANT構文メモ。MySQLへの新規ユーザ追加はGRANT ステートメント利用が推奨されている。</summary>
   <author>
      <name></name>
      
   </author>
         <category term="MySQL" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="64" label="MySQL" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="267" label="SQL" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p>いっつも忘れるGRANT構文メモ。MySQLへの新規ユーザ追加はGRANT ステートメント利用が推奨されている。</p>]]>
      <![CDATA[<h3>GRANT構文</h3>
<pre><code>
GRANT 権限 ON データベース名.テーブル名 TO ユーザ名@ホスト名 IDENTIFIED BY パスワード;
</code></pre>

<h3>サンプル</h3>
<p>全てのデータベース、テーブルに対してすべての処理を行える。(スーパーユーザ)</p>
<pre><code>GRANT ALL ON *.* TO username@localhost IDENTIFIED BY 'passwd';</code></pre>

<p>一般ユーザは大体こんな感じか。</p>
<pre><code>
GRANT
ALTER, CREATE, DELETE, DROP, INDEX, INSERT, SELECT
ON usertable.* TO username@localhost IDENTIFIED BY 'passwd';
</code></pre>

<p>ユーザ追加後、更新しないと反映されない。</p>
<pre><code>FLUSH PRIVILEGES;</code></pre>

<p>設定可能な権限は「<a href="http://dev.mysql.com/doc/refman/4.1/ja/grant.html">4.4.1. GRANT および REVOKE の構文</a>」のとおり。</p>
<table class="btType1">
<tbody>
<tr>
<th>ALL [PRIVILEGES]</th>
<td>
WITH GRANT OPTION
以外のすべての権限を設定
</td>
</tr>

<tr>
<th>ALTER</th>
<td>ALTER TABLE の使用を許可</td>
</tr>

<tr>
<th>CREATE</th>
<td>CREATE TABLE の使用を許可</td>
</tr>

<tr>
<th>CREATE TEMPORARY TABLES</th>
<td>CREATE TEMPORARY TABLE の使用を許可</td>
</tr>

<tr>
<th>DELETE</th>
<td>DELETE の使用を許可</td>
</tr>

<tr>
<th>DROP</th>
<td>DROP TABLE の使用を許可</td>
</tr>

<tr>
<th>EXECUTE</th>
<td>ストアドプロシージャの使用を許可（MySQL 5.0）</td>
</tr>

<tr>
<th>FILE</th>
<td>
SELECT ... INTO OUTFILE および LOAD DATA
INFILE の使用を許可
</td>
</tr>

<tr>
<th>INDEX</th>
<td>CREATE INDEX および DROP INDEXの使用を許可</td>
</tr>

<tr>
<th>INSERT</th>
<td>INSERT の使用を許可</td>
</tr>

<tr>
<th>LOCK TABLES</th>
<td>
SELECT 権限を持つテーブルで LOCK
TABLES の使用を許可
</td>
</tr>

<tr>
<th>PROCESS</th>
<td>SHOW FULL PROCESSLIST の使用を許可</td>
</tr>

<tr>
<th>REFERENCES</th>
<td>将来のために予約</td>
</tr>

<tr>
<th>RELOAD</th>
<td>FLUSH の使用を許可</td>
</tr>

<tr>
<th>REPLICATION CLIENT</th>
<td>スレーブおよびマスタのサーバーを知る権利を付与</td>
</tr>

<tr>
<th>REPLICATION SLAVE</th>
<td>レプリケーションのスレーブに必要(マスタからバイナリログを読み取るため)</td>
</tr>

<tr>
<th>SELECT</th>
<td>SELECT の使用を許可</td>
</tr>

<tr>
<th>SHOW DATABASES</th>
<td>
SHOW DATABASES
によりすべてのデータベースが表示される</td>
</tr>

<tr>
<th>SHUTDOWN</th>
<td>
mysqladmin shutdown の使用を許可</td>
</tr>

<tr>
<th>SUPER</th>
<td>最大接続数に達していても接続を 1
つだけ許可し、コマンド CHANGE
MASTER、KILL
thread、mysqladmin
debug、PURGE MASTER
LOGS、および SET GLOBAL
の実行を許可</td>
</tr>

<tr>
<th>UPDATE</th>
<td>
UPDATE の使用を許可</td>
</tr>

<tr>
<th>USAGE</th>
<td>``権限なし'' のシノニム</td>
</tr>

<tr>
<th>GRANT OPTION</th>
<td>WITH GRANT OPTION のシノニム</td>
</tr>
</tbody>
</table>

<? $KT->getGroupBook('mysql'); ?>]]>
   </content>
</entry>
<entry>
   <title>出来ると思ったけど出来なかったJavascriptコード</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/06/javascript_7.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.228</id>
   
   <published>2008-06-27T11:22:03Z</published>
   <updated>2008-06-27T11:36:06Z</updated>
   
   <summary>「innerText」はFirefoxで利用できないようなので、try〜catchで分岐させようと思ったけどダメだったのでｊQueryのブラウザ判定を利用してみた。</summary>
   <author>
      <name></name>
      
   </author>
         <category term="JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="310" label="jQuery" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="12" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="311" label="ブラウザ判定" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p>「innerText」はFirefoxで利用できないようなので、try〜catchで分岐させようと思ったけどダメだった。</p>
]]>
      <![CDATA[<script language="javascript" type="text/javascript">
onload = function()
{
    var userAgent = navigator.userAgent.toLowerCase();
    var browser = {
        version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
        safari: /webkit/.test( userAgent ),
        opera: /opera/.test( userAgent ),
        msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
        mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
    };
	
    try {
        var t = document.getElementById('SampleText').childNodes[0].innerText;
    }
    catch(e) {
        var t = document.getElementById('SampleText').childNodes[1].textContent;
    }
    
    var bt = document.getElementById('Alert');
    bt.onclick = function() {
        alert(t);
    }
    
    try {
        var t2 = document.getElementById('DummySampleText').childNodes[0].innerText;
    }
    catch(e) {
        /*　IEがここで死ぬんで回避
        var t2 = document.getElementById('SampleText').childNodes[1].textContent;
        */
        var t2 = 'Javascriptテスト';
    }
    
    var bt2 = document.getElementById('Alert2');
    bt2.onclick = function() {
        alert(t2);
    }

    try {
        var t3 = document.getElementById('DummySampleText');
    }
    catch(e) {
        var t3 = document.getElementById('SampleText').childNodes[1].textContent;
    }
    
    var bt3 = document.getElementById('Alert3');
    bt3.onclick = function() {
        alert(t3);
    }
	
    if (browser.msie) {
        var t4 = document.getElementById('SampleText').childNodes[0].innerText;
    } else {
        var t4 = document.getElementById('SampleText').childNodes[1].textContent;
    }
    var bt4 = document.getElementById('Alert4');
    bt4.onclick = function() {
        alert(t4);
    }
}
</script>

<h3>Javascriptエラーテスト</h3>
<h4>サンプルコード</h4>
<pre><code>
-----------------------------------
Javascript
-----------------------------------
onload = function()
{
    // エラーにならない
    try {
        var t = document.getElementById('SampleText').childNodes[0].innerText;
    }
    catch(e) {
        var t = document.getElementById('SampleText').childNodes[1].textContent;
    }
    
    var bt1 = document.getElementById('Alert1');
    bt1.onclick = function() {
        alert(t);
    }
    
    // エラーになる
    try {
        var t2 = document.getElementById('DummySampleText').childNodes[0].innerText;
    }
    catch(e) {
        /*　IEがここで死ぬんで回避
        var t2 = document.getElementById('SampleText').childNodes[1].textContent;
        */
        var t2 = 'Javascriptテスト';
    }
	
    var bt2 = document.getElementById('Alert2');
    bt2.onclick = function() {
        alert(t2);
    }
	
    // エラーにならない
    try {
        var t3 = document.getElementById('DummySampleText');
    }
    catch(e) {
        var t3 = document.getElementById('SampleText').childNodes[1].textContent;
    }

    var bt3 = document.getElementById('Alert3');
    bt3.onclick = function() {
        alert(t3);
    }
}

-----------------------------------
HTML
-----------------------------------
&lt;div id=&quot;SampleText&quot;&gt;
    &lt;p&gt;Javascript のテスト&lt;/p&gt;
&lt;/div&gt;
&lt;input type=&quot;button&quot; value=&quot;ボタン1&quot; id=&quot;Alert&quot; /&gt;
&lt;input type=&quot;button&quot; value=&quot;ボタン2&quot; id=&quot;Alert2&quot; /&gt;
&lt;input type=&quot;button&quot; value=&quot;ボタン3&quot; id=&quot;Alert3&quot; /&gt;

</code></pre>

<h4>実行結果</h4>
<div class="result">
<div id="SampleText">
<p>Javascript のテスト</p>
</div>
<input type="button" value="ボタン1" id="Alert" />
<input type="button" value="ボタン2" id="Alert2" />
<input type="button" value="ボタン3" id="Alert3" />
</div>
<ul>
<li>オブジェクトの存在しないプロパティ(?)の参照はエラーとならない。</li>
<li>存在しないオブジェクトの参照はエラー。</li>
<li>オブジェクトの取得失敗はエラーとならない。</li>
</ul>

<h3>ブラウザ判定による分岐</h3>
<p>結局try〜catchでは分岐できないので、何がしかの分岐処理を実装する必要がある。</p>
<pre><code>
if (t == 'undefined') {
   var t = document.getElementById('SampleText').childNodes[1].textContent;
}

</code></pre>
<p>
一番簡単だけど、いまいち汎用性に乏しいのでいいブラウザ判定ないかと見てみたら
<a href="http://jquery.com/">jQuery</a>のブラウザ判定がすっきりしてていい感じだったので採用。
</p>

<h4>jQueryのブラウザ判定部分を利用したサンプル</h4>
<pre><code>
onload = function()
{
    // jQuery ブラウザ判定部分を拝借
    var userAgent = navigator.userAgent.toLowerCase();
    var browser = {
        version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
        safari: /webkit/.test( userAgent ),
        opera: /opera/.test( userAgent ),
        msie: /msie/.test( userAgent ) &amp;&amp; !/opera/.test( userAgent ),
        mozilla: /mozilla/.test( userAgent ) &amp;&amp; !/(compatible|webkit)/.test( userAgent )
    };
	
    if (browser.msie) {
        var t4 = document.getElementById('SampleText').childNodes[0].innerText;
    } else {
        var t4 = document.getElementById('SampleText').childNodes[1].textContent;
    }
    var bt4 = document.getElementById('Alert4');
    bt4.onclick = function() {
        alert(t4);
    }
}

</code></pre>

<h4>実行結果</h4>
<div class="result">
<input type="button" value="ボタン4" id="Alert4" />
</div>

<p>
勉強のためライブラリを利用しないようにしてたけど、
やっぱり便利だすどす。ってことで今さらながら<a href="http://jquery.com/">jQuery</a>使っていきますかねー。
</p>

<? $KT->getBook('4774134902'); ?>]]>
   </content>
</entry>
<entry>
   <title>PHP4 static修飾子</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/04/php4_static.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.216</id>
   
   <published>2008-04-03T13:19:16Z</published>
   <updated>2008-04-03T13:22:54Z</updated>
   
   <summary>PHP4のstatic修飾子の挙動</summary>
   <author>
      <name></name>
      
   </author>
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="2" label="PHP" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="297" label="static" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p>
pearの<a href="http://pear.php.net/package/Net_UserAgent_Detect">Net_UserAgent_Detect</a>を眺めていたら「static」があった。
「static」なんて使ったことなかったのでどんな動きするのか試してみた。
</p>]]>
      <![CDATA[<h3>そもそもの挙動</h3>
<p>そもそものstaticの挙動は</p>
<blockquote>静的変数はローカル関数スコープのみに 存在しますが、プログラム実行がこのスコープの外で行われるようになってもその値を失わないません。</blockquote>
<p>と<a href="http://jp.php.net/manual/ja/language.variables.scope.php">PHPマニュアル</a>にあるように、変数のスコープが外れても値を保持してくれるということらしいので</p>
<h4>サンプルコード</h4>
<pre><code>
function noStatic()
{
    $count = 0;
    $count++;
    return $count;
}

function yesStatic()
{
    static $count = 0;
    $count++;
    return $count;
}

for ($i=0; $i&lt;3; $i++) {
    echo 'noStatic()' . $i . '回目 : ' . noStatic() . &quot;\n&quot;;
    echo 'yesStatic()' . $i . '回目 : ' . yesStatic() . &quot;\n&quot;;
}

</code></pre>

<h4>実行結果</h4>
<div class="result">
<pre><code>
<?
function noStatic()
{
	$count = 0;
	$count++;
	return $count;
}
function yesStatic()
{
	static $count = 0;
	$count++;
	return $count;
}

for ($i=0; $i<3; $i++) {
	echo 'noStatic()' . $i . '回目 : ' . noStatic() . "\n";
	echo 'yesStatic()' . $i . '回目 : ' . yesStatic() . "\n";
}
?>
</code></pre>
</div>

<p>このような実行結果になるのは問題ない。</p>

<p>
でstaticをクラス内で利用した場合、<a href="http://blog.37to.net/2006/02/php4static/">PHP4のメソッドにおけるstatic変数の挙動</a>
でも書かれているように別オブジェクトであっても共有されるようだ。
</p>

<pre><code>
class StaticTest
{
    var $name;

    function StaticTest($name)
    {
        $this-&gt;name = $name;
    }

    function get()
    {
        static $count = 0;
        $count++;
        return $count;
    }
}

$a = new StaticTest('A');
$b = new StaticTest('B');

for ($i=0; $i&lt;3; $i++) {
    echo $a-&gt;name . $i . '回目 : ' . $a-&gt;get() . &quot;\n&quot;;
    echo $b-&gt;name . $i . '回目 : ' . $b-&gt;get() . &quot;\n&quot;;
}

</code></pre>

<pre><code>
<?
class StaticTest
{
	var $name;
	
	function StaticTest($name)
	{
		$this->name = $name;
	}
	
	function get()
	{
		static $count = 0;
		$count++;
		return $count;
	}

}

$a = new StaticTest('A');
//$b = new StaticTest('B');
$b = $a;
for ($i=0; $i<3; $i++) {
	echo $a->name . $i . '回目 : ' . $a->get() . "\n";
	echo $b->name . $i . '回目 : ' . $b->get() . "\n";
}

?>

</code></pre>

<p><a href="http://blog.37to.net/2006/02/php4static/">PHP4のメソッドにおけるstatic変数の挙動</a>のソースまんまだが確かに共有されている・・・</p>
]]>
   </content>
</entry>
<entry>
   <title>「新しくプログラミング言語を覚えたいときに行うべき10の練習問」をやってみた。-第3問-</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/02/103.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.211</id>
   
   <published>2008-02-12T18:56:55Z</published>
   <updated>2008-02-12T18:48:31Z</updated>
   
   <summary>javascriptで複数の数値を入力させ、昇順に並び替え、最大値と最小値を出すスクリプト</summary>
   <author>
      <name></name>
      
   </author>
         <category term="JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="12" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="292" label="練習問題" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p><a href="http://www.ideaxidea.com/">IDEA*IDEA</a>さんが作ってくれた「<a href="http://www.ideaxidea.com/archives/2008/02/10_7.html">新しくプログラミング言語を覚えたいときに行うべき10の練習問題</a>」3問目をjavascriptの勉強にやってみた。</p>]]>
      <![CDATA[<h3>複数の数値を入力させ、昇順に並び替え、最大値と最小値を出す</h3>
<pre><code>
// とりあえずフォームの取得
function getFormObj(name)
{
    var obj = document.MyForm.elements[name];
    return obj;    
}

// 入力値を配列として保存するクラス
function GoSet(){
    
    // 入力値
    var values = new Array();
    
    // 値をゲット
    this.getter = function(){
        return values;
    }
    
    // セット用
    this.setter = function(num){
        /**
         * 数字以外エラーとして
         * リセットする処理が必要だけど略(爆
         */
        values.push(num);
    }
    
    // リセット用
    this.resetter = function(){
        values = [];
    }

}

// 配列をソートするクラス
function GoSort(values){

    var value = values;
    var result;
    
    // 受け取った配列をソートしてresultに格納
    this.startSort = function(){    
        result = value.sort(this.Func);
    }
    
    // ソート比較関数
    this.Func = function(a, b) {
          return a - b;
    }
    
    // ソート結果を返す
    this.getResult = function(){
        return result;
    }

    this.getMax = function(){
        if(result == null){
            this.startSort();
        }
        return result[(result.length) - 1];
    }
    
    this.getMin = function(){
        if(result == null){
            this.startSort();
        }
        return result[0];
    }
}


function Controller(){

    var setBT = getFormObj('set');
    var sortBT = getFormObj('sort');
    var resetBT = getFormObj('reset');
    this.num = getFormObj('num');
        
    this.set = new GoSet();
        
    var self = this;
    
    // 追加ボタンクリック時の処理
    setBT.onclick = function(){
        self.set.setter(self.num.value);
        alert(self.set.getter());
        self.num.value = '';    
    }
    
    // ソートボタンクリック時の処理
    sortBT.onclick = function(){
        var lastvalue = new GoSort(self.set.getter());
        lastvalue.startSort();
        alert('ソート結果' + lastvalue.getResult());
        alert('最大値は' + lastvalue.getMax());
        alert('最小値は' + lastvalue.getMin());
    }
    
    // 追加ボタンクリック時の処理
    resetBT.onclick = function(){
        self.set.resetter();
        alert('入力値をリセットしました');    
	}
}

onload = Controller;
</code></pre>

<h3>実行結果</h3>
<div class="result">
<script language="javascript" type="text/javascript">
// とりあえずフォームの取得
function getFormObj(name)
{
	var obj = document.MyForm.elements[name];
	return obj;	
}

// 入力値を配列として保存するクラス
function GoSet(){
	
	// 入力値
	var values = new Array();
	
	// 値をゲット
	this.getter = function(){
		return values;
	}
	
	// セット用
	this.setter = function(num){
		/**
		 * 数字以外エラーとして
		 * リセットする処理が必要だけど略(爆
		 */
		values.push(num);
	}
	
	// リセット用
	this.resetter = function(){
		values = [];
	}

}

// 配列をソートするクラス
function GoSort(values){

	var value = values;
	var result;
	
	// 受け取った配列をソートしてresultに格納
	this.startSort = function(){	
		result = value.sort(this.Func);
	}
	
	// ソート比較関数
	this.Func = function(a, b) {
  		return a - b;
	}
	
	// ソート結果を返す
	this.getResult = function(){
		return result;
	}

	this.getMax = function(){
		if(result == null){
			this.startSort();
		}
		return result[(result.length) - 1];
	}
	
	this.getMin = function(){
		if(result == null){
			this.startSort();
		}
		return result[0];
	}
}


function Controller(){

	var setBT = getFormObj('set');
	var sortBT = getFormObj('sort');
	var resetBT = getFormObj('reset');
	this.num = getFormObj('num');
		
	this.set = new GoSet();
		
	var self = this;
	
	// 追加ボタンクリック時の処理
	setBT.onclick = function(){
		self.set.setter(self.num.value);
		alert(self.set.getter());
		self.num.value = '';	
	}
	
	// ソートボタンクリック時の処理
	sortBT.onclick = function(){
		var lastvalue = new GoSort(self.set.getter());
		lastvalue.startSort();
		alert('ソート結果' + lastvalue.getResult());
		alert('最大値は' + lastvalue.getMax());
		alert('最小値は' + lastvalue.getMin());
	}
	
	// 追加ボタンクリック時の処理
	resetBT.onclick = function(){
		self.set.resetter();
		alert('入力値をリセットしました');	
	}
}

onload = Controller;
</script>
<form name="MyForm">
<input type="text" name="num" />
<input type="button" name="set" value="追加" />
<input type="button" name="sort" value="ソート" />
<input type="button" name="reset" value="リセット" />
</form>
</div>
<p>ソート比較関数がよくわからない・・・<a href="http://developer.mozilla.org/ja/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:sort">ここ</a>後で読む。</p>
]]>
   </content>
</entry>
<entry>
   <title>「新しくプログラミング言語を覚えたいときに行うべき10の練習問」をやってみた。-第2問-</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/02/102.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.210</id>
   
   <published>2008-02-12T18:53:38Z</published>
   <updated>2008-02-12T18:45:19Z</updated>
   
   <summary>javascriptで現在時刻にあわせてメッセージを出力するスクリプト</summary>
   <author>
      <name></name>
      
   </author>
         <category term="JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="12" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="292" label="練習問題" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p><a href="http://www.ideaxidea.com/">IDEA*IDEA</a>さんが作ってくれた「<a href="http://www.ideaxidea.com/archives/2008/02/10_7.html">新しくプログラミング言語を覚えたいときに行うべき10の練習問題</a>」2問目をjavascriptの勉強にやってみた。</p>]]>
      <![CDATA[<h3>現在時刻にあわせてメッセージを出力</h3>
<pre><code>
function HourMessage(hour)
{
    var err = 'メッセージは何も無い・・・';
    var message = [
        [0, '今日が始まった'],
        [12, '今日も中盤戦'],
        [23, 'そろそろ今日が終わる']
        ];
					
    for (i=0; i&lt;message.length; i++) {
        if(message[i][0] == hour) {
            return message[i][1];
        }
    }
    return err;
}

onload = function(){
    var displayArea = document.getElementById('message');
    displayArea.innerHTML = HourMessage((new Date()).getHours());	
}
</code></pre>

<h3>実行結果</h3>
<div class="result">
<script language="javascript" type="text/javascript">

function HourMessage(hour)
{
	var err = 'メッセージは何も無い・・・';
	var message = [
					[0, '今日が始まった'],
					[12, '今日も中盤戦'],
					[23, 'そろそろ今日が終わる']
					];
					
	for (i=0; i<message.length; i++) {
		if(message[i][0] == hour) {
			return message[i][1];
		}
	}
	return err;
}

onload = function(){
	var displayArea = document.getElementById('message');
	displayArea.innerHTML = HourMessage((new Date()).getHours());	
}

</script>
<div id="message">

</div>
</div>

<p>※オブジェクト指向的に作ればメッセージの形式が、XMLだったりJSONだったりした場合にも対応できるようになりそう・・・？</p>]]>
   </content>
</entry>
<entry>
   <title>「新しくプログラミング言語を覚えたいときに行うべき10の練習問」をやってみた。-第1問-</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/02/101.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.209</id>
   
   <published>2008-02-12T18:50:59Z</published>
   <updated>2008-02-12T18:43:05Z</updated>
   
   <summary>javascriptで1から100までカウント。3の倍数のときだけ[3の倍数]を追記表示するスクリプト</summary>
   <author>
      <name></name>
      
   </author>
         <category term="JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="12" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="292" label="練習問題" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p><a href="http://www.ideaxidea.com/">IDEA*IDEA</a>さんが作ってくれた「<a href="http://www.ideaxidea.com/archives/2008/02/10_7.html">新しくプログラミング言語を覚えたいときに行うべき10の練習問題</a>」をjavascriptの勉強にやってみた。</p>]]>
      <![CDATA[<p>元ネタより簡単な感じで作ってくれているので自分のような少々プログラムをかじった程度でもなんとかかんとかできそうです。</p>
<h3>1から100までカウント。3の倍数のときだけ[3の倍数]を追記表示する。</h3>
<pre><code>
// 1から100までカウント　3の倍数の時だけ[3の倍数]をつける
function Count()
{
	var i = 1;
	var result = '';

	while (i &lt;= 100) {
		if ((i % 3) == 0) {
			result += i + ' [3の倍数]&lt;br /&gt;'; 
		} else {
			result += i + '&lt;br /&gt;';
		}
		i++;			
	}

	this.getResult = function()
	{
		return result;
	}	
}

onload = function(){	
	var a = new Count();
	var displayArea = document.getElementById('Counter');
	var start = document.getElementById('start');
	
	start.onclick = function(){
		displayArea.innerHTML = a.getResult();
	}
}
</code></pre>

<h3>実行結果</h3>
<div id="result">
<script language="javascript" type="text/javascript">
// 1から100までカウント　3の倍数の時だけ[3の倍数]をつける
function Count()
{
	var i = 1;
	var result = '';

	while (i <= 100) {
		if ((i % 3) == 0) {
			result += i + ' [3の倍数]<br />'; 
		} else {
			result += i + '<br />';
		}
		i++;			
	}

	this.getResult = function()
	{
		return result;
	}	
}

onload = function(){	
	var a = new Count();
	var displayArea = document.getElementById('Counter');
	var start = document.getElementById('start');
	
	start.onclick = function(){
		displayArea.innerHTML = a.getResult();
	}
}
</script>
<div id="Counter">

</div>
<input type="button" name="start" value="start" />
</div>

<p>%が割り算の余りを返すというのを知っていれば解ける問題ですね。</p>]]>
   </content>
</entry>
<entry>
   <title>PHP シリアライズ/アンシリアライズ</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/02/php_3.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.208</id>
   
   <published>2008-02-06T17:34:44Z</published>
   <updated>2008-05-14T01:57:23Z</updated>
   
   <summary>オブジェクトをまるごとDBやテキストに書き込める形式にしてくれるシリアライズ。オブジェクトが保持しているすべての変数が対象。元のオブジェクトに戻すことはアンシリアライズという。</summary>
   <author>
      <name></name>
      
   </author>
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="2" label="PHP" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="291" label="アンシリアライズ" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="290" label="シリアライズ" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p>オブジェクトをまるごとDBやテキストに書き込める形式にしてくれるシリアライズ。オブジェクトが保持しているすべての変数が対象。</p>]]>
      <![CDATA[<p>メソッドは保存されないがクラス名が保存されるのでアンシリアライズ時に紐付けされる??</p>
<p>詳しくはわからないがとりあえずシリアル化するクラスをアンシリアライズするページに読み込んでおけばメソッドの利用も可能になる。</p>

<h3>サンプル</h3>
<pre><code>
 /**
  * シリアル化するオブジェクトのクラス
  * = アンシリアライズに必要なクラス
  */
  class MyItem
  {
     var $item;
     var $price;
     var $lot;
     var $flag;
      
     function MyItem($item, $price, $lot)
     {
         $this-&gt;item = $item;
         $this-&gt;price = $price;
 
         if (Validator::lotCheker($lot)) {
             $this-&gt;lot = $lot;
             $this-&gt;flag = true;
         } else {
             $this-&gt;flag = false;
         }
     }
      
     function getItemName()
     {
         return $this-&gt;item;
     }
      
     function getItemPrice()
     {
         return $this-&gt;price;
     }
     
     function getItemLot()
     {
         return $this-&gt;lot;
     }
  }
   
  // オブジェクトをシリアライズ
  class ItemSerialize
  {
      var $s_item;
       
      function ItemSerialize($obj)
      {
          if (is_object($obj)) {
          $this-&gt;s_item = serialize($obj);
          }
      }
  
      // シリアライズしたデータをどっかに書き込む
      function put()
      {
          // サブクラスで実装
      }
  }
  
  // 表示用　詳細はサブクラスで実装
  class View
  {
      var $obj;
  
      // アンシリアライズ
      function View($s_item)
      {
          $this-&gt;obj = unserialize($s_item);
      }
  
      // 表示
      function viewItem()
      {
          /* サブクラスで実装 */
          $this-&gt;viewItemName();
          $this-&gt;viewItemPrice();
          $this-&gt;viewItemLot();
  
          echo '合計金額は' . $this-&gt;total() . '円';
      }
  
      // 合計金額 = 料金 * 個数
      function total()
      {
          $total = $this-&gt;obj-&gt;price * $this-&gt;obj-&gt;lot;
          return $total;
      }
  }
  
  class ViewEcho extends View
  {
      function viewEcho($s_item)
      {
          parent::View($s_item);
      }
      
      function viewItemName()
      {
          echo '商品名 : ' . $this-&gt;obj-&gt;getItemName() . '&lt;br /&gt;';
      }
      
      function viewItemPrice()
      {
          echo '価格 : ' . $this-&gt;obj-&gt;getItemPrice() . '円&lt;br /&gt;';
      }
      
      function viewItemLot()
      {
          echo '数量 : ' . $this-&gt;obj-&gt;getItemLot() . '個&lt;br /&gt;';
      }
  }
  
  // バリデート
  class Validator
  {
      function lotCheker($lot)
      {
          if (is_numeric($lot)) {
              if (0 &lt; $lot &amp;&amp; $lot &lt; 100) {
                  return true;
              }
              return false;
          }
          return false;
      }
  }
  
  // サニタイズ用
  class Sanitize
  {
  //　略
  }
  
  /**
   * ここからクライアントのコード
   */
  $item = new MyItem('醤油ラーメン', 850, 5);
  if ($item-&gt;flag) {
      // シリアライズ
      $s = new ItemSerialize($item);
      var_dump($s-&gt;s_item); // どんな感じか確認
  
      echo '&lt;hr /&gt;';
  
      // 元に戻せれば成功
      $view = new viewEcho($s-&gt;s_item);
      $view-&gt;viewItem();
  }
</code></pre>

<h3>実行結果</h3>
<div class="result">
<?
/**
 * シリアライズ/アンシリアライズクラス
 *
 *
 *
 *
 */

/**
 * シリアル化するオブジェクトのクラス
 * = アンシリアライズに必要なクラス
 */
class MyItem
{
    var $item;
    var $price;
    var $lot;
    var $flag;

    function MyItem($item, $price, $lot)
    {
        $this->item = $item;
        $this->price = $price;
        
        if (Validator::lotCheker($lot)) {
            $this->lot = $lot;
            $this->flag = true;
        } else {
            $this->flag = false;
        }
    }

    function getItemName()
    {
        return $this->item;
    }

    function getItemPrice()
    {
        return $this->price;
    }

    function getItemLot()
    {
        return $this->lot;
    }
}

// オブジェクトをシリアライズ
class ItemSerialize
{
    var $s_item;

    function ItemSerialize($obj)
    {
        if (is_object($obj)) {
            $this->s_item = serialize($obj);
        }
    }
    
    // シリアライズしたデータをどっかに書き込む
    function put()
    {
        // サブクラスで実装
    }
}

class View
{
    var $obj;
    
	// アンシリアライズ
    function View($s_item)
    {
        $this->obj = unserialize($s_item);
    }
	
	// 表示
    function viewItem()
    {
		/* サブクラスで実装 */
        $this->viewItemName();
        $this->viewItemPrice();
        $this->viewItemLot();
		
        echo '合計金額は' . $this->total() . '円';
    }
	
	// 合計金額 = 料金 * 個数
    function total()
    {
        $total = $this->obj->price * $this->obj->lot;
        return $total;
    }
}

class ViewEcho extends View
{
    function viewEcho($s_item)
    {
        parent::View($s_item);
    }

    function viewItemName()
    {
        echo '商品名 : ' . $this->obj->getItemName() . '<br />';
    }

    function viewItemPrice()
    {
        echo '価格 : ' . $this->obj->getItemPrice() . '円<br />';
    }

    function viewItemLot()
    {
        echo '数量 : ' . $this->obj->getItemLot() . '個<br />';
    }
}

// バリデート用
class Validator
{
    function lotCheker($lot)
    {
        if (is_numeric($lot)) {
            if (0 < $lot && $lot < 100) {
                return true;
            }
            return false;
        }
        return false;
    }
}

/**
 * ここからクライアントのコード
 */
$item = new MyItem('醤油ラーメン', 850, 5);

if ($item->flag) {
	// シリアライズ
    $s = new ItemSerialize($item);
    var_dump($s->s_item); // どんな感じか確認
	
	echo '<hr />';
	
	// 元に戻せれば成功
    $view = new viewEcho($s->s_item);
    $view->viewItem();
}

?>
</div>]]>
   </content>
</entry>
<entry>
   <title>数値関連の比較　is_int()、ctype_digit()、is_numeric()</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/02/is_intctype_digitis_numeric.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.207</id>
   
   <published>2008-02-04T17:37:48Z</published>
   <updated>2008-02-04T17:32:28Z</updated>
   
   <summary>数値関連の調査に使う関数is_int()、ctype_digit()、is_numeric()の違いについて</summary>
   <author>
      <name></name>
      
   </author>
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="2" label="PHP" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="79" label="型比較" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p>数値関連の調査に使う関数is_int()、ctype_digit()、is_numeric()の違いについてメモ。</p>]]>
      <![CDATA[<dl>
<dt><a href="http://jp2.php.net/manual/ja/function.is-int.php">is_int()</a></dt>
<dd>変数が整数型かどうかを検査する。型の比較。</dd>

<dt><a href="http://jp2.php.net/manual/ja/function.ctype-digit.php">ctype_digit()</a></dt>
<dd>数字かどうかを調べる。与えられた変数がすべて数字ならtrue</dd>

<dt><a href="http://jp2.php.net/manual/ja/function.is-numeric.php">is_numeric()</a></dt>
<dd>変数が数字または数値文字列であるかを調べる。16進数などもtrue</dd>
</dl>
<h3>サンプル</h3>
<pre><code>
$num = array(
    0,      	// 0
    null,		// 1
    014,		// 2
    -14,    	// 3
    12.2,   	// 4
    '',     	// 5
    'test', 	// 6
    99 .'aa'	// 7
    '７９４',	// 8
    +0123.45e6	// 9
    0xFF		// 10
    1234		// 11
);

echo '&lt;h5&gt;is_int()&lt;/h5&gt;';

echo '&lt;pre&gt;';
for ($i=0; $i&lt;sizeof($num); $i++) {
    echo $i . ':';
    var_dump(is_int($num[$i]));
}

echo '&lt;hr /&gt;';

// 型の比較なので下記もtrue
var_dump(is_int(intval('整数型だからtrue')));

echo '&lt;/pre&gt;';

echo '&lt;h5&gt;ctype_digit()&lt;/h5&gt;';

echo '&lt;pre&gt;';
for ($i=0; $i&lt;sizeof($num); $i++) {
    echo $i . ':';
    var_dump(ctype_digit($num[$i]));
}
echo '&lt;/pre&gt;';

echo '&lt;h5&gt;is_numeric()&lt;/h5&gt;';

echo '&lt;pre&gt;';
for ($i=0; $i&lt;sizeof($num); $i++) {
    echo $i . ':';
    var_dump(is_numeric($num[$i]));
}
echo '&lt;/pre&gt;';

</code></pre>

<h3>実行結果</h3>
<div class="result">
<?
$num = array(
                0,      // 0
                null,   // 1
                014,    // 2
                -14,    // 3
                12.2,   // 4
                '',     // 5
                'test', // 6
                99 .'aa',// 7
                '７９４',　// 8
                +0123.45e6,	//9
                0xFF,		// 10
                1234		// 11
            );

echo '<h5>is_int()</h5>';

echo '<pre>';
for ($i=0; $i<sizeof($num); $i++) {
    echo $i . ':';
    var_dump(is_int($num[$i]));
}

echo '<hr />';
// 型の比較なので下記もtrue
var_dump(is_int(intval('整数型だからtrue')));
echo '</pre>';

echo '<h5>ctype_digit()</h5>';

echo '<pre>';
for ($i=0; $i<sizeof($num); $i++) {
    echo $i . ':';
    var_dump(ctype_digit($num[$i]));
}

echo '</pre>';

echo '<h5>is_numeric()</h5>';

echo '<pre>';
for ($i=0; $i<sizeof($num); $i++) {
    echo $i . ':';
    var_dump(is_numeric($num[$i]));
}

echo '</pre>';

?>
</div>]]>
   </content>
</entry>
<entry>
   <title>PHP 配列の再帰処理</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/01/php_2.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.206</id>
   
   <published>2008-01-28T18:37:26Z</published>
   <updated>2008-01-28T18:39:07Z</updated>
   
   <summary>PHPで再帰処理</summary>
   <author>
      <name></name>
      
   </author>
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="2" label="PHP" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="289" label="アルゴリズム" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p>ディレクトリ内のファイル取得をごにょごにょやってた時に知った再帰って考え方。</p>]]>
      <![CDATA[<p>配列の処理なんかにも使えたり、色々と役立つ場面は多く感心させられます。</p>

<h3>配列を再帰処理で色々と加工するサンプル</h3>
<pre><code>
class ArrayConvert
{
  var $array_flat = array();
  var $array_replace = array();
  function ArrayConvert($serch, $key, $array)
  {
    $this-&gt;array_flat = $this-&gt;arrayFlatten($array);
    $this-&gt;array_replace = $this-&gt;arrayReplace($serch, $key, $array);
  }
  
  // 多次元配列を一次元配列に
  function arrayFlatten($array)
  {
    foreach ($array as $values) {
      if (is_array($values)) {
        $this-&gt;arrayFlatten($values);
      } else {
        $this-&gt;a[] = $values;
      }
    }
    return $this-&gt;a;
  }
  
  // 配列の構造を保ったまま値を処理
  function arrayReplace($serch, $key, $array)
  {
    foreach ($array as $values) {
      if (is_array($values)) {
        $a = $this-&gt;arrayReplace($serch, $key, $values);
      } else {
        $a = str_replace($serch, $key, $values);
      }
      $b[] = $a;
    }
    return $b;
   }
}
  
// TEST用配列
$array = array(
  0,
  1,
  2,
  array('zero', 'one', 'two', 'three', array(4, 5, 6)),
  array('array' =&gt; '配列テスト'),
  3,
  4
  );
 
$conv = new ArrayConvert(4, 'four', $array);
 
echo '&lt;pre&gt;';
var_dump($conv-&gt;array_flat);
var_dump($conv-&gt;array_replace);
echo '&lt;/pre&gt;';
</code></pre>


<h3>実行結果</h3>
<?
class ArrayConvert
{
    var $array_flat = array();
    var $array_replace = array();

    function ArrayConvert($serch, $key, $array)
    {
        $this->array_flat = $this->arrayFlatten($array);
        $this->array_replace = $this->arrayReplace($serch, $key, $array);
    }

    // 多次元配列を一次元配列に
    function arrayFlatten($array)
    {
        foreach ($array as $values) {
            if (is_array($values)) {
                $this->arrayFlatten($values);
            } else {
                $this->a[] = $values;
            }
        }
        return $this->a;

    }

    // 配列の構造を保ったまま値を処理
    function arrayReplace($serch, $key, $array)
    {
        foreach ($array as $values) {
            if (is_array($values)) {
                $a = $this->arrayReplace($serch, $key, $values);
            } else {
                $a = str_replace($serch, $key, $values);
            }
            $b[] = $a;
        }
        return $b;
    }
}

$array = array(
                0,
                1,
                2,
                array('zero', 'one', 'two', 'three', array(4, 5, 6)),
                array('array' => '配列テスト'),
                3,
                4
            );

$conv = new ArrayConvert(4, 'four', $array);
echo '<pre>';
var_dump($conv->array_flat);
var_dump($conv->array_replace);
echo '</pre>';
?>
<p>サニタイズなんかも再帰でらくらくできちゃいますね。</p>]]>
   </content>
</entry>
<entry>
   <title>PHP クラス関数をコールする「::」演算子</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/01/php_1.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.205</id>
   
   <published>2008-01-23T19:02:07Z</published>
   <updated>2008-01-23T18:56:53Z</updated>
   
   <summary>「::」はクラス関数を呼び出す演算子</summary>
   <author>
      <name></name>
      
   </author>
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="2" label="PHP" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="288" label="クラス" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p>サブクラスでオーバーライドした親クラスのメソッドを呼び出すものと思っていた「::」について調べてみたらそれは使い方の1つに過ぎないようだ。</p>]]>
      <![CDATA[<p>そもそも「::」はクラス関数を呼び出す演算子ということ。なんで下記のようにオブジェクトを作成しなくてもクラス関数を利用できる。</p>
<h3>サンプルコード1</h3>
<pre><code>
class MyClass_A
{
 var $a = 'MyClass_Aプロパティ';
    
 function view()
 {
  echo 'thisは「' . $this-&gt;a . '」利用できない。&lt;br /&gt;';
 }
 
 function view2()
 {
  echo 'これはview2()';
 }
}

MyClass_A::view();
MyClass_A::view2();
/**
 * エラーコード
 * MyClass_A::a;
 * MyClass_A::$a;
 */
</code></pre>
<h3>サンプルコード1実行結果</h3>
<div class="result">
<?
class MyClass_A
{
	var $a = 'MyClass_Aプロパティ';
	
	function view()
	{
		echo 'thisは「' . $this->a . '」利用できない。<br />';
	}
	
	function view2()
	{
		echo 'これはview2()';
	}
}

MyClass_A::view();
MyClass_A::view2();
/**
 * エラーコード
 * MyClass_A::a;
 * MyClass_A::$a;
 */
?>
</div>
<p>クラス関数を呼び出す演算子なんでプロパティを参照することはできません。またオブジェクトを作成してないので$thisは利用できません。</p>
<p>プロパティにアクセスするにはオブジェクトを作成する必要があるってことですね。</p>
<p>でもってサブクラスでオーバーライドした親クラスのメソッドを呼び出すには書き方が下記のように</p>
<h3>サンプルコード2</h3>
<pre><code>
class MyClass_B
{
 var $b = 'MyClass_Bプロパティ';
  
 function get()
 {
  return $this-&gt;b;
 }
}

class MyClass_C extends MyClass_B
{
 var $c = 'MyClass_Cプロパティ';
  
 // get()メソッドをオーバーライド
 function get()
 {
  return $this-&gt;c;
 }
  
 function view()
 {
  echo parent::get() . '&lt;br /&gt;';
  echo MyClass_B::get() . '&lt;br /&gt;';
  echo $this-&gt;get() . '&lt;br /&gt;';
 }
}

$c = new MyClass_C();
$c-&gt;view();
</code></pre>

<h3>サンプルコード2実行結果</h3>
<div class="result">
<?
class MyClass_B
{
	var $b = 'MyClass_Bプロパティ';
	
	function get()
	{
		return $this->b;
	}
}

class MyClass_C extends MyClass_B
{
	var $c = 'MyClass_Cプロパティ';
	
	// get()メソッドをオーバーライド
	function get()
	{
		return $this->c;
	}
	
	function view()
	{
		echo parent::get() . '<br />';
		echo MyClass_B::get() . '<br />';
		echo $this->get() . '<br />';
	}
}

$c = new MyClass_C();
$c->view();
?>
</div>
<p>「親クラス名::メソッド」と「parent::メソッド」の2つありますが「parent::メソッド」のほうがよい。</p>
<p>理由は親クラス名を複数の場所で利用するとクラス名が変更になった際に面倒だから。</p>

<dl>
<dt>参照サイト</dt>
<dd><a href="http://jp.php.net/manual/ja/keyword.paamayim-nekudotayim.php">PHPマニュアル「::」</a></dd>
<dd><a href="http://jp.php.net/manual/ja/keyword.parent.php">PHPマニュアル「親クラス」</a></dd>
</dl>]]>
   </content>
</entry>
<entry>
   <title>MySQLエラー「Column &apos;カラム名&apos; in field list is ambiguous」</title>
   <link rel="alternate" type="text/html" href="http://www.kantenna.com/pg/2008/01/mysqlcolumn_in_field_list_is_a.php" />
   <id>tag:www.kantenna.com,2008:/pg//2.204</id>
   
   <published>2008-01-15T03:09:49Z</published>
   <updated>2008-06-23T17:52:51Z</updated>
   
   <summary>テーブルを結合して出力する場合、どちらのテーブルのカラムか指定しないとエラーになる</summary>
   <author>
      <name></name>
      
   </author>
         <category term="MySQL" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="64" label="MySQL" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="209" label="エラー" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.kantenna.com/pg/">
      <![CDATA[<p>テーブルを結合して出力する場合、どちらのテーブルのカラムか指定しないとエラーになる。</p>]]>
      <![CDATA[<h3>サンプルデータ</h3>
<table class="tableTypeDB">
<caption>test1</caption>
<thead>
<tr>
<th>id</th>
<th>name</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>google</td>
</tr>
<tr>
<td>2</td>
<td>yahoo</td>
</tr>
<tr>
<td>3</td>
<td>MSN</td>
</tr>
</tbody>
</table>

<br />

<table class="tableTypeDB">
<caption>test2</caption>
<thead>
<tr>
<th>id</th>
<th>url</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>http://www.google.co.jp/</td>
</tr>
<tr>
<td>2</td>
<td>http://www.yahoo.co.jp/</td>
</tr>
<tr>
<td>3</td>
<td>http://jp.msn.com/</td>
</tr>
</tbody>
</table>
<p>「Column 'カラム名' in field list is ambiguous」エラーとなるSQL</p>
<pre><code>
SELECT
id, name, url
FROM test1
INNER JOIN test2 ON test1.id = test2.id
</code></pre>

<p>なぜエラーになるのかは下記SQLを実行するとわかりますが「id」が重複していてどちらの「id」なのかわからないので。</p>
<pre><code>
SELECT
*
FROM test1
INNER JOIN test2 ON test1.id = test2.id
</code></pre>

<p>上記を実行した場合の結果</p>
<table class="tableTypeDB">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>id</th>
<th>url</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>google</td>
<td>1</td>
<td>http://www.google.co.jp/</td>
</tr>
<tr>
<td>2</td>
<td>yahoo</td>
<td>2</td>
<td>http://www.yahoo.co.jp/</td>
</tr>
<tr>
<td>3</td>
<td>MSN</td>
<td>3</td>
<td>http://jp.msn.com/</td>
</tr>
</tbody>
</table>

<p>確かにIDが重複してますね。エラーが出ないようにするにはどちらの「ID」かを指定してあげればよい。</p>
<pre><code>
SELECT
test1.id, name, url
FROM test1
INNER JOIN test2 ON test1.id = test2.id
</code></pre>

<p>別名設定前でも大丈夫なかんじ。</p>

<pre><code>
SELECT
a.id, name, url
FROM test1 a
INNER JOIN test2 b ON a.id = b.id
</code></pre>

<? $KT->getGroupBook('mysql'); ?>]]>
   </content>
</entry>

</feed>
