PHPでファイルの所有者を調べる
PHPでファイルグループを調べる
PHPでファイルの種類を調べる
PHPでディレクトリ内のファイルを列挙する
PHPでBASIC認証を行う
PHPで認証されたユーザのみファイル一覧表示
PHPでキャッシュされない画像表示の方法
PHPでセキュリティコード画像の表示
PHPでBASIC認証用の.htaccess、.htpassedファイルの作成
PHPでmecabの使用方法
※時々追加掲載予定です。
サンプルはご自由にお使い頂いて構いませんが、サンプルを使用したことによる損害に関して弊社は一切責任を負いません。利用者の責任においてご利用ください。
また、サンプルについて、当社はバージョンアップ・不具合修正の義務を負いません。
サンプルの著作権は、株式会社リアライズに帰属します。
ファイルから所有者名を調べます。 ※POSIXを無効に設定されている環境では使用できません。
/************************************************
function Get_File_Own ( $filename )
概要 ファイルの所有者名を調べる。
引数 $filename ファイル名
戻値 ファイルの所有者名
************************************************/
function Get_File_Own ( $filename )
{
$own = posix_getpwuid ( fileowner ( $filename ) );
return $own['name'];
}
ファイルからグループ名を調べます。 ※POSIXを無効に設定されている環境では使用できません。
/************************************************
function Get_File_Grp ( $filename )
概要 ファイルのグループ名を調べる。
引数 $filename ファイル名
戻値 ファイルのグループ名
************************************************/
function Get_File_Grp ( $filename )
{
$grp = posix_getgrgid ( filegroup ( $filename ) );
return $grp['name'];
}
ファイルから種類(ファイル、ディレクトリ、リンク)を調べます。
/************************************************
function Get_File_Type ( $filename )
概要 ファイルの種類を調べる。
引数 $filename ファイル名
戻値 以下の文字列のいずれか
file / directory / link / unknown
************************************************/
function Get_File_Type ( $filename )
{
if ( is_file ( $filename ) ) {
$filtype = "file";
} elseif ( is_dir ( $filename) ) {
$filtype = "directory";
} elseif ( is_link ( $filename) ) {
$filtype = "link";
} else {
$filtype = "unknown";
}
return $filtype;
}
ディレクトリ内のファイルを列挙し、一覧表示します。表示内容や方法ははカスタマイズして使ってください。
ex) Enum_Files_HTML ( "." );
サンプルのままですと本サンプルページ内のGet_File_Type ,Get_File_Own ,Get_File_Grp関数が必要です。
/************************************************
function Enum_Files_HTML ( $dirctory = "." )
概要 指定ディレクトリ内のファイルを列挙し、
HTML出力する。
引数 $dirctory ※省略可(デフォルト:'.')
ディレクトリ
戻値 なし
備考 以下の関数が必要。
Get_File_Type ,Get_File_Own ,Get_File_Grp
************************************************/
function Enum_Files_HTML ( $dirctory = "." )
{
if ( $h_dir = opendir ( $dirctory ) ) { // ディレクトリハンドルを得る
echo "<table cellspacing='1' cellpadding='3'>\n";
echo "<tr><th>type</th><th>name</th><th>group</th><th>owner</th><th>last modified</th></tr>\n";
while ( $files = readdir( $h_dir ) ) { // ディレクトリ内のファイルを列挙する
$filtype = Get_File_Type ( $files ); // ファイルの種類を調べる
$grp = Get_File_Grp ( $files );; // ファイルのグループを調べる
$own = Get_File_Own ( $files ); // ファイルの所有者を調べる
echo "<tr><td>".$filtype."</td><td><a href='".$files."'>".$files."</a></td><td>".
$grp."</td><td>".$own."</td><td>".date ( "Y-m-d H:i:s", filemtime ( $files ) )."</td></tr>\n";
}
closedir ( $h_dir );
echo "</table>\n";
}
}
BASIC認証は.htaccessで簡単に実現できますが、PHP(Ver.4.1以降)を使える場合にはPHPでも実現できます。
なお、認証エラー時の画面表示はApacheの出力するエラー表示とよく似たデザインにしてあります。
使い方は処理の最も先頭でBasic_Authを呼び出すことです。認証された場合に実行する内容をそれ以降に記述してください。
ex) Basic_Auth ( "username", "password", "Owners area" );
※username、password、Owners areaはそれぞれ適切なものに変更して使用してください。
/************************************************
function Basic_Auth ( $user, $passwd, $areaname )
概要 BASIC認証を行う。
引数 $user ユーザ名
$passwd パスワード
$areaname エリア名
戻値 なし
備考 Forbidden関数要
************************************************/
function Basic_Auth ( $user, $passwd, $areaname )
{
// 認証画面表示
if ( !isset ( $_SERVER['PHP_AUTH_USER'] ) ) {
header ( "WWW-Authenticate: Basic realm=".$areaname );
header ( "HTTP/1.0 401 Unauthorized" );
}
// ユーザ・パスワードの確認
if ( $_SERVER['PHP_AUTH_USER'] != $user || $_SERVER['PHP_AUTH_PW'] != $passwd ) {
Forbidden ( FALSE ); // アクセス不可
}
}
/************************************************
function Forbidden ( $option_header = TRUE )
概要 ApacheのForbidden類似画面を表示し終了する。
引数 $option_header ※省略可(デフォルト:TRUE)
TRUE:HTTPヘッダ有 / FALSE:HTTPヘッダ無
戻値 なし
************************************************/
function Forbidden ( $option_header = TRUE )
{
if ( $option_header ) header ( "HTTP/1.0 403 Forbidden"); // 403ヘッダ出力
// Forbidden表示、終了
die ( "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>".
"<html><head><style>body { font-family:Times New Roman;}</style>".
"<title>403 Forbidden</title></head><body><h1>Forbidden</h1>You don't have permission to access ".
$_SERVER['REQUEST_URI']." on this server.<p></p><hr>".$_SERVER['SERVER_SIGNATURE']."</body></html>" );
}
これまでのサンプルを組み合わせたものです。
.htaccess で Options Indexes を記述するとindex.html等のファイルが無い場合にディレクトリ一覧を表示しますが、セキュリティ上好ましくありません。
しかし、認証済みユーザには一覧を表示したいといった特殊なニーズを満たせます。※一覧を表示するためにBASIC認証を必要とします。
/************************************************
function Basic_Auth ( $user, $passwd, $areaname )
概要 BASIC認証を行う。
引数 $user ユーザ名
$passwd パスワード
$areaname エリア名
戻値 なし
備考 Forbidden関数要
************************************************/
function Basic_Auth ( $user, $passwd, $areaname )
{
// 認証画面表示
if ( !isset ( $_SERVER['PHP_AUTH_USER'] ) ) {
header ( "WWW-Authenticate: Basic realm=".$areaname );
header ( "HTTP/1.0 401 Unauthorized" );
}
// ユーザ・パスワードの確認
if ( $_SERVER['PHP_AUTH_USER'] != $user || $_SERVER['PHP_AUTH_PW'] != $passwd ) {
Forbidden ( FALSE ); // アクセス不可
}
}
/************************************************
function Forbidden ( $option_header = TRUE )
概要 ApacheのForbidden類似画面を表示し終了する。
引数 $option_header ※省略可(デフォルト:TRUE)
TRUE:HTTPヘッダ有 / FALSE:HTTPヘッダ無
戻値 なし
************************************************/
function Forbidden ( $option_header = TRUE )
{
if ( $option_header ) header ( "HTTP/1.0 403 Forbidden"); // 403ヘッダ出力
// Forbidden表示、終了
die ( "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>".
"<html><head><style>body { font-family:Times New Roman;}</style>".
"<title>403 Forbidden</title></head><body><h1>Forbidden</h1>You don't have permission to access ".
$_SERVER['REQUEST_URI']." on this server.<p></p><hr>".$_SERVER['SERVER_SIGNATURE']."</body></html>" );
}
/************************************************
function Get_File_Type ( $filename )
概要 ファイルの種類を調べる。
引数 $filename ファイル名
戻値 以下の文字列のいずれか
file / directory / link / unknown
************************************************/
function Get_File_Type ( $filename )
{
if ( is_file ( $filename ) ) {
$filtype = "file";
} elseif ( is_dir ( $filename) ) {
$filtype = "directory";
} elseif ( is_link ( $filename) ) {
$filtype = "link";
} else {
$filtype = "unknown";
}
return $filtype;
}
/************************************************
function Get_File_Own ( $filename )
概要 ファイルの所有者名を調べる。
引数 $filename ファイル名
戻値 ファイルの所有者名
************************************************/
function Get_File_Own ( $filename )
{
$own = posix_getpwuid ( fileowner ( $filename ) );
return $own['name'];
}
/************************************************
function Get_File_Grp ( $filename )
概要 ファイルのグループ名を調べる。
引数 $filename ファイル名
戻値 ファイルのグループ名
************************************************/
function Get_File_Grp ( $filename )
{
$grp = posix_getgrgid ( filegroup ( $filename ) );
return $grp['name'];
}
/************************************************
function Enum_Files_HTML ( $dirctory = "." )
概要 指定ディレクトリ内のファイルを列挙し、
HTML出力する。
引数 $dirctory ※省略可(デフォルト:'.')
ディレクトリ
戻値 なし
備考 以下の関数が必要。
Get_File_Type ,Get_File_Own ,Get_File_Grp
************************************************/
function Enum_Files_HTML ( $dirctory = "." )
{
if ( $h_dir = opendir ( $dirctory ) ) { // ディレクトリハンドルを得る
echo "<table cellspacing='1' cellpadding='3'>\n";
echo "<tr><th>type</th><th>name</th><th>group</th><th>owner</th><th>last modified</th></tr>\n";
while ( $files = readdir( $h_dir ) ) { // ディレクトリ内のファイルを列挙する
$filtype = Get_File_Type ( $files ); // ファイルの種類を調べる
$grp = Get_File_Grp ( $files );; // ファイルのグループを調べる
$own = Get_File_Own ( $files ); // ファイルの所有者を調べる
echo "<tr><td>".$filtype."</td><td><a href='".$files."'>".$files."</a></td><td>".
$grp."</td><td>".$own."</td><td>".date ( "Y-m-d H:i:s", filemtime ( $files ) )."</td></tr>\n";
}
closedir ( $h_dir );
echo "</table>\n";
}
}
// BASIC認証を行う。
Basic_Auth ( "username", "password", "Owners area" );
?>
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<style>
body { font-family:Arial;}
table { background:#aaa; }
th { background:#ccc; }
td { background:#eee; }
</style>
<title><?= $_SERVER['REQUEST_URI']?></title>
</head>
<body>
<?php
// 認証されたらディレクトリ内のファイルを一覧表示
Enum_Files_HTML();
?>
</body>
</html>
ウエブ系のシステム開発では画像をアップロードする機能等を含む場合で、ブラウザのキャッシュにより同一名画像ファイルで変更前の画像が表示されたりと問題となる場合があります。
以下の例のように呼び出すことでこの問題から解放されます。
ex) <img src='../preview.php?filename=".$filename."'>
preview.php
<?php
// jpg画像表示
header ( "Content-type: image/jpg" );
$filname = $_GET['filename'];
$hFile = fopen ( $filname ,'r' );
while ( !feof ( $hFile ) ) {
$contents .= fread ( $hFile ,8192 );
}
fclose ( $hFile );
echo $contents;
exit ();
?>
掲示板やブログなどに大量のスパムメッセージを書き込まれる場合があります。これはプログラムによって自動化されているようです。
セキュリティコード画像の表示によって人間のチェックを要するようにする事でこの問題の場合はある程度の解決を図ることができます。
※弊社でもこの仕組みを使用しています(使用例:オンラインサポート掲示板)。
仕組み:
1) <img src='./securitycode.php'>によって画像を表示すると同時にsecuritycode.phpは表示されたセキュリティコードをcookieにセットします。
2) ユーザは表示された画像(png)から文字列を読み取ってテキストボックスに入力し送信します。
3) 送信された文字列とcookieの内容を比較して同じであれば処理を続行し、異なればエラーとします。
入力側に追加するコード例と処理側に追加するコード例、セキュリティコードを表示するファイルサンプルを以下に掲載しますが、実際に使う際は少々変更されたほうが良いでしょう。
セキュリティコード画像表示例)※入力部(HTML/PHP) <form method='POST' action...> : <img src='./securitycode.php'>画像に表示されている5文字のセキュリティコードを入力してください <input type='text' name='securitycode' value='' size='10'> : </form>
チェックするページの例)※処理部(PHP)
require_once "lib.php";
:
// セキュリティコードの照合
if ( $_COOKIE['securitycode'] != md5 ( $_POST['securitycode'] ) ) die ( "セキュリティコードが異なります。\n" );
// クッキー削除
remove_cookie ( 'securitycode' );
// 以下にセキュリティコードが一致した場合の処理を記述
lib.php
// クッキーに関する設定
define("cookie_expire",( 60 * 60 )); // クッキー生存時間(秒) ex) 60 * 60 :3,600秒(1時間)
define("cookie_path","/"); // クッキー有効パス
define("cookie_domain","host.domain"); // クッキー有効ドメイン
define("cookie_secure",0); // SSL使用しない:0 / SSLの使用:1
// cokkie記録
function add_cookie ( $keyname ,$value )
{
setcookie ( $keyname ,$value ,time() + cookie_expire ,cookie_path ,cookie_domain ,cookie_secure );
}
// cookie削除
function remove_cookie ( $keyname )
{
setcookie ( $keyname ,"" ,time() - cookie_expire ,cookie_path ,cookie_domain ,cookie_secure );
}
securitycode.php
<?php
require_once "lib.php";
function DrawPng_text ( $w ,$h ,$securitycode )
{
header ( "Content-type: image/png" );
$img = @imagecreate ( $w , $h ) or die ( "Cannot Initialize new GD image stream" ); // 画像の作成
// 背景色の作成
imagecolorallocate ( $img ,210 ,220 ,220 );
// 使用色の作成
$clr_black[0] = imagecolorallocate ( $img ,100 ,0 ,0 );
$clr_black[1] = imagecolorallocate ( $img ,0 ,100 ,0 );
$clr_black[2] = imagecolorallocate ( $img ,0 ,0 ,100 );
$clr_black[3] = imagecolorallocate ( $img ,0 ,100 ,100 );
$clr_black[4] = imagecolorallocate ( $img ,100 ,100 ,0 );
$clr_glay = imagecolorallocate ( $img ,200 ,200 ,200 );
$clr_white = imagecolorallocate ( $img ,255 ,255 ,255 );
// ランダムな直線と矩形の描画
for ( $j = 0;$j <= 10;$j++ ) {
$point[0] = mt_rand ( 0, $w );
$point[1] = mt_rand ( 0, $h );
$point[2] = mt_rand ( 0, $w );
$point[3] = mt_rand ( 0, $h );
imagerectangle ( $img ,$point[0] ,$point[1] ,$point[2] ,$point[3] ,$clr_glay );
$point[0] = mt_rand ( 0, $w );
$point[1] = mt_rand ( 0, $h );
$point[2] = mt_rand ( 0, $w );
$point[3] = mt_rand ( 0, $h );
imageline ( $img ,$point[0] ,$point[1] ,$point[2] ,$point[3] ,$clr_glay );
}
// 著作権表示
imagestring ( $img ,3 ,65 , 20 , "Realize,Inc." ,$clr_white );
for ( $i = 0;$i <= 5;$i++ ) {
$fontsize = mt_rand ( 3, 10 );
$point[0] = mt_rand ( $w / strlen ( $securitycode ) * $i ,$w / strlen ( $securitycode ) * ( $i + 1 ) - ( $fontsize * 3 ) );
$point[1] = mt_rand ( 0, $h - ( $fontsize * 4 ) );
imagestring ( $img ,$fontsize ,$point[0] ,$point[1] , substr ( $securitycode ,$i ,1 ) ,$clr_black[ mt_rand ( 0 ,4 ) ] );
}
imagepng ( $img ); // PNGイメージを出力する
imagedestroy ( $img ); // 画像の消去
}
// セキュリティコードの作成
$code = "123456789abdefghjmnqrtyABCDEFGHJKLMNPQRSTUVWXYZ"; // 表示する文字列(0やo等わかりづらい文字は含めない)
$securitycode = "";
for ( $i = 1;$i <= 5;$i++ ) {
$j = mt_rand ( 0 ,strlen ( $code ) - 1 );
$securitycode .= substr ( $code ,$j ,1 );
}
// セキュリティコードをmd5ハッシュ計算しcookieにセット
add_cookie ( "securitycode" ,md5 ( $securitycode ) );
// セキュリティコード画像を作成
DrawPng_text ( 150 ,35 ,$securitycode );
?>
使用前に:
認証プログラムを設置する為に事前にディレクトリに書き込み権限を与える必要があります。
本プログラムでできるのは「単一ユーザによるBASIC認証機能を実現する.htaccess、.htpasswdファイルの作成」です。
注意事項:
.htaccess、.htpasswdは作成毎に上書きされますのでご注意ください。セキュリティ上、認証プログラムによる.htpasswdファイルの設置後は、「パーミッションを604にしてください」。
第三者により.htaccess、.htpasswdファイルが閲覧される可能性があります。
本来であれば.htpasswdファイルはドキュメントツリー上に設置すべきではありませんが、本プログラムは同一ディレクトリに.htaccess、.htpasswdを設置します。
※パスワードファイル(.htpasswd)がダウンロードできる可能性があるからです。
暗号化されていることからパスワードが解析できる可能性はあまり高くはありませんが、解析不能ではありません。あくまで簡易設置プログラムであることを忘れないでください。
※.htaccessについて詳しくはApacheのマニュアルを参照ください。
basicauth.php
<?php
/***************************************************************************************************
BASIC認証用.htaccess、.htpasswd設置
セキュリティをあまり必要としない場合で簡易的に第三者からディレクトリ内容の閲覧を制限する
BASIC認証機能を実現するプログラムです。
(C)Realize,Inc.
***************************************************************************************************/
// .htaccessファイルを作成する
function create_htaccess_file ( $path )
{
$hfile = fopen ( $path.".htaccess", "w" );
$htaccess = "AuthUserFile ".$path.".htpasswd\n".
"AuthGroupFile /dev/null\n".
"AuthName \"Restricting Access\"\n".
"AuthType Basic\n".
"require valid-user\n";
fwrite ( $hfile, $htaccess );
fclose ( $hfile );
}
// .htaccess内容を表示する
function view_htaccess_file ( $path )
{
$htaccess = "AuthUserFile ".$path.".htpasswd\n".
"AuthGroupFile /dev/null\n".
"AuthName \"Restricting Access\"\n".
"AuthType Basic\n".
"require valid-user\n";
echo nl2br ( $htaccess );
}
// .htpasswdファイルを作成する
function create_htpasswd_file ( $path, $usr, $passwd )
{
$hfile = fopen ( $path.".htpasswd", "w" );
$htpasswd = $usr. ":". crypt ( $passwd, substr ( $usr, 0, 2 ) )."\n";
fwrite ( $hfile, $htpasswd );
fclose ( $hfile );
}
// .htpasswdを表示する
function view_htpasswd_file ( $path, $usr, $passwd )
{
$htpasswd = $usr. ":". crypt ( $passwd, substr ( $usr, 0, 2 ) )."\n";
echo nl2br($htpasswd);
}
// 実行中のphpファイルのディレクトリとファイル名を取得する
function get_path_file ( $fullpath, $path, $file )
{
$fullpath = __FILE__;
$file = basename ( $fullpath );
$path = dirname ( $fullpath );
}
// パスワード(a〜zA〜Z0〜9`~!@#$%^&*()_+-={}|[]\:";'<>?,./)チェック
function check_passwd ( $buf )
{
if ( !$buf ) {
return FALSE;
} else {
return preg_match ( '/^[a-zA-Z0-9`~!@#$%^&*\(\)_\+\-={}\|\[\]\\:\";\'<>\?,\.\/]*$/i', $buf );
}
}
// 英数字(a〜zA〜Z0〜9)チェック
function check_eisuu ($buf)
{
if (!$buf) {
return FALSE;
} else {
return preg_match('/^[a-zA-Z0-9]*$/i', $buf);
}
}
// 実行中のフルパス、パス、ファイル名をそれぞれ得る
get_path_file ( &$fullpath, &$path, &$file );
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>BASIC認証用.htaccess、.htpasswd設置</title>
<style>
table { background-color : #000000; }
tr { background-color : #ffffff; }
</style>
</head>
<body>
<form method='post' action='<?= $_SERVER['PHP_SELF'] ?>'>
<table cellspacing='1' cellpadding='5'>
<tr><td>設置ディレクトリ</td><td><?= $path."/" ?><input type='text' name='auth_path' size='50'></td></tr>
<tr><td>認証ID</td><td><input type='text' name='auth_usr' size='30'></td></tr>
<tr><td>認証パスワード</td><td><input type='text' name='auth_passwd' size='30'></td></tr>
<tr><td>ファイル作成(上書き)</td><td><input name='create' type='submit' value=' 作 成 '></td></tr>
<tr><td>表示のみ</td><td><input name='view' type='submit' value=' 表 示 '></td></tr>
</table>
</form>
<?php
if ( isset ( $_POST['create'] ) || isset ( $_POST['view'] ) ) {
// 入力内容のチェック
// ディレクトリが存在するか
$auth_path = $path."/".$_POST['auth_path'];
if ( !is_dir ( $auth_path ) ) $err .= "指定ディレクトリが誤っています。\n";
// ユーザ(英数字)
$auth_usr = $_POST['auth_usr'];
if ( !check_eisuu($auth_usr) ) $err .= "ユーザ名が正しくありません。\n";
// パスワード(英数字・記号)
$auth_passwd = $_POST['auth_passwd'];
if ( !check_passwd($auth_passwd) ) $err .= "パスワードが正しくありません。\n";
if ( $err ) { // エラーを表示
echo "<font color='#ff0000'>".nl2br($err)."</font>";
} else { // .htpasswd .htaccess を作成
if ( isset ( $_POST['create'] ) ) {
create_htaccess_file ( $auth_path );
create_htpasswd_file ( $auth_path, $auth_usr, $auth_passwd );
} else {
echo "<strong>.htaccess</strong><br>\n";
view_htaccess_file ( $auth_path );
echo "<br>\n<strong>.htpasswd</strong><br>\n";
view_htpasswd_file ( $auth_path, $auth_usr, $auth_passwd );
}
}
}
?>
</body>
</html>
PHPで形態素解析を行います。 ※mecabが使用できる環境が必要です。
<?php
function mecab ( $str )
{
$cmd = "/usr/local/bin/mecab -O wakati"; // mecab
$descriptorspec = array (
0 => array ( "pipe", "r" ), // stdin は、子プロセスが読み込むパイプです。
1 => array ( "pipe", "w" ) // stdout は、子プロセスが書き込むパイプです。
);
$h_ps = proc_open ( $cmd, $descriptorspec, $pipes );
if ( is_resource ( $h_ps ) ) {
// $pipes
// 0 => 子プロセスの stdin に繋がれた書き込み可能なハンドル
// 1 => 子プロセスの stdout に繋がれた読み込み可能なハンドル
fwrite ( $pipes[0], $str );
fclose ( $pipes[0] );
while ( !feof ( $pipes[1] ) ) {
$result .= fread ( $pipes[1], 4096 );
}
fclose ( $pipes[1] );
proc_close($h_ps);
}
$results = explode ( " ", $result );
return $results;
}
$str = "コードサンプルページを追加しました。";
$results = mecab ( $str );
echo nl2br ( print_r ( $results ,TRUE ) );
?>