82413


例外処理を行うPost.phpとrequire.phpを記述しました。  
条件は「テキストは5文字以上で記述する」ということです。

[code]

    $posts[0] = new Post('hello');
    
[/code]

5文字以上なので、例外は発生せずそのまま

[code]

    hello
    hello again
    
[/code]

と表示されると思っていましたが以下のように例外扱いになります。  
初歩的な質問になるかと思いますが、hello は5文字として扱われないのですか？  
教えて下さい。よろしくお願いいたします

**＜表示結果＞**

[code]

    5文字以上で
    
[/code]

**Post.php**

[code]

    <?php
        
        class Post{
        
          protected  $text;
          public function __construct($text){
            if(strlen($text) <= 5){
              throw new Exception('5文字以上で');
            }
        
          $this->text = $text;
        }
          public function show(){
            printf('%s',$this->text);
          }
        }
        ?>
    
[/code]

**require.php**

[code]

    <?php
    require('main.php');
    try{
    $posts = [];
    $posts[0] = new Post('hello');
    $posts[1] = new Post('hello again');
    
    foreach($posts as $post){
      $post->show();
      echo "<br>";
    }
    
    }catch(Exception $e){
      echo $e->getMessage();
    }
    ?>
    
[/code]


CC BY-SA 4.0
2021-09-10T08:00:48.493
82404
2021-09-11T05:02:59.493
2021-09-10T16:28:43.240
3060
42150
question
php
strlen()関数での文字数の扱い方


既にコメントにあるように `if(strlen($text) <= 5`
は５バイト以下つまり５バイトを含みますので提示の結果はコードに書かれている通りの動作です。ではどう直すと適切かは「文字」の定義次第だったりします。日本語文字とか絵文字とかも１文字と数えるのか否かで結論は違います。

[php の strlen のマニュアル](https://www.php.net/manual/ja/function.strlen.php)
にもきっちり書かれていますが `strlen` が返すのは「文字数」でなくて「バイト数」です。よって `strlen('あいうえお')`
が返すのは５ではありません。では具体的にいくつが返るかはエンコーディング次第です。 10 かもしれないし 15 かもしれませんしほかの値かもしれません。
**それでよいなら** つまり国際化、日本語対応とか一切しないなら `strlen($text)<5` となるでしょう (要するに `=` がいらない)

CJK 漢字や絵文字なども１文字と数えたいのなら使うべきは `strlen` ではなくて `mb_strlen` です [php の mb_strlen
のマニュアル](https://www.php.net/manual/ja/function.mb-strlen.php)
これならバイト数ではなくて真に文字数が得られます。ただし ASCII
以外の文字をどうエンコードするかを事前に決めておく必要があります（正しく運用できないと文字化けします）具体的にどうコード化するかは略していいよね？


CC BY-SA 4.0
2021-09-11T05:02:59.493
82413
2021-09-11T05:02:59.493
8589
82404
answer