PHP のスニペット集

このページは、PHP のスニペットとユーティリティ関数などをまとめたページです。

目次

注意

  • コードのライセンスは CC0 (クレジット表示不要、改変可、商用可) です。
  • PHP 5.3 前後でもできるだけ使用できるようにシンタックスを調整していますが、一部使えない場合があるかもしれません。

スニペット

filter_input()

$x = filter_input(INPUT_GET, 'x'); // $_GET['x'] を string で取得
$x = filter_input(INPUT_GET, 'x', FILTER_VALIDATE_INT); // $_GET['x'] を int で取得
$x = filter_input(INPUT_GET, 'x', FILTER_VALIDATE_FLOAT);  // $_GET['x'] を float で取得
$x = filter_input(INPUT_GET, 'x', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);  // $_GET['x'] を array で取得

$x = filter_input(INPUT_POST, 'x'); // $_POST['x'] を string で取得
$x = filter_input(INPUT_POST, 'x', FILTER_VALIDATE_INT); // $_POST['x'] を int で取得
$x = filter_input(INPUT_POST, 'x', FILTER_VALIDATE_FLOAT);  // $_POST['x'] を float で取得
$x = filter_input(INPUT_POST, 'x', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);  // $_POST['x'] を array で取得

pathname()

$path = '/path/to/test.txt';
$dir = pathinfo($path, PATHINFO_DIRNAME); // フォルダ名取得 (dirname($path)と同じ))
$basename = pathinfo($path, PATHINFO_BASENAME); // ファイル名取得 (basename($path)と同じ)
$name = pathinfo($path, PATHINFO_FILENAME); // ファイル名(拡張子なし)取得
$ext = pathinfo($path, PATHINFO_EXTENSION); // 拡張子取得
header('HTTP/1.1 404 Not Found'); // 404
header('HTTP/1.1 403 Forbidden'); // 403
header('Location: http://example.com/'); // リダイレクト
header('Content-Type: text/plain'); // テキスト
header('Content-Type: text/html; charset=UTF-8'); // HTML

JSON

エンコード (JSON文字列化)

echo json_encode($data); // 通常
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); // 日本語などのマルチバイト文字をそのまま出力 + 整形

デコード (JSON文字列のパース)

$json = json_decode($jsonString); // オブジェクト (stdClass) で取得
$json = json_decode($jsonString, true); // 連想配列で取得

セッションの設定と開始

<?php

// 設定 (別途定数などを定義しておいて取得)
$sessionLifetime = 14*24*60*60; // セッション有効期限 (秒)。例: 14*24*60*60 = 14日
$sessionUrlPath = '/'; // セッション範囲のURLパス
$sessionSavePath = dirname(__FILE__) . '/tmp'; // セッション保存場所 (レンタルサーバーの場合はGC設定が他ユーザーと競合して意図しない動作になるため特に変更が必要)

// ガベージコレクション(GC)の設定
ini_set('session.gc_maxlifetime', max(ini_get('session.gc_maxlifetime'), $sessionLifetime)); // セッション有効期限より長くします

// セッションクッキーの設定
$cookieParams = session_get_cookie_params();
$lifetime = $sessionLifetime;
$path = $sessionUrlPath;
$domain = $cookieParams['domain'];
$secure = isset($_SERVER['HTTPS']) /*&& $_SERVER['HTTPS'] == 'on'*/; // https の時は true
$httponly = true; // 常に true
session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly);

// セッション保存場所変更
if (!is_dir($sessionSavePath)) @mkdir($sessionSavePath, 0700, true);
session_save_path($sessionSavePath);

// セッション開始
@session_start();

CSVデータ読み込み (簡易)

$buf = file_get_contents('test.csv'); // データ取得 (Shift_JIS前提)
$tmp = tmpfile();
if ($buf !== false && $tmp !== false) {
    fwrite($tmp, mb_convert_encoding($buf, 'UTF-8', 'SJIS-win')); // UTF-8に変換して一時ファイルに書き込み
    rewind($tmp);
    setlocale(LC_ALL, 'ja_JP.UTF-8');
    while (($line = fgetcsv($tmp)) !== false) { // CSV読み込み
        print_r($line); // TODO ここで必要な処理を行います。
    }
    fclose($tmp);
}
  • Shift_JIS のCSVファイルを前提にしています。
  • ファイル全体を読み込んでエンコーディング変換をしているため、大きなファイルには向いていません。

file_get_contents()

file_get_contents() での GET リクエスト (単純な形式)

$responseString = @file_get_contents('http://example.com/?key=value');

file_get_contents() での GET リクエスト (追加設定込み)

$url = 'https://example.com'; // リクエスト先のURL
$query = array( // パラメータ
    'key' => 'value',
);

$context = stream_context_create(array(
    'http' => array(
        'timeout' => 10, // タイムアウトの秒数
    ),
    'ssl' => array(
        'verify_peer'      => false, // リクエスト先が https の場合、証明書検証をしない (環境によって動作しない場合があるため)
        'verify_peer_name' => false, // ピア名検証をしない (同上)
    )
));
$responseString = @file_get_contents($url . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986), false, $context); // 応答データ取得

file_get_contents() での POST リクエスト


$url = 'https://example.com'; // リクエスト先のURL
$query = array( // パラメータ
    'key' => 'value',
);

$context = stream_context_create(array(
    'http' => array(
        'method'  => 'POST', // POST送信
        'header'  => 'Content-Type: application/x-www-form-urlencoded',
        'content' => http_build_query($query, '', '&', PHP_QUERY_RFC3986), // 送信データをセット
        'timeout' => 10, // タイムアウトの秒数
    ),
    'ssl' => array(
        'verify_peer'      => false, // リクエスト先が https の場合、証明書検証をしない (環境によって動作しない場合があるため)
        'verify_peer_name' => false, // ピア名検証をしない (同上)
    )
));
$responseString = @file_get_contents($url, false, $context); // 応答データ取得

cURL

cURL での GET リクエスト

$url = 'https://example.com'; // リクエスト先のURL
$query = array( // パラメータ
    'key' => 'value',
);

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986)); // URL
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // リクエスト先が https の場合、証明書検証をしない (環境によって動作しない場合があるため)
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // curl_exec() 経由で応答データを直接取得できるようにする
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); // 接続タイムアウトの秒数
curl_setopt($curl, CURLOPT_REFERER, 'https://example.com'); // リファラセット (必要な場合)
$responseString = curl_exec($curl); // 応答データ取得(失敗した場合false)
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE); // 応答コード
curl_close($curl);

//$json = ($responseString !== false) ? json_decode($responseString, true) : false; // 連想配列で応答データ取得(応答データがJSONのときに使用します)

cURL での POST リクエスト

$url = 'https://example.com'; // リクエスト先のURL
$query = array( // パラメータ
    'key' => 'value',
);

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url ); // URL
curl_setopt($curl, CURLOPT_POST, true); // POST送信
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($query, '', '&', PHP_QUERY_RFC3986)); // 送信データをセット
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // リクエスト先が https の場合、証明書検証をしない (環境によって動作しない場合があるため)
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // curl_exec() 経由で応答データを直接取得できるようにする
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); // 接続タイムアウトの秒数
curl_setopt($curl, CURLOPT_REFERER, 'https://example.com'); // リファラセット (必要な場合)
$responseString = curl_exec($curl); // 応答データ取得(失敗した場合false)
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE); // 応答コード
curl_close($curl);

暗号化

$method = 'AES-128-CBC'; // 暗号化の種類 (http://php.net/manual/ja/function.openssl-get-cipher-methods.php にあるもの)
$key = 'password'; // 任意のキー(パスフレーズ)
$iv = '1234567890123456'; // 任意の初期化ベクトル。AESの場合16桁。openssl_cipher_iv_length($method) で取得した桁をもとに文字をランダム生成してもよいです

$s = 'テスト'; // 暗号化したい文字列
$encrypted = openssl_encrypt($s, $method, $key, 0, $iv); // 暗号化 (バイナリが必要な場合、 0 の部分を OPENSSL_RAW_DATA にします)
$decrypted = openssl_decrypt($encrypted, $method, $key, 0, $iv); // 復号 ($sと同じ文字列になります。バイナリの復号は 0 の部分を OPENSSL_RAW_DATA にします)

ファイルのダウンロード

<?php
$file = 'モンキー.gif'; // ファイルパス (フォルダパスを含めても可)
$name = mb_substr(mb_strrchr('/' . str_replace('\\', '/', $file), '/'), 1); // (ダウンロードファイル名。basename()だとロケール等によって正常に取得できない場合がある)

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $file = mb_convert_encoding($file, 'SJIS-win', 'UTF-8'); // サーバがWindowsの場合SJISに変換

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode($name)); // エンコード
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));

    while (ob_get_level() > 0) ob_end_clean(); // バッファクリア
    readfile($file);
    exit;
}
?>
  • php.netのサンプル に以下を追加しています。
    • サーバーが Windows の場合ファイルパスを SJIS に変換 (file_exists() が false になるのを防ぐ。プログラムと他のサーバーの文字エンコーディングは UTF-8 想定です)
    • ファイル名が日本語でも対応できるようにする (filename* 形式。IE9以降のブラウザでは基本的に対応されています)
    • 出力バッファ (output_buffering の設定や ob_start()) が有効な場合でもダウンロードができるようにするようにバッファクリアする
      (出力バッファ有効時に容量の大きなファイルを readfile するとダウンロード時に出力バッファが詰まってダウンロードファイルのサイズが0バイトになる)

簡易的なBasic認証

.htaccess で Basic 認証ができない場合(サーバーで制限されている場合等)でBasic認証したいときに使用します。

<?php
// IDとパスワード(平文)を「:」で区切ってセットして下さい。複数IDで認証したい場合は「,」で区切って下さい。
// 例: define('BASIC_AUTH_PASSWORD', 'test:testpw,test2:test2pw');
define('BASIC_AUTH_PASSWORD', 'test:test,test2:test2');
 
function basic_auth() {
    // http://stackoverflow.com/questions/3663520/php-auth-user-not-set
    // CGIモードの場合、.htaccessに下記を記述して下さい (CGIだとPHP_AUTH_**がセットされない)
    //     RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    if (substr(php_sapi_name(), 0, 3) == 'cgi' && isset($_SERVER['HTTP_AUTHORIZATION'])) {
        list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
            explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
    }
 
    $user = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
    $pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
 
    $auth = false;
    $pairs = preg_split('/\s*,\s*/', BASIC_AUTH_PASSWORD);
    foreach ($pairs as $pair) {
        list($u, $p) = preg_split('/\s*:\s*/', $pair);
        if ($user == $u && $pass == $p) {
            $auth = true;
            break;
        }
    }
 
    if (!$auth) {
        header('WWW-Authenticate: Basic realm=\'INPUT USER/PW\'');
        header('HTTP/1.0 401 Unauthorized');
        echo '認証に失敗しました。';
        exit;
    }
}
basic_auth();
?>
以下にBASIC認証後のHTMLなどを記載します。非公開領域に置いたファイルを readfile() してきてもよいです。

QRコード生成

Google Chart APIを利用して簡単にQRコードを生成します。

$size = 300; // QRコードのサイズ(px)
$text = 'https://knooto.info/'; // QRコードに埋め込みたいテキスト
$url = "https://chart.googleapis.com/chart?chs={$size}x{$size}&cht=qr&chl=" . rawurlencode($text); // QRコードのURL
?>
<img src="<?php echo htmlspecialchars($url, ENT_QUOTES) ?>">

ユーティリティ関数

(主にフレームワークなどを使う必要が無い小さなプログラム用の関数です)

htmlspecialchars の簡易版

htmlspecialchars(), echo htmlspecialchars() と打つのが長いため、h(), eh() で呼び出せるようにします。

/**
 * 値をHTMLエスケープします。
 * @param mixed $value 対象文字列
 * @return mixed 変換された文字列
 */
function h($value, $encoding = 'UTF-8') { return htmlspecialchars($value, ENT_QUOTES, $encoding); }
/**
 * 値をHTMLエスケープして出力します。
 * @param mixed $value 対象文字列
 * @return mixed 変換された文字列
 */
function eh($value, $encoding = 'UTF-8') { echo h($value, $encoding); }

リダイレクト

header('Location: ...'); を書く煩わしさを軽減するためのものです。

/**
 * 指定されたパスにリダイレクトします。
 * @param string $url URL
 * @param mixed $args 追加引数 
 */
function redirect($url, $args = null) {
	if (!is_null($args)) {
		$query = http_build_query($args, '', '&', PHP_QUERY_RFC3986); // 追加の引数がある場合、クエリとして追加します。
		$url = $url . '?' . $query;
	}
	header('Location: ' . $url);
	exit;
}

// 例:
// redirect('http://example.com/');
// redirect('http://example.com/', array('param' => 'value'));

JSON出力

/**
 * JSONを出力します。
 * @param mixed $data 出力データ
 * @return void
 */
function echo_json($data){
    header('Content-Type: application/json');
    echo json_encode($data);
}

// 例:
// echo_json(array('a' => 1));

GET リクエスト判定

/**
 * リクエストが GET リクエストか確認します。
 * @return boolean GET の場合 true
 */
function is_get() { return (strtoupper($_SERVER['REQUEST_METHOD']) == 'GET'); }

POST リクエスト判定

/**
 * リクエストが POST か確認します。
 * @return boolean POST の場合 true
 */
function is_post() { (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST'); }

Ajax リクエスト判定

/**
 * リクエストがAjaxのものか確認します。
 * @return boolean Ajaxリクエストの場合 (HTTP_X_REQUESTED_WITHが 'XMLHttpRequest' ※case-insentive) true
 */
function is_ajax(){ return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'; }

HTTPS 判定

/**
 * 現在の通信が https かどうかを確認します。
 * @return boolean 現在の通信が https (SSL/TLS) の場合 true
 */
function is_https() {
    if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') $https = true;
    else if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') $https = true;
    else $https = false;
    return $https;
}

現在のページの URL

/**
 * 現在のページの URL を取得します。
 * @return string URL文字列
 */
function current_url() {
    return 'http' . (is_https() ? 's' : '') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; // is_https() を使います
}

文字エンコーディングの変換

SJIS

/**
 * 文字列を SJIS に変換します。
 *
 * @param string $s 文字列
 * @param string $fromEncoding 文字列のエンコーディング
 * @return mixed 変換後の文字列。失敗した場合は false
 */
function sjis($s, $fromEncoding = 'UTF-8') { return mb_convert_encoding($s, 'SJIS-win', $fromEncoding); }

コンソール出力

/**
 * ChromeのDeveloper Tools等に値を表示します。
 * @param mixed $v 表示したい値
 */
function console($v) { ?><script>console.log(<?php echo json_encode($v) ?>);</script><?php }

// $value = array("id" => 1, "name" => "test");
// console($value);

base64 (URL形式) のエンコード・デコード

/**
 * 指定した data を base64 でエンコードします。URLに含められるよう、"+", "/" は "-", "_" に変換し、不要なパディング("=")は除去します。
 *
 * @param string $data エンコードするデータ。
 * @return string エンコードされたデータを文字列で返します。失敗した場合に FALSE を返します。
 */
function base64url_encode($data) {
	$encoded = base64_encode($data);
	if ($encoded === false) return false;

	return rtrim(strtr($encoded, '+/', '-_'), '='); 
}
/**
 * base64 でエンコードされた data をデコードします。base64url_encode() でエンコードされたデータをデコードするための関数です。
 *
 * @param string $data デコードされるデータ
 * @return string デコードしたデータを返します。失敗した場合に FALSE を返します。
 */
function base64url_decode($data) { 
	return base64_decode(strtr($data, '-_', '+/')); // base64_decode() はパディング("=")を埋めなくてもデコード可能です。
}

ユニークID (UUID v4)

/**
 * ユニークID (UUID v4) を生成します。
 * 
 * @return string RRRRRRRR-RRRR-4RRR-rRRR-RRRRRRRRRRRR 形式の文字列 (R = ランダム、4 = 固定数字 4、r = 0b10RR に相当する16進数文字列)
 */
function uuid_v4() {
    return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff),
        mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
        mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
    );
}

JSON データ取得

/**
 * 指定の URL に GET でリクエストし、JSONを取得します。
 *
 * @param string $url 対象URL
 * @param array $query クエリデータ
 * @param boolean $assoc JSONデータを連想配列で取得する場合 true
 * @return mixed JSONデータ (assoc が true の場合連想配列、false の場合 stdClass)。取得に失敗した場合 false
 */
function json_get($url, $query = array(), $assoc = false) {
    if ($query) $url .= ('?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url); // URL
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // リクエスト先が https の場合、証明書検証をしない (環境によって動作しない場合があるため)
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // curl_exec() 経由で応答データを直接取得できるようにする
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); // 接続タイムアウトの秒数
    $responseString = curl_exec($curl); // 応答データ取得
    curl_close($curl);
    return ($responseString !== false) ? json_decode($responseString, $assoc) : false;
}

バイト数のフォーマット

/**
 * バイト数のフォーマットした値を取得します。(例: 2048 → 2 KB, 1234567 → 1.17737484 MB → 1.18 MB)
 *
 * @param integer $bytes バイト数
 * @param integer $precision 小数点の桁数
 * @return string 結果文字列
 */
function byte_format($bytes, $precision = 2) {
    $units = array('B', 'KB', 'MB', 'GB', 'TB'); // 単位
    $sign = '';
    if ($bytes < 0) { // 負数の場合、正にして計算したのち最後に符号を追加します。
        $bytes = $bytes * -1;
        $sign = '-';
    }
    $exp = min(floor(log($bytes, 1024)), count($units) - 1); // 指数を取得
    if ($bytes != 0) $bytes = $bytes / pow(1024, $exp); // 除算 (KB → bytes / 1024, MB → bytes / 1024^2, GB → bytes / 1024^3, ...)
    return $sign . number_format($bytes, $precision) . ' ' . $units[$exp]; // フォーマット
}

ZIP圧縮

/**
 * 指定ディレクトリまたはファイルをZIP圧縮します。
 *
 * @param string|array $source ZIP圧縮するディレクトリパスまたはファイルパス (複数の場合は配列)
 * @param string $dest ZIPファイルの保存先のパス
 * @return bool 成功した場合 true, 失敗した場合 false
 */
function zip($source, $dest) {
    if ((!is_array($source) && strlen($source) == 0) || (is_array($source) && empty($source)) || strlen($dest) == 0) return false;
    if (!is_array($source)) $source = array($source);
    $zip = new ZipArchive();
    if ($zip->open($dest, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) !== true) return false;
    $result = true;
    foreach ($source as $entry) {
        if (is_dir($entry)) {
            $subEntryArray = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($entry, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
            foreach($subEntryArray as $subEntry){
                $relativePath = substr($subEntry, strlen(dirname($entry)) + 1);
                $added = (is_dir($subEntry)) ? $zip->addEmptyDir($relativePath) : $zip->addFile($subEntry, $relativePath);
                if (!$added) {
                    $result = false; break;
                }
            }
            if (!$result) break;
        }
        else if ($zip->addFile($entry) === false) {
            $result = false; break;
        }
    }
    $result = $zip->close() && $result;
    if (!$result) @unlink($source);
    return $result;
}

// zip('/path/to/dir', 'dir.zip');

簡易ログ

<?php
/** ログの出力先ディレクトリパス */
define('DEBUG_LOG_DIR', './log');
/** ログの保持日数 */
define('DEBUG_LOG_DAYS', 7);
/*
 * 簡易ログを出力します。(例: '[2018-01-01 00:00:00] テスト')
 * @param string $message ログメッセージ
 */
function debug_log($message) {
    $dir = defined('DEBUG_LOG_DIR') ? DEBUG_LOG_DIR : null; // 出力先ディレクトリパスを定数から取得
    if (is_null($dir) || (!is_dir($dir) && !@mkdir($dir))) return false; // 出力先ディレクトリパスが無い・生成できない場合中断

    $days = (defined('DEBUG_LOG_DAYS')) ? DEBUG_LOG_DAYS : 7; // 保持日数を定数から取得
    $logPath = $dir . DIRECTORY_SEPARATOR . date('Ymd') . '.log'; // 例: 20180101.log

    // ログファイルを取得して古いログを削除
    $files = glob($dir . DIRECTORY_SEPARATOR . '*.log');
    $oldLogName = date('Ymd', strtotime("-{$days} day")) . '.log'; // $days = 7 の場合7日前のログ
    foreach ($files as $path) {
        $name = basename($path);
        if (preg_match('#\A[0-9]{8}.log\z#', $name) && $name <= $oldLogName) @unlink($path);
    }
    // ログ出力
    $log = '[' . date('Y-m-d H:i:s') . '] ' . $message . PHP_EOL;
    error_log($log, 3, $logPath);
}

// debug_log('テスト');

WordPress にある checked() の超簡易版

ラジオボタンやチェックボックスの checked (checked="checked") を書く煩わしさを軽減するためのものです。

/**
 * 真になる値の場合、checkedを出力します(ラジオボタン、チェックボックス用)。
 * @param mixed $v
 */
function checked($v) { if ($v) echo ' checked="checked" '; }

// 例: $x の値によってラジオボタンのチェックを変える
// <input type="radio" name="x" value="1" <?php checked($x == 1) ?>>
// <input type="radio" name="x" value="2" <?php checked($x == 2) ?>>
// <input type="radio" name="x" value="3" <?php checked($x == 3) ?>>
  • WordPressの場合、例と同じ形で出力するには checked($x, 1, true)checked($x == 1, true, true) とする必要があります。

WordPress にある selected() の超簡易版

プルダウンの selected (selected="selected") を書く煩わしさを軽減するためのものです。

/**
 * 真になる値の場合、selectedを出力します(select用)。
 * @param mixed $v
 */
function selected($v) { if ($v) echo ' selected="selected" '; }

// 例: $x の値によって<select>のチェックを変える
// <select name="x">
//     <option value="1" <?php selected($x === '1') ?>>1</option>
//     <option value="2" <?php selected($x === '2') ?>>2</option>
//     <option value="3" <?php selected($x === '3') ?>>3</option>
// </select>
  • WordPressの場合、例と同じ形で出力するには selected($x, 1, true)selected($x == 1, true, true) とする必要があります。

HTMLの生成関数

<?php
/**
 * HTMLのタグを生成します。
 * ※ 内部で h() を使用します。
 *
 * @param string $tagName タグ名 (例: 'a')
 * @param mixed $attrs 属性 (例; array('href' => 'http://example.com'), 'href="http://example.com"')
 * @param mixed $content タグの内容 (例; 'test', array( html_tag('strong', null, '強調'), '通常' ))
 * @return string HTMLタグ文字列
 */
function html_tag($tagName, $attrs = null, $content = null) {
    $empty = array('area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'); // https://developer.mozilla.org/en-US/docs/Glossary/Empty_element

    $attrString = '';
    if (is_array($attrs)) foreach ($attrs as $n => $v) $attrString .= ' ' . $n . ($v === true ? '' : '="' . h($v) . '"');
    else $attrString = strlen((string)$attrs) > 0 ? ' ' . (string)$attrs : '';

    if (in_array($tagName, $empty, true)) return '<' . $tagName . $attrString . '>';
    return '<' . $tagName . $attrString . '>' . (is_array($content) ? implode('', $content) : $content) . '</' . $tagName . '>';
}

/**
 * 選択肢の中からユーザーに選択させる部品(プルダウン、チェックボックスリスト、ラジオボタンリスト)を生成するための共通処理です。
 * ※ 内部で html_tag() を使用します。
 *
 * @param string $type 選択肢の種類 ('select', 'checkbox', 'radio')
 * @param mixed $attrs 属性
 * @param array $items 選択肢 (例: array('a', 'b', 'c'), array(1 => '北海道', ...)。配列キーが値、配列値がテキストになります。キーがない場合は値、テキストとも配列値を使用します)
 * @param mixed $selectedItem 選択された項目 (例: 1, array(1, 2))
 * @return string HTMLタグ文字列
 */
function html_select_base($type, $attrs, array $items = null, $selectedItem = null) {
    $selectedItems = array();
    if (is_array($selectedItem)) {
        foreach ($selectedItem as $item) $selectedItems[] = (string)$item;
    }
    else if (strlen((string)$selectedItem) > 0) {
        $selectedItems[] = (string)$selectedItem;
    }

    $itemTags = array();
    $i = 0;
    if (is_array($items)) foreach ($items as $k => $v) {
        $value = ($i !== $k) ? $k : $v;
        $text = $v;

        if ($type == 'select') {
            $itemAttrs = array('value' => $value);
            if (in_array((string)$value, $selectedItems, true)) $itemAttrs['selected'] = 'selected';
            $itemTags[] = html_tag('option', $itemAttrs, $text);
        }
        else {
            if (is_array($attrs)) $itemAttrs = array_merge(array('type' => $type, 'value' => $value), $attrs);
            else if (strlen((string)$attrs) > 0) $itemAttrs = 'type="' . h($type) . '" value="' . h($value) . '" ' . $attrs;

            if (in_array((string)$value, $selectedItems, true)) {
                if (is_array($itemAttrs)) $itemAttrs['checked'] = true;
                else $itemAttrs .= ' checked';
            }
            $itemTags[] = ' ' . html_tag('label', null, array( html_tag('input', $itemAttrs), $text ));
        }
        $i++;
    }

    if ($type == 'select') return html_tag('select', $attrs, $itemTags);
    else return implode('', $itemTags);
}
// <select>
function html_select($attrs, $items = null, $selectedItem = null) {
    return html_select_base('select', $attrs, $items, $selectedItem);
}
// <input type="checkbox">
function html_checkbox_list($attrs, $items = null, $checkedItem = null) {
    return html_select_base('checkbox', $attrs, $items, $checkedItem);
}
// <input type="radio">
function html_radio_list($attrs, $items = null, $checkedItem = null) {
    return html_select_base('radio', $attrs, $items, $checkedItem);
}
// 使用例
$items = array(1 => '北海道', 2 => '青森県', 3 => '岩手県');

echo html_tag('html', null, array(
    html_tag('head', null, array(
        html_tag('meta', 'charset="UTF-8"'),
        html_tag('link', 'rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"'),
        html_tag('title', null, 'テスト用HTML'),
    )),
    html_tag('body', null, array(
        html_tag('div', 'class="container"', array(
            html_tag('div', 'class="card"', array(
                html_tag('div', 'class="card-header"', 'テスト'),
                html_tag('div', 'class="card-body"', array(
                    html_select('name="select1" class="form-control"', $items, 1),
                    html_tag('br'),
                    html_checkbox_list('name="check1[]"', $items, array(2, 3)),
                    html_tag('br'),
                    html_radio_list('name="radio1"', $items, 3),
                    html_tag('script', 'src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js')
                ))
            ))
        ))
    ))
));

PDOの簡易関数

ORMやクエリビルダなどのライブラリを使うまでもない場合に使用するためのPDO(SQL)の関数です。

<?php
/**
 * PDOを生成します。
 * @param array|string $params DSN生成用のパラメータまたはDSN文字列
 * @param string $user DBユーザー名
 * @param string $password DBパスワード
 * @param array $options PDOオプション
 * @return PDO
 */
function pdo($params, $user = null, $password = null, array $options = array()) {
    // DSN文字列指定の場合はそのまま使用
    if (is_string($params)) $dsn = $params;
    // その他の場合はDSN文字列化 (MySQL等)
    else {
        $dsn = strtolower($params['driver']) . ':';
        // SQLite: source にあるファイルパスまたは:memory:をセット
        if ($dsn == 'sqlite:') $dsn .= $params['source'];
        // その他: パラメータを文字列化 (mysql:dbname=testdb;host=localhost 等)
        else foreach ($params as $k => $v) $dsn .= "{$k}={$v};";
    }
    $user = (is_array($params) && isset($params['user'])) ? $params['user'] : $user;
    $password = (is_array($params) && isset($params['password'])) ? $params['password'] : $password;
    return new PDO($dsn, $user, $password, $options);
}
/**
 * クエリ(SELECT, INSERT, UPDATE, DELETE)を実行します。
 * @param PDO $pdo 対象PDO
 * @param string $query SQL文
 * @param array $params SQL文のパラメータ
 * @return PDOStatement
 */
function pdo_query(PDO $pdo, $query, array $params = array()) { $st = $pdo->prepare($query); $st->execute($params); return $st; }
/**
 * クエリ(主にSELECT文)を実行し、結果を配列で取得します。
 * @param PDO $pdo 対象PDO
 * @param string $query SQL文
 * @param array $params SQL文のパラメータ
 * @return array
 */
function pdo_query_all(PDO $pdo, $query, array $params = array()) { return pdo_query($pdo, $query, $params)->fetchAll(); }
/**
 * クエリ(主にSELECT文)を実行し、結果を1行取得します。
 * @param PDO $pdo 対象PDO
 * @param string $query SQL文
 * @param array $params SQL文のパラメータ
 * @return mixed
 */
function pdo_query_one(PDO $pdo, $query, array $params = array()) { return pdo_query($pdo, $query, $params)->fetch(); }
/**
 * クエリ(主にSELECT文)を実行し、結果の先頭行の先頭列の値を1つ取得します。
 * @param PDO $pdo 対象PDO
 * @param string $query SQL文
 * @param array $params SQL文のパラメータ
 * @return mixed
 */
function pdo_query_var(PDO $pdo, $query, array $params = array()) { $row = pdo_query($pdo, $query, $params)->fetch(PDO::FETCH_NUM); return $row ? $row[0] : false; }

/**
 * INSERT文を実行します。(引数からSQLを生成して実行します)
 * @param PDO $pdo 対象PDO
 * @param string $table 対象テーブル名
 * @param array $fields 列名と値を持つ連想配列 (array('id' => 1) 等)
 * @return int
 */
function pdo_insert(PDO $pdo, $table, array $fields) {
    $keys = array_keys($fields);
    $isAssoc = ($keys !== range(0, count($keys)-1));
    $columnInfo = $isAssoc ? ( '(' . implode(', ', $keys) . ')' ) : '';
    $st = $pdo->prepare("INSERT INTO {$table}{$columnInfo} VALUES (" . implode(', ', array_fill(0, count($keys), '?')) . ')');
    $st->execute(array_values($fields));
    return $st->rowCount();
}
/**
 * UPDATE文を実行します。(引数からSQLを生成して実行します)
 * @param PDO $pdo 対象PDO
 * @param string $table 対象テーブル名
 * @param array $fields 列名と値を持つ連想配列 (array('id' => 1) 等)
 * @param string $where WHERE句 ('id = ?', 'id = :id' 等)
 * @param array $params WHERE句のパラメータ (array(1), array('id' => 1) 等)
 * @return int
 */
function pdo_update(PDO $pdo, $table, array $fields, $where = null, array $params = array()) {
    $keys = array_keys($fields);
    $paramKeys = array_keys($params);
    $isParamsAssoc = ($paramKeys !== range(0, count($paramKeys)-1));
    if ($isParamsAssoc) {
        $newFields = array();
        $columnInfo = '';
        foreach ($fields as $k => $v) {
            $newFields['__' . $k] = $v;
            $columnInfo .= ", {$k}=:__{$k}";
        }
        $columnInfo = substr($columnInfo, 2);
        $params = array_merge($newFields, $params);
    }
    else {
        $columnInfo = (implode('=?, ', $keys) . '=?');
        $params = array_merge(array_values($fields), $params);
    }
    $st = $pdo->prepare("UPDATE {$table} SET {$columnInfo}" . ($where ? " WHERE {$where}" : ''));
    $st->execute($params);
    return $st->rowCount();
}
/**
 * DELETE文を実行します。(引数からSQLを生成して実行します)
 * @param PDO $pdo 対象PDO
 * @param string $table 対象テーブル名
 * @param string $where WHERE句 ('id = ?', 'id = :id' 等)
 * @param array $params WHERE句のパラメータ (array(1), array('id' => 1) 等)
 * @return int
 */
function pdo_delete(PDO $pdo, $table, $where = null, array $params = array()) {
    $st = pdo_query($pdo, "DELETE FROM {$table}" . ($where ? " WHERE {$where}" : ''), $params);
    return $st->rowCount();
}
// 使用例

// PDO生成

    $pdo = pdo(array('driver' => 'mysql', 'host' => 'localhost', 'dbname' => 'test', 'user' => 'root', 'password' => 'root', 'charset' => 'utf8'));
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); // オブジェクトでデータ取得
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // エラー時に例外

$pdo->beginTransaction();

$userId = 1;

// CREATE TABLE

    pdo_query($pdo, 'CREATE TABLE IF NOT EXISTS user ( id SERIAL, name VARCHAR(255) )');

// DELETE

    // DELETE FROM user WHERE id IN (1, 2)
    $rowCount = pdo_delete($pdo, 'user', 'id IN (:id, :id + 1)', array('id' => $userId));
    echo '削除件数: ' . $rowCount . PHP_EOL;

// INSERT

    // INSERT INTO VALUES (1, '山田') -- 列名未指定形式
    $rowCount  = pdo_insert($pdo, 'user', array($userId, '山田'));
    // INSERT INTO (id, name) VALUES (2, '鈴木') -- 列名指定形式
    $rowCount += pdo_insert($pdo, 'user', array('id' => $userId + 1, 'name' => '鈴木'));
    echo '挿入件数: ' . $rowCount . PHP_EOL;

// UPDATE

    // UPDATE user SET name = '山田2' WHERE id = 1 -- '?' プレースホルダ形式
    $rowCount  = pdo_update($pdo, 'user', array('name' => '山田2'), 'id = ?', array($userId)); 
    // UPDATE user SET name = '鈴木2' WHERE id = 2 -- ':xxx' プレースホルダ形式
    $rowCount += pdo_update($pdo, 'user', array('name' => '鈴木2'), 'id = :id', array('id' => $userId + 1));
    echo '更新件数: ' . $rowCount . PHP_EOL;

// SELECT (一覧)

    // SELECT * FROM user WHERE IN (:id, :id + 1) -- ':xxx' プレースホルダ形式 ('?' でも可)
    $users = pdo_query_all($pdo, 'SELECT * FROM user WHERE id IN (:id, :id + 1)', array('id' => $userId));
    echo '取得データ(一覧): ' . PHP_EOL;
    echo json_encode($users, JSON_UNESCAPED_UNICODE) . PHP_EOL;

// SELECT (1件)

    // SELECT * FROM user WHERE id = 1 -- '?' プレースホルダ形式 (':xxx' でも可)
    $user = pdo_query_one($pdo, 'SELECT * FROM user WHERE id = ?', array($userId));
    echo '取得データ(1件): ' . PHP_EOL;
    echo json_encode($user, JSON_UNESCAPED_UNICODE) . PHP_EOL;

// SELECT (値)

    // SELECT COUNT(*) FROM user -- パラメータ指定しても可
    $count = pdo_query_var($pdo, 'SELECT COUNT(*) FROM user');
    echo '件数: ' . $count . PHP_EOL;

$pdo->commit();