※ パクレゼルヴではWeb開発エンジニアを大募集中!詳細はこちら

Archive

Author Archive

htmlメール  

2010/7/1 木曜日 3:54:13

おいすー^^

とかやってみる

こんばんは のびーにょです

HTMLメールについて

phpでHTMLメールを送る場合、

//送信元アドレス
$from "";
//BCCアドレス
$bcc ="";
//タイトル
$title ="";
//本文
$body ="";
//エラー時の戻り先
$replay="";

mb_language('Japanese');
mb_internal_encoding("UTF-8");
mb_detect_order("ASCII, JIS, UTF-8, EUC-JP, SJIS");
$header = "FROM: ".$from."\n";
$header.= "BCC: ".$bcc."\n";
$header.= "Return-Path: ".$from."\n";
$header.= 'MIME-Version: 1.0' . "\n";
$header.= "Content-Type: text/html; charset=ISO-2022-JP";

$title = mb_convert_kana($title,"KV");
$body = mb_convert_kana($body,"KV");
$body = mb_convert_encoding($body, 'JIS', 'auto');

mb_send_mail($mail,$title,$body,$header,"-f ".$replay);

ってやってやればbodyにhtml書けば送れるらしいよ。

$header.= 'MIME-Version: 1.0' . "\n";
$header.= "Content-Type: text/html; charset=ISO-2022-JP";

要するにヘッダーに上記を追加してやれば良いと言う話。
text/plainじゃなくてtext/htmlにしてやるべし。
MIMEもお忘れなく。

まぁPEARのMailとか使ったほうがいいけど。

と、まぁそんなことは割とどうでもよくて。

CSSで背景指定した場合

background-image:url(hogehoge);

とかね

HTMLメールだと背景画像が表示されないらしい。
主にhotmailとGmail

と、言うことで、じゃぁどうしようか ってなる。

ここで懐かしのテーブル背景!

<table background="hogehoge">

って奴

これならhotmailでもGmailでも背景として画像が使えるらしい

初めて知った

まぁ携帯ばっかり作ってたのでHTMLメールは知らないのです。

携帯のHTMLメールはマルチパート部分が結構複雑な上にキャリアでちょっと違う部分もあるので注意です。

機会があればそのへんも書きたいと思います。

のびーにょ HTMLとか, PHP

mysqlでINは内部的に処理できない  

2010/5/26 水曜日 0:33:39

お久しぶりです。

以前、ボトルネックになっているSQLを探していたら以下のような事がありました。

EXPLAIN SELECT * FROM user_master
	WHERE user_id IN (
		SELECT user_id FROM game_user_status);

とすると

+----+--------------------+------------------+-----------------+---------------+---------+---------+------+------+-------------+
| id | select_type        | table            | type            | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+--------------------+------------------+-----------------+---------------+---------+---------+------+------+-------------+
|  1 | PRIMARY            | user_master      | ALL             | NULL          | NULL    | NULL    | NULL |   86 | Using where |
|  2 | DEPENDENT SUBQUERY | game_user_status | unique_subquery | PRIMARY       | PRIMARY | 4       | func |    1 | Using index |
+----+--------------------+------------------+-----------------+---------------+---------+---------+------+------+-------------+

86*1 
で普通に意図した結果が取得できます。

しかし、サブクエリ中でGROUP BYすると酷いことになりました。

EXPLAIN SELECT * FROM user_master
	WHERE user_id IN (
		SELECT user_id FROM game_user_status GROUP BY user_id);
+----+--------------------+------------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type        | table            | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+--------------------+------------------+-------+---------------+---------+---------+------+------+-------------+
|  1 | PRIMARY            | user_master      | ALL   | NULL          | NULL    | NULL    | NULL |   86 | Using where |
|  2 | DEPENDENT SUBQUERY | game_user_status | index | NULL          | PRIMARY | 4       | NULL |   67 | Using index |
+----+--------------------+------------------+-------+---------------+---------+---------+------+------+-------------+

GROUP BYすると

86*67

と、検索ロジックに大きな違いが出てきます。

で、原因は”IN”句

MySQLは内部的にINを直接処理することができないので、EXISTSに変換することでSQL的には相関のないサブクエリも相関サブクエリになってしまうのである。これがまさにMySQLのサブクエリが遅い!と言われている原因だろう。
なぜMySQLのサブクエリは遅いのか。

だからってGROUP BY使っただけでそこまでしなくても・・・

と、いう事で以下のように書き換えると解決できるようです。

EXPLAIN SELECT * FROM user_master um
WHERE EXISTS
(SELECT 1 FROM game_user_status gus WHERE um.user_id = gus.user_id);
+----+--------------------+-------+--------+---------------+---------+---------+-----------------------+------+-------------+
| id | select_type        | table | type   | possible_keys | key     | key_len | ref                   | rows | Extra       |
+----+--------------------+-------+--------+---------------+---------+---------+-----------------------+------+-------------+
|  1 | PRIMARY            | um    | ALL    | NULL          | NULL    | NULL    | NULL                  |   86 | Using where |
|  2 | DEPENDENT SUBQUERY | gus   | eq_ref | PRIMARY       | PRIMARY | 4       | warui_test.um.user_id |    1 | Using index |
+----+--------------------+-------+--------+---------------+---------+---------+-----------------------+------+-------------+

個人のブログの方でご指摘いただきました内容を解答例とさせていただいています。
安直にINを利用するのは良くないという例でした。

ちなみにgroup by してもしなくても取得結果が変わらない場合もあります。
今回の例なんかはgroup by しなくても取得結果は変わりません。

むやみやたらと色々つければいいって物でも無い いい例です。

のびーにょ MySQL, Tips, データベース

画像認証(CAPTCHA)  

2010/4/16 金曜日 20:42:19

仕事で必要だったので画像認証(CAPTCHA)とか簡単に使えるスクリプトないかなーと探してました

色々あったんですが、ライセンスがどうとか色々言われそうだったので作ってみました。

と、言ってもサンプルコピペに近いですけど。

PEARにText_CAPTCHAってのがあったのでそれ使ってやってみます。

PHPはGDとttfをサポートしていないと使えないので注意してね!

まずPEARインストールでText_CAPTCHAを取得
依存関係の奴も全部

pear install  -a Text_CAPTCHA

ってやったら

Failed to download pear/Text_CAPTCHA within preferred state "stable", latest release is version 0.4.0, stability "alpha", use "channel://pear.php.net/Text_CAPTCHA-0.4.0" to install
install failed

とかって怒られたので

pear install -a channel://pear.php.net/Text_CAPTCHA-0.4.0

で取得
alphaバージョンとかbetaバージョンは普通にインストールできないので、バージョン番号まで入れろって事です

で、phpをファイルを以下のような感じで作ると

< ?php
require_once ("Text/CAPTCHA.php");
$CAPTCHA = Text_Captcha::factory('Image');
//locate .ttfとかやって適当にフォントファイルのパスを見つけて指定してあげてね!
//ちゃんとあるフォントファイル指定してあげてね!
$CAPTCHA->init(200, 70, null, array(
	'font_size' => 22,
	'font_path' => '/usr/share/fonts/japanese/TrueType/',
	'font_file' => 'sazanami-mincho.ttf'
	)
);
$img = $CAPTCHA->getCAPTCHAAsPNG();
//セッションに保存するとかしてね!
$_SESSION['captcha_pass'] = $CAPTCHA->getPhrase();
header('Content-type: image/png');
echo $img;
exit;

ってファイルを作ってやってそのファイルにアクセスしてみる

すると以下のような画像ができるはず!

20100213070928

セッションに保存したフレーズを次のページに遷移するときに、ユーザーが入力した値と比べて
きちんと認証されているか確認してね!

セッションに保存したフレーズは1回できちんと消すようにしないとだめだよ!

セッションにフレーズが保存されていない場合の処理も書かないと、認証スルーするかもしれないから注意だよ!
とかとか、適当にできるっぽいです。

のびーにょ PHP, Tips

携帯電話の特定のキャリアではおかしくなる例  

2009/11/24 火曜日 11:02:53

またまた時間が空いてしまいました。

お久しぶりです。
のびーにょです。

さて、表題の件

ラジオボタンがまともに動作しない場合

ドコモ、ソフトバンクの2キャリアでは正常に動作します。
また、PC等の一般的なブラウザでも正常に動作します。
しかし、auのみ正常に動作しません。

以下サンプル
html

<form action="http://example.com" method="POST">
	<input type="hidden" name="jb" value="test2_ez"/>
	<input type="radio" name="mail_receive" value="ALL"/>ALL<br />
	<input type="radio" name="mail_receive" value="YES" checked/>YES<br />
	<select name="s_hour">
		<option value="00">00</option>
		<option value="01">01</option>
	</select>
	<br />
	<input type="radio" name="mail_receive" value="NO"/>NO<br />
	<div style="text-align:center;">
		<input type="submit" name="regist" value="設定する" /><br />
	</div>
</form>

以下のような表示になります。

20091118161336

複数個のラジオボタンがあってセレクトボックスがある普通のフォームです。

ラジオボタンのグループはすべて同じグループです。

au以外の端末の場合は正常に動作しますが、
auの一部の機種(かなり多そうな感じではありますが)では正常に動作しません。

以下の画像のようになります。
20091118161337

ラジオボタンが複数個選択できてしまいます。
ALLとNOの2個のラジオボタンにチェックが入ってしまう状態です。

もう一度言いますが、グループは同一です。

これでPOSTしてしまうとセレクトボックスの下側(NOの方)が優先されてしまい、
上にあるALL、YESが2度と選択できなくなります。

解決方法は以下のhtml

<form action="http://example.com" method="POST">
	<input type="hidden" name="jb" value="test2_ez"/>
	<input type="radio" name="mail_receive" value="NO"/>NO<br />
	<input type="radio" name="mail_receive" value="ALL"/>ALL<br />
	<input type="radio" name="mail_receive" value="YES" checked/>YES<br />
	<select name="s_hour">
		<option value="00">00</option>
		<option value="01">01</option>
	</select>
	<br />
	<div style="text-align:center;">
		<input type="submit" name="regist" value="設定する" /><br />
	</div>
</form>

ラジオボタンを一か所にまとめてしまい、間にセレクトボックスを挟まないようにします。

HTMLファイルを同一にて記述する場合や、1キャリアのソースをコンバートする場合は注意が必要です。

ドコモの端末で動くからOKとかは危険なので気を付けてください。

セレクトボックスを指定したのにラジオボタンになる

以下のようなHTMLはauでは

次のページにすらいけなくなるので注意が必要です。

<div style="text-align:center;">
	<form action="http://example.com" method="POST">
</div>
	<input type="hidden" name="jb" value="test2_ez"/>
	<select name="s_hour">
		<option value="00">00</option>
		<option value="01">01</option>
	</select>
	<div style="text-align:center;">
		<input type="submit" name="regist" value="設定する" /><br />
	</div>
	</form>

※意図的に上段のdivの<を大文字にしています。
syntaxHighlighterが勝手にformを補完するようなので。。。

HTML的にどうなんだという部分はありますが、このHTMLでも

PCのブラウザやDoCoMo,SoftBankの携帯端末だとまともに表示され、POST,GETが可能です。

普通にこう見えます。
20091118161338

しかしやはりEzWeb ここでもやってくれます。

以下の画像や
20091118161339
こんなことになります。
20091118161340

この状態だとどのボタンを押しても前の画面に戻ります。

次のページへ移動はできません。

解決方法は以下

<form action="http://example.com" method="POST">
	<input type="hidden" name="jb" value="test2_ez"/>
	<select name="s_hour">
		<option value="00">00</option>
		<option value="01">01</option>
	</select>
	<div style="text-align:center;">
		<input type="submit" name="regist" value="設定する" /><br />
	</div>
</form>

まぁ、divの指定が悪いのは見ての通りなので消してやるか、formすべてを囲ってやればOK

最近HTMLの話ばかりでプログラムに関することはほぼ書いてない気がします。
というか、投稿の間隔が空きすぎていますね・・・

なるべく書くようにします。。。

のびーにょ HTMLとか, キャリア, 携帯電話

携帯電話のキャリア毎のHTMLの解釈の差を吸収する  

2009/7/31 金曜日 18:00:20

お久しぶりです

のびーにょです。

さて、携帯電話のHTMLに関するお話でも。

<div>
	<div style = "background-color:#FFAAAA">TITLE</div>
	<div style = "background-color:#CCCCCC">
		コンテンツ<br />
		コンテンツ<br />
		コンテンツ<br />
	</div>
</div>

ってな感じで書いた場合
ドコモ端末だと
block_dc1
ってな感じで
au端末だと
block_au1
こんな感じになっちゃいます。

divタグとdivタグの間に隙間ができてしまって、何ともみっともないことになります。
CSSでどうにかして隙間を埋めてしまいたいのですが、これはほぼ不可能です。

で、これ実はHTMLの書き方だけで同じようなレイアウトになります。

それが以下

<div>
	<div style = "background-color:#CCCCCC">
		<div style = "background-color:#FFAAAA">TITLE</div>
		コンテンツ<br />
		コンテンツ<br />
		コンテンツ<br />
	</div>
</div>

htmlの概念的にはよくはないんですけどね
イメージとしては以下のような感じ
灰色の部分がコンテンツのdivでピンクの部分がタイトルのdiv
s2

普通のイメージは
s1
こんな感じで、タイトルとコンテンツ部分の隙間をなくすようなCSSを書いたりしますが
携帯の場合、サポートしていない場合が多いです。

上記のHTMLで書いた場合は
ドコモ
block_dc2

au
block_au2
ってな感じで表示されて両方同じ見え方になります


もう一個例を出しましょう
1エリアごとに交互に色を入れ変えたい場合
良くあるのがランキングとか一覧表示とか
そのあたり。

<div>
	<div style = "background-color:#FFAAAA">aaaaa</div>
	<div style = "background-color:#CCCCCC">aaaaa</div>
	<div style = "background-color:#FFAAAA">aaaaa</div>
	<div style = "background-color:#CCCCCC">aaaaa</div>
	<div style = "background-color:#FFAAAA">aaaaa</div>
	<div style = "background-color:#CCCCCC">aaaaa</div>
	<div style = "background-color:#FFAAAA">aaaaa</div>
	<div style = "background-color:#CCCCCC">aaaaa</div>
	<div style = "background-color:#FFAAAA">aaaaa</div>
</div>

こんな感じで書きたくなりますよね。
でも、こう書くと
list_dc1
ドコモは問題ない

list_au1
でもやっぱりauで問題が出ます。

これも、以下のようなイメージでHTMLを記述することでドコモと同じように見せることが可能です。

s4

htmlはこんな感じで

<div style = "background-color:#FFAAAA">
	aaaaa
	<div style = "background-color:#CCCCCC">aaaaa</div>
	aaaaa
	<div style = "background-color:#CCCCCC">aaaaa</div>
	aaaaa
	<div style = "background-color:#CCCCCC">aaaaa</div>
	aaaaa
	<div style = "background-color:#CCCCCC">aaaaa</div>
	aaaaa
</div>

そうすると、ドコモ、auが以下のように同じように見えます。
list_dc2
list_au2

まぁ、そんな感じで一つ下のdiv要素の色を上の階層に持ってきてやると意図しない隙間をなくすことができます。


色々めんどくさいですけど、結構HTMLだけでも表現できたり色々便利
例えば、以下のような色分けを隙間なく表示したいときとかも
s5

<div style = "background-color:#FFF0E5">
	<div style = "background-color:#FFD0BF">
		<div style = "background-color:#FDDAF0">
			<div style = "background-color:#FABBEA">
				<div style = "background-color:#A3F27B">
					<div style = "background-color:#C0E9FA">
						<div style = "background-color:#FFF09C">
							<div style = "background-color:#F4DA67">
								<div style = "background-color:#ccccff">
									<div style = "background-color:#9966ff">
										<div style = "background-color:#FFB6C1">
											<div style = "background-color:#FF3333">
												<a href ="">
												<span style = "font-size:medium">
												かおもじ友の会</span>
												</a>
												<br />
											</div>
											┗3000個以上の顔文字やAAを収録!オリジナルな作品も投稿できてみんなで共有できちゃう!
										</div>
										<a href ="">
										<span style = "font-size:medium">
										あなたの過ごした時間</span>
										</a>
										<br />
									</div>
									┗時は金なり。あなたが生まれて今日まで過ごした「時間」について色々な角度から詳しく知りたいと思いませんか?
								</div>
								<a href ="">
								<span style = "font-size:medium">
								ちょいネタフーズ</span>
								</a>
								<br />
								</div>
								┗お手軽料理からネタ料理まで、レシピをケータイで簡単検索!オリジナルレシピも投稿しよう
							</div>
							<a href ="">
							<span style = "font-size:medium">
							切なさ成分解析</span>
							</a>
							<br />
						</div>
						┗身近な素材に含まれる「切なさ」を解析。結果を読むと思わず切なくなるかも?
				</div>
				<a href ="">
				<span style = "font-size:medium">
				明日に向かって叫べ</span>
				</a>
				<br />
			</div>
			┗魂の叫びに賞金がかかります!アナタも賞金首となって追われてみる?
		</div>
		<a href ="">
		<span style = "font-size:medium">
		NAME&nbsp;de&nbsp;QUEST</span>
		</a>
		<br />
	</div>
	┗あなたは世界を救う勇者となって、日頃の鬱憤を晴らすべく魔王に戦いを挑みます!
</div>

のびーにょ HTMLとか, Tips, キャリア, 携帯電話