Skip to content

Instantly share code, notes, and snippets.

@k-holy
Created August 19, 2011 06:06
Show Gist options
  • Save k-holy/1156160 to your computer and use it in GitHub Desktop.
Save k-holy/1156160 to your computer and use it in GitHub Desktop.
PHP5.3 コールバックでクロージャを使うサンプル with はてなハイクAPI
<?php
namespace Holy\Example;
class Util {
public static function H($data, $default=null) {
$var = $default;
if (isset($data) && is_scalar($data) && strlen($data) >= 1) {
$var = htmlspecialchars($data, \ENT_QUOTES, 'UTF-8');
}
return $var;
}
}
class ItemList extends \ArrayIterator {
public function __call($name, $args) {
if (!isset($this->$name) || !is_callable($this->$name)) {
throw new \RuntimeException(
sprintf("The Property '%s' is not callable.", $name));
}
return call_user_func_array($this->$name, $args);
}
}
use Holy\Example\Util as U;
$word = (isset($_GET['word']) && strlen($_GET['word']) >= 1)
? $_GET['word'] : 'いただきます';
$items = new ItemList(json_decode(file_get_contents(
'http://h.hatena.ne.jp/api/statuses/keyword_timeline.json?word='
. rawurlencode($word) . '&page=1&count=50')));
$items->sort = function($name, $desc=false) use ($items) {
if (!property_exists($items[0], $name)) {
throw new \RuntimeException(
sprintf("The field '%s' is not defined.", $name));
}
$items->uasort(function($item1, $item2) use ($name, $desc) {
return ($desc)
? strnatcasecmp($item2->$name, $item1->$name)
: strnatcasecmp($item1->$name, $item2->$name);
});
};
if (isset($_GET['sort'])) {
$items->sort($_GET['sort'],
(isset($_GET['desc'])) ? (bool)$_GET['desc'] : false);
}
$title = 'はてなハイクAPIサンプル';
$fields = array('created_at', 'favorited');
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title><?=U::H($title)?></title>
<style type="text/css">
table {border-collapse:collapse;border-spacing:0px;}
th,td {padding:1px; border:solid 1px #999999;}
</style>
</head>
<body>
<h1><?=U::H($title)?></h1>
<form method="get" action="<?=$_SERVER['SCRIPT_NAME']?>">
keyword:<input type="text" name="word" value="<?=U::H($word)?>" />
<?php foreach ($fields as $value) : ?>
<input type="radio" name="sort"
value="<?=U::H($value)?>" id="sort_<?=U::H($value)?>"
<?=(isset($_GET['sort']) && $_GET['sort'] === $value) ? 'checked="checked"' : ''?>
/><label for="sort_<?=U::H($value)?>"><?=U::H($value)?></label>
<?php endforeach ?>
<input type="checkbox" name="desc" value="1" id="desc"
<?=(isset($_GET['desc']) && $_GET['desc']) ? 'checked="checked"' : ''?>
/><label for="desc">desc</label>
<input type="submit" value="送信" />
</form>
<dl>
<?php foreach ($items as $item) : ?>
<dd>
<?=U::H(date('Y-m-d H:i:s', strtotime($item->created_at)))?>
<?=U::H($item->keyword)?>
</dd>
<dd>
☆<?=U::H($item->favorited)?>
<pre><?=preg_replace_callback(
'~(?:http[s]?://)[-_.!\~*a-zA-Z0-9;/?:@&=+$,%#]+\.(?:jpg|gif|png)~i',
function($matches) {
if (isset($matches[0])) {
return sprintf(
'<img src="%s" width="100" /><a href="%s" target="_blank">■</a>',
U::H($matches[0]),
U::H($matches[0])
);
}
}, mb_substr($item->text, mb_strlen($item->keyword) + 1));?></pre>
</dd>
<?php endforeach ?>
</dl>
</body>
</html>
@k-holy
Copy link
Author

k-holy commented Aug 19, 2011

コールバックでArrayIteratorをソートするのにサンプルデータを用意するのが面倒だったので、はてなハイクAPI使ってみた。
テキストに含まれる画像のURLをimgタグに置換するのにpreg_replace_callback()を使ったりと、結果的にPHP5.3のコールバックっぽい内容になったと思う。

@k-holy
Copy link
Author

k-holy commented Sep 30, 2011

キーワードを入力できるようにした。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment