日本語混在の文字数取得と丸め処理は、mb_strwidthとmb_strimwidthが良さそう!

PHP

PHPでの文字数取得と文字列カット

Instagramに投稿したものをTwitterへも同じように投稿したい場合があります。
IFTTTを使うと簡単に実装できるのですが、一部うまく動かない場合があります。


IFTTTが動かない場合は以下の通りです。


  • 文字数が280文字以上
  • 画像が2枚以上

この場合には処理が行われません。
Instagramは複数枚画像をアップロードできますし、テキストもいっぱい登録することができます。
そのため、IFTTTを使うことをやめて、自分で実装することにしました。


今回写真は置いておいて、文字列280文字の丸め処理について考えることにします。
別のプログラムで、文字列を切り取ってTwitterに投げるものを作っていたのですが、丸め処理がいまいちで時々文字数オーバーとなったり、文字数が越えていないのに「...」が付いたりする場合がありました。
(そもそも実装方法がどこかしらおかしかったのでしょう。文字数オーバーはあれですが、そんなに影響も無かったので見なかったことにしていました。)

そこで今回は、実装方法を見直すことにしました。


実装したい内容は以下の通りです。


  1. 投稿する文字列を取得
  2. 1.の文字列にリンク先を結合
  3. 2.が280文字を越える場合は、1.を丸めて「...」を付けて2.を結合
  4. Twitterへ投稿

やりたいことは簡単なのですが、3番目の文字列を丸める部分で時々不安定なことがありました。
文字列取得と丸め処理には、それぞれmb_strlenとmb_substrを使っていました。


そこで色々と試した結果・・・
mb_strlenとmb_substrの代わりに、mb_strwidthとmb_strimwidthを使うことで解決できました。


$text = '投稿文字列';
$append = '投稿文字列にくっつける文字列';

$left = 280 - mb_strwidth($text. $append, 'UTF-8');

if ($left < 0) {
    $content = mb_strimwidth($text, 0, $left, '...');
} else {
    $content = $text;
}
$content = $content. $append;


とりあえず今回の実装方法であれば、現在のところ文字数オーバーのエラーになることはありませんので、この実装方法で様子見をします。


写真の枚数の方は、4枚まで配列に入れてアップロードすれば良いので、特に難しいことはありません。



追記
mb_strwidthは、改行コードなど制御文字を無視するので、改行コードを余り使わないであろう文字に置き換えて使うか、改行コードの数をsubstr_countで取って足し込んだ方が良いですね。
ただし、mb_strimwidthでも改行コードは無視されるので、正確な数字では丸められないですね。
難しい。正解がないので、改行コードの数を足して丸めることにしました。多少短くなってしまいますが・・・仕方ない。

今後、mb_strwidthとかmb_strimwidthでも、パラメータの設定によって制御文字も数えてくれるようになったらうれしいですね。


--
IFTTTは便利なのですが、細かいことをやりたい場合は自分で実装する方が融通が利くので良いですね。