エス技研

WordPress、CakePHP、PHP、baserCMSなどの Web系システムを中心に情報を提供します!


ob_start、ob_get_contents関数でPHPの標準出力をバッファリング・変数に代入

      2017/05/23

標準出力をバッファリングする関数 ob_start()

 

バッファリング関数 ob_start()とは?

 
PHPの出力関数である echoを実行すると、記述してあるそのタイミングで HTMLに標準出力します。
 
echo "出力";
 
HTMLのソースの中に、PHPの記述を書くと、その書いてあるところで処理され、それが「echo」「print_r()」などの標準出力(表示)する関数であればそのまま HTMLに出力されます。
 

<!DOCTYPE html>
<html lang="ja">
<head>
 :
</head>
<body>
 :
<div id="contents">
<?php echo "出力"; ?>
</div>
 :
</body>
</html>

 
上記のような HTMLの場合は、9行目の echoは、9行目の箇所に出力されますが、記述された場所でそのまま出力されることが標準出力ということになります。
 
 
今回紹介する「ob_start()関数」は、この標準出力を出力せずにバッファリングする機能を提供してくれる関数です。
バッファリングした値を「ob_get_contents()関数」を使って変数に代入したり、「ob_end_flush()関数」を使って出力することができます。
また、「ob_start()関数」を使ってバッファリングを開始を宣言したら、「ob_end_clean()関数」を使って終了を宣言する必要があります。
 
 

ob_start()関数の使い方・基本編

 

echo "1";
ob_start();    // バッファリング開始
echo "2";
$buffer = ob_get_contents();    // 変数に代入
echo "3";
$buffer2 = ob_get_contents();    // 変数に代入
echo "4";
ob_end_clean();    // バッファリング終了
echo "5";
echo $buffer;
echo $buffer2;

 
上記のプログラムを実行すると、結果は「15223」となります。
 
最初の「echo」で「1」が出力された後は、「ob_start();」~「ob_end_clean();」の間はバッファリングされるために出力されません。
そして、「5」が出力された後、「ob_get_contents();」で変数「$buffer」「$buffer2」に代入された「2」「23」がそれぞれ出力されます。
 
変数に代入する「ob_get_contents();」を使うことでバッファリングした内容を任意のタイミングで出力することができるようになります。
また、変数に代入しますので、その値を置換したりやさらに値に代入したりすることも可能になります。
 
 


 

ob_start()関数の使い方・応用編

 
応用編として、外部ファイルを読み込む処理について考えます。
 
PHPの処理が記述された HTML+PHPのファイル「setting.html.php」というファイルがあったとして、これを読み込む場合は、下記のように include()関数で読み込みます。
(「include_once()関数」「require()関数」などでも OKです。)
 
include("setting.html.php")
 
ですが、include()関数の場合は、先ほどの echoと同じく、読み込んだところで処理されてしまいます。
そこで登場するのが、「ob_start()関数」なのです。
 

ob_start();
include("setting.html.php");
$buffer = ob_get_contents();
ob_end_clean();

 
上記のような記述をすることで、include()関数で読み込んだ情報は変数「$buffer」に入っていますので、必要に応じて出力をすることができます。
 
 
これを応用することで、下記のように条件分岐させて include()した情報を必要に応じて出力させることもできます。
変数に代入していますので、複数個所に出力する場合にも利用することができます。
 

ob_start();
if ( $a = "a" ) {
  include("setting_a.html.php");
} else {
  include("setting_b.html.php");
}
$buffer = ob_get_contents();
ob_end_clean();

 
 

ob_start()関数の使い方・応用編2

 
ob_start()関数は、callback関数を引数として与えることができます。
下記の例は、ob_start()でバッファリングしたものに対し、str_replace()関数で文字列を置換する処理を実行しています。
同じデザインのテンプレートを、入力フォーム、入力確認画面に置換して利用する、といった使い方もできるのではないでしょうか。
 

<?php
function callback ( $buffer ) {
  // Apple を Google に置換する
  return (str_replace("Apple", "Google", $buffer));
}
ob_start("callback");
?>
<html>
<body>
<p>I like Apple.</p>
</body>
</html>
<?php
ob_end_flush();    // バッファリングを出力する

 
上記を実行すると、下記のように「Apple」が「Google」に置換されて出力されます。
 

<html>
<body>
<p>I like Google.</p>
</body>
</html>

 
その他、callback関数の使い方によっては多様な処理が考えられるでしょう。
 
 

ob_start()関数に関連する関数

 
ここでは、ob_start()、ob_end_clean()、ob_get_contents()、ob_end_flush()を紹介しましたが、その他、下記のような関数もあるようです。
 
 ob_gzhandler():出力バッファを gzip 圧縮するための ob_start コールバック関数
 ob_iconv_handler():出力バッファハンドラとして文字エンコーディングを変換する
 ob_tidyhandler():ob_tidyhandler — バッファを修正するための ob_start コールバック関数
 
 

ob_start()関数は WordPressのショートコードの処理で必要

 
さてさて、なんで ob_start()関数の記事を書いたのか。
 
実は、WordPressのショートコードで処理を作る際にどうしても必要になったのです。
 
ショートコードの処理を作っていく際に、HTMLは当然のように外部に持たせて、その外部ファイルを include()関数で読み込んで....
 
するとどういうことでしょう!!
include()を実行したタイミングで読み込んだ HTMLが出力されるじゃないですか!!
include()関数で読み込んだ値を変数に代入することもできないし...
 
これを解消する方法がこの標準出力をバッファリングしてくれる「ob_start()関数」だったというわけです。
 
WordPressに組み込む解説をした記事は「ob_start、ob_get_contentsを利用しショートコード内でinclude・WordPressプラグイン開発」に書いていますので、WordPressで使う方はこちらの記事も読んでください。
 
と、実は長い長い前ふり記事でした。

 - PHP・Smarty・ECCUBE

最後までお読みいただきましてありがとうございます。
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!

Comment

  1. 松本 より:

    初めまして。
    千葉でエンジニアをしております松本と申します。

    ob_startの使い方について検索していたところこのブログがヒットし、
    基本編のサンプルが非常にわかりやすく、すぐに理解できました。

    このようなわかりやすい例が書いてある技術ブログはなかなかないので
    大変助かりました。

    ありがとうございます。

    • エス技研 より:

      松本さん、コメントありがとうございます。
      「分かりやすい」と言っていただけるとすごく嬉しいですね。
      私自身がネットで探してもよく分からず、悩んだことをなるべく記事にしていこうと思って書いていますが、それが役に立ったということで、すごく嬉しいですね。
       
      今後も分かりやすい記事を書いていこうと思いますので、また見に来てくださいね!

Message

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

下記の空欄を埋めてください。 * Time limit is exhausted. Please reload CAPTCHA.

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

※入力いただいたコメントは管理者の承認後に掲載されます。

  関連記事

PHPで1ヵ月前、先月、今月1日、来月末の日付などの算出はDateTimeImmutableを使う
PHPで1ヵ月前、先月、今月1日、来月末の日付などの算出はDateTimeImmutableを使う

PHPには日時をオブジェクトとして生成する関数「DateTimeImmutable」「DateTime」が用意されている。これを利用して1ヶ月後、月初日、月末日、5日後などを指定して日付を取得できる。

ECCUBEを開発環境から本番ドメインに変更でエラーが・パス変更について

レンタルサーバでサーバ会社から割り当てられたURLで開発し、本番公開時にドメインを当てたらエラーが!そんな場合の対処方法の解説。対処方法は簡単ですが管理画面からは対応不可。

ECCUBEでアップロードできない。upload_max_filesizeを設定する場所

テンプレートをアップロードする際に発生するエラー「テンプレートファイルがアップロードされていません」の対処方法。これはファイル容量の制限に引っかかっています。

路線・駅検索のために緯度経度からPHPで簡易的に距離を計算する処理解説
路線・駅検索のために緯度経度からPHPで2点間の距離を計算する処理解説

路線・駅検索の仕組みの構築は大変。それを簡易に実装するために緯度経度を元に距離計算をする仕組みを考案。まずは2点間の距離を計算する仕組みを解説し、距離計算にまつわる関連技術も紹介。

PHPのcURLでAPIやWebサイトへのアクセス方法。file_get_contentsとの比較
PHPのcURLでAPIやWebサイトへのアクセス方法。file_get_contentsとの比較

PHPからWebサイトにアクセスしてHTMLを取得、APIにアクセスして情報を取得する場合は、cURLがオススメ。file_get_contentsでも可能だがエラー制御に難がありトラブルのもとになる。

配列の値をテキスト表示する際に「、」でつなげるときの処理方法の一例
配列の値をテキスト表示する際に「、」でつなげるときの処理方法の一例

配列の値を「、」でつないで出力する際、単純にforeachで繰り返し処理をすると「イヌ、サル、キジ、」となるが文字列最後の「、」を出力しない方法を3つ解説している。

PHPでスクレイピング。phpQueryとphp-simple-html-dom-parserの比較と設置方法
PHPでスクレイピング。phpQueryとphp-simple-html-dom-parserの比較と設置方法

「PHP スクレイピング」で検索すると「phpQuery」ばかりヒットするが、10年以上も放置されている。なので今も開発が続いている「PHP Simple HTML DOM Parser」をオススメする。

PHP画面が真っ白 header(“Location: $url”);

PHPの開発で header(“Location: $url”);を使うと画面が真っ白になる不具合が出る場合もあります。

連想配列のキーも値もまとめてhtmlspecialchars()でサニタイズする関数の作成解説
連想配列のキーも値もまとめてhtmlspecialchars()でサニタイズする関数の作成解説

PHPの配列・連想配列のキーと値をまとめてhtmlspecialchars()関数でサニタイズ(無害化、無毒化)を行う関数を作成。連想配列のキーはarray_map()関数でのサニタイズは無理。

GMOペイメントゲートウェイのjava.io.IOExceptionのエラー

ECCUBEの決済でGMOペイメントゲートウェイのモジュールを使ってテスト決済を行った場合の不具合、java.io.IOExceptionと言うエラーの原因と対策方法の解説です。


Warning: Trying to access array offset on null in /home/ss-giken/s-giken.net/public_html/blog/wp-content/plugins/amazonjs/amazonjs.php on line 637