コンテンツにスキップ

PHP Web基礎

PHPのWeb関連の記法をメモ。

1. WEBの値の受け渡し

1.1. GETメソッド

if (!empty($_GET['name'])){
    $val = $_GET['name'];
}

1.2. POSTメソッド

if (!empty($_POST['name'])){
    $val = $_POST['name'];
}

2. 入力フォームのセキュリティ実装

2.1. XSS対策

htmlspecialchars関数

入力フォームのサニタイズを行う関数。

function ($str){
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

クリックジャッキング対策

クリックジャッキング対策に使用できる関数。

header('X-FRAME-OPTIONS:DENY');

2.2. CSRF対策

SESSIONによるトークンで識別

SESSIONによるセッションが残る性質を利用したもの

session_start();

if(!isset($_SESSION['csrtToken'])){
    $csrfToken = bin2hex(random_bytes(32));
    $_SESSION['csrtToken'] = $csrfToken;
}
$token = $_SESSION['csrtToken']; //$tokenを<input hidden>で転送する
<?php if($_POST['csrf'] === $_SESSION['csrtToken'])>
<?php endif; >
//session放棄
unset($_SESSION['csrtToken']);

2.3. バリテーション

フロントエンド/バックエンド両方でバリテーションが必要になる。

function validation($request){
    $errors = [];

    if(empty($request['value'] || 20 < mb_strlen($request['value']))){
        $ errors[] = "この値は必須です";
    }

    if(!isset($request['value2'] || 20 < mb_strlen($request['value']))){ //emptyは0でtrueになるため
        $ errors[] = "この値は必須です";
    }

    // Email
    // https://www.php.net/manual/ja/function.filter-var.php
    if(empty($request['value3'] || !filter_var($request['value3'], FILTER_VALIDATE_EMAIL))){ 
        $ errors[] = "この値は必須です";
    }

    // URL
    // https://www.php.net/manual/ja/function.filter-var.php
    if(!filter_var($request['value3'], FILTER_VALIDATE_URL)){ 
        $ errors[] = "この値は必須です";
    }

    return $errors;
}

3. ベーシック認証

.htaccess.htpasswdで設定を行う。

htaccessは以下。

AuthType Basic
AuthName "IDとパスワードを入力してください"
AuthUserFile <.htpasswdのパス>
require valid-user

htpasswdは以下。

admin:<ハッシュ化したパスワード>

サンプルファイル

<?php
    echo __File__;

    echo '<br>';

    echo(password_hash('password', PASSWORD_BCRYPT0));
>

4. ファイル操作

4.1. ファイル名操作型

file_get_contents関数

ファイルの中身を丸ごと読み込める関数。

$file = 'ファイル名'

$fileContents = file_get_contents($file);

file_put_contents関数

$file = 'ファイル名'

# ファイルの上書き
$fileContents = file_put_contents($file, "書き込み");
# ファイルの追記
$fileContents = file_put_contents($file, "書き込み", FILE_APPEND);
# 区切り文字で追記
$allData = file($contactFile); // テスト1, テスト2, テスト3

foreach($allData as $lineData){
    $lines = explode(',', $lineData);
    echo $lines[0]. '<br>';
    echo $lines[1]. '<br>';
    echo $lines[2]. '<br>';
}

4.2. ストリーム型

ストリーム型のファイル操作の流れは以下の通り。

  1. ファイルを開く(fopen関数(r,w,a))
  2. 排他ロック(flock関数)
  3. 読み込み/書き込み/追記(fgets/fwrite関数)
  4. 閉じる(fclose関数)

fopen関数

ファイルの操作を準備する関数。

https://www.php.net/manual/ja/function.fopen

fclose関数

ファイル操作を終了する関数。

https://www.php.net/manual/ja/function.fwrite

fgets関数

https://www.php.net/manual/ja/function.fgets.php

fwrite関数

文字列をファイルに書き込む関数。

https://www.php.net/manual/ja/function.fwrite.php

4.2. オブジェクト型

大量のファイルを読み込む際に便利な関数。

SpFileObject関数

5. データべースとの接続/連携

5.1. データベースとの接続方法

PHP7.0系は2種類ある。

  • PDOの使用
  • Mysqliの使用

PDO(PHP Data Object)の使用

DBの接続処理を記述。

<?php
const DB_HOST = 'mysql:dbname=test_php;host=127.0.0.1;charset=utf8';
const DB_USER = 'user';
const DB_PASSWORD = 'password';

//DBがつながっているかな繋がっていないか
try{
    $pdo = new PDO(DB_HOST, DB_USER, DB_PASSWORD, [
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, //連想配列に格納
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //例外を表示する
        PDO::ATTR_EMULATE_PREPARES => false, //SQLインジェクション対策
    ]);
    echo '接続成功';

} catch(PDOException $e){
    echo '接続失敗' . $e->getMessage() . '\n';
    exit();
}

?>

5.2. SQLの使用とトランザクション

SQLによるREAD処理

// ユーザ入力なし (query)
$sql = 'SELECT * FROM CONTACTS WHERE ID = 4';
$stmt = $pdo->query($sql); //sqlのステートメント

$result = $stmt->fetchall();

//ユーザ入力あり (prepare,bind, execute)
$sql = 'SELECT * FROM CONTACTS WHERE ID = :id'; //プレースホルダ
$stmt = $pdo->prepare($sql); //プリペアードステートメント
$stmt->bindValue('id', 4, PDO::PARAM_INT); //入力値の紐づけ
$stmt->execute(); //実行

$result = $stmt->fetchall();

SQLによるCREATE処理

$params = [
        'id' => null,
        'your_name' => "山田太郎",
        'age' => '2',
        'created_at' => null
];

$count = 0;
$columns = '';
$values = '';

foreach(array_keys($params) as $key){
    if($count++ > 0){
        $columns .= ',';
        $values .= ',';
    }
    $columns .= $key;
    $values .= ':'.$key;
}

$sql = 'INSERT INTO CONTACTS ('. $columns .') VALUES ('.$values.')'; //プレースホルダ
$stmt = $pdo->prepare($sql); //プリペアードステートメント
$stmt->execute($params); //実行

トランザクション

トランザクションはまとまった処理を行う際必要になる処理。 うまくいかないときはロールバックで戻す。

$pdo->beginTransaction();

try {
    // =======================
    // sql処理をここに記述
    // =======================

    $pdo->commit();

} catch (PDOException $e){
    $pdo->rollback(); //DB更新のキャンセル
}

6. クッキーとセッション

簡単なCookieとSessionの違いは以下の通り。

項目 特徴 保存場所
Cookie パスワード保存はNG クライアント側(ブラウザ)
Session セッション認証やCSRF対策に使用 サーバ側

6.1. セッション

# セッションの開始
session_start();

# セッションの破棄
$_SESSION = [];

session_destroy();

6.2. クッキー

# クッキーのセット
setcookie('キー', 'value', '有効期限', '/');
// setcookie('key', 'value', 'time() - 1800', '/');

# クッキーの破棄
if(isset($_COOKIE['PHPSESSID'])){
    setcookie('PHPSESSID', '', time() - 1800, '/');
}