PHPプロ!TIPS+

1. PEAR::HTML_QuickForm_Livesearchを試してみよう

PEAR::HTML_QuickForm_LivesearchはPEAR::HTML_QuickFormパッケージの一つで、Livesearch機能を持つinputテキスト要素を生成します。

Livesearch機能とは、ちょうどGoogle suggestのような、テキストボックスにキー入力が行われる度にその段階までの入力での検索結果がドロップダウンリストとして返される、AJAX技術を用いた動的な検索機能です。

HTML_QuickForm_Livesearchは現在バージョン0.3.2のbetaバージョンとなっています。

http://pear.php.net/package/HTML_QuickForm_Livesearch

-- インストール --
pear install HTML_QuickForm_Livesearch-beta
※HTML_QuickForm 及び HTML_AJAXも必要です。

-- index.php --
<?php
require_once 'HTML/QuickForm.php';
require_once 
'HTML/QuickForm/livesearch_select.php';
require_once 
'myfunction.php';
$form = new HTML_QuickForm('firstForm');
$form->addElement('livesearch_select''Program''プログラム言語',
                 array(
                      
'elementId' => 'search',
                      
'callback' => array('Test''getTestName'),
                      
'searchZeroLength' => 1,
                      
'buffer' => 350,
                      
'printStyle' => 1,
                      
'autoComplete' => 1
                      
),
                      array(
'size' => '50')
                  );
$form->addElement('submit'null'送信'array('id'=>'submit'));
$form->addRule('Program''入力して下さい''required'null'server');
if (
$form->validate()) {
  
$form->freeze();
   
$form->addElement('text''back''<a href="index.php">戻る</a>');
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  <title>Livesearch QuickForm Test</title>
  <link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<?php
$form
->display();
?>
</body>
</html>

-- myfunction.php --
<?php
/**
 * callback用クラス
 */
class Test {
    function 
getTestName($dbh$id) {
        
$livesearch array(
                              
=> 'PHP',
                              
=> 'Perl',
                              
=> 'Java',
                              
=> 'Ruby',
                              
=> 'Python',
                              
=> 'JavaScript',
                              
=> 'CSS',
                           );
        if (
$id 0) {
            return 
$livesearch[$id];
        }
    }
}
?>

-- auto_server.php --
<?php
/**
 * Ajaxリクエスト処理クラス
 */
include 'HTML/AJAX/Server.php';
class 
LiveServer extends HTML_AJAX_Server {
  var 
$initMethods true;
  function 
initLivesearch() {
    include 
'livesearch.class.php';
    
$this->registerClass(new livesearch());
  }
}
$server = new LiveServer();
$server->registerJSLibrary('QfLiveSearch','live.js','./');
$server->handleRequest();
?>

-- livesearch.class.php --
<?php
/**
 * Ajaxリクエスト検索クラス
 */
class livesearch {
  var 
$livesearch array(
    
=> 'PHP',
    
=> 'Perl',
    
=> 'Java',
    
=> 'Ruby',
    
=> 'Python',
    
=> 'JavaScript',
    
=> 'CSS',
    );
  function 
search($input) {
    
$ret array();
    foreach(
$this->livesearch as $key => $value) {
      if (
stristr($value,$input)) {
        
$ret[$key] = $value;
      }
    }
    return 
$ret;
  }
}
?>

このサンプルでは、inputボックスにアルファベットを入力すると、一覧に含まれる文字があれば、該当項目を返して、選択できるようになります。検索方法は livesearch.class.phpにて自由に変更できます。

実際の動作ですが、IE6.0 & Firefox1.5では動作しましたが、Operaでは上下キーでの選択ができないようです。また、選択項目をEnterキーで決定した場合、同時にSubmitされてしまったりと、動作に不安定な部分も見られます。

Suggestの機能を実装するにはJavaScriptのライブラリの「script.aculo.us」や「YUI Library」などがありますが、PEAR::HTML_QuickForm_Livesearchの場合、HTML_QuickFormを使っている方は作成が簡単に行えることや、PHPのコードだけを書けばいいので管理もしやすくなるのではないでしょうか。安定版リリースの際には検討してみるのもいいかもしれません。

2. スクリプト上で楽にデータをPOST送信しよう

Webサイトを構築していると様々な形でデータを送信する必要がでてきます。例えば、Ping送信のように多数のサイトへ同じデータを渡すこともあるでしょう。特に、データサイズが大きい場合や、トラックバックのようにPOST形式で送信しなければならないこともあります。そこで今回はスクリプト内で POST送信を実行する簡単な方法を紹介します。

PHPに組み込まれている関数のみでデータをPOSTする場合、HTTPヘッダを自分で作成し、これにデータを付加しなければなりません。例えば、以下のようになります。

<?php
$data 
'hoge=' urlencode($value)
     . 
'&name=' urlencode($name);

$post "POST http://www.example.com/test.php HTTP/1.1\r\n"
      
"Host: www.example.com\r\n"
      
"Content-Type: application/x-www-form-urlencoded\r\n"
      
"Content-Length: " strlen($data) . "\r\n\r\n"
      
$data ."\r\n";
?>

ご覧の通りいささか面倒です。そこでこの労力を軽減してくれるパッケージを2つ紹介したいと思います。PEAR::HTTP_Requestと Zend_Http_Clientです。

1. PEAR::HTTP_Request

PEAR::HTTP_RequestはNet_URLとNet_Socketパッケージに依存しています。インストールするときは、

pear install --alldeps HTTP_Request

のように--alldepsオプションを用いて依存関係にあるパッケージも一緒にインストールすると便利です。

HTTP_Requestの使い方は簡単です。インスタンスを作成し、メソッドを指定します。必要なデータとURLを登録し、sendRequestメソッドで指定URLへデータを送信します。

<?php
require_once 'HTTP/Request.php';

// ソケットを開き、送信形式を指定し、データを送信する
$req = new HTTP_Request();
$req->setMethod(HTTP_REQUEST_METHOD_POST);
$req->addPostData('hoge'$value);
$req->addPostData('name'$name);

// $uri_list = array(uri1, uri2, ...)とする
foreach ($uri_list as $uri) {
  
// 送信先を設定し、レスポンスを取得する
  
$req->setURL($uri);
  
  if (!
PEAR::isError($req->sendRequest())) {
    
$response $req->getResponseBody();
  }
}
?>

2. Zend_Http_Client

このクラスはZendフレームワーク(http://framework.zend.com/)で提供されています。本家のサイトからダウンロードして下さい。

使い方はインスタンスにデータとURLを渡し、送信するだけです。ただし、ただし、現在のバージョン(執筆当時 バージョン0.2.0)ではヘッダ情報で"Content-Type:application/x-www-form-urlencoded"を指定しなければなりません。

<?php
require_once 'Zend/Http/Client.php';

// 送信するデータを整形する
$data 'hoge=' urlencode($value) . '&name=' urlencode($name);
$headers array("Content-Type: application/x-www-form-urlencoded");

// インスタンスを作成する
$http = new Zend_Http_Client();
$http->setHeaders($headers);

// $uri_list = array(uri1, uri2, ...)とする
foreach ($uri_list as $uri) {
  
// HTTP POSTリクエストを送信し、HTTPレスポンスを取得する
  
$http->setUri($uri);
  
$httpResponse $http->post($data);
}
?>

3. callbackあれこれ

PHPの関数の中には、callback関数を適用することでユーザーが任意の操作を行えるようにする関数も多く存在します。今回は、callbackまわりのちょっとした小ネタについてご紹介します。

callback関数を呼び出すような関数を使用しようとすると、単純な処理にもかかわらずいちいち関数を定義しなければいけません。1つぐらいなら気になりませんが、いくつも使用することになると、1回しか使わない関数定義が増えてしまって、ちょっと気になります。

そのような場合には、create_function関数を活用することができます。create_function関数は匿名関数を作成する関数で、第1引数に匿名関数の引数となる文字列、第2引数にコードブロックに該当する文字列を指定します。

例えば、以下のような処理を行う際

$result = array_map('call_func', $array1, $array2);

function call_func($arg1, $arg2)
{
  return $arg1 . ":" . $arg2 . "\n";
}

creater_function関数を使用すれば、以下のように書き換えることができます。

$result = array_map(create_function('$arg1,$arg2', 'return $arg1 . ":" .
$arg2 . "\n";'), $array1, $array2);

これを使用すれば、callback関数まで含めてワンライナーで書くことができ、便利です。

なお、create_function関数の引数をダブルクォートで囲ってしまうと、中で使用するための引数として指定した$arg1などが展開されてしまうので注意が必要です。

また、callback関数にクラスメソッドの処理を流用したい場合などもあるかと思います。そのような場合に、いちいち別の関数でラッピングするのは冗長です。そのような時、以下のように配列の形式で指定することで、オブジェクトのメソッドをcallback関数として指定できます。

class myClass
{
  var $data;

  function myClass($var)
  {
    $this->data = $var;
  }

  function myFunc($value)
  {
    return $this->data . ":" . $value;
  }
}

$class = new myClass("value");
$array = range(1,5);
$res = array_map(array($class, "myFunc"), $array);
print_r($res);

静的メソッドの場合には、array("myClass", "myFunc")のように指定しても呼び出すことが可能です。

このような使い方も、覚えておくとちょっとしたところで役に立つかもしれません

バックナンバーについて

TIPS-MLは、毎週金曜日に更新され、新しい記事が掲載されます。

Tipsꗗy[W 

Pick Up Q&A

Q
array_mergeの再帰処理の動作について
 このエントリーをはてなブックマークに追加 
A
>1個になったとき$leftを返しますが、 >このとき、最終的な$leftはnullになるかと思います。 いいえ、最後は「渡された配列をそのまま」返します。要素が2以上あるときとの違いは(並べ替えずに戻るので...

>>続きを読む

再帰関数は最初の内は混乱しますが、非常に上手く使える場面もいずれ出てきます。これを機会に学んでいけるといいですね。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)