【PHP】質問スレッドpart34【php】
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2006/03/21(火) 10:19:14ID:???【ガイドライン】
質問の前にgoogleやマニュアルを検索してください。
http://www.php.net/manual/ja/
http://php.s3.to/namazu/
◆質問する場合の注意
1. 自分のIDを表示させること。(メール欄には何も記述しないでください)
2. ハードウェア、OSのバージョン等を明記すること。
3. 己の行った操作、変更などを詳しく明記すること。
4. エラーメッセージはそのまま表記すること。
5. 質問者としても態度をわきまえること。
◆質問後の注意
・質問者は必ずIDを表示させてください。
書き込む場合はメール欄に何も記述しないでください。
・2回目以降は最初に質問した際のレス番号を名前欄に入れてください。
(逆に回答者は質問者に対して>>(アンカー)をつけて答えてください。)
・解決しなくても回答をもらった場合はお礼を言う。
(荒らし、煽りは除く)
【その他諸注意】
・正規表現・PEAR・テンプレート(Smarty等)・フレームワークはそれぞれの該当スレへ
・SQLについての質問はデータベース板(PCカテゴリ)の各スレで
・オブジェクト指向については良スレがないから本を買え
・速さについては自分でベンチをとってここに書け(違う環境の人も調べてくれるかも)
過去スレ、関連リンク、FAQ等>>2-10辺り
0203nobodyさん
2006/03/32(土) 00:44:03ID:???0204nobodyさん
2006/03/32(土) 01:38:41ID:???0205nobodyさん
2006/03/32(土) 11:46:23ID:???NHKでポロリ画像!!
0206nobodyさん
2006/03/32(土) 13:08:55ID:???function getPost() は、DBから投稿を取って配列を返す関数なのですが、
DB取得に失敗した場合、return falseにしています。
これだと、成功時に配列、失敗時にfalseというわけのわからない関数になってしまうのですが
みなさんはどうしていますか?
0208nobodyさん
2006/03/32(土) 13:44:24ID:???ま、マジですか???
呼び出し側で使いづらい…
PHP4なんですが、例外をthrowってできるんでしょうか…
0209nobodyさん
2006/03/32(土) 13:52:16ID:???例外はPHP4じゃできない。
呼び出すときは
if ($result === false)
みたいなコードを必ず入れる。
PHPは標準関数だってそういうのだらけでしょ。
別に0件取得できたのと失敗で取得できなかったのとの間に何の違いも必要ないならarray()を返してもいいけど。
いちおう一般的な方法はfalseを返すってことだけ言っておく。
あとは好きにして。
0210nobodyさん
2006/03/32(土) 14:06:33ID:???丁寧にありがとうございます。
すごくよくわかりました。
#そっか、0件と失敗は違うか…ヤバイな俺
その通りやってみます。
0211nobodyさん
2006/03/32(土) 15:32:40ID:???配列処理関数(countとか)も引数にスカラーを
受け付けるようにして欲しいよな。(array()と同じ扱いで)
エラー判定マンドクセ
0212nobodyさん
2006/03/32(土) 17:02:14ID:???@ foreach とか書ければましだったのに。
0213nobodyさん
2006/03/32(土) 18:25:31ID:???0214213
2006/03/32(土) 18:26:21ID:???0215nobodyさん
2006/03/32(土) 18:57:46ID:???たかだか2行ぐらい書くのも出来ないのか?
if ($filelist = glob()) {
foreach($filelist as $file) {
}
}
0218nobodyさん
2006/04/02(日) 14:17:12ID:???「PHP側でHTTPコネクションを接続状態のまま維持しつづけることについて」のご意見をお聞きしたいのです。
やりたいことはレスポンスがほぼリアルタイムなWebチャットです。
現在のWebチャットは、ブラウザが5秒毎や10秒毎にサーバーにHTTP接続し、更新が無いかチェックしていますよね。
それを↓こうすることによって、ほぼ即レスポンスなチャットを実現したいのです。
writeTalk($str); // 自分の発言を記録
while(true)
{
Sleep(1); // 1秒くらいは流石にスリープさせよう。
if (checkRenew()) // 更新チェック。
{
// 更新があったので、更新内容を受け取らせる
print readRenew();
return;
}
}
実際はクライアント側がタイムアウトしてしまうので、30秒に一度くらいは接続張りなおしが必要になると思いますが、概念的にはこんな感じです。
これなら、理論上1秒ちょい程度の遅れでほぼ即レスポンスなチャットが作れます。
実際にこれで作ってみて、そうなることも確認しました。
ただ、サーバー負荷が非常に心配です。10000人とか接続したらどうなることやら。
更新内容を1秒毎に読みに行っており、例えばfopenでtxtを扱っているとしたらファイル読み込みが頻繁に起こります。
しかもHTTPコネクション張りっぱなしですし。(Apacheはそんなに大量にコネクションを張れるのかな?)
これを軽減する良い知恵はないものでしょうか。
0219nobodyさん
2006/04/02(日) 15:02:33ID:???まずベータテストを実施して負荷を計測。
負荷がひどいならサーバを増設するとかキャッシュするとか更新チェックの頻度を減らすとかの処置をする。
0220nobodyさん
2006/04/02(日) 15:56:58ID:???1万人が一斉に書き込んで1万人に同時配信するだけでもかなりの帯域が必要。
ログもすぐ溢れるね。
0221nobodyさん
2006/04/02(日) 16:05:47ID:???ふつうのサーバでApache使ってちまちまやってる場合じゃなくて分散システムとか導入しないと無理じゃないの?
つーかそんなシステムをPHPで書く時点ですごい度胸だ・・・
0222nobodyさん
2006/04/02(日) 17:33:27ID:???0223nobodyさん
2006/04/02(日) 17:54:33ID:???0224nobodyさん
2006/04/02(日) 18:20:25ID:???お返事ありがとうございます。
やっぱり実施してみるしかないですかね。
>>221
通常のチャットですと、10000人が利用していても10秒間隔とかだからいいんですけどね。
これでやると実人数と等しい数のコネクトが行われているわけで
>>222
Ajaxは裏でHTTP通信するだけのシステムですから。
実際これのテストはAjaxを使ったチャット+ボードゲームでした。なかなかいいレスポンスでいいんですよね。
大規模に持っていければ商売にと思ってるんですが…
0225nobodyさん
2006/04/02(日) 22:45:31ID:???0226nobodyさん
2006/04/02(日) 23:53:58ID:???0227nobodyさん
2006/04/03(月) 01:51:15ID:???0228nobodyさん
2006/04/03(月) 01:57:26ID:???0230nobodyさん
2006/04/03(月) 02:31:50ID:???0231nobodyさん
2006/04/03(月) 04:22:01ID:???0232nobodyさん
2006/04/03(月) 06:55:49ID:???0233nobodyさん
2006/04/03(月) 08:32:05ID:???「ぜひ買いたいこの一冊(脆弱性コードレビュー練習用その1)」
http://takagi-hiromitsu.jp/diary/20060114.html#p01
> p.340 に書いてあった。
> function indi_check($p_string, $p_name) {
> if (strlen($p_string) == 0) {
> $this->disp_err_message($p_name." は必ず入力してください");
> }
> }
> 脱力。SQLインジェクション脆弱性だ。
なぜこれがSQLインジェクションになるのかわかりません。その上のコード(SQLを生成している部分)なら話はわかるのですが。
0234nobodyさん
2006/04/03(月) 09:07:11ID:???その上のコードでindi_checkとやらを呼び出しているけど、その定義部分で「p.340 に書いてあった〜」のようなチェックしかしていないからSQLインジェクション脆弱性だと言いたいんじゃないの?
0235nobodyさん
2006/04/03(月) 10:36:17ID:???SQLインジェクション対策をしているんだろうと思われる関数を見たら文字数しかチェックしてないんで脱力したんだろ。
0236nobodyさん
2006/04/03(月) 10:45:25ID:???ああなるほど。じゃあfunction indi_check()自体にSQLインジェクションがあるのではないということですね。しかしわかりにくい文章だな。
解答ありがとうございました。
0237nobodyさん
2006/04/04(火) 09:37:31ID:???0238nobodyさん
2006/04/04(火) 09:50:03ID:???0239nobodyさん
2006/04/04(火) 09:53:43ID:???必死すぎて笑えるのもいるけど。
0240nobodyさん
2006/04/04(火) 10:13:12ID:???趣味で書いたコードばら撒いてごめんね。
0241nobodyさん
2006/04/04(火) 10:14:23ID:???仕事くれれば「いくらでもやりますよ」なんて奴が多い業界は終わるだろ。
0242nobodyさん
2006/04/04(火) 13:03:45ID:???phpもオープンソースだから無料だよね。じゃあハード代だけでいいよね。
究極は、ハードディスク代出すから、phpのサイトコピーして納品してじゃね?
ソフトウェアは将来無料になるな。
0243nobodyさん
2006/04/04(火) 13:34:22ID:???0244nobodyさん
2006/04/04(火) 14:00:54ID:???無料無料に集中しすぎで労力が対価にあってない
0245nobodyさん
2006/04/04(火) 15:06:44ID:???利用者が納得しない。時代の流れってものがある
テクノロジーの進化、スキルの進化、出来ない企業は淘汰されてゆく
0246nobodyさん
2006/04/04(火) 19:55:15ID:???WindowsとASPでもいいじゃん。
帯域は、一般向けは安く定額でも、大規模鯖でIXとかに1Gbpsとかで繋ぐと従量課金だからなあ。
0247nobodyさん
2006/04/05(水) 01:17:08ID:???0248nobodyさん
2006/04/05(水) 03:16:31ID:???経済なんか自然界なみに激しいぜ
0249nobodyさん
2006/04/05(水) 17:52:10ID:zzYD4Tt9webで実行する時は、$_SERVER['HTTP_HOST'] で知ることができるのですが…。
0250nobodyさん
2006/04/05(水) 18:07:57ID:???CGIならともかくCLIでは判らんと思うよ。
CGIにCLI版を使ってるなら、環境変数に入ってると思うけど。
0251nobodyさん
2006/04/05(水) 18:13:46ID:DBudPhX7どういうことかというと、ASP(A8とかcross-A等)がIMGタグで呼び出されたphpファイルからcookieを読み込んでいるようなので、
顧客からの要望でそれと同じことをやりたいんですが・・・。
よろしくお願いします。
0253nobodyさん
2006/04/05(水) 18:43:08ID:???お! php -r 'var_dump($_ENV);' は、 array(0){} で空っぽでした。
が、 php -r 'echo `hostname`;' では、ホスト名取れました!
OSはFreeBSDです。
0254nobodyさん
2006/04/05(水) 18:55:17ID:???状況が全然わからん。
ユーザーから実際に送られたクッキーは全て$_COOKIEに入っているし、$_COOKIEで取得できないものはどうあがいても取得できないよ。
PHP内でさらに別のドメインにリクエストを送ってたりするってこと?
0255251
2006/04/05(水) 19:15:46ID:DBudPhX7レスありがとうございます。分かりにくい説明ですいません。
自分のサイトAと顧客のサイトBがあるとして、
サイトAでクッキーを発行して、その後サイトBでサイトAのPHPファイルをIMGタグで呼び出してもらいます。
この際に、発行したクッキーを$_COOKIEで読み込むことができないんです。
ただASPはこの方法でクッキー読み込んでいるようなので、
技術的には可能だと思います。
色々調べてみたのですが、分かりませんでした。
宜しくお願いします。
0258nobodyさん
2006/04/05(水) 20:13:50ID:???サイトA - hakkou.php
<?php setcookie(〜) ?>
サイトB - page.html
<img src="http://サイトA/image.php" />
サイトA - image.php
<?php $_COOKIE ?>
これで取得できないってこと?
ユーザーはクッキーを発行するページには前もってアクセスしてるの?
0259nobodyさん
2006/04/05(水) 20:30:49ID:???0260nobodyさん
2006/04/05(水) 21:19:43ID:???A8って自サイトでCookie発行して自サイトで読み込んでるじゃん。
いつから別ドメインで発行するようになったのよ。
0261nobodyさん
2006/04/05(水) 23:34:05ID:m1J71QWp< Query Result >
hoge | fuga
--------------
1 | AA
1 | BB
1 | CCC
2 | AA
このようなクエリを返すようにSQLを発酵し、fetchallで全件を$resultに格納しました。
このクエリ結果をsmartyを使ってテンプレートに貼り付けたいのですが、
1 : AA , BB , CCC
2 : AA
と表示するようにしたいのです。
そこで、次のようにしてみたのですが、何故か$hogeの最後にスペースが入ってしまい、
テンプレート側で「存在しないインデックス」だと怒られてしまいます。
どうしたら仕様のように表示できるのでしょうか。
0262nobodyさん
2006/04/05(水) 23:36:09ID:m1J71QWp// 以下ソース
for($i = 0 ; $i < count($result) ; $i++) {
while(list($key , $val) = each($result[$i])) {
if($key == "hoge") {
if(empty($hoge) || ($hoge != $val)) { $hoge = $val; }
}
if($key == "fuga") {
if(empty($data{$hoge})) { $data{$hoge} = $val; }
else { $data{$hoge} .= " , " . $val; }
}
}
}
$arr = array("1" => "あ" , "2" => "い");
$smatry->assign("result_data" , $data);
$smatry->assign("array_data" , $arr);
//----テンプレートファイル
{foreach from $result_data key="key" item="item"}
{$array_data.$key} : {$item}<br>
{/foreach}
0263nobodyさん
2006/04/05(水) 23:39:00ID:m1J71QWpあ : AA , BB , CCC
い : AA
と、表示したいのです
0264nobodyさん
2006/04/05(水) 23:55:38ID:???多分これが要因かな→$data{$hoge}
基本的な配列の使い方の間違い
if($key == "fuga") {
if(empty($data[$hoge])) { $data[$hoge] = $val; }
else { $data[$hoge] .= " , " . $val; }
}
検証してないが
0265nobodyさん
2006/04/06(木) 00:01:44ID:m1J71QWp$array[1]とかと同じように、$array[1](1は文字列)ってできるんですか?
殆どの参考文献では、$array{'apple'}みたいな書き方をしていたので・・・
$key = 'apple'; $array{$key} = "red";
みたいな。
0266nobodyさん
2006/04/06(木) 00:07:24ID:???http://pc8.2ch.net/test/read.cgi/php/1118799352/
0267nobodyさん
2006/04/06(木) 00:20:22ID:94BcmyXjなぜか$hogeの値が「"1"」でなく「"1 "」になってしまっているんです。
おかげで、$array_data.$keyが「存在しないインデックス」としてエラーになっちゃって・・・
smartyスレにしようかと悩んだのですが、エラー的な部分がsmartyでなく
PHP自体のほうにあると思ったので、こちらで質問させていただいた次第です。
一応、自分なりの解決策として、chop($hoge); を行ってみたのですが、効果はありませんでした。
0268nobodyさん
2006/04/06(木) 00:23:55ID:d/Co19xeどこかPHPの正規表現の解説&サンプルがあるサイトしりませんか?
なければperlでもいいです。
0271nobodyさん
2006/04/06(木) 00:58:21ID:???> あー・・・書いてなかったけど、hogeフィールドに入っている値はchar型なのです・・・
> $array[1]とかと同じように、$array[1](1は文字列)ってできるんですか?
$array["1"]って書けばOK。
> 殆どの参考文献では、$array{'apple'}みたいな書き方をしていたので・・・
それはPerlの書き方。
0272nobodyさん
2006/04/06(木) 01:01:21ID:???262のソースちゃんと読まないで言うが、
array(2) {
["あ"]=>
array(3) {
[0]=>
string(2) "AA"
[1]=>
string(2) "BB"
[2]=>
string(2) "CC"
}
["い"]=>
array(1) {
[0]=>
string(2) "AA"
}
}
こういった配列に集計されるように作った方が良いんではない。
0273nobodyさん
2006/04/06(木) 04:52:30ID:???実は$array['1']と$array[1]は同じなんだな。
自動変換が入るので区別するのは無理。
つか
>殆どの参考文献では、$array{'apple'}みたいな書き方をしていたので・・・
の時点で、PHPの参考文献を読み直す時点からやり直し
0274nobodyさん
2006/04/06(木) 06:07:05ID:???0276nobodyさん
2006/04/06(木) 20:36:07ID:eXsgEawwエラー時やデバッグ用にログファイルに情報を出力するLogクラスを作りました。
プログラムのどこからでもこのメソッドを簡単に呼べるように
インスタンスを生成することなしに
Log::write_log();
のようにしてアクセスできるようにと考えました。
1つ問題があって
出力先のログファイルを実行時に指定できるようにしたかったのですが
そのためには
インスタンスを生成するようにして
そのインスタンスのメンバ変数を変更するような実装にしないと
実現できませんよね?
ただそれだと、そのインスタンスを
プログラム内のログ処理を行う多くの関数で
グローバル宣言が必要になるので面倒で悩んでます。
よくある処理だと思うのですが
このログ出力のような実装はどのようにするべきなのでしょうか?
・クラスを使わずにただの関数として実装
・インスタンスなしのクラス + ファイル名などの設定値はグローバル変数で実装
一応思いついたのは上の2つですがどうもすっきりしません。
よろしくおねがいします
0278nobodyさん
2006/04/06(木) 22:07:12ID:???0279nobodyさん
2006/04/06(木) 22:54:00ID:???private static $fileName, $fp;
みたいにしといてLog::fileName()メソッドでファイル名を設定+fopen。
Log::writeLog()メソッドでは、ファイル名が指定されていない場合は例外投げるとかtrigger_error呼ぶとか。
あとクラス使わない他の方法としては、trigger_errorとphp.iniのlog_errorsで対応するとか、ログを取る場所をプログラム内であちこちに分散させないように設計するとか色々。
もちろん普通に関数やメソッドの引数でファイル名指定とかでもいいと思うし。
0280nobodyさん
2006/04/06(木) 23:56:36ID:94BcmyXj頂いたアドバイスをヒントに考慮した結果、無事に求めていた表示を出すことが出来ました。
0281nobodyさん
2006/04/07(金) 00:00:28ID:???0282nobodyさん
2006/04/07(金) 00:15:11ID:???$array[intval($item)]としてみたら空白が消えた。
よくよく考えたら「数字の文字列」なんだから、数字に変換しても問題ないんじゃないかな、とおもって。
お騒がせしました・・・・orz
0283nobodyさん
2006/04/07(金) 03:03:34ID:???続きなら以前のレス番を書くなり、アンカーなり付けてくれ
0284nobodyさん
2006/04/07(金) 05:46:44ID:???鯖の設定ミスでソース見れちゃうような言語はダメ。
0285nobodyさん
2006/04/07(金) 06:46:45ID:???0286276
2006/04/07(金) 10:20:43ID:???ありがとうございます
試してみてうまくいきました
こういうときはメンバ変数もstaticで宣言すればよかったんですね
これですっきり実装できそうです
0287nobodyさん
2006/04/07(金) 11:49:59ID:jJE5oi/7ある値について、「その値が文字列型であり、かつ、空文字列ではない」かどうかを
手っ取り早く判別する方法があれば教えてください。
単純に boolean 型にキャストするだけだと、'0' が FALSE として扱われるので駄目なのです。
自分が考えたのは、例えば
・ (boolean)strlen($var)
・ (is_string($var) && $var !== '')
などです。
ただし、前者の場合は、文字数を正確に数えるだけ処理が無駄ですし、
後者の場合はやや煩雑であるのが欠点です。
その他に何か良い方法がありますでしょうか?
0289nobodyさん
2006/04/07(金) 14:02:32ID:???0290nobodyさん
2006/04/07(金) 14:37:53ID:???「その値が文字列型であり、かつ、空文字列ではない」かどうかを調べたいんだから、素直に書いておくのが良いと思う。
(is_string($var) && $var !== '')
よりも良い書き方はなさそう。
あとstrlenが文字数を「数える」と思ってるらしいけど、そんなことはないから安心しなよ。
0291nobodyさん
2006/04/07(金) 14:44:13ID:???名前空間が汚れないってこととか、必要ならprivateなメソッドを増やして拡張できること、ってのもあるんじゃない?
あと例えばログのフォーマットをするメソッドをうまく分離しておけば、後々他人が使わざるを得ないときに、継承して楽に拡張できる可能性もある。
すばやくコーディングすることだけが目的ならばクラスは必要ないけどね。
備えあれば憂い無しってやつ。
0292nobodyさん
2006/04/07(金) 15:05:53ID:???>あとstrlenが文字数を「数える」と思ってるらしいけど、そんなことはないから安心しなよ。
そうなの?数えないんだ?
mb_strlen() はどうでしょう?こっちは数えますか?
0293nobodyさん
2006/04/07(金) 15:25:18ID:???> mb_strlen() はどうでしょう?こっちは数えますか?
エンコーディングの種類に応じて数える。
いろんな長さの文字列で時間測ってみればわかる。
ちなみに手元にあるPHP/4.3.3のソースでは
strlen - Zend/zend_builtin_functions.c:256 zend_if_strlen()
mb_strlen - ext/mbstring/mbfilter.c:7599 mbfl_strlen()
PHP5でもmbstring系のファイル分けで移動されてるけど内容はまったく同じ。
0296 ◆Ve5JH752sw
2006/04/07(金) 20:34:50ID:uvHuopgEdefine(PATH, pathtopath);
PHP勉強してる初心者ですが、
変数と定数の機能は同じに思えるのですが
どう違うんでしょうか?
0297nobodyさん
2006/04/07(金) 20:41:19ID:???> 定数を定義することができるのは、define()関数 のみです。単なる代入による定義はできません。
> 定数は、定義することができ、変数のスコープ規則に関係なく、あら ゆる場所からアクセス可能です。
> 定数は一度設定されると再定義または未定義とすることはできません。
> 定数は、スカラー値としてのみ評価可能です。
0298nobodyさん
2006/04/07(金) 20:42:47ID:???http://www.shigeweb.jp/php/project_p/?section=first&page=const
0299nobodyさん
2006/04/07(金) 21:19:11ID:???俺も最初同じじゃん、定数いらないじゃんと思っていた。
ポイントは>>297にあるように
1.書き換えられない
2.あらゆる場所からアクセス可能
ってところじゃない
0300nobodyさん
2006/04/08(土) 05:19:01ID:???定数って、例えば掲示板なら、ログのパスとか保存件数とかタイトルとか…そういう設定を定義する際に使ってた。
変数と違ってスコープとか関係ないから、関数の中からでもすぐに呼び出せて便利だなとか思ってた。
perlから入ったのでなおさらそう感じていた。(perlでは変数は特に宣言しなければグローバルなので)
ところが、例えばヒアドキュメント内に使いたければ一度変数に入れてから展開しなければいけないとか、
変数と違って"hage{$hoge}fuge"とか出来ないし、web用の設計してるとどうも不便な事が多い(特に出力面で)と感じ始めた。
結局、設定値は$CFGという連想配列作って
$CFG['xxx'] = 'yyy';
$CFG['aaa'] = 'bbb';
という具合に設定するやり方に帰結した。
お前らはどうしてますか?
■ このスレッドは過去ログ倉庫に格納されています