ソースコードで学ぶWebプログラミング

PHPでデータを取得する6つの方法

Webプログラムをライフサイクルで見た場合、処理内容を3つに分類できます。

Webプログラムのライフサイクル

・入力データの受取 ・データの変換 ・データの出力処理

これはWebサイトでの処理が「ブラウザからの入力」「出力するデータの作成」「データの出力」で構成されるためです。 このページでは主にブラウザや保存データからの「入力データの受取」を習得できるように解説します。

ここでの「入力データ」とはユーザーがブラウザから主体的に送信したデータだけではなく、 ブラウザにレスポンスとして返す「表示データ」を準備するために、プログラムの変数へと代入するすべての「入力データ」を対象とします。

「スーパーグローバル変数」から受け取る

PHPでは、Webプログラミングで必要となる入力データなどが自動的に変数に入力されています。 これはプログラムのどこでも利用できる「スーパーグローバル変数」と呼ばれる連想配列に入っています。

PHPの主なスーパーグローバル変数

$_GET $_POST S_SERVER $_COOKIE $_FILES $_SESSION

スーパーグローバル変数は連想配列なので、キーとなる文字列で値を取り出せます。 連想配列からキーで取得する時、キーが存在しないとエラーが出るためisset()、empty()などでチェックする必要があります。

<?php /* GET送信の受取 */ //$value には「名前」が入っている $value = isset($_GET['name']) ? $_GET['name']: ''; ?> <form method="get"> <input type="text" name="name" value="名前"> <input type="submit" value="送信"> </form> <?php /* POST送信の受取 */ //$value には「名前」が入っている $value = isset($_POST['name']) ? $_POST['name']: ''; ?> <form method="post"> <input type="text" name="name" value="名前"> <input type="submit" value="送信"> </form>

「isset() ? : ;」の部分は「三項演算子」と呼ばれるもので、条件文を簡潔に表現できます。 「条件式 ? 式A: 式B;」の構成で、条件式が true の時、式Aが返され、false の時、式B が返されます。 今回は連想配列にキーがある時、その値が返され、ない時、空欄が返されます。

一つの変数を受け取るたびに isset() でチェックするコードは面倒なので、関数化しておくと便利です。

/* キーでGET入力の値を返す */ function gGET($key){ return isset($_GET[$key]) ? $_GET[$key]: ''; } /* キーでPOST入力の値を返す */ function gPOST($key){ return isset($_POST[$key]) ? $_POST[$key]: ''; } /* キーでSERVERの値を返す */ function gSERVER($key){ return isset($_SERVER[$key]) ? $_SERVER[$key]: ''; } /* キーでCOOKIEの値を返す */ function gCOOKIE($key){ return isset($_COOKIE[$key]) ? $_COOKIE[$key]: ''; } /* キーでSESSIONの値を返す */ function gSSN($key){ return isset($_SESSION[$key]) ? $_SESSION[$key]: ''; }

$_SERVERにはサーバ情報やページアクセス時の環境情報が入っています。 ほぼ固定のキーで取得できますが、まれにサーバによってキーが存在しない事があります。

/* ユーザのIPアドレス */ $ip = $_SERVER['REMOTE_ADDR']; /* メソッド名 GET POST など */ $method = $_SERVER['REQUEST_METHOD']; /* URLの?以降 */ $query = $_SERVER['QUERY_STRING']; /* ブラウザ情報 */ $ua = $_SERVER['HTTP_USER_AGENT']; /* スクリプトのパスと名前 */ $script_path = $_SERVER['SCRIPT_NAME']; /* 動作サーバのIPアドレス */ $sip = $_SERVER['SERVER_ADDR'];

$_FILESには、サーバへアップロードされたファイル情報が入力されています。 アップロードされた実ファイルはサーバに一時ファイルとして保存されています。 PHPでのファイルアップロード処理については、別記事で詳しく解説しているので、そちらを参考にして下さい。

▼参考記事
データ「csvファイル」を受け取る

$_SESSIONは、session_start()でセッションを開始した場合にのみ、入力されています。 セッションとは、ユーザがサイト上で別のページに移動した時などに、情報を保持したまま再利用できるように するためのものです。ログイン状態や一旦、確認画面を表示する時などに利用されます。

<?php /* セッション開始 */ session_start(); /* POST送信の時 */ if ($_SERVER['REQUEST_METHOD']=='POST') { /* POSTデータをセッションデータに */ $_SESSION['post'] = $_POST; } else { /* セッションにあるPOSTデータを受け取り */ $post = $_SESSION['post']; }

入力の受け取りについてもっと詳しく

ここまでは、キーで値を取得して処理を行っていく想定となっていますが、 一連の処理パターンを作成しておいて、一括して処理させる方法もあります。 フレームワークのモデルなどが該当します。

/* フレームワークの場合 */ /* $DBは、$_POSTのキーリストを保持、入力チェックパターンを持つ */ $data = $DB->validate($_POST); /* $DBは、$_POSTのキーリストを保持、保存処理を行う */ $DB->set($_POST);

コードを理解するには、初心者には難しい前提事項が含まれています。 このページはWebプログラミングの基礎力を付けるためのページなので、 入力データを一括して処理させる方法もある事だけ理解しておいて下さい。

参考程度にコード内容を説明します。 「->」はクラスのメンバを呼び出していて、上ではメソッドを実行しています。 クラスとは、オブジェクト指向の仕組みで、一連の処理パターンが実装されたものです。 メソッドとは、クラス内に定義された関数です。 オブジェクト指向とは、処理を担当するオブジェクトを作成し、 後はオブジェクトに指示をするだけの状態にするコーディング方法と言えます。

「ファイル」から受け取る

ブラウザにレスポンスとして返す「表示データ」には、サーバに保存済のファイルなどもあります。

<?php /* 入力元となるデータファイル */ define('FILE_DATA','bbs.dat'); /* 代入する変数 */ $lines = array(); /* ファイルからデータを一行ずつ受け取る */ $fp = fopen(FILE_DATA,'r'); while($line = fgets($fp)){ $lines[] = $line; } fclose($fp); /* ファイルからデータを一括で受け取る */ $data = file_get_content(FILE_DATA); /* ファイルからデータを配列で受け取る */ $lines = file(FILE_DATA);

「データベース」から受け取る

PHPで開発されたWebアプリケーションでは、主にMySQLPostgreSQLSQLiteなどのデータベースが 利用されています。データベースは基本的にプログラムが動作しているサーバで起動している必要があります。多くのレンタルサーバでは データベースも稼働しており、データベース接続が可能です。

<?php /* MySQLに接続 */ /* ホスト名設定 */ define('DB_HOST', 'localhost'); /* データベース名 */ define('DB_NAME', ''); /* 接続ユーザー名 */ define('DB_USER', ''); /* 接続パスワード */ define('DB_PASS', ''); /* エラーを代入する変数 */ $ERROR = array(); /* 接続エラーを取得するための記述 */ try { /* データベース操作用のオブジェクトを作成 */ $db = new PDO('mysql:dbname='.DB_NAME.';host='.DB_HOST.';charset=utf8', DB_USER, DB_PASS); /* データベースを操作するSQL文 */ $sql = 'SELECT * FROM posts WHERE category_id=?'; /* SQL文として渡す入力データ */ $q = array('100'); /* SQL文を実行するための準備 */ $sth = $db->prepare($sql); /* SQL文を実行 */ $sth->execute($q); /* データベースからの結果を連想配列の配列で受け取る */ $r = $sth->fetchAll(PDO::FETCH_ASSOC); /* 接続エラーの例外を処理 */ } catch(PDOException $e) { $ERROR[] = $e->getMessage(); }

やっている事

・define() で接続に必要なデータベース設定を定義 ・try{}catch(){} で例外を処理 ・new PDO() でMySQL接続の設定、操作オブジェクトを作成 ・->prepare() でプリペアドステートメントを準備 ・->execute() で入力用の配列でSQL文を実行 ・->fetchAll(PDO::FETCH_ASSOC) SQL文の実行結果を受け取り ・$e->getMessage() で例外メッセージを取得

SQLとは、データベース言語のことで、データベースの操作内容を記述したものです。 主にデータベースのテーブル作成(CREATE)、テーブル削除(DROP)、レコード取得(SELECT)、 レコード挿入(INSERT)、レコード更新(UPDATE)、レコード削除(DELETE)などがあります。

上のコードでは postsテーブル から category_id が 100 のレコードを取得しています。 ->prepare() に渡すSQL文には、ユーザーの入力などを直接入れないように置き換えを前提として「?」を記述します。 置き換える入力データは配列で、->execute() に渡して実行します。 この時、「?」の数と配列の個数が異なるとエラーとなります。

データベース処理は、セキュリティ上問題となる事がありますが、->prepare() を使うことで SQLインジェクション対策に必要なエスケープ処理が自動的に行われます。

/* ユーザーの入力がないSQL文 */ $sql = 'SELECT * FROM categories'; /* SQL文の実行と結果の受け取り */ $r = $db->query($sql, PDO::FETCH_ASSOC); /* 結果の受け取りが必要ない場合 */ $db->exec('DELETE FROM logs');

エスケープ処理が必要のない固定のSQL文を実行する場合は、->query()や->exec() を使用します。

/* SQL文の実行エラーを表示確認 */ print_r($db->errorInfo()); /* 変数に入れる場合 */ $ERROR[] = print_r($db->errorInfo(),true);

エラー情報は、->errorInfo() で取得することができます。 デバッグ用の画面にて、表示確認を行うか、ファイルに保存して後で確認する方法もあります。

/* 直前にINSERTされたレコードのIDを受け取る */ $id = $db->lastInsertId();

データベースに新規登録したレコードのIDは、->lastInsertId() で取得できます。IDとは、データベースのテーブル内で 一意にレコードを識別できる情報で、オートインクリメントなどが該当します。

インターネット上の「外部URL」から受け取る

同一サイト内でも可能ですが、URLへアクセスを行ってデータを取得することが出来ます。 通常のWebページやAPIのエンドポイントなどへのアクセスが一般的です。

<?php /* URL情報 */ $url = ''; /* URLにGETアクセス */ $data = file_get_contents($url); /* アクセス時の設定を行ってアクセス */ $opts = array( 'http'=>array( 'method'=>'POST', 'header'=>"Cookie: key=val\r\n", ) ); $data = file_get_contents($url, false, stream_context_create($opts)); /* レスポンスのヘッダー確認 */ print_r($http_response_header);

さらに詳細設定を行ってアクセスしたい場合は、curl() が利用できます。これは別記事で詳しく説明しているので、 そちらを参考にして下さい。

▼参考記事
データ「Webサイトレスポンス」を受け取る

「メモリ」から受け取る

ファイルやデータベースへのアクセスが重い時などに、キャッシュ化対策として、メモリ上にデータを保存しておく方法があります。 APC 関数を利用しますが、サーバ環境によっては使用できない事があります。

<?php /* 識別ID URLなどの一意の文字列 */ $id = ''; /* データの存在確認 */ if (apc_exists($id)) { /* キャッシュから取得 */ $data = unserialize( apc_fetch($id) ); } else { /* ここで重い処理を行う */ /* 重い処理の結果、$dataの連想配列にデータが入っている想定 */ $data = array(); /* 変数を有効期限までキャッシュ */ apc_store($id, serialize($data), 3600); } /* ここで $data の表示処理 */ /* 共有メモリの状態を確認する場合 */ print_r(apc_sma_info());

キャッシュは有効期限が切れるまで表示され続けます。プログラムの更新を行った際にキャッシュも更新したい場合は、 コードでキャッシュを削除します。

/* キャッシュをすべてクリアする場合 */ apc_clear_cache(); /* 特定のキャッシュを削除する場合 */ apc_delete($id);

キャッシュ目的ではなく、ディスクアクセスをせずに高速処理を目的としてメモリを利用することも出来ます。

/* ファイルを作成せず、メモリ上で処理したい場合 */ $fp = fopen('php://memory','r+'); /* ファイルデータとして処理 */ /* メモリが解放される */ fclose($fp);

「標準関数」から受け取る

標準関数とは、標準状態で利用可能な関数です。特にライブラリ読込やインストールなどを行わなくても 使える関数で、レスポンスとして利用できる関数をまとめます。

<?php /* タイムゾーンを設定 */ date_default_timezone_set('Asia/Tokyo'); /* 日時の受け取り */ $date = date('Y/m/d H:i:s');//年/月/日 時:分:秒 /* Unixタイムスタンプを取得 */ $time = time(); /* Unixタイムスタンプをマイクロ秒まで取得 */ list($msec, $sec) = explode(' ', microtime());//$msec にマイクロ秒 /* ファイルの更新日時 */ $mtime = filemtime($f); /* ファイルサイズ */ $size = filesize($f); /* ファイルタイプ */ $ftype = mime_content_type($f); /* ファイルのmd5ハッシュ値を取得 */ $md5 = md5_file($f); /* 一意の英数字を取得 */ $id = uniqid(); /* 文字列の長さ バイト数 */ $len = strlen($txt); /* 文字列の長さ 文字数 */ $len = mb_strlen($txt); /* 文字列のmd5ハッシュ値を取得 */ $md5 = md5($str); /* ランダムな数値 1-100 */ $r = mt_rand(1, 100); /* コマンドの実行結果 例として df は空き容量確認 */ exec('df -h', $o); /* 実行結果の確認 */ print_r($o); /* 指定ディレクトリ内のファイル一覧 */ $files = scandir($dir);