2009年3月27日金曜日

PHPの fputcsv()で CSVを出力する

(2011/1/17 追記:まとめ的なものも書いた → floatingdays: PHPで CSVをダウンロードするための参考サイトとサンプルコード


PHPでCSVを出力するなら、fputcsv()が便利。

$fp = fopen('test.csv', 'w');
fputcsv($fp, array(123, 'abc', '"quoted"', ',,,', 'あああ'));
fclose($fp);



123,abc,"""quoted""",",,,",あああ

ポイント
  • 必要に応じてダブルクォートで囲ってくれる
  • データにダブルクォートを含む場合、ダブルクォートを2重にしてエスケープしてくれる


デフォルトではカンマ区切りになるが、第3引数で区切り文字を指定できる。

タブ区切り(TSV)にする場合の例
$fp = fopen('test.csv', 'w');
fputcsv($fp, array(123, 'abc', '"quoted"', ',,,', 'あああ'), "\t");
fclose($fp);


難点は文字コードの指定ができないこと。
CSVをExcelで普通に開く場合、マルチバイト文字がShift_JISでないと文字化けしてしまう。
事前にSJISに変換しておくしかないのか。



Google Codeの JavaScriptファイルを外部サイトから読み込んでも良い?

Google CodeでホスティングしているJavaScriptファイルやCSSファイルを、自分のサイトで読み込んでよいか?について調査。

Google自身によるIE7.jsやgmaps utility libraryなどのプロジェクトを見ると、Google CodeからJavaScriptを読み込んでも良いように書いてある。

Upgrade MSIE5-6 to be compatible with MSIE7.
<!--[if lt IE 7]>
<script src="http://ie7-js.googlecode.com/svn/version/2.0(beta3)/IE7.js" type="text/javascript"></script>
<![endif]-->
What's the purpose of this project?
We've realized that there are many possibly useful extensions of the Google Maps API for adventurous developers, but that the common user needs a reliable and quick-loading API.
(中略)
I want to use a library here in my maps mashup. What do I link to in my script include?
If you want to use a stable release, you should link to the code in the release project here: http://gmaps-utility-library.googlecode.com/svn/trunk/
Links to the release versions of each library are listed on the Libraries page.


また、(たぶん)Googleに在籍しているDaniel O'Brienさん
Is it ok to host javascript directly from Google Code?

Yes, so long as it doesn't send an extreme amount of traffic our way,

at which point requests might start being throttled.

と回答している。

なので、ある程度大量のトラフィックじゃなければOKみたい。


でも、Google Code Prettifyのところを見ると、自分のサーバに置いて使わないといけないと書いてある。
Include the script and stylesheets in your document (you will need to make sure the css and js file are on your server, and adjust the paths in the script and link tag)
from Javascript code prettifier

うーん?

JavaScript Hostを使ったほうがいいのかなあ?

PHPの ZipArchiveのエラーコード

ZipArchiveをopen()した時のエラーコードの定数と、実際の値を調べたのでメモ。

ZIPARCHIVE::ER_EXISTS = 10
ZIPARCHIVE::ER_INCONS = 21
ZIPARCHIVE::ER_INVAL = 18
ZIPARCHIVE::ER_MEMORY = 14
ZIPARCHIVE::ER_NOENT = 9
ZIPARCHIVE::ER_NOZIP = 19
ZIPARCHIVE::ER_OPEN = 11
ZIPARCHIVE::ER_READ = 5
ZIPARCHIVE::ER_SEEK = 4

でも、PHP: 定義済み定数 - Manual(コメント欄)にはもっと詳しく書いてあった。


参考:PHP: ZipArchive::open - Manual

PHPの ZipArchiveの open()に失敗する問題の解決方法

下記のようにPHPでZIPを作成する処理。

$zipArc = new ZipArchive();
$zipArc->open($path, ZIPARCHIVE::OVERWRITE);

以前は普通に実行できたのに、PHPをバージョンアップしたらできなくなっていた。

PHP: ZipArchive::open - Manualに解決策が書いてあり、それに従って下記のようにコードを変えたら実行できるようになった。
$zipArc = new ZipArchive();
$zipArc->open($path, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);

キーワードが少なくてGoogle検索し辛い問題だった。

ちなみに、定数の値は下記のようになっていた。
ZIPARCHIVE::CREATE = 1
ZIPARCHIVE::OVERWRITE = 8

2009年3月19日木曜日

主要JavaScriptフレームワークのデザインパターン傾向の比較

Prototype、jQuery、MooTools、YUI、Dojoを比較。
痒いところに手が届く、addEvent系とHTMLエレメントのclass操作を中心に見てみる。
大きくは、エレメントをグローバルオブジェクトにパラメータとして渡す"Managerパターン"と、エレメントを包んで機能を拡張する"Wrapperパターン"に分かれる。

  • Prototype.js
    • event追加
      • <element>.observe(eventName, handler)
      • Event.observe(element, eventName, observer, flg)
    • dom ready event追加
      • Event.observe(document, "dom:loaded", func)
    • class追加
      • Element.addClassName(element, className)
    • class削除
      • Element.removeClassName(element, className)
    • class有無
      • Element.hasClassName(element, className)
    • 全子要素に実行
      • <enumObj>.each(iterator)
    • デザインパターン
      • Managerパターン
      • Managerが役割分担でたくさんいる
  • jQuery
    • event追加
      • $(~).bind(type, data, func)
      • jQuery.event.add(elem, types, handler, data)
    • dom ready event追加
      • $(document).ready(func)
    • class追加
      • $(〜).addClass(className)
    • class削除
      • $(〜).removeClass(className)
    • class有無
      • $(〜).hasClass(className)
    • 全子要素に実行
      • $(〜).each(func)
    • デザインパターン
      • Wrapperパターン
  • MooTools
    • event追加
      • $(〜).addEvent(type, func)
    • dom ready event追加
      • window.addEvent("domready", func)
    • class追加
      • $(〜).addClass(className)
    • class削除
      • $(〜).removeClass(className)
    • class有無
      • $(〜).hasClass(className)
    • 全子要素に実行
      • <iterable>.forEach(func, bind)
      • <iterable>.each(func, bind) ※forEachのalias
      • $each(iterable, func, bind)
    • デザインパターン
      • Wrapperパターン
      • 関数名が素直で分かりやすい
  • YUI
    • event追加
      • YAHOO.util.Event.addListener(element, type, func, data, overrideContextFlg)
      • obj.customEvent.Subscribe(func) ※selectEvent等のCustomEventを持っているObjectの場合
    • dom ready event追加
      • YAHOO.util.Event.onDOMReady(func, data, overrideContextFlg)
    • class追加
      • YAHOO.util.Dom.addClass(element, className)
      • YAHOO.util.Dom.replaceClass(element, oldClassName, newClassName) ※classの変換
    • class削除
      • YAHOO.util.Dom.removeClass(element, className)
    • class有無
      • YAHOO.util.Dom.hasClass(element, className)
    • 全子要素に実行
      • 無し?
    • デザインパターン
      • Managerパターン。一部、Wrapperパターン。
      • グローバルオブジェクトが構造的に整理されている
  • Dojo
    • event追加
      • dojo.connect(element, type, context, func, dontFixFlg)
    • dom ready event追加

    • class追加
      • dojo.addClass(element, className)
    • class削除
      • dojo.removeClass(element, className)
    • class有無
      • dojo.hasClass(element, className)
    • 全子要素に実行
      • dojo.forEach(array, func, thisObject)
    • デザインパターン
      • Managerパターン


参考

Googleの CDNを使って jQuery UI Tabsを使う例

探してみたら、GoogleはCSSもホスティングしていた。
(jQuery UIのDemoがどこからCSS読み込んでるかを見てみてみたら、発見した。)


CSS&JavaScript

<link type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/blitzer/jquery-ui.css" rel="stylesheet" />

<script src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("jquery", "1");
google.load("jqueryui", "1");
google.setOnLoadCallback(function(){ $("#tabs").tabs() });
</script>
テーマはjQuery UI - ThemeRollerから選ぶ。(上記では"blitzer"。)
JavaScriptも静的読み込みにした方がレスポンスは良さそう。


HTML
<div id="tabs">

<ul>
<li><a href="#tab1">タブ1に表示する文字列</a></li>
<li><a href="#tab2">タブ2に表示する文字列</a></li>
<li><a href="#tab3">タブ3に表示する文字列</a></li>
</ul>

<div id="tab1">タブ1の内容</div>
<div id="tab2">タブ2の内容</div>
<div id="tab3">タブ3の内容</div>

</div>


関連記事:floatingdays: jQuery UI Tabsでタブのリンクを静的リンクにする方法


参考

2009年3月14日土曜日

Flexigridのサイトを見つけられない人へ

jQueryのプラグインでHTML Tableをリッチにするライブラリ"Flexigrid"のサイト(http://webplicity.net/flexigrid)をみようとすると、

This Account Has Been Suspended
Please contact the billing/support department as soon as possible.
と表示されて困っている人へ。

現在のサイトはFlexigrid - Web 2.0 Javscript Grid for jQueryですよ。
本体はGoogle Code上にあって、flexigrid - Google Codeですよ。

あと、flexigrid()のパラメータについては【ハウツー】わずか数行で"ものすごいテーブル"に! - jQueryプラグイン「Flexigrid」 (4)(中略)マイコミジャーナルを参照。

でもGoogle CodeからのリンクはSuspendedされた方のURLになっている...。

2009年3月5日木曜日

YUIの Menu Control Widgetを最小限のコードで使う例

ページ上部のシンプルなメニューの場合。
YUI Loaderを使うと一瞬、素のHTMLが表示されるので、事前にCSS・JavaScriptを読み込んでセットアップしたほうが見栄えがよい。

(2009/03/15 追記:htmlのbody要素開始タグにclass属性を追加)


CSS

<link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/yui/2.7.0/build/menu/assets/skins/sam/menu.css">

<style type="text/css">
.active-menu{
/* アクティブなメニューボタンの装飾をする */
background: #fff;
}
</style>

JavaScript
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/yui/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/yui/2.7.0/build/container/container_core-min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/yui/2.7.0/build/menu/menu-min.js"></script>
<script type="text/javascript">
YAHOO.util.Event.onContentReady("menu", function(){ new YAHOO.widget.MenuBar("menu"); });
</script>

HTML
<body class="yui-skin-sam">
<div id="menu" class="yuimenubarnav">
<div class="bd">
<ul>
<li class="active-menu"><a class="yuimenuitemlabel" href="http://google.jp">google</a></li>
<li><a class="yuimenuitemlabel" href="http://yahoo.jp">yahoo</a></li>
<li><a class="yuimenuitemlabel" href="http://goo.jp">goo</a></li>
</ul>
</div>
</div>

Googleの CDNを使って Dojoを使う例

google.load()を使った動的ロードだとロードされるまでの画面表示が辛いので、静的ロードにする。



CSS
@importではなく、link要素にしてみた。
@importを使う例が多いけど、違いは何だろう?

<link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/dojo/1.2.3/dijit/themes/soria/soria.css" />
<!-- or
<link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/dojo/1.2.3/dijit/themes/tundra/tundra.css" />
-->
<link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/dojo/1.2.3/dojo/resources/dojo.css" />


JavaScript

これでdjConfig属性が効いているのかは知らない
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.2.3/dojo/dojo.xd.js" djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dijit.form.Button"); //必要なものを読み込む
</script>


HTML
<body class="soria">
<button dojoType="dijit.form.Button" id="helloButton">
Hello World!
<script type="dojo/method" event="onClick">
alert('You pressed the button');
</script>
</button>
</body>


html要素を拡張していくという発想が面白い。VBライク?


参考:
Hello World - Dojo for the Attention-Impaired | The Dojo Toolkit
Developer's Guide - AJAX Libraries API - Google Code
tnomuraのブログ : Dojo の基本的な使い方
【特集】詳解! Dojo Toolkit 1.0(Dijit編) - ウィジェットプログラミングのツボ (4) イベント処理もマークアップで!(1) (中略)マイコミジャーナル

PHPで文字列の中から特定の文字列を探す関数の比較

PHP5での実行例。


検索対象の文字列と探したい文字列

$src = 'Sweet Apples, Pineapples and Green apples are.';
$search = 'apple';


/*** 位置を探す ***/
strrpos()はPHP4では$searchの最初の1文字のみが対象らしい。
//前から探す
var_dump(strpos($src, $search)); // -> 18
//前から探す(大文字小文字の区別なし)
var_dump(stripos($src, $search)); // -> 6
//後ろから探す
var_dump(strrpos($src, $search)); // -> 35
//後ろから探す(大文字小文字の区別なし)
var_dump(strripos($src, $search)); // -> 35


/*** それ以降の文字列を取得する ***/
strrchr()は、$searchの最初の1文字のみが対象なので注意。
strrichr()は無いようだ
//前から探す
var_dump(strstr($src, $search)); // -> 'apples and Green apples are.'
//前から探す(大文字小文字の区別なし)
var_dump(stristr($src, $search)); // -> 'Apples, Pineapples and Green apples are.'
//後ろから探す
var_dump(strrchr($src, $search)); // -> 'are.'


/*** マルチバイト対応の関数で探す ***/
文字列がマルチバイトの場合にはこちらで
//前から探す
var_dump(mb_strpos($src, $search)); // -> 18
//前から探す(大文字小文字の区別なし)
var_dump(mb_stripos($src, $search)); // -> 6
//後ろから探す
var_dump(mb_strrpos($src, $search)); // -> 35
//後ろから探す(大文字小文字の区別なし)
var_dump(mb_strripos($src, $search)); // -> 35


/*** マルチバイト対応の関数で、それ以降の文字列を取得する ***/
文字列がマルチバイトの場合にはこちらで
//前から探す
var_dump(mb_strstr($src, $search)); // -> 'apples and Green apples are.'
//前から探す(大文字小文字の区別なし)
var_dump(mb_stristr($src, $search)); // -> 'Apples, Pineapples and Green apples are.'
//後ろから探す
var_dump(mb_strrchr($src, $search)); // -> 'apples are.'
//前から探す(大文字小文字の区別なし)
var_dump(mb_strrichr($src, $search)); // -> 'apples are.'


/*** 正規表現(Perl互換)で探す ***/
戻り値はヒットした数
//最初の1つを探す
$rtn = preg_match('/' . $search . '/', $src, $matches);
var_dump($rtn); // -> 1
var_dump($matches); // -> array('apple')
//全て探す
$rtn = preg_match_all('/' . $search . '/', $src, $matches);
var_dump($rtn); // -> 2
var_dump($matches); // -> array('apple', 'apple')


/*** 正規表現(マルチバイト対応版)で探す ***/
3番目の引数を渡した場合、戻り値はヒットした文字列のバイト数
//最初の1つを探す
$rtn = mb_ereg($search, $src, $matches);
var_dump($rtn); // -> 5
var_dump($matches); // -> array('apple')
//最初の1つを探す(大文字小文字の区別なし)
$rtn = mb_eregi($search, $src, $matches);
var_dump($rtn); // -> 5
var_dump($matches); // -> array('Apple')
//先頭から一致するか調べる
var_dump(mb_ereg_match('.*' . $search, $src)); // -> true



参考:
PHP: String 関数 - Manual
PHP: マルチバイト文字列 関数 - Manual
PHP: PCRE 関数 - Manual (Perl互換正規表現関数)

Whatever:hoverの version 3 (csshover3.htc)がリリースされていた

Whatever:hoverのversion 3がリリースされていた。

詳細はれぶろぐ - [JavaScript] Whatever:hover の :focus 擬似クラスへの対応についてが詳しい。

でも:hoverをたくさん使っているページでのIEの挙動は相変わらずもっさりカクカク。

参考:» onmouseout IE flickering problem (Blog Archive) Alex Mauzon

Apacheで特定の User-Agentだけアクセス拒否する設定

メモ。

SetEnvIf User-Agent "^DoCoMo/2.0 P90liS" deny_agent

<Location />

 Order allow,deny
 Allow from all
 Deny from env=deny_agent

</Location>




参考:

mod_setenvif - Apache HTTP サーバ

mod_authz_host - Apache HTTP サーバ

ブログ アーカイブ

tags