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

Archive

Archive for the ‘HTMLとか’ Category

簡単な入力フォームこそ気を付けよう  

2010/5/31 月曜日 22:57:17

phpで作る入力フォームでやってしまいがちな事を紹介します。

入力した情報を確認画面で表示させる、というよくあるパターン。
(ベタ書きで失礼します。)

▼form.php(入力画面)

<form method="post" action="./confirm.php">
	ニックネーム: <input type="text" name="title" value="" /><br />
	<input type="submit" value="送信" />
</form>

▼confirm.php(確認画面)

< ?php
if(isset($_POST['title']) && $_POST['title']){
	echo htmlspecialchars($_POST['title']);
}else{
	echo '未入力';
}
?>

これ、一見問題無さそうですが、ある文字を入力すると未入力と表示されてしまいます。

そうです。

0(ゼロ)です。

TRUEかFALSEかで判断しているため、post送信された0はFALSEとして見なされます。

なのでこうやりましょう。

▼confirm.php(確認画面)

< ?php
if(isset($_POST['title']) && $_POST['title'] != ''){
	echo htmlspecialchars($_POST['title']);
}else{
	echo '未入力';
}
?>

どうしても「0」という名前で登録したいんだ!というお客様がいないとも限りませんからね。。

 

さて、もう一つ紹介します。

クロスサイトスクリプティング(XSS)のお話です。

今度は同じphpファイル自身にpost送信するパターン。
▼http://example.com/test.php

< ?php
// なんらかの処理
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
…
</form>

action先に何の迷いも無く

$_SERVER['PHP_SELF']

と書くと、実はこれが結構危ないのです。

他のhtmlファイルで下記のようなソースを書き、上記のスクリプトへのリンクを貼りましょう。
そして、クリックしてみましょう。(攻撃!)

<a href="http://example.com/test.php/%22%3E%3Cscript%3Ealert('xss');%3C/script%3E/">攻撃</a>

JavaScriptが実行され、アラートが表示されるかと思います。

URLの後半部分はURLエンコードされたものです。

$_SERVER['PHP_SELF']は、渡されたURIのホスト部分の後から、
GETクエリ部分の前まで(?の前まで)をURLデコードした形で格納します。

つまり、$_SERVER ['PHP_SELF']は、

/test.php/"><script>alert('xss');</script>/

となるので、

<form method="post" action="/test.php/"><script>alert('xss');</script>/">

となり、JavaScriptが実行されてしまうわけです。

 
では結論。
このようにしましょう。

</form><form method="post" action="">
…
</form>
<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
…
</form>
<form method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>">
…
</form>

空にしてあげるのが一番ラクかと思います。

MoriMoriMoriMori HTMLとか, PHP

カラーコード、カラーネームのバリデーション  

2010/4/30 金曜日 17:14:35

久しぶりの投稿です。
HNはチョコボールでしたがMoriMoriMoriMoriに変えます。
無意味にCamelCaseで。

管理画面でdivブロックのタイトル背景色なんかを設定する項目で、
入力項目に正しいカラーネーム、カラーコードが入力されているかどうかをチェックする
バリデーションの関数を紹介します。

// 有効なカラーネーム(147色)もしくはカラーコードかどうかチェック
function checkColor($str, $name)
{
	if($str == ''){
		return '';
	}
	// カラーネーム配列(147色)
	$arrColorName = array('aliceblue','antiquewhite','aqua','aquamarine','azure','beige','bisque','black','blanchedalmond','blue','blueviolet','brass','brown','burlywood','cadetblue','chartreuse','chocolate','coolcopper','copper','coral','cornflower','cornflowerblue','cornsilk','crimson','cyan','darkblue','darkbrown','darkcyan','darkgoldenrod','darkgray','darkgreen','darkkhaki','darkmagenta','darkolivegreen','darkorange','darkorchid','darkred','darksalmon','darkseagreen','darkslateblue','darkslategray','darkturquoise','darkviolet','deeppink','deepskyblue','dimgray','dodgerblue','feldsper','firebrick','floralwhite','forestgreen','fuchsia','gainsboro','ghostwhite','gold','goldenrod','gray','green','greenyellow','honeydew','hotpink','indianred','indigo','ivory','khaki','lavender','lavenderblush','lawngreen','lemonchiffon','lightblue','lightcoral','lightcyan','lightgoldenrodyellow','lightgreen','lightgrey','lightpink','lightsalmon','lightseagreen','lightskyblue','lightslategray','lightsteelblue','lightyellow','lime','limegreen','linen','magenta','maroon','mediumaquamarine','mediumblue','mediumorchid','mediumpurple','mediumseagreen','mediumslateblue','mediumspringgreen','mediumturquoise','mediumvioletred','midnightblue','mintcream','mistyrose','moccasin','navajowhite','navy','oldlace','olive','olivedrab','orange','orangered','orchid','palegoldenrod','palegreen','paleturquoise','palevioletred','papayawhip','peachpuff','peru','pink','plum','powderblue','purple','red','richblue','rosybrown','royalblue','saddlebrown','salmon','sandybrown','seagreen','seashell','sienna','silver','skyblue','slateblue','slategray','snow','springgreen','steelblue','tan','teal','thistle','tomato','turquoise','violet','wheat','white','whitesmoke','yellow','yellowgreen');

	// 精査用に小文字に統一
	$str = strtolower($str);
	if(!preg_match("/^[0-9a-f]{6}$/",$str) && !preg_match("/^[0-9a-f]{3}$/",$str) && !in_array($str, $arrColorName)){
		return $name.'のカラー指定が不正です。<br />';
	}
	return '';
}

データベースへの登録の際、カラムには、カラーネームの場合はそのまま入れ、
カラーコードの場合は、「#ffcc33」のように先頭に#を付けて登録してあげたほうが良いかと思います。
なぜなら、出力の度にカラーコードの場合は#を付ける、
といった判定をする処理を入れるのはパフォーマンスが悪いからです。
微々たる差異ですが。

出力の際のコーディング(ベタ書き)です。

if($title['bgcolor'] == ''){
	echo '<div style="text-align:center;">'
}else{
	echo '<div style="text-align:center;background-color:'.$title['bgcolor'].';">';
}
echo 'ブロックタイトル';

XHTMLでは16進数のカラーコードの英字は小文字で指定した方が良いので、
XHTML前提で利用する場合、「FFCCCC」のように入力された場合は強制的に
「#ffcccc」のように小文字にして(#もつけて)登録してあげてもいいかもしれません。
また、入力欄にカラーコードの場合、#つきで入力されても通るようにしてあげるとさらに親切かと。

fontタグのcolor属性の値やbodyタグのtext属性の値等は、
3桁の16進数での表記は当然ダメですよ!

■ダメな例

<body text="#000">
<font color="#fff">

ついでに書きますが、XHTMLでの属性checkedの誤った書き方。

<input type="radio" checked />

属性=”属性値”という書き方が基本なので、

<input type="radio" checked="checked" />

と書きましょう!

以上、MoriMoriMoriMoriMoriMoriでした。

MoriMoriMoriMori HTMLとか, MySQL, PHP, データベース

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

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, キャリア, 携帯電話

携帯CSSちょっとメモ  

2008/9/19 金曜日 23:37:57

こんばんわ。かーつんです。

さっき調べてて分かったことを、
ちょこっと残しときます。

携帯でCSSを使うとき、
例えば以下のように書くと

style="font-size:xx-small"

携帯の機種によっては思わぬ表示が起こります。
今回遭遇したのは、xx-largeを指定していた文字同士が、

行間が狂って重なり合って表示される。

コレを解消するには。

style="font-size:xx-small;"

と、キチンと「;」を付け忘れることなく、
正しい書き方で書く。

そう。これだけ。。。

意外と忘れてしまいがちな「;」ですが、
PCでは何ともない事が携帯では大惨事に繋がるようです。

かーつん HTMLとか, 携帯電話