HOME » 備忘録 » 2017 » PHPの備忘録

PHPの備忘録

ちょっと覚えておいたほうがよさそうな処理などのメモ

作成日時:2017-10-09 / 最終更新:2018-01-16

動作環境のPHPバージョンチェック

バージョンによって処理を変えたい場合に使用。

if (version_compare(PHP_VERSION, '5.0.0', '>=') ) echo "PHPのバージョンは5以上です";

簡易的な処理時間計測

二度目以降の実行にはオペコードキャッシングが効いている可能性があるので、その点を留意する。
コードとしての特定範囲の時間を取得するだけなので、レキサーやパーサーはもちろん、Apacheのモジュールとして展開するなどのオーバーヘッドは計測できない。

$time_start = microtime(true);
	// 計測したい処理
$time = microtime(true) – $time_start;
echo "{$time} 秒";

PHPでシステムコマンドを使用する際に

exec、shell_exec、system、passthru?などはコマンドライン上エラーになった場合は標準エラー出力になるため、返り値がNULLになる。
エラーも取得して内容を文字操作で解析する場合は出力を標準出力に指定する必要がある。

exec('mysqladmin ping 2>&1',$array);
var_dump($array);

// または
$res = shell_exec("mysqladmin ping 2>&1");
echo $res;

// ついでにラッパー
function execute($command, $captureStderr = false){
	$output = array();
	$return = 0;
	if($captureStderr === true)$command .= ' 2>&1';
	exec($command, $output, $return);
	$output = implode("\n", $output);
	return array('output' => $output, 'return' => $return);
}

includeファイルをすべて表示

大きいシステムだとなに読み込んでいるのか追うのがめんどくさいので一気に出力させる

$included_files = get_included_files();
foreach ($included_files as $filename) {
	echo "$filename\n";
}

画面出力できないときに変数をダンプする

ob_start();
	// ダンプしたい変数など
	var_dump($target);
$out = ob_get_contents();
ob_end_clean();
$fp = fopen("/var/www/html/dump.txt", "a+");
fputs($fp, $out);
fclose( $fp );

PDO接続

接続時には必ず例外処理を行う、PHPの設定や仕様変更でエラーが起きた際に接続情報が丸見えになる可能性があるため。
エラーは「PDOException」が投げられるためキャッチしてメッセージのみの出力を行う。

class DB{

	private $dsn;
	private $user;
	private $passwd;
	private $prefix;

	public function __construct($DB_NAME, $DB_USER, $DB_PASS, $MODX_PREFIX) {
		$this->dsn    = 'mysql:dbname=' . $DB_NAME . ';host=localhost;charset=utf8';
		$this->user   = $DB_USER;
		$this->passwd = $DB_PASS;
		$this->prefix = $MODX_PREFIX;
	}

	public function getMODXSettings(){
		try{
			$dbh = new PDO($this->dsn, $this->user, $this->passwd);
			$sql = "SELECT * FROM `{$this->prefix}_system_settings`";
			$sth = $dbh->prepare($sql);
			$sth->execute();//'pre' => $this->prefix  array('tablename'=>'evo')
			//$stmt = $dbh->query($sql);
			$result = $sth->fetchAll(PDO::FETCH_ASSOC);
		}catch(PDOException $e){
			print( 'Connection failed:' . $e->getMessage() . ' / DB->getMODXSettings');
			die();
		}
		// 切断
		$dbh = null;
		return $this->makeResults2Array($result);
	}

	public function makeResults2Array($result){
		for($i=0; $i < count($result); $i++){
			$rs[ $result[$i]['setting_name'] ] = $result[$i]['setting_value'];
		}
		return $rs;
	}
}

CLIからの実行か判定する

コマンドライン上から実行したときとライブラリで呼び出されたときなどで分岐させることができる。
他にも$argv、$argcといった引数をチェックする変数をカウントして分岐する方法も可能かも?

if (php_sapi_name() == 'cli') {
	//CLI上での実行
	echo '実行結果をプレーンテキストで返そうかな';
} else {
	//CLI上での実行でない
	echo '<p>実行結果をHTMLで返そうかな</p>';
}

画像を直接ダウンロードさせる

特典画像など設置した際にダウンロードボタンを使用する際に使う。
「Content-disposition: attachment;」がダウンロードを促す部分になるが、LINEブラウザでは対応していないこともあるので注意。
主要ブラウザはちゃんと解釈してくれます。

$fpath = '/var/www/html/images/gazou.png';// 画像パス
$fname = 'thank-you.png';// ファイル名

header('Content-Length: '.filesize($fpath));
header('Content-Type: image/png');
header('Content-disposition: attachment; filename="'.$fname.'"');
readfile($fpath);
exit();

テンプレートエンジン

配列のvalue変数のキー名をテンプレートファイルから探して値で置換
置換対象はSmartyのように%%string%%で設置できます。

function templateEngine($tplPath, $value) {
	$pattern = '%%(.*)%%/e';
	$replacement_variable = '$value[\'$1\']';
	$template = file_get_contents($tplPath);
	return $output = preg_replace($pattern, $replacement_variable, $template);
}

2重投稿防止

ハッシュ値がすでにセッション中に存在する場合は二重投稿とする

function checkPrevious(){
	foreach ($this->parm as $value) {
		$data .= strval($value);
	}
	$cur_md5 = md5($data);

	if ($_SESSION['prev_md5'] == $cur_md5) {
		return false;
	} else {
		$_SESSION['prev_md5'] = $cur_md5;
		return true;
	}
}

URLにリンク付与

ついでに改行。

$pattern = '/((?:https?|ftp):\/\/[-_.!~*\'()a-zA-Z0-9;\/?:@&=+$,%#]+)/u';
$replacement = '<a href="\1">\1</a>';
$text= preg_replace($pattern,$replacement,$p_text);
echo nl2br($text);

expiresを抽出するだけの処理

誰得。

<?php
$data = <<< EFO
<ifModule mod_expires.c>
  ExpiresActive On
  ExpiresDefault "access plus 1 seconds"
  ExpiresByType image/png "access plus 1 months"
  ExpiresByType image/jpeg "access plus 1 months"
  ExpiresByType image/gif "access plus 1 months"
  ExpiresByType image/x-icon "access plus 1 months"
  ExpiresByType application/x-font-ttf "access plus 1 months"
  ExpiresByType application/x-font-woff "access plus 1 months"
  ExpiresByType application/x-javascript "access plus 1 months"
  ExpiresByType text/javascript "access plus 1 months"
  ExpiresByType text/css "access plus 12 hours"
</ifModule>
EFO;

$reg = '/<ifModule mod_expires\.c>(.*?)<\/ifModule>/si';
if ( !preg_match($reg, $data, $expires) ) return;

$expires_array = explode("\n",$expires[1]);

for($i = 0; $i < count($expires_array); $i++){
	$line_array = explode( " ",trim($expires_array[$i]) );

	switch ($line_array[0]) {
		case 'ExpiresDefault':
			$result['default'] = $line_array[3]
				. rtrim($line_array[4], '"');
			break;

		case 'ExpiresByType':
			$result[] = $line_array[1]
				. ' ' . $line_array[4]
				. rtrim($line_array[5], '"');
			break;

		default:
			break;
	}
}
var_dump($result);