🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

4回答

1447閲覧

PHP explodeでなぜこうなるかわかりません

teratail_user_

総合スコア1

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2021/01/21 23:48

前提・実現したいこと

タイトルの通りです
まず$uにhello+改行を20個入れます

この時点での結果は
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
改行

という中身になります
それをexplode("\n",$u)で分割します
次に
for($i=20;$i>=10;$i--){
$ssj=$b[$i]."
".$ssj;
}
echo $ssj;
これをすると
hello

hello

hello

hello

hello

hello

hello

hello

hello

hello

という結果になります
疑問です
\nで分割して、さらに改行を加えたら

まず$uにhello+改行を20個入れます←この結果と同じになるはずじゃありませんか?

なぜhelloのあとに改行が2つも生まれてるんでしょうか

該当のソースコード

php

1<?php 2 3for($j=0;$j<20;$j++){ 4$u="hello 5".$u; 6} 7 8 9$b=explode("\n",$u); 10 11 12for($i=20;$i>=10;$i--){ 13$ssj=$b[$i]." 14".$ssj; 15} 16echo $ssj; 17?>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/01/21 23:52

OSやバージョンがわかりませんが PHP_EOL 改行としたい部分を↑に入れ替えるとどうなりますか?
teratail_user_

2021/01/21 23:59

PHP5です Firefoxで実行しました ブラウザ関係あるのかわかりませんがhelloが10行しか表示されない結果になっています
teratail_user_

2021/01/22 00:01

同じ結果になります 1つのhelloに改行が二つ入っています
guest

回答4

0

ベストアンサー

おそらく環境依存。
paiza.ioなどでは再現しませんでした。
Windowsにてeclipseからcli実行したら再現しました。

$bをvar_dump()してみればわかります。
explodeの結果、改行込みになってます。

string(6) "hello "

環境によって¥nと同じではなくなります。
Windowsでは¥r¥n
このような依存対応をなくすべく、「改行コード」は全てPHP_EOL使いましょう。
explodeのときだけでなく、文字列投入時も全てです。
現在のコードは厳密には「同じ文字コード」で区切られていません。
投入時と出力時は同じですが、explodeのときがちがいます。
explodeのときも同じように投入すれば確かに同じ出力にはなりますが、
根本解決にはなりません。

投稿2021/01/22 00:02

編集2021/01/22 00:06
m.ts10806

総合スコア80875

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2021/01/22 00:03

CRLFのCRだけ残っているとか、そういう状況かもしれないですね。
teratail_user_

2021/01/22 00:06

<?php for($j=0;$j<20;$j++){ $u="hello".PHP_EOL.$u; } $b=explode("\n",$u); for($i=20;$i>=10;$i--){ $ssj=$b[$i].PHP_EOL.$ssj; } echo $ssj; ?> 上記で無事できました このようなケースは稀なんですか? 今までこういう書き方の処理で、このようになったことはありませんでした
m.ts10806

2021/01/22 00:08

追記してます。 書いたとおりにしか動かないプログラミングにおいて「稀」ということはなく、「なるべくしてなった」ということです。 「同じ文字」で区切ってないですからね。
teratail_user_

2021/01/22 00:10

今まで全てPHP_EOLを使わず改行入れて動くプログラムを書いてたんですが、これだとクライアントが実行したOSによってバグが起こる可能性が出てくるということですか
m.ts10806

2021/01/22 00:15 編集

今回がその一例ですね。 デフォルトで定義済みの定数はそういったOS依存をなくすために用意されている部分もあるので、活用してください。
m.ts10806

2021/01/22 00:14

あ、一部勘違いあります。 クライアントはあくまでクライアント。 PHPはサーバーサイドで実行されるのでクライアントOSには依存しません
m.ts10806

2021/01/22 00:15

「Windowsでローカルサーバーたてて開発して本番がLinux」というときには問題が起きます。
teratail_user_

2021/01/22 00:16

初めて知りました いままの膨大なプログラムを全てPHP_EOLにします しかし、よく今まで他者から不具合の報告が起きなかったものです、、、
m.ts10806

2021/01/22 00:26 編集

「完全に同じ」にしておけばなかなか起きることではないです。 今回を例にすると下記のようにすれば「同じ」です。 $b=explode(" ",$u); ¥n¥rなどを個別で使うと問題がおきやすくなります。 まあクライアントが関係するのはあくまでブラウザ、htmlの話なので、そこに影響ない実装になっているのなら良いのではと。 改行コード込の情報をDBやテキストファイルに保存して、そこから出力してるようなところがあれば、そこだけデバッグしつつ検証していくだけでひとまずは良いのでは。 全部やる必要はないですよおそらく。今後意識してプログラミングできれば。
teratail_user_

2021/01/22 00:33

勉強になりました 感謝します
guest

0

【PHP】PHP_EOL - Qiita
PHP: 定義済みの定数 - Manual

PHP_EOLについて

このプラットフォームの行末文字。 PHP 5.0.2 以降で利用可能。

実行環境によって、\nでいい場合と、\r\nとするべき場合があるから、
PHP_EOLを使いましょうってことなんだと思う。

WindowsでXAMPPで組んでる人とか、意識しとかないとね。

投稿2021/01/22 00:08

編集2021/01/22 00:10
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

指摘のような状況が再現しません。

3v4lで実行した結果では、helloの間の改行は1つだけです。

投稿2021/01/21 23:51

maisumakun

総合スコア145970

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2021/01/21 23:55

PHPのバージョンや文字コードは何でしょうか?
maisumakun

2021/01/22 00:05

改行コードは何でしょうか? ("\n"はLFに対応する文字ですので、CRLF改行だとCRだけ残ることが考えられます)
teratail_user_

2021/01/22 00:07

改行コードですか? 考えたこともなかったです ENTER直打ちでしたが、意味が違いますか?
maisumakun

2021/01/22 00:08

> ENTER直打ちでしたが、意味が違いますか? それがファイルに「LF(\n)」として保存されるか、「CRLF(\r\n)」として保存されるか、2通りの流儀があります。
teratail_user_

2021/01/22 00:13

ファイルの設定はいじっていませんが 今までは別のプログラムでは正常に動いてたのに このファイルだけ設定が変わったんですか?
guest

0

php

1$ssj=$b[$i]." 2".$ssj;

上記の箇所で任意に改行を入れているからです
同じ結果を得たいなら

php

1$ssj=$b[$i].$ssj;

でいいかと

投稿2021/01/21 23:59

SakuBlade

総合スコア375

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teratail_user_

2021/01/22 00:02

分割されてますから$b自体の\nはないはずですが違いますか?
SakuBlade

2021/01/22 00:10

因みにm.ts10806さんの指摘通りPHP_EOLを使用すると再現しませんでした
m.ts10806

2021/01/22 00:11

本質からずれているので低評価しています。 「同じ結果にしたい」ではなく「なぜこうなるか」ですから。 帳尻合わせを覚えたところで後で困ることになるだけです。
SakuBlade

2021/01/22 00:16

確かに本質とはかけ離れた回答でした 知見不足で申し訳ございません
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問