@blog.justoneplanet.info

日々勉強

PHPをデバッグしやすく環境設定しよう

■対象

  • php.iniファイル(PHP設定ファイル)を編集できる方
  • テストサーバーをワンサカ持ってない、1台で運用してるような方

■設定方法

php.iniの設定
  1. php.iniを設定する(ファイルの場所はphpinfo関数で表示されるConfiguration File (php.ini) Pathの項目に記載されている)
  2. display_errors = On
  3. error_reporting = 0
プログラムの書き方

とりあえずプログラムにバグがあっても表示されなくなる。但し制作中のプログラムなどで、どうしてもエラーメッセージを表示させたいときもある。そんな時はプログラムの最初に・・・

error_reporting(E_ALL);

と記述すればエラーが表示されるわけですな。なお本番運用を始めるときはerror_reporting();関数を忘れず削除しましょう。

WP_MultilingualでWordPressを多言語化

・・・できるんですが、パーマリンクの設定を行うとバグが発生するようです。具体的には・・・

■Wordpress通常版

デフォルト以外のラジオボタンを選択すると

  • リダイレクトがループして表示できなくなる。

対処方法としてはパーマリンク設定を変更しない!?「数字ベース」を選択するとブログの表示は出来るようだが、設定画面でエラーがでる。

■Wordpress MU

設定>パーマリンクの設定をクリックすると

  • リダイレクトがループして表示できなくなる。
  • 「管理」が表示されなくなる。

言語のアクティベートを解除して、もう一度アクティベートをすると不具合が解消される。ただしパーマリンク設定の変更は現状出来ない。

■ダウンロード

こちらから行えます

PDOを使おう(接続)

■ソース

<?php
try{
    $dsn = 'mysql:host=localhost;dbname=library';
    $dbh = new PDO($dsn, 'dbuser', 'dbpass');
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e){
    echo 'Failed: ' . $e->getMessage();
}
?>

まぁコンナ感じだ。localhostの部分はIPアドレスになる場合もドメイン名になる場合もある。

setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
上手く接続できなかったりしたときの挙動、ERRMODE_EXCEPTION(例外)を発生させる。
catch(PDOException $e)
発生する例外はPDOException

JavaScript Object

■オブジェクトを生成

オブジェクトリテラルを使った生成

世間的には一般的である。

var obj = {};
var john = {
    "name" : "John Norton",
    "age" : 28,
    "married" : true
};

new演算子を使った生成

個人的には以下のようにnew演算子とコンストラクタ関数を定義する方法が好きだ。

function Person(name, age, married){
    this.name = name;
    this.age = age;
    this.married = married;
}
var john = new Person('John Norton', 28, true);

引数の順番が固定なのが嫌なので、以下の様な方法も個人的には使ったりする。

function Person(arg){
    this.name = arg.name;
    this.age = arg.age;
    this.married = arg.married;
}
var john = new Person({
    "name" : "John Norton",
    "age" : 28,
    "married" : true
});

■オブジェクトのプロパティ

var book = {};
book.title= "桃太郎";
book.chapter1 = new Object();
book.chapter1.title = "おじいさん芝刈り";
book.chapter2 = {
    "title" : "おばあさん川へ洗濯"
}

プロパティの調査

以下のようにするとユーザ定義のプロパティが調べられる。

function surveyProperties(obj){
    var txt = '';
    for(var p in obj){
        txt .= p + "\n";
    }
    alert(txt);
}

但し、継承されたプロパティは返されない。

プロパティの存在確認

存在しないプロパティを参照するとundefinedが返る。

if(john.name !== undefined){
    //code
}

以下のようにin演算子を使用しても確認できる。

if("name" in john){
    //code
}

プロパティが存在し、undefined(未定義値)が代入されていた場合、上述のコードは異なった結果をもたらす。

プロパティの削除

以下のようにdelete演算子を使用して、プロパティを削除する。

delete john.name;

■連想配列とオブジェクト

JavaScriptにおける連想配列はオブジェクトのプロパティである。

alert(john.name);//John Norton
alert(john['name']);//John Norton

つまりJavaScriptではプロパティの名前を文字列として与えられるので、プログラム中で生成する事が出来る。

■プロパティ

コンストラクタプロパティ

constructorプロパティにはコンストラクタ関数が格納されている。但し、alertした場合は関数名だけでなく内部のコードも表示される。

var date = new Date();
alert(date.constructor === Date);// true
function Person(arg){
    this.name = arg.name;
    this.age = arg.age;
    this.married = arg.married;
}
var john = new Person({
    "name" : "John Norton",
    "age" : 28,
    "married" : true
});
alert(john.constructor);
/*
function Person(arg) {
    this.name = arg.name;
    this.age = arg.age;
    this.married = arg.married;
}
*/
alert(john.constructor === Person);//true

以下のようにtypeof演算子を使用して、変数の型を調べられる。

function Person(arg){
    this.name = arg.name;
    this.age = arg.age;
    this.married = arg.married;
}
var john = new Person({
    "name" : "John Norton",
    "age" : 28,
    "married" : true
});
if(typeof john ==="object"){
    alert('"john" is a Object');
}

以下のようにinstanceof演算子を使用して、任意のクラスのインスタンスかどうかテストできる。

function Person(arg){
    this.name = arg.name;
    this.age = arg.age;
    this.married = arg.married;
}
var john = new Person({
    "name" : "John Norton",
    "age" : 28,
    "married" : true
});
if(john instanceof Person){
    alert('"john" is instance of Person');
}

■メソッド

hasOwnProperty()メソッド

引数で指定した名前のプロパティを持つかどうかを返す。但し、継承したものはfalseとなる。

function Person(arg){
    this.name = arg.name;
    this.age = arg.age;
    this.married = arg.married;
}
var john = new Person({
    "name" : "John Norton",
    "age" : 28,
    "married" : true
});
john.hasOwnProperty('toString');//false
john.hasOwnProperty('name');//true

propertyIsEnumerable()メソッド

hasOwnProperty()メソッドでtrueを返し、さらにfor/inループで列挙が可能なものかどうかを返す。

function Person(arg){
    this.name = arg.name;
    this.age = arg.age;
    this.married = arg.married;
}
var john = new Person({
    "name" : "John Norton",
    "age" : 28,
    "married" : true
});
john.hasOwnProperty('toString');//false
john.hasOwnProperty('name');//true

isPrototypeOf()メソッド

引数で指定したオブジェクトのprototypeオブジェクトであるかどうかを返す。

var john = {};
alert(Object.prototype.isPrototypeOf(john));//true
alert(Object.isPrototypeOf(john));//false
alert(john.isPrototypeOf(Object.prototype));//false
alert(Function.prototype.isPrototypeOf(Object));//true

デザインパターン:Singleton(一枚札)

■趣旨

サンプルソースです。複数のクラスからデータベースに接続している場合、DBハンドラが複数できてしまうのはリソースの無駄遣い。。。なので1つのDBハンドラ(オブジェクト)を使いまわすクラスです。Singletonパターンとはオブジェクトが一定の少数しか生成されない事を保障するパターンである。

■DirectoryFile.class.php

<php
class DbConnection {
    protected static $dbh;
    protected function __construct(){
        self::$dbh = new PDO("mysql:dbname=sample;host=localhost", "user", "pass");
    }
    public static function getDbConnection(){
        if(!self::$dbh){
            new self();
        }
        return self::$dbh;
    }
}
?>

■あとがき

素敵なソースを見つけたので・・・constructorをprotectedにし自身の中からしか呼び出せないようにし、staticなfunction、getDbConnectionからnew self()としている。コロンブスの卵的なトリッキー&ひらめき的な素敵さだ。

デザインパターン:Composite(複合)

■趣旨

サンプルソースです。ツリー構造を実現するパターンです。ノードとなるクラスを定義し、そのサブクラスとして、子要素を持つクラスと、子要素を持たないクラス(葉)を実装します。

■DirectoryFile.class.php

<?php
abstract class DirectoryFile {
    protected $name;
    public function __construct($name){
        $this->name = $name;
    }
    public function getName(){
        return $this->name;
    }
    abstract public function add(DirectoryFile $child);
    abstract public function remove (DirectoryFile $child);
    abstract public function getChildren();
    abstract public function display($level);
}
class File extends DirectoryFile {
    public function add(DirectoryFile $child){
        echo('File cannot have any elements.');
        return null;
    }
    public function remove(DirectoryFile $child){
        echo('File don\'t have any elements.');
        return null;
    }
    public function getChildren(){
        return null;
    }
    public function display($level){
        echo(str_repeat("\t", $level) . $this->name . "\n");
    }
}
class Dir extends DirectoryFile {
    private $files;
    public function __construct($name){
        parent::__construct($name);
        $this->files = array();
    }
    public function add(DirectoryFile $child){
        $this->files[] = $child;
        return $this;
    }
    public function remove(DirectoryFile $child){
        return array_splice($this->files, array_search($child, $files, true), 1);
    }
    public function getChildren(){
        return $this->files;
    }
    public function display($level){
        echo(str_repeat("\t", $level) . $this->name. "\n");
        foreach($this->files as $child){
            $child->display($level + 1);
        }
    }
}
?>

■sample.php

<?php
require_once('DirectoryFile.class.php');
$root = new Dir('root');
$dir0 = new Dir('dir0');
$dir1 = new Dir('dir1');
$root->add($dir0)->add($dir1);
$file00 = new File('file00');
$file01 = new File('file01');
$dir0->add($file00)->add($file01);
$dir10 = new Dir('dir10');
$file10 = new File('file10');
$dir1->add($dir10)->add($file10);
$file101 = new File('file101');
$file102 = new File('file102');
$dir1->add($file101)->add($file102);
$root->display(0);
?>

■あとがき

素敵なソースを見つけたので・・・結果はsample.phpを実行して試してみてください。

PHPでSessionを使う

■趣旨

サンプルソースです。

■prefts.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>色の設定</title>
</head>
<body>
<form action="prefs.php" method="post">
<label>背景色
<select name="background" id="background">
<option value="black">黒</option>
<option value="白">白</option>
<option value="赤">赤</option>
<option value="青">青</option>
</select>
</label><br />
<label>文字色
<select name="foreground" id="foreground">
<option value="black">黒</option>
<option value="白">白</option>
<option value="赤">赤</option>
<option value="青">青</option>
</select>
</label><br />
<input type="submit" value="設定の変更" />
</form>
</body>
</html>

■prefts.php

<?php
$colors = array(
    'black' => '#000000',
    'white' => '#ffffff',
    'red'   => '#ff0000',
    'blue'  => '#0000ff'
);
session_start();
//session_register('bg');
//session_register('fg');
$bg_name = $_POST['background'];
$fg_name = $_POST['foreground'];
$_SESSION['bg'] = $colors[$bg_name];
$_SESSION['fg'] = $colors[$fg_name];
?>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>設定の登録</title>
</head>
<body>
<p>ありがとうございました。以下のように設定を変更しました。</p>
<ul>
<li>背景色:<?php echo $bg_name ?></li>
<li>文字色:<?php echo $fg_name ?></li>
</ul>
<p><a href=”prefs_demo.php”>ここ</a>をクリックすると、設定が有効になります。</p>
</body>
</html>

■prefts_demo.php

<?php
session_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>玄関</title>
<style type="text/css">
body {
    background-color: <?php echo $_SESSION['bg']; ?>;
    color: <?php echo $_SESSION['fg']; ?>;
}
</style>
</head>
<body>
<h1>いらっしゃいませ</h1>
<p>様々な商品を取り揃えております。</p>
<p><a href=”prefs.html”>設定を変更</a>しますか?</p>
</body>
</html>

■あとがき

  1. prefs.htmlにアクセスし、背景色と文字色を選択しprefs.phpにデータを送信
  2. prefs.phpはデータを受け取りデータを元にサーバー側の文字列をセッションにセット
  3. prefs-demo.phpでCookieからPHPSESSIDを読み出し、それに基づく値をサーバー内から読み出し背景色と文字色になる

PHPでCookieを使う

■趣旨

サンプルソースです。

■prefts.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>色の設定</title>
</head>
<body>
<form action="prefs.php" method="post">
<label>背景色
<select name="background" id="background">
<option value="black">黒</option>
<option value="白">白</option>
<option value="赤">赤</option>
<option value="青">青</option>
</select>
</label><br />
<label>文字色
<select name="foreground" id="foreground">
<option value="black">黒</option>
<option value="白">白</option>
<option value="赤">赤</option>
<option value="青">青</option>
</select>
</label><br />
<input type="submit" value="設定の変更" />
</form>
</body>
</html>

■prefts.php

<?php
$colors = array(
    'black' => '#000000',
    'white' => '#ffffff',
    'red'   => '#ff0000',
    'blue'  => '#0000ff'
);
$bg_name = $_POST['background'];
$fg_name = $_POST['foreground'];
setcookie(’bg’, $colors[$bg_name]);
setcookie(’fg’, $colors[$fg_name]);
?>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>設定の登録</title>
</head>
<body>
<p>ありがとうございました。以下のように設定を変更しました。</p>
<ul>
<li>背景色:<?php echo $bg_name ?></li>
<li>文字色:<?php echo $fg_name ?></li>
</ul>
<p><a href=”prefs_demo.php”>ここ</a>をクリックすると、設定が有効になります。</p>
</body>
</html>

■prefts_demo.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>玄関</title>
<?php
$bg = $_COOKIE['bg'];
$fg = $_COOKIE['fg'];
?>
<style type=”text/css”>
body {
background-color: <?php echo $bg; ?>;
color: <?php echo $fg; ?>;
}
</style>
</head>
<body>
<h1>いらっしゃいませ</h1>
<p>様々な商品を取り揃えております。</p>
<p><a href=”prefs.html”>設定を変更</a>しますか?</p>
</body>
</html>

■あとがき

  1. prefs.htmlにアクセスし、背景色と文字色を選択しprefs.phpにデータを送信
  2. prefs.phpはデータを受け取りデータを元にサーバー側の文字列をクッキーにセット
  3. prefs-demo.phpでCookieを読み出し、それに基づく背景色と文字色になる