質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

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

Q&A

解決済

2回答

2783閲覧

PHP 文字の丸め込みと改行

gsuisk

総合スコア72

PHP

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

0グッド

0クリップ

投稿2017/09/08 16:06

編集2017/09/09 11:32

フォームの<textarea>で文章を入力し、submitすると文章を最初の8文字に丸めて出力するプログラムを作りました。(最後に...がつくので半角だと最初の5文字+...が出力)

<textarea> は name="note" です。 以下はプログラムの一部です。 ``` if(isset($_POST["note"])){ $note = $_POST["note"]; $note = strip_tags($note); $note = mb_substr($note, 0, 1000); $note = escape($note); //HTMLエスケープ }else { $note = ""; } ``` ``` $len = mb_strlen($note); if($len > 0){ echo "<hr>"; $note_br = nl2br($note, false); $short = mb_strimwidth($note, 0, 8, "..."); echo $short; } ``` 通常は問題なく動作するのですが、改行に関しての挙動が理解できません。 以下のようにテキストに入力したときです。(コードではないので青い色は気にしないで下さい。) ``` A B C D E F G H I ``` 結果は「A B ...」となります。 改行なしで入力すると「ABCDE...」と予想通りの結果になってくれます。 (半角5文字+... の8文字に丸められている) ABCDEの5文字未満のところで改行すると、「ABCDE...」(半角5文字が表示)とならずに、 「A B ...」のように2文字しか表示されなかったりします。(一文字ずつ改行するとAとBの2文字しか表示されません。) 何度どこで改行しても、半角5文字+...となるように丸めることは可能でしょうか?

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

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

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

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

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

kei344

2017/09/08 16:27

「結果がおかしく」とはどのような状況でしょうか。
gsuisk

2017/09/09 05:55

mb_strimwidth($note, 0, 8, "...") としたので半角では、「5文字+...」 となるはずなのに、A B ... と「2文字+...」になってしまっているということです。
gsuisk

2017/09/09 05:56

関係ないですがなぜか、この追記欄改行できませんね...
kei344

2017/09/09 06:07

質問文の編集を促すためのコメント欄ですので、質問を編集されてはいかがでしょうか。
guest

回答2

0

ベストアンサー

結果は「A B ...」となります。

ご存知かもしれませんが、AとBの間は半角スペースではないです。「A\n(改行)B」です。
ブラウザで右クリックして「ソースを表示」とするとHTMLコードが見られます。

mb_strimwidth()widthオプションは文字幅(半角英数字、半角カタカナは1で、すべての全角文字列は2)で指定します。mb_xxx()ということは全角考慮ということなので、文字の丸め込みはmb_strimwidth()だと非常にめんどくさいです。勉強ならいいんですけど。

下記のように、mb_substr().'...'とすれば簡単に丸め込みができます。

php

1<?php 2function escape($v) { 3 $v = trim($v); 4 $v = str_replace(["\r","\n"], ['',''], $v); 5 $v = strip_tags($v); 6 return htmlspecialchars($v, ENT_QUOTES, "UTF-8"); 7 8 //デバッグしづらいのでお勧めしませんが、下記のように書いても同じです。 9 //return htmlspecialchars(strip_tags(str_replace(["\r","\n"], ['',''], trim($v))), ENT_QUOTES, "UTF-8"); 10 11 //↓上記と等価ではありませんが個人的にはこっちのほうが好きです 12 //$v = filter_input(INPUT_POST, 'note', FILTER_SANITIZE_FULL_SPECIAL_CHARS); 13 //return str_replace(["\r","\n"], ['',''], trim($v)); 14} 15 16if(isset($_POST["note"])){ 17 $note = escape($_POST["note"]); 18 if (strlen($note) > 0) { 19 echo '<hr>'.mb_substr($note, 0, 5).'...'; 20 } 21} 22?>

投稿2017/09/09 12:19

編集2017/09/09 12:24
Tomak

総合スコア1652

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

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

gsuisk

2017/09/09 12:40

できました!ありがとうございました。
guest

0

改行文字が含まれているので、切るときも改行文字のバイトを含んで計算しています。改行文字を無視してしまうと大変なことになりますが、無視するときはこんな幹事でできます

PHP

1<?php 2function escape($v) { 3 return htmlspecialchars($v, ENT_QUOTES, "UTF-8"); 4} 5 6$t2 = "..."; 7$r = ""; 8 9if (isset($_POST["note"])) { 10 $note = mb_substr(strip_tags($_POST["note"]), 0, 1000); 11} else { 12 $note = ""; 13} 14if (mb_strlen($note) > 0) { 15 echo "<hr>"; 16 $t = array_values(array_filter(explode("<br>", str_replace(["\n", "\r", "\r\n"], "<br>", $note)))); 17 foreach ($t as $k => $v) { 18 if (strlen($r . $t2) >= 8) { 19 array_splice($t, $k); 20 $r = implode("<br>", $t) . $t2; 21 break; 22 } 23 $r .= $v; 24 } 25} 26?> 27<form action="" method="post"> 28 <label> 29 <textarea name="note"></textarea> 30 </label> 31 <input type="submit"> 32</form> 33<?php if (!empty($r)) { ?> 34 <?php echo $r; ?> 35<?php } ?> 36

投稿2017/09/08 20:28

shinpo

総合スコア14

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

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

退会済みユーザー

退会済みユーザー

2017/09/09 05:49

このコード、いろいろと要件にあっていないと思います。
gsuisk

2017/09/09 06:01

ありがとうございます! 書いていただいたコードでは、改行しても正しく(5文字+...)となりました。 A B C D E... このような結果になるのですが、「ABCDE...」のように、表示は改行させないようにはできないでしょうか?
退会済みユーザー

退会済みユーザー

2017/09/09 06:08

ABCDEFGHIJK も ABCDE... とはならないはずです。 分割した配列の累積を次のループで判断しているので、次のループが無い場合、処理前に出力されてしまします。
退会済みユーザー

退会済みユーザー

2017/09/09 11:55

回答としては、shinpo さんがすでに記述しているんで、終了しても良い気がするのですが?
gsuisk

2017/09/09 12:40

参考になります!ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問