ヘッダーをスキップ
Oracle Database 2日でPHP開発者ガイド
11g リリース2(11.2)
B56267-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

7 イメージのロード

この章では、新しい従業員レコードのJPEGイメージをアップロードして「Employees」ページに表示するためにアプリケーションを変更する方法について説明します。内容は次のとおりです。

BLOBを使用した従業員イメージの保存およびロード

この項では、従業員のレコードに写真を格納できるようにアプリケーション・コードを変更します。

従業員レコードに従業員のイメージを格納できるようにするには、次の手順を実行します。

  1. chap7ディレクトリを作成し、chap6からアプリケーション・ファイルをコピーし、新しく作成したディレクトリに移動します。

    Windowsの場合:

    mkdir c:\program files\Apache Group\Apache2\htdocs\chap7
    cd c:\program files\Apache Group\Apache2\htdocs\chap7
    copy ..\chap6\* .
    

    Linuxの場合:

    mkdir $HOME/public_html/chap7
    cd $HOME/public_html/chap7
    cp ../chap6/* .
    
  2. SQL Developerを起動し、HRサンプル・スキーマへの接続をオープンします。

  3. hrユーザーとしてHRサンプル・スキーマにログインします。

  4. SQLワークシートを開き、次のCREATE TABLE文を入力して、従業員イメージを格納するための新しい表を作成します。

    CREATE TABLE employee_photos(
      employee_id        NUMBER,
      employee_thumbnail BLOB);
    
    chap7_hrcreatetable.gifの説明が続きます。
    chap7_hrcreatetable.gifの説明

  5. HRユーザーがこのコマンドを実行するには、CREATE TABLE権限が必要です。「insufficient privileges」エラー・メッセージが戻された場合は、HRユーザーとしてログアウトしてから、systemとしてログインし、次のGRANTコマンドを実行します。

    GRANT create table TO hr;
    

    次に、再度HRとしてログインして、CREATE TABLE文を実行します。

  6. anyco_ui.incファイルを編集します。 ui_print_employees()関数のEMPLOYEES表に「Photograph」列を追加します。

    <th>Commission<br>(%)</th>
    <th>Remuneration</th>
    <th>Photograph</th>
    

    「Photograph」列のデータは、<img>タグ付きで移入されます。このタグでは、src属性が新しいanyco_im.phpファイルへのURL参照として定義されているため、従業員レコードごとにイメージが表示されます。

  7. anyco_ui.incファイルを編集します。 ui_print_employees()関数に、従業員IDをパラメータとして指定して、anyco_im.phpファイルを参照する<img>タグを生成するコードを追加します。

    echo '<td align="right">'
         .htmlentities($emp['REMUNERATION']).'</td>';
    echo '<td><img src="anyco_im.php?showempphoto='.$emp['EMPLOYEE_ID']
         .'" alt="Employee photo"></td>';
    
  8. anyco_ui.incファイルを編集します。 新しい従業員レコードの作成時にイメージをアップロードできるようにするには、ui_print_insert_employee()関数の<form>タグにenctype属性を追加します。

    <form method="post" action="$posturl" enctype="multipart/form-data">
    

    フォームの下部にアップロード用のフィールドを追加し、その入力タイプをfileに設定します。

    <tr>
      <td>Commission (%)</td>
      <td><input type="text" name="commpct" value="0" size="20"></td>
    </tr>
    <tr>
      <td>Photo</td>
      <td><input type="file" name="empphoto"></td>
    </tr>
    
  9. anyco_im.php fileファイルを作成します。 このファイルは、URLパラメータとして従業員IDをとり、その従業員レコードの「Photograph」列からイメージを読み取り、表示するサムネイル・イメージを戻します。

    <?php    // anyco_im.php
    
    require('anyco_cn.inc');
    require('anyco_db.inc');
    construct_image();
    
    function construct_image()
    {
      if (!isset($_GET['showempphoto'])) {
        return;
      }
    
      $empid = $_GET['showempphoto'];
    
      $conn = db_connect($err);
    
      if (!$conn) {
        return;
      }
    
      $query =
        'SELECT employee_thumbnail
         FROM   employee_photos
         WHERE  employee_id = :eid';
    
      $stid = oci_parse($conn, $query);
      $r = oci_bind_by_name($stid, ":eid", $empid, -1);
      if (!$r) {
        return;
      }
      $r = oci_execute($stid, OCI_DEFAULT);
      if (!$r) {
        return;
      }
    
      $arr = oci_fetch_row($stid);
      if (!$arr) {
        return;                     // photo not found
      }
    
      $result = $arr[0]->load();
    
      // If any text (or whitespace!) is printed before this header is sent,
      // the text is not displayed. The image also is not displayed properly.
      // Comment out the "header" line to see the text and debug.
      header("Content-type: image/JPEG");
      echo $result;
    }
    
    ?>
    

    construct_image()関数は、OCI-Lob->load()関数を使用して、イメージ・データであるOracle LOBデータを取り出します。 PHPのheader()関数は、HTTPレスポンス・ヘッダーにMIMEタイプを設定して、ブラウザがデータをJPEGイメージとして認識できるようにします。

    他のイメージ・タイプを表示する場合は、そのタイプに応じてContent-typeを変更する必要があります。

  10. anyco_db.incファイルを編集します。 EMPLOYEE_PHOTOS表にイメージを挿入する新しい関数db_insert_thumbnail()を追加します。

    function db_insert_thumbnail($conn, $empid, $imgfile, &$e)
    {
      $lob = oci_new_descriptor($conn, OCI_D_LOB);
      if (!$lob) {
        $e = db_error($conn, __FILE__, __LINE__);
        return false;
      }
    
      $insstmt =
        'INSERT INTO employee_photos (employee_id, employee_thumbnail)
         VALUES(:eid, empty_blob())
         RETURNING employee_thumbnail into :etn';
    
      $stmt = oci_parse($conn, $insstmt);
      $r = oci_bind_by_name($stmt, ':etn', $lob, -1, OCI_B_BLOB);
      if (!$r) {
        $e = db_error($stid, __FILE__, __LINE__);
        return false;
      }
      $r = oci_bind_by_name($stmt, ':eid', $empid, -1);
      if (!$r) {
        $e = db_error($stid, __FILE__, __LINE__);
        return false;
      }
      $r = oci_execute($stmt, OCI_DEFAULT);
      if (!$r) {
        $e = db_error($stid, __FILE__, __LINE__);
        return false;
      }
    
      if (!$lob->savefile($imgfile)) {
        $e = db_error($stid, __FILE__, __LINE__);
        return false;
      }
      $lob->free();
    
      return true;
    }
    

    新しいEMPLOYEE_PHOTOS表とEMPLOYEES表を結び付けるには、両方の表で同じ従業員IDを使用する必要があります。

  11. anyco_db.incファイルを編集します。 OUTバインド変数値がデータベースから戻されるように、db_execute_statement()関数の$bindvarsパラメータを&$bindvarsに変更します。 この関数の下部に、戻されたバインド変数値を設定するループを追加します。

    function db_execute_statement($conn, $statement, &$e, &$bindvars = array())
    {
      ...
      $r = @oci_execute($stid);
      if (!$r) {
        $e = db_error($stid, __FILE__, __LINE__);
        return false;
      }
      $outbinds = array();
      foreach ($bindvars as $b) {
        $outbinds[$b[0]] = $$b[0];
      }
       $bindvars = $outbinds;
       return true;
    }
    
  12. anyco.phpファイルを編集します。バインド変数:neweidに新しい従業員IDが戻されるように、insert_new_emp()関数のINSERT文を変更します。 この値がイメージとともに新しいEMPLOYEE_PHOTOS表に挿入されます。

    $statement =
      'INSERT INTO employees
                   (employee_id, first_name, last_name, email, hire_date,
                   job_id, salary, commission_pct, department_id)
       VALUES (employees_seq.nextval, :fnm, :lnm, :eml, :hdt,
              :jid, :sal, :cpt, :did)
       RETURNING employee_id into :neweid';
    

    また、insert_new_emp()関数で、array_push()関数へのコールを追加して、新しいバインド変数NEWEIDarray_push()コールのリストの最後に設定します。

    array_push($bindargs, array('CPT', $newemp['commpct'], -1));
    array_push($bindargs, array('DID', $newemp['deptid'], -1));
    array_push($bindargs, array('NEWEID', null, 10));
    

    NEWIDの値はINSERT文のRETURNING句で取り出されるため、その初期値はNULLに設定します。長さは、戻り値に十分な桁を確保するために10に設定します。

  13. anyco.phpファイルを編集します。insert_new_emp()関数で、db_execute_statement()コールとconstruct_employees()コールの間にサムネイル・イメージを挿入するコールを追加します。

    $r = db_execute_statement($conn, $statement, $err, $bindargs);
    if ($r) {
      $r = db_insert_thumbnail($conn, $bindargs['NEWEID'],
                               $_FILES['empphoto']['tmp_name'], $e);
      construct_employees();
    }
    
  14. ブラウザに、次のアプリケーションURLを入力します。

    Windowsの場合:

    http://localhost/chap7/anyco.php
    

    Linuxの場合:

    http://localhost/~<username>/chap7/anyco.php
    
  15. 「Departments」ページで、「Show Employees」をクリックして「Employees」ページにナビゲートします。

    chap7_loadimg_005.gifの説明が続きます。
    chap7_loadimg_005.gifの説明

  16. 「Employees」ページで、新しい従業員レコードを挿入するには、「Insert new employee」をクリックします。

    chap7_loadimg_006.gifの説明が続きます。
    chap7_loadimg_006.gifの説明

  17. 「Insert New Employee」フォームでは、データベースにアップロードするシステム上のサムネイル・イメージを選択できます。次の各フィールドに独自の値を入力するか、または表示されている値を使用します。「Browse」をクリックします。

    chap7_loadimg_007.gifの説明が続きます。
    chap7_loadimg_007.gifの説明

  18. 「File Upload」ウィンドウで、JPEGイメージ・ファイルを参照して選択し、「Open」をクリックします。

    chap7_loadimg_008.gifの説明が続きます。
    chap7_loadimg_008.gifの説明

  19. 「Insert New Employee」ページで、「Save」をクリックします。

    chap7_loadimg_022.gifの説明が続きます。
    chap7_loadimg_022.gifの説明

    「Employees」ページに、元のサイズのイメージを含む新しい従業員レコードが表示されます。

    chap7_loadimg_009.gifの説明が続きます。
    chap7_loadimg_009.gifの説明

イメージのサイズ変更

この項では、アプリケーション・コードをさらに変更して、指定したイメージからサムネイル・イメージを作成し、従業員のレコードにそのサムネイル・イメージを格納します。

PHPのGDグラフィックス拡張モジュールを使用して、従業員イメージをサイズ変更します。

  1. Apacheを再起動します。ApacheMonitorユーティリティを使用するか、またはWindowsのサービスを使用できます。

    ApacheMonitorユーティリティを使用するには、Apacheのbinディレクトリに移動し、ApacheMonitor.exeをダブルクリックします。デフォルトのインストールでは、Apacheのbinディレクトリはc:\Program Files\Apache Group\Apache2\binです。

    Windowsのサービスにアクセスするには、Windowsの「スタート」メニューで、「スタート」「コントロール パネル」「管理ツール」「サービス」を選択します。「標準」タブを選択します。「Apache2 HTTP Server」を右クリックし、「再起動」を選択します。

  2. anyco_db.incファイルを編集します。 イメージをサイズ変更してサムネイル・イメージを作成するには、db_insert_thumbnail()関数で$lob->savefile($imgfile)へのコールの前に次のコードを追加します。

    $r = oci_execute($stmt, OCI_DEFAULT);
    if (!$r) {
      $e = db_error($stid, __FILE__, __LINE__);
      return false;
    }
    
    // Resize the image to a thumbnail
    define('MAX_THUMBNAIL_DIMENSION', 100);
    $src_img = imagecreatefromjpeg($imgfile);
    list($w, $h) = getimagesize($imgfile);
    if ($w > MAX_THUMBNAIL_DIMENSION || $h > MAX_THUMBNAIL_DIMENSION)
    {
      $scale =  MAX_THUMBNAIL_DIMENSION / (($h > $w) ? $h : $w);
      $nw = $w * $scale;
      $nh = $h * $scale;
    
      $dest_img = imagecreatetruecolor($nw, $nh);
      imagecopyresampled($dest_img, $src_img, 0, 0, 0, 0, $nw, $nh, $w, $h);
    
      imagejpeg($dest_img, $imgfile);  // overwrite file with new thumbnail
    
      imagedestroy($src_img);
      imagedestroy($dest_img);
    }
    
    if (!$lob->savefile($imgfile)) {
    ...
    

    imagecreatefromjpeg()関数を使用して、JPEGファイルを読み取り、後続のGD関数で使用される内部表現を作成しています。次に、最長側面が100ピクセル以下の新しい次元を計算しています。imagecreatetruecolor()関数を使用して、その新しいサイズのテンプレート・イメージを作成しています。imagecopyresampled()関数を使用して元のイメージのデータをそのテンプレート・イメージにサンプリングして、サムネイル・イメージを作成しています。 サムネイル・イメージを元のファイルに書き戻し、イメージの内部表現を解放しています。

    db_insert_thumbnail()関数の既存のコードは、以前の実装と同様に、データベースにイメージ・ファイルをアップロードします。

  3. ブラウザに次のURLを入力して、アプリケーションの変更をテストします。

    Windowsの場合:

    http://localhost/chap7/anyco.php
    

    Linuxの場合:

    http://localhost/~<username>/chap7/anyco.php
    
  4. 「Departments」ページで、「Show Employees」をクリックして、「Employees」ページにナビゲートします。

    chap7_loadimg_018.gifの説明が続きます。
    chap7_loadimg_018.gifの説明

  5. 「Employees」ページで、新しい従業員レコードを挿入するには、「Insert new employee」をクリックします。

    chap7_loadimg_019.gifの説明が続きます。
    chap7_loadimg_019.gifの説明

  6. 新しく従業員の詳細を入力するか、または表示されている値を使用します。従業員イメージを参照するには、「Browse」をクリックします。

    chap7_loadimg_020.gifの説明が続きます。
    chap7_loadimg_020.gifの説明

  7. サイズが100ピクセルより大きいJPEGイメージを検索して選択し、「Open」をクリックします。

    chap7_loadimg_021.gifの説明が続きます。
    chap7_loadimg_021.gifの説明

  8. 「Insert New Employee」ページで、「Save」をクリックします。

    chap7_loadimg_022.gifの説明が続きます。
    chap7_loadimg_022.gifの説明

    「Employees」ページに、新しくアップロードしたJPEGイメージが表示されます。そのイメージ・サイズは、イメージ・サイズ変更コードを含める前にロードしたイメージと比較すると小さくなります。

    chap7_loadimg_023.gifの説明が続きます。
    chap7_loadimg_023.gifの説明