【PHP】質問スレッドpart19【php】

このエントリーをはてなブックマークに追加
131 ◆JirmzAivjs
>>128
http://www.teu.ac.jp/chiit/~dsuzuki/phpdoc/function.array-multisort.html
<?php
$list[0] = array('A2','A1','A0');
$list[1] = array('B1','B2','B0');
$list[2] = array('C0','C1','C2');
//ソート前
print("ソート前<br>\n");
for ($i=0;$i<sizeof($list);$i++) {
for ($j=0;$j<sizeof($list[$i]);$j++) {
$str = $list[$i][$j];
print("$str\n");
}
print("<br>\n");
}
array_multisort ($list[1],SORT_DESC,SORT_STRING,$list[0],$list[2]);
//ソート後
print("ソート後<br>\n");
for ($i=0;$i<sizeof($list);$i++) {
for ($j=0;$j<sizeof($list[$i]);$j++) {
$str = $list[$i][$j];
print("$str\n");
}
print("<br>\n");
}
?>
これを自分なりに変えてみ。
http://pc5.2ch.net/test/read.cgi/jisaku/1089171507/
でがんばってまつ。
132xxx:04/07/20 01:57 ID:zj8DyYfz
ごめんなさい!本当に分からないです。
Array ( [0] => 2004072000<>0<>xxx<>2<>0 [1] => 2004072000<>0<>index<>0<>0 )
の配列を中の[3]の配列の値でソートして、[2]の値のついたdatファイルを読み込んで表示させたいんです。
どうしたらいいか分かりません…。
どうしたらいいんでしょう?
133nobodyさん:04/07/20 02:34 ID:TlHHsRNJ
すいませんが解決法あったら教えてください。
HTML中の一部を繰り返したいのですが、

<html>
<body>
<?php
for(i=0;i<10;i++){
?>
test<br>
<?php
}
?>
みたいに書くことってできないんですか?JSPのように。
なんかエラーになってしまったんですが。
134133:04/07/20 02:37 ID:???
ごめん。
<?
for($i=0;$i<10;i++){
?>
だった。<?だけでいいんだね。↑は$もついてないし。
ごめん。
マジごめん。
135xxx:04/07/20 02:58 ID:zj8DyYfz
<html>
<body>
<?php
for($i=0;$i<10;$i++){
print("test<br>\n");
}
?>
じゃだめなの?
136 ◆JirmzAivjs :04/07/20 03:50 ID:???
>>132
http://www.mdir.org/tesss?act=0
http://www.mdir.org/tesss?act=1
>>131
の見てできんのかい(o_ _)ノ彡☆
137xxx:04/07/20 04:10 ID:zj8DyYfz
>136
いざむ(136)さん、出来ました。
ありがとうございました!!
138nobodyさん:04/07/20 05:08 ID:???
>>133
ちゃんとしたスクリプトを書けばできるよ。
(134でもまちがってるだろw)
たしかPHPの処理としては、<?php ?>の間以外は
そのままechoしてるのと同じ処理だからwhileとか
分割されてもできる。
139nobodyさん:04/07/20 07:55 ID:???
上で同じ事で迷っているようだから代わりに返事しよう
使用OS WinXp

php.ini
[mbstring]
mbstring.language = Japanese
mbstring.internal_encoding = SJIS
mbstring.http_input = auto
mbstring.http_output = SJIS
mbstring.encoding_translation = On
mbstring.detect_order = auto
mbstring.substitute_character = none;
;mbstring.func_overload = 0

これでSJISしか使えないEUCで書くと文字化け 
mbstring.internal_encoding = EUC-JP
mbstring.http_output = EUC-JP
これでEUCしか使えないSJISで書くと文字化け 
というのは理解できる。

mbstring.internal_encoding = EUC-JP
mbstring.http_output = SJIS
こうするとSJIS、EUC-JPとも文字化け

EUC-JPとSJISどっちも使えるようにするにはどうしたらいい?

尚phpのヴァージョン
5.0.0及び4.3.8〜4.3.4辺りまでのpackage及びinstallerは試してみたが全部だめだった
140 ◆JirmzAivjs :04/07/20 08:11 ID:???
>>139
default_charset = "Shift_JIS"を宣言していますか?

mbstringを有効にするのならば
phpインストールフォルダ以下のextensionディレクトリに
php_mbstring.dllは入ってますか?
extension=php_mbstring.dllのコメントはずしてますか?
141nobodyさん:04/07/20 10:50 ID:fJEHV2g/
print_r(array_values($mail=PReg_Grep($grep, $mail)));
こうしたら結果が下のように出るんですが

Array
(
[0] => [email protected]
[1] => <[email protected]>;
[2] => [email protected]
[3] => <[email protected]>;

)

print $mail[0];
としても何も表示されないのは何ででしょうか?
142nobodyさん:04/07/20 11:28 ID:???
>>141
print_r(preg_grep($grep, $mail));
143nobodyさん:04/07/20 11:33 ID:fJEHV2g/
>142
ありがとうございます。
しかし、print_r だと、配列の中身全部出てしまいます。

[0] => [email protected] ← このメールアドレスだけを、とって、処理に使いたいんです。
144nobodyさん:04/07/20 11:38 ID:???
>>1-143
マニュアル嫁
これで事足りる
145141:04/07/20 12:50 ID:fJEHV2g/
はまった・・
ob_implicit_flush(1);
while (@ob_end_flush());

これ先頭に書いたら表示されました
146nobodyさん:04/07/20 12:57 ID:yRgYyr5n
データベースとの連携で質問です。
フォームから得た値で
$query ="insert into table values(0,'$name','$type',$price,'$old','$grade',)";
とレコード追加をしようとしていますが

項目によってはフォーム未入力時も追加可としたいのですが
このままではエラーがでます。
上のコードの前に
if ($***=="") $***=0;
とすれば解決するのですが

もっと簡単な方法はないのでしょうか?
みなさんはどのようにしていますか?
147nobodyさん:04/07/20 13:10 ID:???
>>146
フォームから得るキーとそのデフォルトを配列にしておいて、
ループしながらやってる。
どのみち最低でもSQLインジェクション対処せんきゃならんし。
148nobodyさん:04/07/20 13:15 ID:???
フォーム入力のデータは一通り入力チェックかける様にしてる
SQL発行する際はPREPARE使ってる
149nobodyさん:04/07/20 14:45 ID:???
DBに書き込む際
型がおかしいとき、DBが判断してくれるのでDBが弾くのを任せるか
前もってPHP側で見てやるか、どっちがいいでしょう
150nobodyさん:04/07/20 14:49 ID:???
親切にエラーが出たフォームとか教えてやるにはPHP側でやるしか無かんべ
151nobodyさん:04/07/20 15:02 ID:???
PHP側でチェック
152nobodyさん:04/07/20 16:21 ID:yRgYyr5n
>>147
>>148
なるほど。有難う御座いました。
153nobodyさん:04/07/20 18:12 ID:???
フォームから得た値は管理者が入力するフォームで無い限りちゃんとサニタイズしろよ。
154nobodyさん:04/07/20 18:58 ID:???
WebProg作るならクロスサイトスクリプティングの脆弱性ぐらい気をつけんとね。
155nobodyさん:04/07/20 19:04 ID:???
DBに突っ込むだけの場合はサニタイズしてません
156nobodyさん:04/07/20 19:06 ID:???
>>155
なんで?真面目にその理由を聞きたい
157nobodyさん:04/07/20 19:07 ID:???
ログイン時に照会されるのみの情報だからです
158nobodyさん:04/07/20 19:09 ID:???
>>157
全然意味がわからんのだが
フォームデータにSQL仕込まれたらどうすんの?
159nobodyさん:04/07/20 19:15 ID:???
SQLから出したデータにもhtmlspecialcharsしておくべきですかね?
160nobodyさん:04/07/20 19:15 ID:???
入れるときにしてるんなら必要ないよ。
161nobodyさん:04/07/20 19:16 ID:???
意味が分からんねぇ・・・
"select * from auth where ID = ".$_POST['ID']
としてあとのパスワードやらをmysql_fetch_assocでDBから情報とって調べる
162nobodyさん:04/07/20 19:17 ID:???
え、俺、自分の欲しい物リストスクリプト作って使ってるんだが
全然サニタイズしてないや
したほうがいいのかなぁ・・・
163nobodyさん:04/07/20 19:18 ID:???
perlと違ってhtmlspecialchars()関数一個ですむのになぜめんどくさがるかねぇ
164nobodyさん:04/07/20 19:19 ID:???
function postVar($name){
if(isset($_POST[$name])) return htmlspecialchars(mb_convert_encoding($_POST[$name],"EUC-JP","UTF-8, UTF-7, ASCII, EUC-JP,SJIS, eucJP-win, SJIS-win, JIS, ISO-2022-JP"));
else return;
}


Nucleusからパクッた。マジお勧め
165nobodyさん:04/07/20 19:38 ID:???
>>161
$POST['ID']='aaa; delete from auth'みたいなのが入ってきたらどうすんの?
166139:04/07/20 19:56 ID:???
>140
サンクス!
default_charset = "Shift_JIS" が抜けてたらしい

php.ini

default_charset = "Shift_JIS"
extension_dir = "extensionsのある場所"
extension=php_mbstring.dll
[mbstring]
mbstring.language = Japanese
mbstring.internal_encoding = SJIS
mbstring.http_input = auto
mbstring.http_output = SJIS
mbstring.encoding_translation = On
mbstring.detect_order = auto
mbstring.substitute_character = none;
;mbstring.func_overload = 0

これでSJISもEUCも、使えるようになったが
↑以外の設定だとSJISで書いたプログラム側が文字化けしたことを報告する
つまり >108 のいう「例 3. SJISユーザ用のphp.iniの設定」では文字化け発生

追加として鯖システムはUNHTTPD。Apacheは他の奴報告してくれ
167nobodyさん:04/07/20 20:18 ID:???
<form accept-encoding="xxx">これ最強。
PEARのHTML_QuickFormを使えば再帰的にstripslashesしてくれて便利。

サニタイズはPEAR DBのquoteSmart使えばOK.
(数値型のデータなら事前にintval/floatvalしとく
 HTML_QuickFormのaddRuleと組み合わせるとなおよし)
168nobodyさん:04/07/20 20:30 ID:???
>>165
それでやられちゃうのか
全然知らん買ったよ
sql文を防ぐってdelete select insert updateぐらいをフォームデータに入ってるかチェックでいい?
169nobodyさん:04/07/20 20:37 ID:???
サニタイズってhtmlspecialcharsだけじゃだめ?
170nobodyさん:04/07/20 20:38 ID:???
SQLインジェクションはヤバイ。まじでヤバイよ。
まずdeleteできちゃう。もう1レコードなんてもんじゃない。テーブルごと。
何しろ無制限。スゲェ!なんか制限とかないの。
しかも他のテーブルも消せちゃう。ヤバイよ、真っ白だよ。
だって普通は削除できないじゃん。だって削除されたら困るじゃん。
データ消えたら困るっしょ。
だからそのCGIはロールバックできる。話のわかるヤツだ。
けど普通のCGIはヤバイ。そんなの気にしない。消えるだけ。

とにかく貴様ら、SQLインジェクションのヤバさをもっと知るべきだと思います。
そんなヤバい仕事をしてる貴様らとか超偉い。もっとがんばれ、超がんばれ。
171nobodyさん:04/07/20 20:39 ID:???
>>168
問題なのはこれ→「;」
一度セキュリティ関連のサイトを読むことをお奨めする
172nobodyさん:04/07/20 20:44 ID:???
>>171
なるほど。
でも、上の場合だと複問い合わせされることもあるよね?
その場合はselectとか見る必要あるよね?
173nobodyさん:04/07/20 20:44 ID:???
>>168 ポイントがずれてる
>>169 ぜんぜんだめ
MySQLならmysql_real_escape_stringした文字列をさらに'(シングルクォート)で囲む。
(PHP4.3.0未満はmysql_escape_string, PostgreSQLはpg_escape_string)
DB_common::quoteSmartは型を考慮してそこらへんを自動でやってくれる。
174nobodyさん:04/07/20 20:46 ID:???
>>173
へぇ
じゃあDB_common::quoteSmartだけ使えばいいんですね
175nobodyさん:04/07/20 20:55 ID:???
>>174
ごめん、説明の仕方が悪かった。quoteSmartは静的呼び出し無理ぽ。
PEARのDBクラスを使うときは
$db = &DB::connect($dsn);
$num = (int) $num; // 整数型のデータの場合
$str = $db->quoteSmart($str); // 文字列型のデータの場合
$sql = "SELECT * FROM hoge WHERE foo = $num AND bar = $str;';
$db->query($sql);
こんな感じでやります。詳しくはPEARマニュアル。
テーブル名やカラム名をquoteIdentifierするのが望ましいけど長くなるので省略。
176nobodyさん:04/07/20 20:58 ID:???
>>175
どうもありがとう。
今までPEARは全然使ったことなかったよ。
使った方が簡単そうでいいね。
177nobodyさん:04/07/20 21:21 ID:???
mysql_real_escape_stringは「;」が素通りしてしまうのですね
178nobodyさん:04/07/20 21:22 ID:???
>>166
そもそも本家(php.net)で配布しているWindows用バイナリは
「mbstring.internal_encoding = SJIS」
に対応してないことは知ってるんだろうな…
http://jp2.php.net/mbstring
「PHPで動作しない文字エンコーディング:JIS, SJIS」

スクリプトの記述エンコーディングにSJISを使うのなら
自分でビルド時にちゃんと「--enable-zend-multibyte」指定しないと駄目。
そうやってビルドしたWindows用バイナリは廣川さんが公開してくれている。
RPM等のバイナリも通常は「--enable-zend-multibyte」な指定はしないから、
ちゃんと確認して使用すること。
179nobodyさん:04/07/20 21:30 ID:???
フォームデータでどれをソートするかという情報を送るのですが
その場合、許可する文字列を列挙して
$regex=hoge|moge;

if ( isset($_GET['sort']) && ereg($regex,$_GET['sort']) $sort=$_GET['sort'];
としてるんですが、これで十分ですよね?
180nobodyさん:04/07/20 21:33 ID:???
>>176
DB_DataObject(を継承したクラス)を使えばもっと楽で、
型のキャストとか文字列のエスケープとかを気にしなくてよくなります。
マジおすすめ。
ひとつのクエリにひとつDB_DataObject(を継承したクラス)のインスタンスをつくって使います。
厳密にはそこまでしなくていいかもしれないけど、そうした方がハマらないと思う。
DB接続はグローバル変数に登録して使い回すので大丈夫。

>>177
文字列は''で囲むもんだから。
181nobodyさん:04/07/20 21:40 ID:???
>>180
自己レス。微妙に嘘ついてた。
WHERE句やORDER BY句とかは自分でサニタイズする必要ありです。
182nobodyさん:04/07/20 21:44 ID:???
>>180
DBにおいてはWHERE dat='$dat'としておけば$datに「;」が含まれていても
問題が起きにくいという事ですね
PHP5で遊んでいる環境なのでPEARも使えないですし、脆弱性についても
知識不足で穴だらけだったので大変勉強になりますm(_)m
183166:04/07/20 21:49 ID:???
>178
無論それを読んで、きちんと仕様通り試して文字化け発生して泡食って
最新からある程度古いのまでのWin用package及びinstallerを入れて、試した上で
日本語メーリングを検索かけて対応策が出てこなくて
こっちに辿り着いているのだが

それでも一つ見落としている辺り節穴だけどさ

ソースをビルドする技術が無いんじゃ使うのは無理ってことだよな?
184nobodyさん:04/07/20 21:56 ID:???
>>182
ダメだよ。
$datが data';delete from table;...
というように、'が入っていると...
' をエスケープしないと意味無い。
185nobodyさん:04/07/20 22:03 ID:???
>>184
あ、言葉足らずですいません^^;
私はINSERT INTO table SET でしか使わないので、こんな感じで
処理しようと考えているのですが大丈夫でしょうか?

function sql_esc_set($name,$var){
return $name."='".mysql_real_escape_string($var)."'";
}
186nobodyさん:04/07/20 22:17 ID:???
>>182
もし$datに'や\等の特種文字が入っていたら、問題が起こるので
必ず $dat = mysql_real_escape($dat); しておかないとだめ。
...と書いてたら>>184,185の流れが...
$name に MySQLの予約語(tableとかcreateとか色々)を使うことがあるなら
return "`" . $name . "`='" . mysql_real_escape_string($var) . "'";
だけど、その予定がないならそれでOK.

#PHP5でもPEARのメジャーなクラスは対応しているし、数は少ないけどPHP5専用のクラスもあります。
187185:04/07/20 22:18 ID:???
ん、難しく考える必要なかったのかも知れない・・・・
Formからのからのデータを全てhtmlspecialcharsとaddslashesとし、
SQLへはdat='$dat'とすれば良いのですよね?
188nobodyさん:04/07/20 22:23 ID:???
Webプログラミングする人は最初にこのページでも読んでください

IPA ISEC セキュア・プログラミング講座
http://www.ipa.go.jp/security/awareness/vendor/programming/index.html
189nobodyさん:04/07/20 22:29 ID:???
最初から出せカス
190nobodyさん:04/07/20 22:30 ID:???
インプット/アウトプット先 (DB, シェル, HTML ..) に合わせてエスケープ/除去する
それに必要な関数は全部 PHP に揃ってる。

QF とか便利だが、何故・どうしてを理解しないまま道具に頼って終わりってのは違うと思う。

で質問なんですが、
$db->query(,"SELECT * FROM hore WHERE id = {$_GET['id']}");
とかやってたとして、具体的に被害出せます?
例えば '";DELETE FROM hoge; とか突っ込んでも大抵の DB だと無効なクエリになるのでは、、
191nobodyさん:04/07/20 22:33 ID:???
俺もオモタ
>>165は失敗するんじゃないか?
1文として送信するんじゃないの?
192nobodyさん:04/07/20 23:08 ID:???
>>190-191
実行するよ。実際やってみれ。
要は$db->query("SELECT * FROM table;DELETE FROM table");
で後ろのDELETE文を実行してしまうかどうかだが、実行する。
193 ◆JirmzAivjs :04/07/20 23:20 ID:???
>>190-191
すべて有効になりますね。drop databaseなんて打たれたらどうします?
全部アボーンっすよ((;゚Д゚)ガクガクブルブル
194nobodyさん:04/07/20 23:23 ID:???
まあdrop権限など無いわけだが
195nobodyさん:04/07/20 23:27 ID:???
prepare使えるならprepare使っておけば問題ないよね?
196190:04/07/20 23:53 ID:???
>>192
やってみた。

index.php?gid=50001;DELETE%20FROM%20groups;
で、生成されたクエリが
SELECT * FROM groups WHERE gid = 50001;DELETE FROM groups;
実行結果は
DB Error: syntax error

index.php
--
$db = DB::connect($dsn);
$query = "SELECT * FROM groups WHERE gid = {$_GET['gid']}";
$rs =& $db->query($query);
while ($result = $rs->fetchRow())
{
print "<pre>"; print_r($result); print "</pre><hr>";
}
print "done";

('A`
197190:04/07/21 00:05 ID:???
>>196
おや、DBによって挙動が異なるのかな?
以前検証したときは、pgsqlでPearDBじゃなくてpg_queryだったんだけど、
確かに後ろ側も実行してましたよ。
198nobodyさん:04/07/21 01:38 ID:???
ファイルの最終行を取得する効率的な方法ない?
めっちゃファイルサイズ大きくて、全部読み込むの大変。
199nobodyさん:04/07/21 01:48 ID:???
>>198
$l = exec("tail -n 1 $filename");
200nobodyさん:04/07/21 01:58 ID:???
ていうか
delete from groupsでは構文がおかしくないか?
201198:04/07/21 02:11 ID:???
あ、tailを使えば良いのか。PHPでやろうとしてたらかなぁ、頭になかった。
ありがとん。
202190:04/07/21 02:28 ID:???
>>197
mysql だす。
MSSQL とか、初期設定で複数のクエリを通すので危険とか昔聞いたような聞いてないような。

>>200
普通に DELETE FROM groups で SQL 発行したら groups デーブルがきれいに空になりますた。


昔、ボルチモアテクノロジーのサイトが脆弱性吐いてた時に発見者の某 ML の中の人が
具体的な exploit コードを晒していたから何かあると思ったんだけど、、

結局、複数のクエリの実行を許していない時は、具体的な攻撃方法は今は無いって事で FA ?

データベース方面は必要最低限しかしらないもので、、頼り切りですまそ。
203nobodyさん:04/07/21 02:46 ID:???
readfileを使って、重めのファイル(5Mbくらい)を呼び出してダウンロードさせたいのだけど、
あんまりファイルのサイズが大きいとサーバー側に(「RLimitCPU」(CPU占有時間制限)で)
CGIプログラムの暴走と見なされることがあるのではないかと心配してるんですが、
実際の所どうなのか、分かる方おりますか?
204nobodyさん:04/07/21 03:40 ID:/GR6B3Fp


preg_replace_callback('/>([0-9]+)/','trans',$str);
function trans($str) {
//for($i=0;$i<count($str);$i++)
//{
$str[0]=$str[0];
//$str[$i]="<a href="'right.php'" name=$text[$i]>".$str[$i]."</a>";
//}
return $str;
}

実際にはfunction内のコメントアウト部とそうでない部分を入れ替えて使いたいのですがこの状態ですら機能しません。

エラーメッセージは
preg_replace_callback("/>([0-9]+)/","trans",$str); function trans($str[$i]) { //for($i=0;$i".$str[$i].""; //} return $str; }
Fatal error: Call to undefined function: trans()  in right.php on line 184

right.phpの184は
$text[$i]=trans($text[$i]);
以上のとおりです。preg_replace_callbackの設定に問題がるのでしょうか?



205nobodyさん:04/07/21 04:05 ID:/GR6B3Fp
ちなみにこれだと

<?php
preg_replace_callback('/>([0-9]+)/','henkan',$str);

function henkan($str)
{
for($i=0;$i<count($str);$i++){

$str[$i]="<a href='http://'>'.$str[$i].'</a>";
}

return $str;
}
?>

$text[$i]=henkan(text[$i]);

$twext[$i] に >1  と入れた場合のhenkan(text[$i]) は <1 と不等号の向きが変わってしまいアンカーもつきませんでした。
206nobodyさん:04/07/21 04:40 ID:???
つっこみどころ大杉。思い込みで間違った記述をしてる。
1. マニュアル(ttp://jp.php.net/manual/ja/function.preg-replace-callback.php)をよく読む。
2. マニュアルのサンプルコードを改造してやってみる。(一から書かない!)
3. それでもダメならもう一度ここに来る。
207nobodyさん:04/07/21 05:10 ID:/GR6B3Fp
>206
ありがとうございました。
解決いたしました。
何でああいう思い込みをしていたのか自分でも想像がつきません。
おそらくどこかのサンプルページを真似て書いたつもりだったのでしょうが、お恥ずかしい限りです。
済みませんでした。
208nobodyさん:04/07/21 09:18 ID:???
っていうかさ、サニタイズするのも当然だけどお前らバインド使えよw
209nobodyさん:04/07/21 09:26 ID:???
昨日からの書き込みを見てセキュリティを何も考えずプログラミングしている奴がいっぱいいて吃驚