PHP 基本情報

  PHP の情報を取得



  
<?php 
phpinfo();
?>
  

通常は、上記コードでほとんどの情報を取得する事ができますが、セキュリティ上の都合により、phpinfo の実行が禁止されている場合があります。

そのような場合は以下のようなコードが役に立ちます

  
<?php
	print "PHP version : " . phpversion() . "<br>";
	print "include_path : " . get_include_path() . "<br>";
	print "get_magic_quotes : " . get_magic_quotes_gpc() . "<br>";

	print "<HR>";
	print "<b style='font-size:24;font-weight:bold'>Loaded_extensions</b><br>";

	$target = get_loaded_extensions();
	foreach( $target as $Key => $Value ) {
		print "$Key => $Value<br>";
	}

	print "<HR>";
	print "<b style='font-size:24;font-weight:bold'>定義済のクラス</b><br>";

	$target = get_declared_classes ();
	foreach( $target as $Key => $Value ) {
		print "$Key => $Value<br>";
	}

	print "<HR>";
	print "<b style='font-size:24;font-weight:bold'>\$_SERVER</b><br>";

	foreach( $_SERVER as $Key => $Value ) {
		print "$Key => $Value<br>";
	}

	print "<HR>";
	print "<b style='font-size:24;font-weight:bold'>\$_ENV</b><br>";

	foreach( $_ENV as $Key => $Value ) {
		print "$Key => $Value<br>";
	}

	print "<HR>";
	print "<b style='font-size:24;font-weight:bold'>ini_get_all</b><br>";
	print "<PRE>";
	$inis = ini_get_all();
	print_r($inis);
	print "</PRE>";
?>
  






  セッション



  
session_start();
  

セッションを使用するには、とにかくソースコードの先頭で上記コードを実行しておけば良いでしょう。

セッションデータは、デフォルトでファイルに保存され、session_save_path 関数で、その場所の取得が可能です。その結果 /TMP と表示された場合、Windows の場合、ソースコードがあるドライブのルートにある TMP というディレクトリ内です。windows 以外では /TMP です。しかし、session_save_path 関数の取得結果が無かった場合、Windows では、システムのテンポラリディレクトリが使用されます( php.ini の該当エントリを確認する必要があります => session.save_path )

session_save_path 関数では、その場所の設定も可能です。

また、セッションデータのクリアは以下ようにして実行します

  
$_SESSION = array();
  

※ 参照

  
<?php
# 場所を変える場合は、session_start() の前に実行
session_save_path("/homepage/tmp");
session_start();

print session_save_path() . "<br>";
$_SESSION['count']++;
print session_id() . "<br>";
print $_SESSION['count'] . "<br>";
?>
  

セッション関数






  キャラクタセット変換

  
$str = mb_convert_encoding( $str, "UTF-8", "eucJP-win" );
  

内部コードは、EUC-JP でも UTF-8 でも大差ありません
( SHIFT_JIS は不可です )

  
mb_language( "ja" );
// 内部文字エンコーディングを設定
mb_internal_encoding("UTF-8");

$str = mb_convert_encoding( $str, "変換後", "変換前" );

$d : 変換後の文字列
$s : 変換前の文字列

キャラクタセット : CP932, eucJP-win, UTF-8
  

※ cp932 は SHIFT_JIS です。






  テキストファイル一括読み込み

  
# **********************************************************
# テキストファイル一括読み込み ( 配列読みを利用 )
# FILE_IGNORE_NEW_LINES : 配列の各要素の最後に改行文字を追加しません。
# **********************************************************
function txt_get_all_array( $path ) {

	$txt_array = @file( $path, FILE_IGNORE_NEW_LINES );
	if ( $txt_array === FALSE ) {
		return FALSE;
	}

	return $txt_array;

}
  

テキストを一括読みするだけならば、file_get_contents を使用しますが、
配列で取得しておくと、入力したデータを改変するような場合に有効なので、
上の方法を知っておくと良いでしょう

  
# **********************************************************
# テキストファイル一括読み込み
# **********************************************************
function txt_get_all( $path ) {

	$txt = @file_get_contents( $path );
	if ( $txt === FALSE ) {
		return FALSE;
	}

	return $txt;

}
  



  ディレクトリリスト

  
# **********************************************************
# ディリクトリリスト取得 ( 戻り値 : 配列 )
# **********************************************************
function GetDirList( $Path ) {

	$ret = array();

	if ( $dh = opendir( $Path ) ) {
		while ( ($file = readdir($dh) ) !== false ) {
			if ( filetype( $Path . "/"  . $file ) == 'dir' ) {
				if ( $file != "." && $file != ".." ) {
					$ret[] = $file;
				}
			}
		}
		closedir( $dh );
	}

	return $ret;

}
  

1) $ret = array(); で、$ret は空の配列となります ( is_array で TRUE となる )

2) !== については、以下のマニュアルの引用を読んで下さい
返り値が FALSE と一致することを、明示的に調べています。
なぜなら、そうしないと FALSE と評価されてしまうディレクトリエントリ (例: "0" という名前のディレクトリ)
があった場合にループが とまってしまうからです。

3) $ret[] = $file; は配列への値の追加で、array_push を要素毎に呼び出すのと同じです



  関数 or die

<?php
$a = "この関数が実行されました";

if ( @file("test.txt") or print_r( $a ) ) {
	print "OK";
}
else {
	print "ERR";
}
?>

複合条件では、最初の条件が成り立ってしまうと以降の処理をする意味が無いので、ここでは print_r は処理されません。(file 関数が正しく実行されると、配列を返すので true 扱いとなり、失敗すると false を返す)

逆に最初の条件が成り立たなければ次の処理を必ず行うというアルゴリズムを利用して、関数 or die が使用されます。



  @ エラー処理

  
<?

# @(エラー制御演算子)の使用に伴って、
# エラーメッセージを取得する為のセッティング
ini_set( "track_errors", "1" );

# no.txt は存在しないファイル
$ret = @file( "no.txt" );

# failed to open stream: No such file or directory
# 上記メッセージがセットされている
print $php_errormsg;

# ユーザ関数にも有効
# 但し、$php_errormsg には自分でセットする
@user_error_test();

print $php_errormsg;

# ユーザ関数
function user_error_test() {

	global $php_errormsg;

	$message = "失敗しました";
	$php_errormsg = $message;
	trigger_error( $message, E_USER_WARNING );

	return TRUE;
}

?>
  



  print_r と var_dump

単純に配列を一つ表示したいだけならば、あまり差はありませんが、
以下のような違いがあります

  
<?
$a = array( 0, 1, "A", "B" );
$b = array( 1, "A", $a );

# 2番目の引数を指定する事によって、結果を変数に取得できる
$ret = print_r( $b, TRUE );

print "<PRE>$ret</PRE>";

$a[0] = 100;

# 結果は、出力制御関数を使用しないと取得できないが、
# 一度に複数の変数を指定できる
print "<PRE>";
var_dump( $a, $b );
print "</PRE>";

#---------------------------------------------------------
# 上記例では、$a はクローンなので、$b の中は変化しない
print "<hr>";
# 下記例では参照をセットしたので変化する
#---------------------------------------------------------

$a = array( 0, 1, "A", "B" );
$b = array( 1, "A", &$a );

print "<PRE>$ret</PRE>";

$a[0] = 100;
print "<PRE>";
var_dump( $a, $b );
print "</PRE>";

?>
  

Array
(
    [0] => 1
    [1] => A
    [2] => Array
        (
            [0] => 0
            [1] => 1
            [2] => A
            [3] => B
        )

)

array(4) {
  [0]=>
  int(100)
  [1]=>
  int(1)
  [2]=>
  string(1) "A"
  [3]=>
  string(1) "B"
}
array(3) {
  [0]=>
  int(1)
  [1]=>
  string(1) "A"
  [2]=>
  array(4) {
    [0]=>
    int(0)
    [1]=>
    int(1)
    [2]=>
    string(1) "A"
    [3]=>
    string(1) "B"
  }
}


--------------------------------------------------------------------------------

Array
(
    [0] => 1
    [1] => A
    [2] => Array
        (
            [0] => 0
            [1] => 1
            [2] => A
            [3] => B
        )

)

array(4) {
  [0]=>
  int(100)
  [1]=>
  int(1)
  [2]=>
  string(1) "A"
  [3]=>
  string(1) "B"
}
array(3) {
  [0]=>
  int(1)
  [1]=>
  string(1) "A"
  [2]=>
  &array(4) {
    [0]=>
    int(100)
    [1]=>
    int(1)
    [2]=>
    string(1) "A"
    [3]=>
    string(1) "B"
  }
}



以下はオブジェクトの出力例

  
<?
$a = new myData;
$b = array( 1, "A", &$a );

$ret = print_r( $b, TRUE );
print "<PRE>$ret</PRE>";

$a->add();

var_dump( $a, $b );

class myData
{
	var $no;

	function myData() {
		$this->no = 1;
	}
	function add() {
		$this->no++;
	}
}
?>
  

Array
(
    [0] => 1
    [1] => A
    [2] => myData Object
        (
            [no] => 1
        )

)

object(myData)#1 (1) {
  ["no"]=>
  int(2)
}
array(3) {
  [0]=>
  int(1)
  [1]=>
  string(1) "A"
  [2]=>
  &object(myData)#1 (1) {
    ["no"]=>
    int(2)
  }
}






  セッションログインとリダイレクトとパスワード

セッション利用の入門プログラムとしては、「ログイン処理」が最も理解しやすいと思います。

※ 代表的な仕様として以下のようなものが考えられます。

1) ログイン画面以外の URL にアクセスした場合
  a) ログインしていない場合 --> ログイン画面にジャンプする。
  b) ログイン済みの場合 --> なにもしない。

2) ログイン画面を表示してログインした場合
  a) 1) の a) の理由により、ログイン画面を表示した場合 --> 1) でアクセスした画面へ戻る
  b) 以外の原因でログイン画面が表示した場合 --> システムのデフォルトの画面を表示する


1) を実現する為のコード(ログイン画面以外)
  
session_start();
if ( $_GET['ボタンの名前'] == 'ログアウト' ) {
	$_SESSION = array();
}
if ( $_SESSION['user'] == "" ) {
	$_SESSION['return_url'] = $_SERVER['このスクリプトの位置を示す変数'];
	// リダイレクト
	header( "Location: ログイン画面の相対 URL" );
	exit();
}
  

2) を実現する為のコード(ログイン画面)
  
session_start();
if ( $_GET['ボタンの名前'] == 'ログアウト' ) {
	$_SESSION = array();
}
if ( $_GET['user'] != "" ) {
	if ( $_GET['user'] == "有効なユーザ名" ) {
		if ( $_GET['pass'] == "ユーザ名に対応する正しいパスワード" ) {
			$_SESSION['user'] = "有効なユーザ名";
			if ( $_SESSION['return_url'] != "" ) {
				// リダイレクト
				header( "Location: {$_SESSION['return_url']}" );
				$_SESSION['return_url'] = "";
				exit();
			}
			else {
				// リダイレクト
				header( "Location: デフォルト画面のURL" );
				$_SESSION['return_url'] = "";
				exit();
			}
		}
		else {
			// エラー処理
		}
	}
	else {
		// エラー処理
	}
}
  

パスワードをサーバ側でそのまま保存するとデータが流出した時に問題が出るので、
保存時に1方向(非可逆)の暗号化を行って保存します。

crypt( $_GET['user'], "sd" );

※ sd は二文字で暗号化の種です(サーバー側で決めます)。
※ 暗号化されるのは8バイトまでなので、8バイト毎に暗号化して結合します。



  eval 実行

eval は、文字列内の PHP コードを実行する関数ですが、リテラルで実行するのは
$ 等のエスケープが面倒なので、テキストファイルを読み込んで実行すると良いでしょう。

※ eval の戻り値には、3通りのパターンがあります

  
<?

$data = "ABC-";

$txt = @file_get_contents( "php.txt" );

$ret = @eval( $txt );
# パターン1
if ( $ret === NULL ) {
	print "return を指定していません<br>";
}
# パターン2
if ( $ret === FALSE ) {
	print "異常終了しました<br>";
}
# パターン3
if ( $ret === $data ) {
	print "return を指定しました<br>";
}

# eval でセットされた変数の値を表示
print $a;

?>
  

# パターン1
  
$a = $data;
  

# パターン2
  
# 致命的エラー( セミコロン無し )
$a = $data
  

# パターン3
  
$a = $data;

return $a;
  

以下のように、HTML モードへの移行もできます

php.txt
  
$a = $data;
?>
ここはそのまま表示されます<br>
<?
  

また、テキストファイル内にある PHP の変数と判断できる文字列を実際実行時の変数
とみなして置き換えるには以下のようにします。

  
$x = "ABC";
$txt = @file_get_contents( "php.txt" );
eval("\$txt = \"$txt\";");

print $txt;
  

php.txt
  
select * from table_name where id = '$x'
  



  バイナリレスポンスと URL ダウンロード

バイナリレスポンス
  
<?
header( "Content-Type: image/jpeg" );

print file_get_contents( "temp.jpg" );

?>
  


PHP4 での URL ダウンロード
  
<?

$url = "http://winofsql.jp";
$fp = fopen( "download.htm", "wb" );
fwrite( $fp, file_get_contents( $url ) );
fclose( $fp );

?>
Done
  

PHP5 での URL ダウンロード
  
<?

$url = "http://winofsql.jp";
file_put_contents( "download.htm", file_get_contents( $url ) );

?>
Done
  



  定型ファイルアップロード

act.bat
  
set PHP_BIN=c:\php\cli\php.exe
set LBOX_SERVER=xxxxxxxxxxxxx
set LBOX_USER=yyyyyyyy
set LBOX_PASS=zzzzzzzz
set LBOX_REMOTE=/????/????/????/????/enum/webclass
set LBOX_LOCAL=D:\????\????\enum\webclass

%PHP_BIN% ftp_upload.php

pause
  

ftp_upload.php
  
<?
$ftp_server	= $_ENV['LBOX_SERVER'];
$ftp_user	= $_ENV['LBOX_USER'];
$ftp_pass	= $_ENV['LBOX_PASS'];
$base_dir	= $_ENV['LBOX_REMOTE'];
$local_dir	= $_ENV['LBOX_LOCAL'];

$conn=ftp_connect($ftp_server);
if (!$conn) {
	die('接続できません' . "\n");
}

$result=@ftp_login($conn, $ftp_user, $ftp_pass); 
if (!$result) {
	die('ログインできません' . "\n");
}

ftp_pasv($conn, true);

ftp_put($conn, $base_dir . "/control.htm", $local_dir . "\control.htm", FTP_ASCII );
ftp_put($conn, $base_dir . "/logo.htm", $local_dir . "\logo.htm", FTP_ASCII );
ftp_put($conn, $base_dir . "/frame.htm", $local_dir . "\frame.htm", FTP_ASCII );


ftp_close($conn);

print "処理が終了しました\n";
?>
  



  HTML の数値文字列参照作成

  
mb_language( "ja" );
mb_internal_encoding("UTF-8"");

$bin_unicode = mb_convert_encoding( "あ", "unicode", "キャラクタセット" );
$hex_unicode = bin2hex($bin_unicode);
$num_unicode = ('0x'.$hex_unicode)+0;
$target = '&#' . $num_unicode . ';';
  










  infoboard   管理者用   
このエントリーをはてなブックマークに追加





フリーフォントWEBサービス
SQLの窓WEBサービス

SQLの窓フリーソフト

素材

一般WEBツールリンク

SQLの窓

フリーソフト

JSライブラリ