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

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

ただいまの
回答率

90.49%

  • PHP

    24444questions

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

PHP 文字の丸め込みと改行

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 867

gsuisk

score 64

フォームの<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文字+...となるように丸めることは可能でしょうか?

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2017/09/09 01:27

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

    キャンセル

  • gsuisk

    2017/09/09 14:55

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

    キャンセル

  • gsuisk

    2017/09/09 14:56

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

    キャンセル

  • kei344

    2017/09/09 15:07

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

    キャンセル

回答 2

checkベストアンサー

+3

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

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

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

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

<?php
function escape($v) {
    $v = trim($v);
    $v = str_replace(["\r","\n"], ['',''], $v);
    $v = strip_tags($v);
    return htmlspecialchars($v, ENT_QUOTES, "UTF-8");

    //デバッグしづらいのでお勧めしませんが、下記のように書いても同じです。
    //return htmlspecialchars(strip_tags(str_replace(["\r","\n"], ['',''], trim($v))), ENT_QUOTES, "UTF-8");

    //↓上記と等価ではありませんが個人的にはこっちのほうが好きです
    //$v = filter_input(INPUT_POST, 'note', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    //return str_replace(["\r","\n"], ['',''], trim($v));
}

if(isset($_POST["note"])){
    $note = escape($_POST["note"]);
    if (strlen($note) > 0) {
        echo '<hr>'.mb_substr($note, 0, 5).'...';
    }
}
?>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/09 21:40

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

    キャンセル

+1

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

<?php
function escape($v) {
    return htmlspecialchars($v, ENT_QUOTES, "UTF-8");
}

$t2 = "...";
$r = "";

if (isset($_POST["note"])) {
    $note = mb_substr(strip_tags($_POST["note"]), 0, 1000);
} else {
    $note = "";
}
if (mb_strlen($note) > 0) {
    echo "<hr>";
    $t = array_values(array_filter(explode("<br>", str_replace(["\n", "\r", "\r\n"], "<br>", $note))));
    foreach ($t as $k => $v) {
        if (strlen($r . $t2) >= 8) {
            array_splice($t, $k);
            $r = implode("<br>", $t) . $t2;
            break;
        }
        $r .= $v;
    }
}
?>
<form action="" method="post">
    <label>
        <textarea name="note"></textarea>
    </label>
    <input type="submit">
</form>
<?php if (!empty($r)) { ?>
    <?php echo $r; ?>
<?php } ?>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/09 14:49

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

    キャンセル

  • 2017/09/09 15:01

    ありがとうございます!
    書いていただいたコードでは、改行しても正しく(5文字+...)となりました。

    A
    B
    C
    D
    E...

    このような結果になるのですが、「ABCDE...」のように、表示は改行させないようにはできないでしょうか?

    キャンセル

  • 2017/09/09 15:08

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

    キャンセル

  • 2017/09/09 20:55

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

    キャンセル

  • 2017/09/09 21:40

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

    キャンセル

同じタグがついた質問を見る

  • PHP

    24444questions

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