PHP のスニペット集

このページは、PHP のスニペットをまとめたページです。

注意

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

ダウンロード

<?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() してきてもよいです。

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); // 拡張子取得

暗号化

$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 にします)

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); }

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) とする必要があります。

リダイレクト

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

/**
 * 指定されたパスにリダイレクトします。
 * @param string $url URL
 * @param mixed $args 追加引数 
 */
function redirect($url, $args = null) {
	if (!is_null($args)) {
		$query = http_build_query($args, '', '&'); // 追加の引数がある場合、クエリとして追加します。
		$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));

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";
}

コンソール出力

/**
 * 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);

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();