PHPの覚書

暗号化関数の拡張版 md5Ex
md5関数では破られる可能性があるため、この関数はより暗号強化している。
md5関数と同様に、パスワードなど秘密文字をGET,POST,登録確認キーなどに利用する。
なお、複合化はできない。

	/**
     * 拡張暗号化
     * MD5関数では破られる可能性があるため、この関数はより暗号強化している。
     * なお複合化(戻し)はできない。
     * 
     * @param $pw パスワードなど秘密の文字
     * @param $dummy1 任意の文字列1
     * @param $dummy2 任意の文字列2
     * 
     */
    function md5Ex($pw,$dummy1='nL7q',$dummy2='ho48j4P'){
    	
    	$pw2 = MD5($pw);
    	$pw3 = $dummy1.$pw2.$dummy2;
    	$pw4 = hash('sha256',$pw3);
    	
    	return $pw4;

    }
	
参考:PHPで覚えておくと便利な関数まとめ3

日時入力チェックのバリデーション

	/**
 * 日時入力チェックのバリデーション
 * ※日付のみあるいは時刻は異常と見なす。
 * @param string $str_dt	日時文字列
 * @param bool $req	入力必須フラグ false:空許可(デフォ), true:入力必須
 * @return string	エラー文字列  正常のときはnull
 * @date 2015-10-5 | 2019-8-12
 */
function isDatetime($str_dt, $req=false){
	
	//空値且つ、必須入力がnullであれば、trueを返す。
	if(empty($str_dt) && empty($req)){
		return null;
	}
	
	//日時を 年月日時分秒に分解する。
	//$aryA =preg_split( '|[ /:_-]|', $str_dt );
	$aryA =preg_split("[\/|-|:|\s]", $str_dt );
	if(count($aryA)!=6){
		return '日時形式ではありません。';
	}
	
	foreach ($aryA as $key => $val){
		
		//▼正数以外が混じっているば、即座にfalseを返して処理終了
		if (!preg_match("/^[0-9]+$/", $val)) {
			return '文字列が混じっています。';
		}
		
	}
	
	//▼グレゴリオ暦と整合正が取れてるかチェック。(閏年などはエラー) ※さくらサーバーではemptyでチェックするとバグになるので注意。×→if(empty(checkdate(12,11,2012))){・・・}
	if(checkdate($aryA[1],$aryA[2],$aryA[0])==false){
		return '存在しない日付です(グレゴリオ暦)。';
	}
	
	//▼時刻の整合性をチェック
	if($aryA[3] < 0 || $aryA[3] > 23){
		return '時刻に異常があります。';
	}
	if($aryA[4] < 0 ||  $aryA[4] > 59){
		return '「分」に異常があります。';
	}
	if($aryA[5] < 0 || $aryA[5] > 59){
		return '秒に異常があります。';
	}
	
	return null;
}
	

	/**
	 * 日時入力チェックのバリデーション
	 * ※日付のみあるいは時刻は異常と見なす。
	 * @param $strDateTime	日時文字列
	 * @param $reqFlg	必須許可フラグ
	 * @return boolean	true:正常   false:異常
	 * @date 2015-10-5	改良
	 */
	function isDatetime($strDateTime,$reqFlg){

		//空値且つ、必須入力がnullであれば、trueを返す。
		if(empty($strDateTime) && empty($reqFlg)){
			return true;
		}
		
		//空値且つ、必須入力がtrueであれば、falseを返す。
		if(empty($strDateTime) && !empty($reqFlg)){
			return false;
		}
	
	
		//日時を 年月日時分秒に分解する。
		$aryA =preg_split( '|[ /:_-]|', $strDateTime );
		if(count($aryA)!=6){
			return false;
		}
		
		foreach ($aryA as $key => $val){
				
			//▼正数以外が混じっているば、即座にfalseを返して処理終了
			if (!preg_match("/^[0-9]+$/", $val)) {
				return false;
			}
			
		}
		
		//▼グレゴリオ暦と整合正が取れてるかチェック。(閏年などはエラー) ※さくらサーバーではemptyでチェックするとバグになるので注意。×→if(empty(checkdate(12,11,2012))){・・・}
		if(checkdate($aryA[1],$aryA[2],$aryA[0])==false){
			return false;
		}
	
		//▼時刻の整合性をチェック
		if($aryA[3] < 0 || $aryA[3] > 23){
			return false;
		}
		if($aryA[4] < 0 ||  $aryA[4] > 59){
			return false;
		}
		if($aryA[5] < 0 || $aryA[5] > 59){
			return false;
		}
		
		return true;
	}
	
サンプル

現在のUNIXタイムスタンプを取得 | time()
	$u=time();//現在のUNIXタイムスタンプを取得
	$d=date("Y-m-d H:i:s",$u);//フォーマット変換
	

数日後、数年前、数秒後などの日付を取得する

基本型

$date2 = date('Y-m-d', strtotime("3 day", strtotime($date1)));

年月日時分秒を検証

数日後、数日前、数年後、数ヶ月後、数時間後、数分後、数秒後を取得する。
	$date1='2016-6-15 01:02:03';
	echo "基準日:".$date1.'<br>';
	
	// 3日後を取得
	$date2 = date('Y-m-d', strtotime("3 day", strtotime($date1)));
	echo "3日後:".$date2.'<br>';
	
	// 3日前を取得
	$date2 = date('Y-m-d', strtotime("-3 day", strtotime($date1)));
	echo "3日前:".$date2.'<br>';
	
	// 3年後を取得
	$date2 = date('Y-m-d', strtotime("3 year", strtotime($date1)));
	echo "3年後:".$date2.'<br>';
	
	// 3月後を取得
	$date2 = date('Y-m-d', strtotime("3 month", strtotime($date1)));
	echo "3月後:".$date2.'<br>';
	
	// 3時間後を取得
	$date2 = date('Y-m-d H:i:s', strtotime("3 hour", strtotime($date1)));
	echo "3時間後:".$date2.'<br>';
	
	// 3分後を取得
	$date2 = date('Y-m-d H:i:s', strtotime("3 minute", strtotime($date1)));
	echo "3分後:".$date2.'<br>';
	
	// 3秒後を取得
	$date2 = date('Y-m-d H:i:s', strtotime("3 second", strtotime($date1)));
	echo "3秒後:".$date2.'<br>';
	

出力
	基準日:2016-6-15 01:02:03
	3日後:2016-06-18
	3日前:2016-06-12
	3年後:2019-06-15
	3月後:2016-09-15
	3時間後:2016-06-15 04:02:03
	3分後:2016-06-15 01:05:03
	3秒後:2016-06-15 01:02:06
	

閏年の検証

2016-2-29から3年後の場合、2016-3-1になる。


旧式

指定日から数日後を取得する
	$date1='2012-12-1 01:02:03';
	$date2 = fewDaysLater($date1,100);
	echo '指定日:'.$date1.'<br>';
	echo '数日後:'.$date2.'<br>';
	
	/**
	 * 指定日から数日後を取得する
	 * 
	 * @param string or date $date1 指定日。
	 * @param int $dayCnt 経過日数。負値で以前の日を取得できる。
	 * @param string $format 日付フォーマット。省略可能。
	 * @return string 数日後の日付
	 */
	function fewDaysLater($date1,$dayCnt,$format='Y-m-d'){
		$u1=strtotime($date1);//UNIXタイムスタンプに変換
		$du = 86400 * $dayCnt;
		$u2 = $u1 + $du;
		$d2=date($format,$u2);//日時フォーマット変換
		return $d2;
	}
	

出力
	指定日:2012-12-1 01:02:03
	数日後:2013-03-11
	


旧式:日時に1時間を加算する例

日時をUNIXタイムスタンプに変換してから加算を行う。
	$d1='2012-12-1 01:02:03';
	$u1=strtotime($d1);//UNIXタイムスタンプに変換
	$h1=3600;//加算する値(1時間=3600秒)
	$u2=$u1 + $h1;//加算
	$d2=date("Y-m-d H:i:s",$u2);//日時フォーマット変換

	//↓出力
	//'$d1=2012-12-1 01:02:03'
	//'$d2=2012-12-01 02:02:03'
	

chaekdate関数の要注意バグ
checkdate実在する日付かどうか調べることができます。
閏年(2/29)にも対応しています。
bool checkdate ( int $month , int $day , int $year )

checkdate関数をemptyで判定するとバグになる
emptyを使った判定には注意が必要です。PHPのバージョンによって動く場合と動かない場合があります。
しかもエラー出力があいまいであり、原因特定に手間がかかってしまいます。
ローカル環境で動くがサーバー環境では動かず原因もよく分からない、という事態になりかねないので、 必ずfalseによる比較を行うようにします。
さくらサーバーではエラーになることを確認済みです。(2015年10月時点)

正しい判定方法
	if(checkdate($month,$day,$year])==false){
		//日付でない場合の処理
	}
	

PHPのバージョンによって動いたり、エラーになったりする危険な判定方法。
	//×危険
	if(empty(checkdate($month,$day,$year])){
		//日付でない場合の処理
	}
	

遷移元URLであるリファラを取得する | $_SERVER['HTTP_REFERER']
遷移元URLであるリファラを取得するコード
$referer=$_SERVER['HTTP_REFERER'];
クロスドメインでもアクセス元のリファラを取得できる。

URLからドメイン、パス、クエリ、ポート番号などを取得する | parse_url
parse_url関数でドメイン、パス、クエリ、ポート番号などを取得できる。
サンプルURL:
http://user_name99:pass_word99@www.example.com:8080/animals/neko?id=99&xx=88#kani
URLの部位名コード取得例
プロトコル名$url_scheme=parse_url($url_a,PHP_URL_SCHEME);http
FQDN(ホスト.ドメイン)$url_host=parse_url($url_a,PHP_URL_HOST);www.example.com(wwwはホスト、example.comはドメイン)
パス$url_path=parse_url($url_a,PHP_URL_PATH);/animals/neko
クエリ$url_query=parse_url($url_a,PHP_URL_QUERY);id=99&xx=88
ポート番号$url_port=parse_url($url_a,PHP_URL_PORT);8080
フラグメント識別子$url_fragment=parse_url($url_a,PHP_URL_FRAGMENT);kani
ユーザー$url_user=parse_url($url_a,PHP_URL_USER);user_name99
パスワード$url_pass=parse_url($url_a,PHP_URL_PASS);pass_word99
サンプル

英数字のランダム文字列を生成する
	/**
	 * 英数字のランダム文字列を生成する
	 * @param $length: ランダム文字数
	 * @return 英数字のランダム文字列
	 */
	function makeRandStr($length) {
		$str = array_merge(range('a', 'z'), range('0', '9'), range('A', 'Z'));
		$r_str = null;
		for ($i = 0; $i <; $length; $i++) {
			$r_str .= $str[rand(0, count($str))];
		}
		return $r_str;
	}
	
ソースコード元:ピグの部屋

ホスト(ドメイン)からハッシュを作成する
遷移元のURLからホストを抜き出しハッシュを生成する。

ソースコード
		$url=$_SERVER['HTTP_REFERER'];//遷移元URLを取得
		$url_host=parse_url($url,PHP_URL_HOST);//ホストを抜き出す。
		$hash = hash('sha256',MD5($url_host));
		
		echo 'URL = '.$url.'<;br>;';
		echo 'HOST = '.$url_host.'<;br>;';
		echo 'HASH = '.$hash.'<;br>;';
	
	URL = http://amaraimusi.sakura.ne.jp/sample/php/index.html
	HOST = amaraimusi.sakura.ne.jp
	HASH = 0cf96c2702ef8e3a1c2369387363f52c78d957875c80ddd305c954ce57192081
	
サンプル

連想配列をインデック型である普通の配列に変換する | array_values
ソースコード
	$ary=array(
		'neko'=>'ネコ',
		'yagi'=>'ヤギ',
		'kani'=>'カニ',
		'same'=>'サメ',
	);
	$ary2=array_values($ary);
	Debugger::dump($ary2);
	
出力→$ary2
	array(
		(int) 0 => 'ネコ',
		(int) 1 => 'ヤギ',
		(int) 2 => 'カニ',
		(int) 3 => 'サメ'
	)