すぐ忘れるので、検索のためにメモ。
CGI版とCLI版がある。違いはHTTPヘッダを出力するか否か。WebサーバーからみであればCGIで実行するか、サーバーのモジュールとして実行するか。CGIは建前上リクエストがあるたびに起動するので、オーバーヘッドがある。そのため、サーバーのほうが速度的に有利。CGIであれば、個別ユーザーで実行できる。(suEXEC)。共有サーバーではCGI版が利用される。各ユーザーのリソース消費がつかみやすいため。
/* ブロックコメント */
// 行コメント
変数は先頭に$、英文字か_で始まり、英文字・数字・_が続く。
定数はdefine("定数名",値);
文字列連結はピリオド。分の区切りはセミコロン。
特殊な変数(名前の通り)
$GLOVALS
$_SERVER
$_GET$_POST
$_COOKIE
$_FILES
$_ENV
$_REQUEST
$_SESSION
date('Y-m-d') strftime('%H:%M:%S',time()) strftime("%Y-%m-%d %H:%M:%S") 日付・時間表示関連
整数の精度はビルドやOSに依存。符号無しは無し。約20億。
文字列はバイト扱い。直接的にマルチバイトは扱えないが、関数をマルチバイトにオーバーロードできる。mbstring.func_overloadに1ならmail、2なら文字列、4なら正規表現関数で全部オーバーロードならば7。内部エンコーディングとしてSJISは使用すべきでない。今やUTF8が事実上のスタンダードなので、UTF8が良いか。ただし、マルチバイトの取り扱いを明示的に日本語に指定した場合、UTF8ではなく、EUCがデフォルトになるので、設定が必要かも。mbstring.languageのデフォルトはneutralでこれはUTF8なので、いじらない方がいいかも。特に多国語対応の場合。
文字リテラルは3通りの表現がある。シングルコーティションで囲めば、その内容をそのまま、ダブルコーティーションなら、変数とエスケープシーケンスが展開される。変数は${ver}と表現する。3つめはヒアドキュメントで<<<に続くIDから、行頭に書かれたIDまでの間をリテラルとして扱う。実際に変数に代入する場合は、最後のIDの後ろの;を忘れないように。
浮動小数点の精度は整数と同様にシステム依存。十進数で14桁程度であるが、他の言語と同様に誤差の問題を含んでいる。
論理型はTRUE、FALSEであるが、大文字でも、小文字でも同じ。大文字推奨。
変数の型が知りたければver_dump()で出力できる。
演算子では比較演算子に値だけを比較する==と型の一致も確かめる===が存在する。同様に!=と!==が存在する。
特殊な物として実行演算子が存在する。逆クオート`で囲んだコマンドの標準出力を値とする。
論理演算子ではandと&&、orと||が利用できるが、andとorは&&と||より優先順位が高い。
文字列操作ではピリオド+イコール.=で文字列の追加になる。
条件 ? 真の場合 : 偽の場合の3項演算子が利用できる。
配列は基本連想配列。キーに実数を指定した場合は切り捨てで整数に丸められる。整数を文字列の形で指定しても、整数として指定しても同じキーとして取り扱われる。実数を文字列として指定すると、そのまま文字列扱い。$a[]=10とキーを省略した場合は、0を基数として存在する最大の正の整数のキーの値+1がキーになる。(キーの基数と増分は変更できるかもしれない。)
配列へ値を与えるときはarray(1,2,3...)でキー指定無し=0基数の整数のキーとなる。キーも指定する場合はarray(1=>10,2=>50,...)で指定する。キー指定とキー無しの指定を混ぜた場合、キー無しの指定では$a[]=10とキー省略時と同様に、その時点で存在している正の最大整数キー値+1に指定される。
配列をまとめて出力したいときはprint_r()関数が利用できる。
PHP4の変数スコープはグローバル、関数内、クラス内の3つ。PHP5ではnamespace Namae{ }で名前空間が指定可能。参照はNamae::を付ける。namespaceのネストはできない。
const CONST = 定数値 を利用してクラス内、名前空間内で定数を定義可能。
PHP4のコンストラクタはクラス名と同じ物、デストラクタはない。PHP5では__constract()と__destruct()の固定名。PHPのクラスでは、存在しない変数への参照と代入も許される。PHP5ではこのような場合、代入時は__set()、参照時は__get()が呼び出される。通常は存在しないメソッドの呼び出しはエラー。PHP5では__call()が存在していれば、そちらが呼び出される。
PHP5では存在しないクラスの呼び出し時に__autoload()が呼び出される。この中でrequire_onceで呼び出せば、あらかじめ使用する可能性のあるクラスを全部呼び込むオーバーヘッドが軽くできるかもしれない。
if (条件1) {
実行ブロック1
} elseif(条件2) {
実行ブロック2
} else {
実行ブロック3
}
switch(式)
{
case 値1:
実行文
break;
case 値2:
実行文
// break無しなら、そのまま次の条件判断へ
case 値3:
case 値4:
実行文
// 値3と4の実行パス
break;
default:
実行文
}
while (条件) {
}
do {
} while(条件)
for(初期化; 条件; 実行文終了後の処理) {
}
foreach(配列 as $val) {
}
foreach(配列 as $key => $val) {
}
function 関数名(引数リスト) {
// 引数リストには省略時の値を$argument=20の形式で渡せる。
// &$で引数を宣言すると、常に参照渡しになる。
// もし、呼び出し側で参照渡しにしたい場合はaaa(&$val)で呼び出す。
}
モジュールの呼び出し:
include 'ファイル名' ファイルが存在しないと警告
include_once 'ファイル名' ファイルが存在しないと警告、もし以前に読み込まれていたなら、読み込まない。
require 'ファイル名' ファイルが存在しないとエラー
require 'ファイル名' ファイルが存在しないとエラー、もし以前に読み込まれていたなら、読み込まない。
例外処理を全部捉えるならばtry{実行部} catch(Exception $e) {例外処理} Exceptionクラスの拡張は、クラスライブラリーやフレームワークを作成する際に、設計する。その場合、throwされた例外ごとにcatchで受けられる。そこまでやらなくていい場合は、例外処理の中で$eの内容で分岐する方が軽くていいかも。
URLルーティングは次の方法で、index.php以降の指定を取得し、処理する。
$requestURI = explode(‘/’, $_SERVER[‘REQUEST_URI’]);
$scriptName = explode(‘/’,$_SERVER[‘SCRIPT_NAME’]);
for($i= 0;$i < sizeof($scriptName);$i++)
{
if ($requestURI[$i] == $scriptName[$i])
{
unset($requestURI[$i]);
}
}
$command = array_values($requestURI);基本認証のコード:
$user = 'admin';
$password = 'pass';
if (!isset($_SERVER['PHP_AUTH_USER'])){
header('WWW-Authenticate: Basic realm="Private Page"');
header('HTTP/1.0 401 Unauthorized');
die('このページを見るにはログインが必要です');
}else{
if ($_SERVER['PHP_AUTH_USER'] != $user
|| $_SERVER['PHP_AUTH_PW'] != $password){
header('WWW-Authenticate: Basic realm="Private Page"');
header('HTTP/1.0 401 Unauthorized');
die('このページを見るにはログインが必要です');
}
}
/* 認証に成功すればここに処理が来る */
echo 'Welcome to Mufufu page :)';
クッキーの読み書きの基本、すべての引数の説明をコメントで。
if (isset($_COOKIE['cookiename'])) {
$val = $_COOKIE['cookiename'] + 1;
} else {
/* クッキーがないときの処理 */
$val = 1;
}
/*
* 有効期限の計算、現時点+秒数
* 期限がなしか、0の場合は、そのセッション=ブラウザが閉じられるまで
*/
$exp = time() + 30 * 24 * 60 * 60; /* 30日 */
/* 有効パス、'/'でそのドメイン下全部で有効
* /booなら/boo以下全部で有効
* デフォルトは、クッキーをセットしたディレクトリー
*/
$path = '/';
/*
* 有効ドメイン domain.comならそのドメインで有効
* .domain.comなら、サブドメイン間でも有効
*/
$domain = 'localhost';
/*
* SSLの指定:デフォルトは0で、SSL有無両方で有効
* 1にすると、SSL通信の場合のみ有効
*/
$ssl = 0;
/*
* クッキーの書き込み
* クッキーはheaderに書き込まれるため、
* クッキーの出力前に、何かを出力していると
* FALSEになり、失敗する。flash()でバッファを
* 明示的に出力しない限り、バッファリングされているらしいので
* 余り心配ない様子。ただし、バッファがいっぱいになれば
* 出力されるだろうから、そのせいでバグが出るかも
*/
$flag = setcookie('cookiename', $val, $exp, $path, $domain, $ssl);
if($flag) echo $val.'time(s)';
else echo 'Cookie Write ERROR!!!!';
クッキーの有効チェック、一度書き込み、リダイレクトする。ただし、この関数を毎回呼び出すのは、非効率。人間がアクセスしてくるブラウザなら、今は大抵クッキーはオンになっているので、クッキーが見つからない場合のみ、これを呼び出し、クッキーがサポートされていない場合のみ、警告するか、情報表示しない方向で使用。
function iscookie() {
$myself = basename($_SERVER['SCRIPT_NAME']);
if (!isset($_GET['test'])) {
// クッキーセット
setcookie('TEST', TRUE);
// ?testを付け、リダイレクト
header("Location: $myself?test=on");
die(); // 明確に死んだほうが良い
} else {
// リダイレクト後
if (isset($_COOKIE['TEST'])) {
$ret = TRUE;
} else {
$ret = FALSE;
}
setcookie('TEST', '', time() - 3600);
}
return $ret;
}
セッションのコントロール例。セッションIDの再生時に引数にTRUEを渡し、古いIDを明確に壊す。セッションを破棄する場合、セッションに保持してあった内容、セッションのクッキー、サーバー側のセッションIDの破棄の三つを行う。
// セッションの開始
session_start();
if (!isset($_SESSION["visited"])) {
echo '初回アクセス、';
$_SESSION["visited"] = 1;
$_SESSION["date"] = date('c');
} else {
// セッション継続中
$visited = $_SESSION["visited"];
$visited++;
echo '訪問回数は' . $_SESSION["visited"] . 'です。<br />';
$_SESSION["visited"] = $visited;
if (isset($_SESSION["date"])) {
echo '前回の訪問日時は' . $_SESSION["date"] . 'です。<br />';
}
$_SESSION["date"] = date('c');
echo 'セッションIDは' . session_id() . 'です。<br />';
if ($visited == 4) {
echo '3回目のセッションです。セッションIDを再生成します。<br />';
session_regenerate_id(TRUE); // 精製後、古いIDを破壊する
echo '新しいセッションIDは' . session_id() . 'です。<br />';
}
if ($visited == 7) {
echo '6回目のセッションです。セッションを破棄します。<br />';
// セッション変数を解放
$_SESSION = array();
// セッションクッキー削除する。
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time() - 3600);
}
// 最終的に、サーバーサイドのセッションを破棄
session_destroy();
echo 'セッションを破棄しました。<br />';
}
}
PHP5の変更
interfaceの実装。必要な関数の宣言、変数は指定できない。定数は宣言可能。
abstruct classの実装。interfaceと異なり、関数の実装も可能。実装せず宣言だけでも可能。もちろん、変数指定なども可能。
intefaceとabstructを両方実装するクラスを作成するなら、順番は、class OneClass extends AbsClass impliments Interfaceの順番。
クラスの多重継承はできない。近いことをしたい場合、以下の様に、interfaceとインスタンスを利用して実現する。
interface Ainter {
function func_a();
}
class Aclass implements Ainter {
function func_a() {
echo 'func_a<br />';
}
}
class Bclass {
function __construct() {
// 今回は何も行わない
}
function func_b() {
echo 'func_b<br />';
}
}
class AandBclass extends Bclass implements Ainter {
private $instanceA;
function __construct() {
parent::__construct();
$this->instanceA = new Aclass();
}
function func_a() {
$this->instanceA->func_a();
}
}
final classで宣言すると継承できなくなる。
final functionはオーバーライトできなくなる。
php4でもクラスのインスタンスを関数の引数に渡せるが、php5ではfunction aaa(ClassName $inst)の形式で、特定のクラスのインスタンス以外をエラーで弾くことが出来る。
クラスのオートロード:
function __autoload($className) {
include_once("class/".$className.'.inc');
}
クラスに存在しないメンバ変数へのアクセス時に呼び出される関数__set($name,$val)と__get($name)ができた。
クラスに存在しないメンバ関数の呼び出し時には__call($name, $param)が呼び出される。
クラスがechoなどで出力された際の出力を決める__toString()を定義できる。
Javaでおなじみのtry { } catch()でのエラー処理が出来るようになった。
| php dbメモ< 前 | 次 >携帯サイトのセッションメモ |
|---|
| < 前 | 次 > |
|---|