【PHP】質問スレッドpart18【php】
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
04/06/14 14:36ID:???・新規質問の方は上げてください。age進行でお願いします。
・質問する際には環境も明記。
・正しい日本語で分かりやすく。
・レスがつかないからって逆切れする厨お断り。
・解決しなくてもこたえてもらったら礼を。
■本家
http://www.php.net/
■日本 PHP ユーザ会
http://www.php.gr.jp/
■PHP マニュアル
http://www.php.net/manual/ja/
■PEAR マニュアル
http://pear.php.net/manual/ja/
過去スレ, 関連スレ等>>2-4
抜けているものがあったら補足願います
0020nobodyさん
04/06/15 01:01ID:???0021nobodyさん
04/06/15 01:07ID:???0022nobodyさん
04/06/15 02:24ID:???0023nobodyさん
04/06/15 03:21ID:???cgi.f13.aaacafe.ne.jp/~mugen/perlvsphp/mysql_mj/
PHPの内部プログラムに関しては全て高速設計。
出てくるデータ変換もPerl交互の正規表現で対処しているし、
何よりもセッションをファイルではなく、DBサイドでやってしまっている点。
素人がもたつく部分は、全て天才的なやり方が解決してきた。
将来的には箱庭を超えるもんに仕上がればいいと思っています(ぉ。
0024nobodyさん
04/06/15 03:29ID:???0026nobodyさん
04/06/15 08:37ID:???これってそんなに大層なことか?
0029nobodyさん
04/06/15 10:32ID:???常識的な技術を「僕チン凄いことやってるよー」みたいに見せかけて人を騙そうとする所なんか特にね
頭が悪いから詐欺師にはなれないと思うけど
0030nobodyさん
04/06/15 10:52ID:VBE/CSzdエラーメッセージやワーニングの改行が
<br /> になるのが気に入りません。
どうしたらいいでしょうか?
0031nobodyさん
04/06/15 11:03ID:???CLI版のPHPを使う。
http://www.php.net/manual/ja/features.commandline.php
CGI版も含めて、そもそも他のSAPIのものはHTTPを通して使うのが前提だからね。
どうしてもって言うなら出力バッファリングを使って、自分で取り除く。
0032nobodyさん
04/06/15 11:07ID:???0033nobodyさん
04/06/15 11:12ID:lLtRoZvOhtml_errors = Off
0034nobodyさん
04/06/15 13:29ID:GnjSLWGD0035nobodyさん
04/06/15 13:34ID:???0036nobodyさん
04/06/15 13:39ID:???echoやprintした内容がメモリに蓄積されているみたいで
例えばPostgresqlのラージオブジェクトから数GBのファイルを
出力しようとするとOut of Memoryで死んでしまいます。
というわけで、Postgresqlのラージオブジェクトから
メモリを節約しつつデータを出力させる方法を教えてくだsaina
0037nobodyさん
04/06/15 13:55ID:???$db = pg_connect(DB_CONNECT);
pg_query($db, "BEGIN");
$dblo = pg_lo_open($db, $oid, 'r');
while ($buf = pg_lo_read($dblo, 4096)) echo $buf;
pg_lo_close($dblo);
pg_query($db, "COMMIT");
pg_close($db);
0038nobodyさん
04/06/15 14:00ID:???0040nobodyさん
04/06/15 14:17ID:GnjSLWGDtelnetアクセスができないんですよ。
0041nobodyさん
04/06/15 14:23ID:???php.iniでは
output_buffering = Off
を宣言しており、スクリプト中でも特に変更はしていないつもりです。
output_handlerやzlib.output_compression等も無効にしています。
>>39
pg_lo_read_allで書くと便利で簡単なのですが、
なぜかメモリ使用量が今よりも大きくなってしまうので、現在の方法に変更しました。
0045nobodyさん
04/06/15 16:13ID:???004636
04/06/15 16:54ID:???そうなのです。
もしかして、httpで1GBを超えるデータは扱えないとか・・・
>>45
バッファリングを行うと、逆にメモリ使用量は増えてしまいますね。
implicit_flushはパフォーマンスが低下してしまうので、デバッグ用のようです。
試してみましたがやはり無理でした。
Apache2のフィルタ機能(複数のモジュールを通すことができる)が怪しい気がするので、
一度Apache1で試してみます。(PHPじゃないじゃんかYp!)
改善したらまた報告に来ます。
004736(解決!)
04/06/15 17:06ID:???46で「試してみましたがやはり無理でした」と書きながらも、ちょっと気になっていたので
調べてみると、「flushはechoの後でflush()を呼び出すのと等価」ということを聞き、
明示的に指定してみたところうまく動作するようになりました。
(45さん微妙にスマンカッタ)
$db = pg_connect(DB_CONNECT);
pg_query($db, "BEGIN");
$dblo = pg_lo_open($db, $oid, 'r');
while ($buf = pg_lo_read($dblo, 4096)) {
echo $buf;
flush();
}
pg_lo_close($dblo);
pg_query($db, "COMMIT");
pg_close($db);
お答えいただいた皆様ありがとうございました!
0048nobodyさん
04/06/15 18:42ID:???一次元だとforeach($array as $key => $value)でできたのですが・・・
0049nobodyさん
04/06/15 18:51ID:???005048
04/06/15 18:55ID:???$array[]としてもうまくいかないし。。どうすればいいでしょうか
0051nobodyさん
04/06/15 19:09ID:???という具合ではいかが?
0053nobodyさん
04/06/15 20:23ID:???多次元なので、
function array_echo ($_array){
static $indent = 0;
foreach ($_array as $key=>$value){
echo str_repeat("\t", $indent).$key."\n";
if (is_array($value)){
$indent++;
array_echo($value);
$indent--;
} else {
echo str_repeat('\t',$indent + 1)."=>$value\n";
}
}
}
っていう関数はどうかな。と思ったけど、var_dump() の方がいいよ。
0055nobodyさん
04/06/15 22:22ID:???0057nobodyさん
04/06/15 23:27ID:gVK53Lr1005855
04/06/15 23:42ID:???0059nobodyさん
04/06/16 00:22ID:???むぅ。カポコン日記には結構ためになる事書かれてるな。
多分、コイツはPHPメーリングもしっかり見てるぞ。
DBのセッションは結構アルゴリズムが人によって違うし、
使う関数も違っていたりするから大層なことだろ。
セッションを語れんでPHP語るなっていう名言があるの知ってる?
大体Javaが本業な奴に間違いは少ない、これ間違いなし。
ただカポコンはもう出てくるな。
0062nobodyさん
04/06/16 11:59ID:???0063nobodyさん
04/06/16 12:04ID:???telnetやsshによるシェル・アクセスの可否と
crontab使用の可否は直接の関連性はないよ。
シェルでメンテナンスが出来ないので、
スクリプトのチェックとか面倒な部分もあるけど。
使ってるサービスでcrontabの登録を出来る方法はないの?
コンパネ使うとか、フォームで申請するとか。
0065nobodyさん
04/06/16 13:27ID:???if(A)
と
if(A!=0)
どっちの方がいいのですか?教えてエロイ人
0067nobodyさん
04/06/16 14:13ID:???0070nobodyさん
04/06/16 15:22ID:???どっちも同じ結果になるので、どっちでもいいと思う。
コードを短かく書くことを優先するなら前者。
(あとで見てそれとわかるように)「0ではない」という意味を尊重して書きたければ後者。
PEAR のコーディング規約だとどーなんだろ?
false と 0 を違うものとして扱いたいとかゆーことであれば、"===", "!==" とか使う。
0071nobodyさん
04/06/16 15:35ID:???マニュアルの言語リファレンス・制御構造、言語リファレンス・型・論理型を見てみ。
FALSEと見なすものの多さに呆れて、明示的に比較したくなると思われ。
0072nobodyさん
04/06/16 15:38ID:hmUL29ONereg_replace str_replace strtr等使っても変換されません。
置換する対象の文字列はarrayの1つを受け取ったものなんですが
これが原因なのでしょうか?
$str=$array[0];
$str=ereg_replace("ア","イ",$str)?
0073nobodyさん
04/06/16 15:39ID:???booleanの FALSE
integerの 0 (ゼ ロ)
floatの 0.0 (ゼロ)
空の文字列、 および文字列の "0"
ゼロを要素とする 配列
ゼロを要素とする オブジェ クト
特別な値 NULL (値がセット されていない変数を含む)
007572
04/06/16 16:00ID:hmUL29ON文字コードがEUCっていうのは関係あるのでしょうか?
0076nobodyさん
04/06/16 16:14ID:???デフォルトだと内部エンコーディングが使われるので、もし違うなら
mb_regex_encodingで設定。
あってるなら、ちとわからぬ。
ちなみにphp4.2.0以上なので、それ以下なら使えないっぽ。
007772
04/06/16 16:25ID:hmUL29ON原因はなんだろう・・
直接 文字を入れた変数になら置換できるのに・・
0078nobodyさん
04/06/16 16:40ID:???マテ、配列からちゃんととれているのか?
配列は値が入っているのか?
print_r($array);
print "{$array[0]}";
$str = $array[0];
print "{$str}";
これで全部表示される事を確認したまい。
007972
04/06/16 17:06ID:hmUL29ON0080nobodyさん
04/06/16 17:14ID:???(;´Д`)?
あー、問題なければその配列の作成部分から取得->置き換え->出力までの流れを書いてみてくれ。
もうさっぱりだ。
0081nobodyさん
04/06/16 17:15ID:???0082nobodyさん
04/06/16 17:17ID:???0083nobodyさん
04/06/16 17:18ID:???0085nobodyさん
04/06/16 19:02ID:FlwZGV+n入力フォームから追加して、一覧にするまではできました。
問題は、編集時に文字化けが起こるんです。
list.phpが一覧表で、こんな感じに出力してます。
echo '<td><a href="redit.php?mode=edit&sid='.$row["sid"].'&brand='.$row["brand"].'&item='.$row["item"].'&c_price='.$row["c_price"].">編集</a></td>';
echo "<td> ".$row["sid"]."</td>\n";
echo "<td> ".$row["brand"]."</td>\n";
echo "<td> ".$row["item"]."</td>\n";
echo "<td> ".$row["c_price"]."</td>\n";
redit.phpへ $mode = 'edit' の時編集モードに入り、各値をGETで渡して、
echo '<form action="'.$_SERVER["PHP_SELF"].'?mode=edit&sid='.$sid.'" method="post">';
echo "<font size=\"3\"><strong>編集/削除</strong></font>";
echo '<tr align="center"><th>ブランド名</th><td><input type="text" name="brand" size="30" value="'.$brand.'"></td></tr>';
echo '<tr align="center"><th>アイテム</th><td><input type="text" name="item" size="30" value="'.$item.'"></td></tr>';
echo '<tr align="center"><th>仕入原価</th><td><input type="text" name="c_price" size="30" value="'.$c_price.'"></td></tr>';
echo "<tr align=\"center\"><td colspan=\"2\"><input type=\"submit\" name=\"post_mode\" value=\"編集\">
このように、valueで値をフォームに表示していますが、'ム'とか、ある一定の文字で文字化けが起こるんです。
PHPにも禁止文字ってあるんですかね?
この対処方をどなたか教えて頂けませんでしょうか?
文字コードはeuc で作成していて、サーバーLinuxでeucです。
0086nobodyさん
04/06/16 19:06ID:???http://jp.php.net/mbstring
0087nobodyさん
04/06/16 19:19ID:???とりあえずphp.iniかhttpd.confの文字設定あたりかな?
0088nobodyさん
04/06/16 19:30ID:FlwZGV+nご返答ありがとうございます。
さっきのURLのところの
PHP 4.3.0以降、このオプション --enable-mbstr-enc-trans は廃止され、mbstring.encoding_translation に変更となります。HTTP入力文字エンコーディング変換は、 このオプションをOnに設定した場合のみ 有効となります。 (デフォルトは、Offです。)
この辺が関係あるのかなとも思いますが、今は自鯖なんで設定いじれるからいいんですが
サーバーの仕様に関係なく表示させる方法ってないもんですかね?
そのまま処理が問題だとすると
フォームから追加するときに、sjisでSQLに入ってるから、
それをeucで表示しようとして、文字が化けるってことですかね?
でも、リストでは化けないので。。。うーん
0089nobodyさん
04/06/16 20:04ID:???1つ前のページからちゃんときてない場合(直リン、お気に入り等)は見れないようにしたいんです。
どうやるんですか?
0090nobodyさん
04/06/16 20:11ID:???そうならlistのほうもsqlから取った値は派手に化けるかと思うんだけど、、。
listでは化けないのにreditで化けるということは、reditへgetで値が渡ってくる時に、
ブラウザがエンコードした文字列の処理でこけてるということっぽい。
ムが化けたりするってことはブラウザからはsjisで来てるんだろうけど、
mb_detect_encoding()でエンコードが所望のものかどうかチェックしてみたほうがいいかも。
ブラウザからの値を内部エンコに変換する方法としは、iniをいじらないなら、
reditのほうでmb_language() + mb_http_input()で入力値を自動変換したり、
$_getの各値をmb_convert_encodingやjcode.phpで逐一変換してから処理するとか。
0091nobodyさん
04/06/16 20:13ID:BaSzqMZ7わからんけど
<a href="redit.php?mode=edit&sid='.urlencode($row["sid"]).'&brand='.urlencode($row["brand"]).'&item=以下略
はどうでしょう。
0092nobodyさん
04/06/16 20:19ID:???ブラウザが送ってくるrefererを見る。
リファラを送る機能の無いブラウザやセキュリティ対策ソフトを入れてるヒトは巻き添えで見られない。
.htaccessなど鯖側でやるものでphpではやらない。
session使えばもう少し複雑なコントロールもできるかな。
0093nobodyさん
04/06/16 20:23ID:???まあその辺りだろうな。
91のやり方は変更が少なくていいと思うが、
ユーザから編集後の文字列が渡ってくるわけだから、
どのみちエンコードは変換する必要がでてくることないか?
009472
04/06/16 21:37ID:hmUL29ON$fp = fopen($file,"r");
flock($fp, 1);
$file = fread($fp , filesize($file));
$file=mb_convert_encoding($file,"EUC","auto");
$csv=split("[\n]",$file);
for($i=1;$i<count($csv)-1;$i++){
$array=split(",",$csv[$i]);
$str=$array[11];
$str=mb_ereg_replace("あ","い",$str);
echo $str;
}
こんな感じでしょうか?
0097nobodyさん
04/06/16 22:13ID:???0100nobodyさん
04/06/17 00:24ID:???先のこと考えずに作るなら 取りあえず何にしてる?
0101nobodyさん
04/06/17 00:35ID:???0102nobodyさん
04/06/17 00:42ID:???OSがEUCなんでスクリプトもDBもEUCにしてる。
下手な小細工要らないし。スプリクトそのものはWin上で
EUCと改行コードLFで書いているんだけどな。
んだけど、UTF8なFedoraCore鯖がそろそろまわってきそうな悪寒。
文字コードそのものはFTPで転送するときに変換すりゃ済むのだが、
メタタグも書き換えるのは面倒そう。http鯖の設定でしのぐ方が
いいのか?
0103nobodyさん
04/06/17 00:52ID:???0104nobodyさん
04/06/17 00:58ID:???簡単な掲示板みたいのを作っているのですが入力されたテキストを
ファイルに保存する際に1件につき1行で格納したいと思います。
ファイルから読み出して表示する際には改行もありの状態にしたいので
保存・読み込みのそれぞれで、テキスト中の文字を以下のように相互変換して
やれば良いかなと思ったのですが・・・
[CR]←→"\r" [LF]←→"\n" \←→"\\"
下記のコードで、$s1 と %s3 が等しければ、相互変換は可能ということになりますよね?
$arr1 = array("\\", "\r", "\n");
$arr2 = array("\\\\", "\\r", "\\n");
$s1 = "ABC\r\nEFG \1,000";
$s2 = str_replace($arr1, $arr2, $s1);
$s3 = str_replace($arr2, $arr1, $s2);
echo "<pre>" . $s1 . </pre>";
echo "<pre>" . $s3 . </pre>";
ところが $s1が上のような場合は問題なく$s3で元に戻るのですが
$s1 = "ABC\\nDEF\\nGHI\\JKL"
などとすると元にもどりません。
何か間違っているでしょうか。
長文ですみませんが、ご教授ください。
0105104
04/06/17 01:00ID:???正しくはこうです。
echo "<pre>" . $s1 . "</pre>";
echo "<pre>" . $s3 . "</pre>";
0106nobodyさん
04/06/17 02:20ID:WEWy3iw0まだ実験的なものとかって書いてあるんだけどじゃあ何を使えっていうんだい?
だれか経験者いない?
0107nobodyさん
04/06/17 02:29ID:???1. 元データ $s1 → ABC\nDEF\nGHI\JKL
2. 変換 $s2 → ABC\\nDEF\\nGHI\\JKL
3. 逆変換 $s3 → ABC\nDEF\nGHI\JKL
各段階での変数の内容(リテラル)はこうなってるんだと思うが。
1で\\nはエスケープされて改行コードではなく文字列それ自体(ABC\nDEF)として$s1に代入、
2でその\nの\が\\に置換され(ABC\\nDEF)、
3で\\が\に置換される(ABC\nDEF)。
LFは$s1にそもそも入ってないから関係なし、と。
したがってコードはかかれたとおり正常に動作してる。
0108nobodyさん
04/06/17 02:34ID:???ってかなんでfor文を1から始めてるの?
ファイルの一行目は使わないってこと?
配列は0から始まるって事を勘違いしてたとしたら
$str=$array[11];
は
$str=$array[10];
の間違い。って事はない?
0109nobodyさん
04/06/17 02:36ID:???dom関数使えばいいよ。
phpでやろうというならdomかdomxmlかxmlparser(expat)かsimplexmlか、pearライブラリの
いずれかを選んでやるしかない。
0111nobodyさん
04/06/17 02:44ID:???なら変更があるといってもよほど妙な機能を使ってない限り
大したことないような。
漏れはSimpleXml関数とXml関数で足りてるからDOMのことば
よう知らんけど。
0112nobodyさん
04/06/17 02:51ID:???csvなら一行目が定義フィールドな可能性はある。
まあイテレータが1から始まる理由にはならんけど。
つーかそれ以前にエラー処理とかflockの定数とかありえない文字コードの指定とか
splitを使ってるとことかキャラクタクラスが\nなとことか""で囲まれた値を考慮してないとか
毎回countしてるとことかfgetcsvを使ってないこととか無意味な代入とか、
ようするに釣りじゃなければなんだってことのほうが重要だと思うけど。
0113nobodyさん
04/06/17 02:58ID:zQROHTgZ0114104
04/06/17 02:59ID:???ありがとうございます。
それが正常にならないのです。
各段階を実際に出力させてみると、以下のようになってしまいます。
(上から$s1 $s2 $s3 です)
<pre>ABC\nDEF\nGHI\JKL</pre>
<pre>ABC\\nDEF\\nGHI\\JKL</pre>
<pre>ABC
DEF
GHI\JKL</pre>
書き忘れていましたが環境は PHP4.3.7 + IIS5.0 です。
0115104
04/06/17 03:00ID:???実際には空いていません。
<pre>ABC
DEF
GHI\JKL</pre>
0116nobodyさん
04/06/17 03:13ID:???検索語・置換語が複数渡ってるから、まず
s2の ABC\\nDEF\\nGHI\\JKL が ABC\nDEF\nGHI\JKL に置換されて、
さらに ABC\nDEF\nGHI\JKL が残りの$arr2の置換(\n -> LF)をやって
s3に改行が入るんだろうね。
0117nobodyさん
04/06/17 03:38ID:???出力時どれも改行に逆変換されちまうってことですな。
だからリテラル\nがもとに戻らず改行になってしまう。
\nという文字列を入力できなくするのはナンセンスだし、エスケープを実装するとコスト高なので、
入力される可能性のない文字列に置換して保存するしかないか。
■ このスレッドは過去ログ倉庫に格納されています