ちょっとなげやり。
PHPではデスクトップアプリは普通作れないので、なにかWindowsで使えるプログラムが使いたいと思った。
PHP以外のプログラム経験はというと、一応Cで基本情報取ったので理論上Cが使えるということになるはずなのだが私が取得した2007年秋のCは言語知識が一切無くても点数取れるというちょっとどうなのよそれ状態だったので未だにポインタが理解できず、BASICはMSX-BASICが最後でかつExcelVBAでテキスト操作が多少できる程度であり、JavaはSJC-WCもSJC-WSも持っておきながらHelloWorldが限界ではっきりいって何もできないのと同義である。
そんなわけで使う言語を選ぼうと思ったが、どうせなら統合開発環境が楽でよかろう。
というわけでマイクロソフトからはVB、VC++、VC#の3種類が提供されている。
http://www.microsoft.com/japan/msdn/vstudio/
高いものは数百万とかするが、何れもフリーで使用できるExpressEditionがあり、個人使用レベルならそれで十分だろう。
ちょっとだけ試してみた結果では、やはりVBが圧倒的に簡単なようで一瞬で電卓が出来た。
C++は難しすぎてちょっと無理そうなのでVBかVC#でもぼちぼちやってみようかなと。
というわけで早速何故かXNA入れてみた。
http://www.microsoft.com/japan/msdn/vstudio/
XNAとはC#の一種で、これで開発するとWindowsとXBOX360どちらでも動くプログラムが出来るそうだ。
適当なサンプルを打ち込んでみたらエラー。
No suitable graphic card found.
Could not find a Direct3D device that haz a Direct3D 9 level driver and supports pixel shader 1.1 or grater.
This program requires pixel shader 1.1 and vertex shader 1.1.
残念。
Smarty/pluginsフォルダあたりを覗いてみると、modifier.escape.phpといったファイルが並んでいます。
実はこれが修正子の正体です。
仕組みは単純で、Smarty内で{$data|escape}という修正子が現れたらmodifier.escape.phpを読み込み、その中のsmarty_modifier_escapeという関数を実行するということになっています。
ところでtruncate修正子に日本語を突っ込むと、区切る文字数も正しくないし区切ったところが文字化けしたりします。
modifier.truncate.phpを見てみると、文字を区切るときにsubstrを使用しています。
substrは日本語に対応していないのでtruncate修正子では日本語を扱うことができません。
そこで日本語に対応したmb_truncate修正子を作成してみましょう。
まずpluginフォルダ内にmodifier.mb_truncate.phpを作成。
中身は簡単にこんなかんじ。
modifier.mb_truncate.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
function smarty_modifier_mb_truncate($string, $length = 80, $etc = '...'){
//引数
$length+=0;
if(!$string || $length == 0){return '';}
//返却
if(mb_strlen($string)>$length){
//長ければ切って返す
return mb_substr($string,0,$length).$etc;
}else{
//短ければそのまま
return $string;
}
}
|
使用するときはテンプレートに
{'あいうえお'|mb_truncate:3}
と書くだけです。
これで自動的にmb_truncate修正子を利用してくれます。
さて、このmb_truncateはSmarty改造の入り口みたいなもので、色々なサイトで解説されています。
http://webtech-walker.com/archive/2007/04/26154112.html
http://jbar.jp/ishimaken/xoops/
http://c-brains.jp/blog/wsg/07/06/14-160910.php
一番下のソースと全く同じことになってますが本当に偶然ですから。
誰が書いてもこんなもんだって。
数年来ヲチしているDAKINIですが、一言で言うと電波です。
別に素人が適当扱いてるとかならどうでもいいしそんなブログありふれているのでどうでもいいんですが、
問題は彼が開発者を自称しているところです。
しかもミリオン売ったとか豪語してましたからな。
そんなわけでついた名前がミリデレ(ミリオンディレクター)
時々エアミリデレとも呼ばれます。
というか大抵のことについて底が浅いので、大抵のことについてエア**と呼ばれます。
その酷さは、2ちゃんねるの最底辺と言われているゲハ住民の、なおかつ思想的に近そうな関係でありそうなPSファンボーイですら忌み嫌うほど。
実際今回のエントリとコメントを見るだけでもその理由がわかります。
>最初からPSフォーマットで出さなかった事に対して、申し訳なかったという気持ちを正しく表明する必要がありますよね。
発言者が開発者だなんて信じられますか?
気違い以外の何者でもない。
過去のエントリも大概これクラスの暴言妄言珍言だらけで頭が腐ります。
それに比べて本物の開発者の発言の如何に重みがあるものか。
http://dochikushow.blog3.fc2.com/blog-entry-1211.html
>とりあえず、仕事としてゲームに口挟む奴は、それなりの覚悟をもってして欲しい。
ん?そうでもないか?
かつてゲハ板の底辺としてA助というこれまた頭のおかしい人物が居たのですが、というか今も居るのですが、最近ではこのA助をも凌ぐ人気っぷりを披露しています。
怒りに身を任せてみたい方にお勧めのブログです。
あんまりまとまってないまとめWiki
http://www24.atwiki.jp/dakini/
言うまでもなく私はゲーム開発者ではなく素人なので、言いっぱなしです。
exec、passthru、バッククォートといった命令は直接OSコマンドを叩いてくれます。
正直これらの命令の違いがいまいちわからないのですが、バイナリじゃなければとりあえずexecでいいやー的な。
問題点としては、OSのコマンドを直接叩くので環境によって互換性がありません。
typeはLinuxではコマンドの詳細を表示するコマンドですが、Windowsではファイルを読み込んで表示するコマンドです。
うっかりバッククォートを使ってしまうと環境移動の際に大変な目に遭うこともありますが、PHPでは処理が面倒なことをシェルコマンドを使用することで非常に簡単に処理できたりするといったメリットもあります。
ディレクトリ内の一部ファイルをページャーつきで新しい順に取得したい、などといった要求があった場合、PHPだけで処理を行うのは非常に困難です。
標準関数ではopendir、readdir、is_fileあたりを駆使して一旦全ファイルを取得後ソートしなければなりません。
あるいはdirクラスやDirectoryIteratorなんかもありますが、これらには取得条件を変更するメソッドなどは無いので、やはり一旦全ファイルを取得して並び替える必要があります。
ファイルが少数ならまだいいですが、何年も動いてるWebサーバのアクセスログをどうにかしろとか言われてもご勘弁願いたいところです。
こんなときこそOSコマンド。
exec('ls -At /var/log/apache2 | grep user_log | head -100 | tail -20',$dir);
わずか一行で済んでしまいました。
あとはheadやtailのところに適当にページャを埋め込めばさくっとログビューアの完成です。
最初に書いたとおり互換性には乏しく、bashのコマンドを使用しているのでLinux専用となっています。
Windowsのコマンドプロンプトにはlsもgrepもheadもtailも/var/log/apache2も存在しないため、このコマンドは動作しません。
Windowsと両対応させるにはおとなしくopendir等を利用するしかないでしょう。
配列を丸ごと保存して後で内容を確認したいとかいう場合、実はいまいち便利な関数がありません。
その場で表示するならvar_dump()するだけで中身を全部表示してくれますが、この関数、結果を返り値として受け取ることができません。
print_r()は結果を取得できますが、var_dump()程の詳細な情報は取得できません。
implode()は一次元配列しか使えませんし、serialize()だとPHPではわかりやすくても人間の目にはわかりづらくなってしまいます。
Pear::XML_Serializerに突っ込めば簡単にXMLになりますが、単に配列を表示したいだけなのにPearだのXMLだのをわざわざ使用するのもなんだかなーといった感じです。
結局foreachでぐるぐる回すといった力業になりがちです。
そんなときにバッファリング。
var_dump_buffering.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
//なんか適当な配列
$arr=array(
1
,2
,3=>array(
'hoge'=>'fuga'
)
,4=>'aaaaa'
);
//文字列として取得
$ret=ob_var_dump($arr);
print($ret);
//var_dumpの中身を返す関数
function ob_var_dump($obj){
ob_start();
var_dump($obj);
$ret=ob_get_contents();
ob_end_clean();
return $ret;
}
|
出力を簡単に取得することができました。
これをそのままログに突っ込めば、後から人間に見やすい形になるでしょう。
まあ、この使い方はマニュアルに堂々と書いてあるんですがね。
http://jp.php.net/manual/ja/function.var-dump.php
Qtip 1.0.0-rc3
http://craigsworks.com/projects/qtip/
リンク上にカーソルを動かしたときにツールチップを表示するjQueryプラグインです。
onMouseOverで適当にテキストを挿入するなり、なんならJavaScriptを使用せずCSSだけでもできたりはします。
またalt属性やtitle属性を指定すれば大概のブラウザはその内容を自動的に表示したりしてくれます。
http://phpspot.org/blog/archives/2008/03/javascriptcss_2.html
まあとりあえずcssとqTipでそれぞれツールチップを書いてみます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="jquery.qtip-1.0.0-rc3.min.js"></script>
<script type="text/javascript"><!-- //JavaScriptでツールチップ
$(document).ready(function(){
$('#qtip_tooltip').qtip({ //id="qtip_tooltip"に対して
content: 'qTipで吹き出し' //表示する文
,style:{ //スタイル
color:"red"
,background:"lightgreen"
,border:{ //外枠
color:"#000000"
,radius:2
}
,tip: {corner:"leftTop"} //角
}
,show: 'mouseover' //表示、非表示にするタイミング
,hide: 'mouseout'
});
});
--></script>
<style type="text/css"><!-- /* CSSでツールチップ */
/* ツールチップを隠す */
#css_tooltip span#css_tooltip_span {
display:none; padding:2px 3px; margin-left:8px; width:130px;
}
/* マウスオーバーで表示する */
#css_tooltip:hover span#css_tooltip_span{
display:inline; position:absolute;
background:lightgreen;
border:1px solid #000000;
color:red;
text-decoration:none;
}
--></style>
</head>
<body>
<a href="#" id="css_tooltip">
CSSでツールチップ
<span id="css_tooltip_span">CSSで吹き出し</span>
</a>
<br />
<a href="#" id="qtip_tooltip">
qTipでツールチップ
</a>
</body>
</html>
|
実際の動作はこのようになります(マウスオーバーで動作)
CSSでツールチップ CSSで吹き出し
qTipでツールチップ
この程度ならCSSでもqTipでもたいして変わらないですね。
qTipが便利なのは、ポップアップする場所やタイミングといった内容をHTMLに直接書くこと無しに、jQueryのセレクタやイベントを使って書けるということでしょう。
マウスオーバー時だけではなく、クリック時やオンロード時といった好きなタイミングで自由なポップアップを行うことができます。
セレクタもIDさえあればonclickみたいなロジックを書く必要も無く、HTMLからロジックを完全に排除して書くことができるようになります。
Smartyでは変数の出力時に簡単にフィルタをかけることができます。
これらは修正子と呼ばれています。
{$str|escape}
と書くと、$strにhtmlspecialchars()が適用された上で表示されます。
他に{$str|nl2br}
とすると変数内の改行が<br />に、
{$str|replace:'a':'b'}
とすると$str中の'a'が'b'に置換されて表示されます。
引数がある場合は:で区切って指定します。
また、複数の修正子を|で連結させて適用することもできます。
{$str|upper|lower}
とすると、$strを大文字に変更し、その後小文字に変更して表示します(結局小文字になる)
それ以外にも、何気にマニュアルに書かれているとおり、すべてのPHP関数を修正子として利用できます。
{$str|substr:5:3}
とするとsubstr($str,5,3)と同じ意味になります。
この場合第一引数が$str、substrの後ろが順に第二以降の引数という解釈になります。
というわけでこれを使用して、
$smarty->assign('yesterday',time()-60*60*24);
{'Y-m-d H:i:s'|date:$yesterday}
みたいな書き方もできたりします。
このような書き方は結構知られてないような気がします。
まあ普通は
{$yesterday|date_format:"%Y-%m-%d %H:%M:%S"}
としますけれども。
どうでもいいがdate_formatって名前なのにstrftimeの解釈をするのはどうなんだ。
さて、XSS対策に毎回エスケープかけるのは面倒臭い、という場合のためにデフォルトでエスケープする、というオプションがあります。
$smarty->default_modifiers=array('escape:html');
これをSmarty.phpに書いてみましょう。
この場合、出力は常にエスケープされて表示され、例外的にエスケープしたくない場合に
{$str|smarty:nodefaults}
というふうにするとエスケープせずにそのまま表示することができます。
基本的にこのオプションを使うほうが安全ですが、明示的に:escapeした方が明らかにエスケープしたとわかりやすいですし、そこは場合によると言うことで。
古いSmartyにはdefault_modifiersを指定すると配列が使えなくなるというバグがあったようですが、2.6.22では修正されているようです。
プログラムの規模が大きくなってくると、ロジックとデザインを一緒にしていたのでは見通しの悪く分かり難いプログラムになってしまいます。
そこでMVCパターンを使用したロジックとデザインの分離が現場ではよく使われています。
PHPでも各種フレームワークの開発が盛んですが、今回はフレームワークと言うほど本格的ではなく気軽に使えて普遍性の高いSmartyを使ってみます。
まずはSmartyを解凍すると色々フォルダが出てきますが、必要なのはlibsフォルダだけです。
アップロードを行う場合、できるだけhtdocsより上のフォルダ、ブラウザからは見えないところに置きましょう。
レンタルサーバ等で権限がないなら仕方ありませんが、その場合は推測しにくいフォルダ名にした上で、.htaccessやダミーのindex.hrml等を設置して直接覗かれる可能性を減らしておきましょう。
一応言っておきますが、公開フォルダに置く=公開する、です。
今回はこのような形で設置しました。
homes
├htdocs
│ └(各phpファイル)
└smarty
├libsフォルダ
│ ├Smarty.php
│ └(各Smarty関連ファイル)
├templatesフォルダ
└templates_cフォルダ
smarty/libsはSmartyファイルを置く場所です。
smarty/templatesは、表示用のテンプレートファイルを置きます。
画面表示のデザインなどはテンプレートファイルで行い、ロジックはhtdocs以下のphpファイルで行うことで、ロジックとデザインを切り離すことができます。
smarty/templates_cはコンパイルされたファイルを置きます。
Smartyの特徴として、一度表示されたファイルをその状態で保存しておくことができます。
二度目以降のアクセス時にはそのファイルを表示することで、ロジックを経由する時間と負荷を軽減することができます。
コンパイルフォルダはPHPが書き込みを行いますので、所有者と権限を変更しておきましょう。
smarty/libs/Smarty.phpは下記スクリプトで、Smartyクラスをインスタンス化し、上記のテンプレートの位置を決める等の初期設定を行います。
別にsmarty/libs/Smarty.class.php等を直接変更してカスタマイズしてもいいのですが、その場合元に戻したりするのが面倒なので別ファイルで行います。
smarty/Smarty.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//定義
//Smartyの場所(SMARTY_DIRはSmarty内部でも使用)
define('SMARTY_DIR',dirname(__FILE__).'/');
//テンプレートファイル置き場
$smarty_templates_dir=SMARTY_DIR.'../templates/';
//コンパイル済ファイル置き場
$smarty_templates_c_dir=SMARTY_DIR.'../templates_c/';
//Smartyセット
require_once(SMARTY_DIR.'Smarty.class.php');
$smarty=new Smarty();
$smarty->template_dir = $smarty_templates_dir;
$smarty->compile_dir = $smarty_templates_c_dir;
|
このファイルをincludeすることで、$smartyでSmartyインスタンスにアクセスすることができるようになります。
簡単に使ってみましょう。
htdocs/index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
//Smarty
require_once('./../smarty/libs/Smarty.php');
//変数
$str='string';
$arr=array(
'hoge'=>'<b>11111</b>'
,'hage'=>'<i>22222<i>'
);
//変数アサイン
$smarty->assign('a',$str);
$smarty->assign('b',$arr);
//表示
$smarty->display('index.html');
|
Smartyインスタンスにaとbふたつの変数をアサインし、index.htmlを表示せよ、と書かれています。
というわけで最後にindex.htmlを作ります。
smarty/templates/index.html
1
2
3
4
5
|
<html><body>
$str:{$a}<br />
$arr->hoge:{$b.hoge}<br />
$arr->hage:{$b.hage|escape}<br /></body></html>
|
これでどうなるかというと、
$arr->hoge:11111
$arr->hage:<i>22222<i>
</body></html>
このようなソースが出力されます。
Smartyテンプレート中で{$a}と書くと、その部分が$smarty->assignした変数の内容で置き換えられます。
同様に{$b.hoge}はアサインされた配列$b['hoge']が表示されます。
このように、テンプレート側では表示以外のことをさせないことで、表示のためにロジックをいじられたりすることを防ぐことができます。
またロジック側でも、表示側を考えることなく必要な変数をSmartyインスタンスに投げ込むだけでよくなります。
分業を行うことで、プログラムの見通しをよくすることができます。
またロジックを書くPG、テンプレートを書くコーダー等複数人が関わるプロジェクトに対し開発効率が上昇します。
逆に問題点としては、両者で変数の命名規則や配置方法などについてしっかり取り決めておかないと、あの変数は何処にあるんだ等行方不明になりやすくなったり、うまく表示するために奇怪なロジックを組んだりしなくてはならなくなったりします。
前回の続き?
文字列の暗号化とサーバ←→クライアント間の暗号化はまったく別のレイヤのお話です。
単に文字列だけではなく、サーバからの応答それ自体を暗号化しないといけませんので、PHPで云々ではなくApacheの設定、httpd.confの編集が必要です。
XAMPPの場合、関連する内容毎に設定ファイルを分けてくれていますので、C:\xampp\apache\conf\extra\httpd-ssl.confあたりがSSL関連の設定になります。
で、SSLCertificateFile、SSLCertificateKeyFileあたりがその設定になるのですが……実はhttpsでアクセスした場合、XAMPPでは最初から前回作成したserver.crt、server.keyが自動的に使われるようになっています。
これまでのURLを単にhttpsにするだけで、普通にSSLによる暗号化通信が可能となります。
問題点としては、認証局に認証を受けていないオレオレ証明書なので、初回通信時に警告が現れ、「許可する」を選ばない限り通信ができません。
これは、その証明書が、ルート認証局を辿れないだけの正しい証明書なのか、それとも悪人が途中ですり替えた偽物の証明書なのか区別が付かないためです。
これを銀行なんかがやってしまうと大問題なわけですが、個人レベルで高い金払って購入するのも馬鹿っぽいのでまあこんなものでいいでしょう。
さて、httpd-ssl.confにある、
<VirtualHost _default_:443>
の部分がSSL接続時の動作となっています。
デフォルトではhttp通信時と同じになっていますが、ここを変更することでSSL通信時のみの挙動を変更するなんてことができます。
<VirtualHost _default_:443>
DocumentRoot "C:/xampp/htdocs_ssl"
このようにすると、httpで接続した場合は元々の表示先であるところの"C:/xampp/htdocs"フォルダが、https接続の場合はこちらで設定した"C:/xampp/htdocs_ssl"フォルダがドキュメントルートになります。
このようにフォルダを分けることで、httpではどうやっても"C:/xampp/htdocs_ssl"に接続できない、といった設定を行うことができます。
会員登録などで必ずSSLを使わせたい場合などに有効です。
ただし、本気で個人情報を扱うような場合、オレオレ証明書は使用してはいけません。
しまった、PHP関係ない。