Tag Archives: Ajax

[PHP, JS]jQuery UI autocompleteを使った自動補完(候補予測)

Share on Facebook
Bookmark this on Delicious
LINEで送る
Pocket

キーワード検索を行う際、入力欄に文字の一部を入力すると当てはまる単語をリストアップしてくれるオートコンプリート(自動補完)機能は便利です。
jQuery UI には Autocomplete というウィジェットが用意されており、それを使えば簡単に実現できます。
あらかじめ単語が決まっていて、数が少ないのであればそのまま Javascript 内に単語一覧を書いてしまえばいいのですが、MySQL などのデータベースに登録されている情報を元に候補一覧を表示したい場合、Ajax を利用して PHP などから動的に取得する必要があります。

form.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Auto Complete</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/jquery-ui.min.js"></script>
<script>
$(function() {
	$("#sample").autocomplete({
		source: "./autocomplete.php"
	});
});
</script>
</head>
<body>

<form>
<input type="text" id="sample" />
</form>

</body>
</html>

autocomplete.php

<?php
// 単語のリスト
$list = array(
	'Apple',
	'Orange',
	'Grape',
	'Banana',
	'Pear',
	'Melon',
	'Peach',
	'Lemon'
);

$words = array();

// 現在入力中の文字を取得
$term = (isset($_GET['term']) && is_string($_GET['term'])) ? $_GET['term'] : '';

// 部分一致で検索
foreach($list as $word){
	if(mb_stripos( $word, $term) !== FALSE){
		$words[] = $word;
	}	
}

header("Content-Type: application/json; charset=utf-8");
echo json_encode($words);

必要となるのはフォームの記述されたファイルと Ajax 処理を行う PHP ファイルです。
データの受け渡しは JSON で行われ、テキストボックスに現在入力中の文字は通常 term に格納されて渡されます。
サンプルでは単純に固定の単語一覧を JSON に変換して表示していますが、データベースから取得する場合は WHERE ~ LIKE で絞り込んだ単語一覧を JSON に変換します。データベースへの負荷を減らすためにセッション等にキャッシュするのも良いと思います。
デフォルトでは一文字入力していれば候補を表示しますが、オプションで minLength を指定すれば最小文字数を変更できます。

$( "#sample" ).autocomplete({
    source: "./autocomplete.php",
    minLength: 3
});

参考: Autocomplete Widget
http://api.jqueryui.com/autocomplete/

Posted in PHP, JavaScript | Tagged , , , | Leave a comment

[PHP, JS]jQueryのAjaxによるPHP、Javascript間の送受信(JSON)

Share on Facebook
Bookmark this on Delicious
LINEで送る
Pocket

Ajax(非同期通信)を用いれば画面遷移なしでデータのやり取りができるため、最近では定番の技術として頻繁に用いられています。

今回は Javascript から JSON 形式のパラメータを POST で送信し、
PHP で処理した後、それを再び Javascript で受信する API のようなものを作ってみます。

・index.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<title>Ajax</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<script type="text/javascript">
$(document).ready(function(){
	$("#button").click(function(){
	
		var param = { "text": "Hello" };

		$.ajax({
			type: "post",
			url: "ajax.php",
			data: JSON.stringify(param),
			// crossDomain: true,
			dataType : "jsonp",
			scriptCharset: 'utf-8'
		}).done(function(data){
			alert(data.text);
		}).fail(function(XMLHttpRequest, textStatus, errorThrown){
			alert(errorThrown);
		});
	 });
});
</script> 
	
</head>

<body>
<input type="button" id="button" value="Hello" /></form>
</body>
</html>

・ajax.php

<?php
// Ajax以外からのアクセスを遮断
$request = isset($_SERVER['HTTP_X_REQUESTED_WITH']) ? strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) : '';
if($request !== 'xmlhttprequest') exit;

$json = file_get_contents('php://input');
$data = json_decode($json, true);

$text      = isset($data['text'])       ? $data['text']	    : "";
$callback  = isset($_GET['callback'])   ? $_GET["callback"] : "";
$callback  = htmlspecialchars(strip_tags($callback));

$param = array( 'text' => $text . ", World!" );

header('Content-type: text/javascript; charset=utf-8');
printf("{$callback}(%s)", json_encode( $param ));

出力結果

Hello, World!

「Hello」と書かれたボタンを押すと、JavaScript から PHP に「Hello」という文字列が送信されます。
PHP はそれに「, World!」という文字列を加えて返します。
Javascript は結果を受け取り「Hello, World!」と表示する流れです。

パラメータの受け渡しには JSON(JavaScript Object Notation) を利用しました。
PHP には JSON 読み書きに関する関数が充実しているので Javascript とデータの送受信をする場合は XML と並んでよく使われます。

参考:
http://www.learningjquery.com/2010/03/detecting-ajax-events-on-the-server/

Posted in PHP, JavaScript | Tagged , , , | Leave a comment

[PHP][jQuery]Ajax(非同期通信)を使ったチャット

Share on Facebook
Bookmark this on Delicious
LINEで送る
Pocket

あまり JavaScript の Ajax に関して経験がないので、
ちょっとした練習としてチャットのようなものを作ってみました。
練習用の単純なプログラムですので脆弱性等の問題があります。実際のサーバーでは運用しないで下さい。
また、Google Chrome ではローカルファイルの読み込みに制限があります。

非同期通信を利用するために jQuery を利用しています。

・表示部分(HTMLファイル)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Chat</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<style type="text/css">
#log {
	border: 1px solid #AAA;
	height:400px;
	width:600px;
	overflow: scroll;
}
</style>

</head>

<body>

<script type="text/javascript">

function load_log()
{
	$.ajax({
		type: 'post',
		url: './log.txt',
		success: function( data ){
			log = data.replace(/[\n\r]/g, "<br />");
			$('#log').html(log);
		}
	});
}

function write_message()
{
	$.ajax({
		type: 'post',
		url: 'write.php',
		data: {
			'message' : $("#message").val()
		},
		success: function(){
			load_log();
			$("#message").val('');
		}
	});
}

$(document).ready(function()
{
	load_log();
	setInterval('load_log()', 5000);
});

</script>

<form method="post" onsubmit="write_message();return false;">
  <input id="message" name="message" type="text" value="" />
  <input type="button" value="送信" onclick="write_message()">
</form>

<div id="log"></div>

</body>
</html>

・write.php(書き込み部分)

<?php
// Ajax以外からのアクセスを遮断
$request = isset($_SERVER['HTTP_X_REQUESTED_WITH']) ?
	strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) : '';
if($request !== 'xmlhttprequest') exit;

$message = (isset($_POST['message']) && is_string($_POST['message'])) ?
	htmlspecialchars($_POST['message'], ENT_QUOTES) : "";
if($message == "") exit;

$max   = 30;		// 行の上限
$count = 0;
$log   = '';

$fp = fopen('log.txt', 'r');
if(flock($fp, LOCK_SH)){
	while(!feof($fp)){
		if($count >= $max - 1) break;
		$log .= fgets($fp);
		$count++;
	}
	flock($fp, LOCK_UN);
}
fclose($fp);

$log = date("Y-m-d H:i:s") . ' - ' . $message . "\n" . $log;
file_put_contents('log.txt', $log, LOCK_EX);

5 秒間隔で log.txt を読み込み、表示しているだけなので負荷は高めです。
本来であれば JSON で日付や発言者等の細かいパラメータを含めて渡したほうがよいでしょう。

実用的なチャットにするためには、ログイン機能の実装と、負荷対策として Comet のような仕組みを取り入れる必要があると思います。

Posted in PHP, JavaScript | Tagged , , , | Leave a comment