φ(..)メモとして残しておこう… -9ページ目

ページにアクセスする事にランダムに読み込んだデータの「もっと見る」ボタン。


なんだかよくわからないタイトルになってしまいましたが、つまりはこういうこと。

ページにアクセスするたびに、ランダムにデータを読み込む。
   ▼
読み込んだデータは、10件づつ「もっと見る」ボタンで読み込みたい。

「もっと読む」ボタンを押すごとに、SQL投げてデータベースからデータを取得するわけですが、毎回ランダムにデータを取得しなおすと重複しちゃう。

やりたいのは「ランダムに取り出しはするけど、もっと見るボタンを押した時の挙動は、前回読み込んだデータの続きを取得したい」ということなわけです。


まずは、読み込み側のHTMLにこんなJavaScriptを。

var start = 9;
var num = Math.floor( Math.random() * 100 );

function loadMore() {

$("a#loading").html("<img src='../images/loadingnow.gif'>");

$.post('items.php', { start : start, num : num },
function(res){
$("a#loading").html("もっと見る");
$("#items").append(res);
});
start += 9;
}


jQueryのpost()を使って、items.phpの結果をDOMに追加してます。
この時、items.phpに「start」と「num」ってパラメータをpostしてます。

このpostデータをどう使うかは、items.phpで。

    /*全部のカウント数を取得*/
$count_data = $DB->SQL("SELECT count(*) FROM items;");
$all_count = $count_data[0]["count(*)"];



//ランダムに取得してくる場合
$items = $DB->SQL("SELECT * FROM items ORDER BY RAND(" . $_POST['num'] . ") limit " . $_POST['start'] . ", 9;");

//新着順に取得してくる場合
//$items = $DB->SQL("SELECT * FROM items ORDER BY item_id DESC limit " . $_POST['start'] . ", 9;");


//================出力ループ==================

//3つづつ並べるので、カウンターを定義
$count = 0;

foreach ($items as $val){

if ( $count == 0 ){$dat = "a";}
if ( $count == 1 ){$dat = "b";}
if ( $count == 2 ){$dat = "c";}

print <<< EOF
<div class="ui-block-{$dat}">
<a href="****.html" data-ajax="false">
<img src="/thumb/{$val['thumb_img']}">
</a>
<p class="thumb_text">{$val['item_name']}</p>
</div>\n
EOF;

$count++;

//3つ並べたらカウンターを元に戻す
if ($count > 2){$count= 0;}

}

/*もし、全カウントから読み込みスタート位置を引いた数が
9以下なら、ボタンを消す処理
*/
if ( $all_count - $_POST['start'] < 9 ){
echo "<script>$(\"a#loading\").hide();</script>";
}


とりあえず「items.php」は上記のようになってます。
jQueryMobileの3カラムレイアウトを使ってるので、3つづつ並べて出力しているのはいいとして…問題はランダムに取得する方法です。

そんな大したことをしているわけではなく、ORDER BY RAND() でランダムにソートして LIMIT 句で取得したい件数だけを取得しているわけですが…。

SELECT * FROM items ORDER BY RAND(" . $_POST['num'] . ") limit " . $_POST['start'] . ", 9;


「ORDER BY RAND()」は、RANDの括弧の中に何も入れないとクエリ実行の度にランダムにデータを取得します。
なので、
・ページを読み込んだタイミングでランダムな数字を生成(JavaScriptで)
    ▼
・post()でPHPにデータを渡す
    ▼
・ORDER BY RAND()の括弧の中にそいつを入れる
    ▼
・SQL実行の度(もっと見るボタンを押すごと)に、ランダムにソートした結果の「続き」が取得できる


ということになります。





jQueryのprettyPhotoの「pp_descriptions」に外部リンクを設定。



jQuery-PrettyPhoto

上記URLでダウンロードできる「jQuery-PrettyPhoto」のtitle部分(正確には呼び出されたページのpp_description部分)にリンクを貼れるようにJSを改造したのでメモ。


まずは、呼び出すアンカータグの中に「data-link="リンク"」を追加。

<a href="***.jpg"
rel="prettyPhoto"
class="p-img"
title="つか、説明"
data-link="http://www.google.com/">見る</a>


でもって
pp_descriptions = (isSet) ? jQuery.map(matchedObjects, function(…
の次あたりに、以下を追加。

pp_links = (isSet) ? jQuery.map(matchedObjects, function(n, i){
if($(n).attr('rel').indexOf(theRel) != -1) return ($(n).attr('data-link')) ? $(n).attr('data-link') : "";
}) : $.makeArray($(this).attr('data-link'));


要するに、jQueryの「attr()」でdata-link=""の中身を取得するってわけです。
実際に、pp_descriptionsやらpp_titlesやらも同じように取得しているので。

この当たりを見ると<img>タグのalt属性を表示タイトルとして、<a>タグのtitle=""の中身をpp_descriptions(下の方の説明)としているようです。

あとは「$.prettyPhoto.open = function(…」の中にある「pp_descriptions」の表示処理をリンクで囲むように書き換えるだけです。
267行目付近を変更します。
$pp_pic_holder.find('.pp_description').show().html(unescape(pp_descriptions[set_position]));

▼こんな感じで書き換え▼

$pp_pic_holder.find('.pp_description').show().html(
'<a href="' + pp_links + '">' + pp_descriptions[set_position] + '</a>'
);


jQueryのプラグインは、jQueryの使い方がわかってると結構簡単にカスタマイズ出来るので、よく使います。

jQueryをお仕事で使う場合、結構カスタマイズの要望が多いですからね…。

「data-*属性」を使っておけば、HTML5で新たに規定されたdataset IDL属性からDOMStringMapオブジェクトを取得出来ることになっているようなので、独自属性のコンテンツは「data-*属性」を使うようにしておきましょう。

このへんとか参考になるかも…。

徹底解説 HTML5マークアップガイドブック 最終草案対応版―全要素・全属性完全収録



徹底解説 HTML5 APIガイドブック ビジュアル系API編




徹底解説HTML5マークアップガイドブック




徹底解説 HTML5 APIガイドブック コミュニケーション系API編




さくらで借りてたVPSをしばらく放置していたら…


以前に、さくらのVPSを借りたまましばらく放置(忙しくて)していたら、さくらからこんなメールが来た。


平素は弊社サービスをご利用いただき、誠にありがとうございます。
さくらインターネットabuse対策チームの○○と申します。

 この度、ご利用いただいております 「さくらのVPS(IPアドレス:
**.**.**.**)」のサーバより、不正アクセスがあったとの連絡が
弊社に寄せられましたのでご連絡いたします。

 提供されましたログを添付いたしますので、調査、ご対応をいただきま
すようお願いいたします。また、調査結果及びご対応内容につきましては
本メール返信にてご連絡いただきますようお願いいたします。

 尚、調査の結果クラッキングが行われていると確定した場合、そのまま
の状態でサーバを運用し続けるのは非常に危険です。
これが確定した際には、必ずOSの再インストールを実施いただけますよう
お願いいたします。

 本件に関しまして、2011/**/** 正午をご対応の期限とさせていただき
ます。

 期限までにお客さまのご連絡が確認できない場合及び、対応期限前でも
弊社の業務の遂行に支障が生じると弊社が判断いたします場合には、緊急
措置として該当のサーバを一時停止させていただく場合がございますので、
予めご了承願います。

 また、同措置を行いました場合は、お客様にてOS再インストールを実施
いただく以外、一時停止解除を承ることはいたしかねますので、この点に
つきましても予めご了承願います。

 バックアップ等が必要の場合につきましては予め採取いただけますよう
お願いいたします。

以下、提供されましたログ情報となります。
======================================================================
*** ** **:**:** www sshd[15861]: Invalid user postgres from **.**.**.**
*** 26 **:**:** www sshd[7137]: Invalid user danny from **.**.**.**
======================================================================

 以上、よろしくお願いいたします。

 不明点・お気づきの点などございましたら、本メール返信にてお問い合わせ
ください。



この時は結局、OSを再インストールして環境を再構築で対応したけど、環境の再構築にかかる時間は大体1時間もあれば十分。

もし、僕がこのサーバーで色々とサービスをやっているのであれば「サーバーメンテナンス中…」ということで1時間くらい集中的に作業をしてhosts設定とかちゃんとするかな…。


SSHアクセスのip制限
この記事で書いたような処置を忘れていたので、海外から大量のアタックを受けて中に入られて踏み台にされていたようなので…。

特にサーバーを「新たに」借りて、そこにサービスを移転する必要は全くないと思われます。


既にEC-CUBEなどでサービスを動かしていたとしても、カード決済会社に新しいIPアドレスを申請して切り替えてもらう作業やらDNS情報の書き換えやらで、タイムラグが発生してサービスに支障をきたすことは目に見えているので、アクセスの少ない夜中に作業を1時間ほど行うってことで大丈夫かな…と。



データセンター/世界で同一水準のITシステムを求めるグローバル企業の需要に対応できないと、大手DCは本格的な成長が見込めない

 …1年間フル稼働した場合で99・98%以上という高稼働率の保証など「世界一厳しい」とされる日本企業の要求に耐えてきた品質の高さが売り物だ…

2010/11/17, 日本経済新聞



いや…まあ…サービスを止めないってことは大事かとは思うけれど、手間やリスク(DNS書き換え、あるいはクレジット決済のIPアドレス切り替え等)を考えたら、1時間でもいいのでサーバーを止めてメンテナンスしたほうがいいんでないかと思ったり。

その1時間に行う作業を何度もシミュレートして備えるって方が、胃が痛くならないし。


「本件に関しまして、2011/**/** 正午をご対応の期限とさせていただきます。」

しかし、さくらはホント上からですよね…もの言いが。
昨日の産経新聞の朝刊の3面読んでびっくりしちゃったわけで、今日はこんな記事を書きました。

コードだけを書く…とか言っておきながら、この件について書こうと産経の朝刊を読んで思ったので、エントリーを。

一応、PHPのコードスニペットのエントリーもアップしたんでお許しを。


家に帰ってきたら、元気になったぉ。
さて…ゆっくり寝るとしますか。

けっこう捗るPHPスニペットいろいろ…メモ。


プレーンテキストをBase64エンコード&デコード



ちょっと前にアメブロのgif画像をBase64エンコードで貼り付けたりしましたが…。
プレーンテキストをBase64デコードしたり、エンコードしたりとか。

//base64 encode
function base64url_encode($plainText) {
$base64 = base64_encode($plainText);
$base64url = strtr($base64, '+/=', '-_,');
return $base64url;
}

//base64 decode
function base64url_decode($plainText) {
$base64url = strtr($plainText, '-_,', '+/=');
$base64 = base64_decode($base64url);
return $base64;
}



秒数を入力すると「○日と○時間○分○秒」って返してくれる関数



需要あるかないかはわからないけど…。

function secsToStr($secs) {
if($secs>=86400){$days=floor($secs/86400);$secs=$secs%86400;$r=$days.' day';if($days<>1){$r.='s';}if($secs>0){$r.=', ';}}
if($secs>=3600){$hours=floor($secs/3600);$secs=$secs%3600;$r.=$hours.' hour';if($hours<>1){$r.='s';}if($secs>0){$r.=', ';}}
if($secs>=60){$minutes=floor($secs/60);$secs=$secs%60;$r.=$minutes.' minute';if($minutes<>1){$r.='s';}if($secs>0){$r.=', ';}}
$r.=$secs.' second';if($secs<>1){$r.='s';}
return $r;
}




クレジットカード番号のバリデート



function validateCC($cc_num, $type) {

if($type == "American") {
$denum = "American Express";
} elseif($type == "Dinners") {
$denum = "Diner's Club";
} elseif($type == "Discover") {
$denum = "Discover";
} elseif($type == "Master") {
$denum = "Master Card";
} elseif($type == "Visa") {
$denum = "Visa";
}

if($type == "American") {
$pattern = "/^([34|37]{2})([0-9]{13})$/";//American Express
if (preg_match($pattern,$cc_num)) {
$verified = true;
} else {
$verified = false;
}


} elseif($type == "Dinners") {
$pattern = "/^([30|36|38]{2})([0-9]{12})$/";//Diner's Club
if (preg_match($pattern,$cc_num)) {
$verified = true;
} else {
$verified = false;
}


} elseif($type == "Discover") {
$pattern = "/^([6011]{4})([0-9]{12})$/";//Discover Card
if (preg_match($pattern,$cc_num)) {
$verified = true;
} else {
$verified = false;
}


} elseif($type == "Master") {
$pattern = "/^([51|52|53|54|55]{2})([0-9]{14})$/";//Mastercard
if (preg_match($pattern,$cc_num)) {
$verified = true;
} else {
$verified = false;
}


} elseif($type == "Visa") {
$pattern = "/^([4]{1})([0-9]{12,15})$/";//Visa
if (preg_match($pattern,$cc_num)) {
$verified = true;
} else {
$verified = false;
}

}

//使い方
echo validateCC("4542333312349999","Visa");


カードの番号とブランドをいちいちバリデートにかける理由ってなんだろ…?
こういうバリデートプログラムがかけるということは、逆を言えば番号からブランドが解るってことなわけで、いちいちバリデートする意味がわからないのですが…。

ただ、楽天とかそれをしているので「楽天とかやってるから」というだけの理由で、EC-CUBEのクレジットカードモジュールのテンプレートにそれっぽいダミーフォームを追加させられたことはあります。

むしろ、お客様が「Visa」を使おうと思って間違えて「AMEX」のカード番号入力しても認証が通ってしまうわけで、そっちの方がヤバイんでない?…とか思ったり。

「どこそこがやってるから」ってだけで、その意味を考えずにそれっぽくすることの危険性とか認識したほうがいいかもです。

じゃあ、バリデートとか載せるなよって言われちゃうと困るんですが。。。

出社拒否症の症状


出社拒否症の体の症状



動悸
息苦しさ
倦怠感
頭痛
腹痛
吐き気
下痢など。



そうか…。

動悸、息苦しさ、倦怠感、吐き気、目眩、腹痛、下痢…。


当てはまることだらけ…。


今月末に退社が決まっているけど、有給の消化は月内は困る…と言われて取得できないし。

あと2週間頑張れるかな…。



p.s.
結局、退職の際に有給休暇を消化しました。
有給休暇の取得は労働者に認められた正当な権利なのですが、恩着せがましく取らせてやる的な物言いをされました。

うーん。。。

ハッキリ言って琉球インタラ○ティブという会社はブラックですな。

便利で使えるPHPのコードスニペットあれこれ。(リターンズ)



任意のWebページのソースコードを表示する


$lines = file('http://google.com/');
foreach ($lines as $line_num => $line) {
echo "Line #{$line_num} : " . htmlspecialchars($line) . "
\n";
}




メモリの使用状況に関する情報を取得



echo "Initial: ".memory_get_usage()." bytes \n";
/* 結果
Initial: ****** bytes
*/

// let's use up some memory
for ($i = 0; $i < 100000; $i++) {
$array []= md5($i);
}

// let's remove half of the array
for ($i = 0; $i < 100000; $i++) {
unset($array[$i]);
}

echo "Final: ".memory_get_usage()." bytes \n";
/* 結果
Final: 885912 bytes
*/

echo "Peak: ".memory_get_peak_usage()." bytes \n";
/* 結果
Peak: 13687072 bytes
*/




gzcompress()を使用してデータを圧縮



$string ="
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
";

$compressed = gzcompress($string);

//-------------

echo "Original size: ". strlen($string)."\n";
echo "Compressed size: ". strlen($compressed)."\n";

//圧縮された文字列
echo $compressed;
//解凍
echo gzuncompress($compressed);

// 解凍
$original = gzuncompress($compressed);




PHPのエラーメッセージを表示させずにメールで受け取る
(ユーザ定義のエラーハンドラ関数)



function nettuts_error_handler($number, $message, $file, $line, $vars){
$email = "

An error ($number) occurred on line
$line and in the file: $file.

$message

";

$email .= "
" . print_r($vars, 1) . "
";

$headers = 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

error_log($email, 1, 'mail@example.com', $headers);

//画面上に表示する文章
if ( ($number !== E_NOTICE) && ($number < 2048) ) {
die("エラーが発生しました。後でもう一度やり直してください。");
}
}

// set_error_handler()で関数をセット
set_error_handler('nettuts_error_handler');



msSQLやMySQL、Oracle、PostgreSQL…あたりを使うならezSQLが捗るかも



PHPでDBにアクセスしてあれこれやるとき、便利なライブラリはないかなと思って探してたら「ezSQL」なるものを発見。

たいていの人は「PEAR MDB2」あたりを使うのだろうけど、機能が豊富すぎ…のガチムチ系ライブラリ(しかも、ほとんど使うことのない機能も盛りだくさん)なので、僕はちょっと…ということで探したのが今回のライブラリです。

使い方も簡単なので、初心者向けかもしれません。
あるいは、僕のように「とりあえずDB操作がしたい」って人も。


長くなってしまいそうなんで、とりあえずPDFファイルにしてみました。

「ezsql.pdf (850kb)」


個人的に使いやすいな…と思ったのが
$db->debug();

で直近のSQLの結果が「表」で表示される辺り。

PDFを見てもらってもわかるように、僕は「Navicat」というGUIツールを使っているので、結果表示がGUIっぽいとわかりやすいのです。

DBやるのにGUIかよ!

なんて声も聞こえてきそうですが、サーバー設定とかも「Webmin」使ってたりするくらいなので、GUIでできればそれでいいんだと思ってます。

スティーブ・ジョブズがGUIにこだわったのもうなずけるかな…。

GUIはパーソナルなコンピュータのためだけに有るわけではないし、個人的にはサーバーをGUIで操作してもいいんじゃないかと思ってます。


便利で使えるPHPのコードスニペットあれこれ。


文字列にURL(http://~)があったら、リンクを貼る


function link2anchor($text) {  
$text = eregi_replace('(((f|ht){1}tp://)[-a-zA-Z0-9@:%_+.~#?&//=]+)',
'<a href="\1">\1</a>', $text);
$text = eregi_replace('([[:space:]()[{}])(www.[-a-zA-Z0-9@:%_+.~#?&//=]+)',
'\1<a href="http://\2">\2</a>', $text);
$text = eregi_replace('([_.0-9a-z-]+@([0-9a-z][0-9a-z-]+.)+[a-z]{2,3})',
'<a href="mailto:\1">\1</a>', $text);
return $text;
}




AJAX要求を検出


if(!emptyempty($_SERVER['HTTP_X_REQUESTED_WITH']) 
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH'])
== 'xmlhttprequest'){
//If AJAX Request Then
}else{
//something else
}




ランダムなローマ字読みの言葉を生成


子音+母音で生成なので、偶数を指定。
function readable_random_string($even_length){  
$conso=array("b","c","d","f","g","h","j","k","l",
"m","n","p","r","s","t","v","w","x","y","z");
$vocal=array("a","e","i","o","u");
$password="";
srand ((double)microtime()*1000000);
$max = $even_length/2;
for($i=1; $i<=$max; $i++)
{
$password.=$conso[rand(0,19)];
$password.=$vocal[rand(0,4)];
}
return $password;
}




ランダムな文字列を生成


function generate_rand($l){
$random = "";
$c= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
srand((double)microtime()*1000000);
for($i=0; $i<$l; $i++) {
$rr = rand() % strlen($c);
$random.= $c[$rr];
}
return $random;
}




メールアドレスをエンコードしてJavaScriptで表示


function encode_email($email, $linkText, $attrs ) {  
// remplazar aroba y puntos
$email = str_replace('@', '@', $email);
$email = str_replace('.', '.', $email);
$email = str_split($email, 5);

$linkText = str_replace('@', '@', $linkText);
$linkText = str_replace('.', '.', $linkText);
$linkText = str_split($linkText, 5);

$part1 = '<a href="ma';
$part2 = 'ilto:';
$part3 = '" '. $attrs .' >';
$part4 = '</a>';

$encoded = '<script type="text/javascript">';
$encoded .= "document.write('$part1');";
$encoded .= "document.write('$part2');";
foreach($email as $e)
{
$encoded .= "document.write('$e');";
}
$encoded .= "document.write('$part3');";
foreach($linkText as $l)
{
$encoded .= "document.write('$l');";
}
$encoded .= "document.write('$part4');";
$encoded .= '</script>';

return $encoded;
}


echo encode_email('メールアドレス','リンク文字','class="email"');
ってやると、こんな感じのソースを吐きます。
<script type="text/javascript">document.write('<a href="ma');document.write('ilto:');document.write('メãƒ');document.write('¼ãƒ«ã');document.write('‚¢ãƒ‰');document.write('レã‚');document.write('¹');document.write('" class="email" >');document.write('リãƒ');document.write('³ã‚¯æ');document.write('–‡å­—');document.write('');</script>

あら?文字化けしてら。。。
文字化け注意。



メールアドレスの検証(バリデート)



function is_valid_email($email, $test_mx = false)  
{
if(preg_match("(^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$)", $email))
if($test_mx)
{
list($username, $domain) = split("@", $email);
return getmxrr($domain, $mxrecords);
}
else
return true;
else
return false;
}

echo is_valid_email('mail@webmage.pro');




ディレクトリの中身一覧を取得



function list_files($dir)  
{
if(is_dir($dir))
{
if($handle = opendir($dir))
{
while(($file = readdir($handle)) !== false)
{
if($file != "." && $file != ".." && $file != "Thumbs.db")
{
echo $file."<br>\n";
}
}
closedir($handle);
}
}
}




JSONデータの扱いについて


Twitterとか、APIを介してデータを提供するようなサービスの多くはJSONを使っている場合が多いので、json_decodeの使い方を知っていると便利。

$json_string='{"id":123,"name":"webmage","email":"mail@example.com","arr":["ec-cube","osCommerce"]} ';  

$obj=json_decode($json_string);

echo $obj->id; //123を表示
echo $obj->name; //webmageを表示
echo $obj->email; //mail@example.com
echo $obj->arr[0]; //配列arrの0番目を表示
echo $obj->arr[1]; //配列arrの1番目を表示




半角英数字(とハイフン)以外をハイフンに置き換える


function create_slug($string){  
$slug = preg_replace('/[^A-Za-z0-9-]+/', '-', $string);
return $slug;
}





クライアントの実IPアドレスを取得


プロキシサーバーを使っていても、この関数はユーザの実際のIPアドレスを取得します。
function getRealIpAddr(){  
if (!emptyempty($_SERVER['HTTP_CLIENT_IP']))
{
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!emptyempty($_SERVER['HTTP_X_FORWARDED_FOR']))

{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}


ホントかよ?



強制的にファイルダウンロード



サーバーのMIME設定をしていなくても、ファイルを強制的にダウンロードさせる関数。
function force_download($file)  {  
if ((isset($file))&&(file_exists($file))) {
header("Content-length: ".filesize($file));
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file . '"');
readfile("$file");
} else {
echo "No file selected";
}
}




タグクラウドの作成


function getCloud( $data, $minFontSize, $maxFontSize )  {  
$minimumCount = min($data);
$maximumCount = max($data);
$spread = $maximumCount - $minimumCount;
$cloudHTML = '';
$cloudTags = array();

$spread == 0 && $spread = 1;

foreach( $data as $tag => $count )
{
$size = $minFontSize + ( $count - $minimumCount )
* ( $maxFontSize - $minFontSize ) / $spread;
$cloudTags[] = ''
. htmlspecialchars( stripslashes( $tag ) ) . '
';
}

return join( "\n", $cloudTags ) . "\n";
}


//SAMPLE (キーとカウント数を配列に)
$arr = Array('Actionscript' => 35, 'Adobe' => 22, 'Array' => 44, 'Background' => 43,
'Blur' => 18, 'Canvas' => 33, 'Class' => 15, 'Color Palette' => 11, 'Crop' => 42,
'Delimiter' => 13, 'Depth' => 34, 'Design' => 8, 'Encode' => 12, 'Encryption' => 30,
'Extract' => 28, 'Filters' => 1);
echo getCloud($arr, 12, 36);


個人的に思うんだけどタグクラウドってなんぞ?
あまり必要性を感じないんですが…。



複数のファイルをZIP圧縮する


これは結構使えるかも…。

function create_zip($files = array(),$destination = '',$overwrite = false) {  

if(file_exists($destination) && !$overwrite) { return false; }

$valid_files = array();

if(is_array($files)) {

foreach($files as $file) {

if(file_exists($file)) {
$valid_files[] = $file;
}
}
}

if(count($valid_files)) {

$zip = new ZipArchive();
if($zip->open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
return false;
}

foreach($valid_files as $file) {
$zip->addFile($file,$file);
}
//デバッグ時はコメントアウトを外す
//echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status;

$zip->close();


return file_exists($destination);
}
else
{
return false;
}
}
/***** 使い方 ***/
$files=array('file1.jpg', 'file2.jpg', 'file3.gif');
create_zip($files, 'zipfile-name.zip', true);




ZIPファイルの解凍



圧縮があれば当然解凍の方法もあるわけで…。
function unzip_file($file, $destination){  
// create object
$zip = new ZipArchive() ;
// open archive
if ($zip->open($file) !== TRUE) {
die (’Could not open archive’);
}
// extract contents to destination directory
$zip->extractTo($destination);
// close archive
$zip->close();
echo 'Archive extracted to directory';
}




まぁ、必要になったときのためにメモとして残すということで…。

jQueryを使ってiFrameの中のコンテンツデータを取得したい!!!!


例えば、iframeの中に
<div id="frame1" data="http://www.google.com">データだよ。</div>

こんなコンテンツがあった場合に、
「data=""」の中身とか「<div>」の中のテキストデータとかを取得したい場合は、こんな感じで取得する。

var data = $('iframe').contents().find('div#frame1').attr('data');
var value = $('iframe').contents().find('div#frame').val();


でいいと思うけど…。





iPhone向けSafari専用のあれこれ。


自分用メモ。

iPhone向けSafariでのみ使える拡張属性




属性名 使用可能説明
autocapitalize on / off input
textarea
文頭文字の大文字化機能の
On/Off
autocorrect on / off input
textarea
オートコレクト機能の
On/Off
ongesturechange [JavaScriptコード] ほぼ全てのタグ マルチタッチによる画面操作中に位置が移動したときに実行するスクリプト
ongestureend [JavaScriptコード] ほぼ全てのタグ マルチタッチによる画面操作が終了したときに実行するスクリプト
ongesturestart [JavaScriptコード] ほぼ全てのタグ マルチタッチによる画面操作が開始したときに実行するスクリプト
onorientationchange [JavaScriptコード] body 端末の向きが変化したときに実行するスクリプト
ontouchcancel [JavaScriptコード] ほぼ全てのタグ 画面タッチがキャンセルされたときに実行するスクリプト
ontouchend [JavaScriptコード] ほぼ全てのタグ 画面タッチ中に指が離れたときに実行するスクリプト
ontouchmove [JavaScriptコード] ほぼ全てのタグ 画面タッチ中に位置が移動したときに実行するスクリプト
ontouchstart [JavaScriptコード] ほぼ全てのタグ 画面タッチが開始したときに実行するスクリプト




ongestureから始まる属性



ongestureから始まる属性は、複数の指による画面操作(ジェスチャー)を行った際に実行されるイベントハンドラ。
<img src="images/example.jpg" ongesturestart="function();">

みたいな感じで使う模様。


onorientationchange属性



iPhoneを横向きや縦向きに変更したときに実行されるイベントハンドラ。
<body onorientationchange="function();">  

こう書くより良いのかな…?
window.onorientationchange = function () {
switch ( window.orientation ) {
case 0:
break;
case 90:
alert('横向きには対応していません');
break;
case -90:
alert('横向きには対応していません');
break;
}
}



ontouch属性



マウスで言うところの「onmousemove」とかそういうのっぽい。
<img src="images/rectangle.gif" ontouchstart="function();">  



iPhone向けSafari専用のmetaタグ



metaタグのname属性 content属性 説明
apple-mobile-web-app-capableyesフルスクリーンモードを指定する
apple-mobile-web-app-status-bar-styledefault / black /
black-translucent
ステータスバーの表示を制御する
format-detectiontelephone=noキーワード認識機能を制御する
viewportwidth=device-width など多数論理ウィンドウサイズを指定する


Safariから「ホーム画面に登録」したあと、そのアイコン(ブックマーク)からページにアクセスすると、Safariのステータスバーなどが一切表示されないので、まるでネイティブアプリみたいになるので、こいつは特に捗るかも。

<meta name="apple-mobile-web-app-capable" content="yes">



Mobile Bookmark Bubbleと組み合わせるとけっこういいかも。