【PHP】全角・半角が混在する文字列でも文字数を指定して同じ長さで改行する方法

ネットを検索すると指定した文字数で文字列を改行するコードがたくさん出てきます。
しかし半角のアルファベットなどが混じっていると同じ文字数で改行できても1行の長さが異なってしまうので、半角アルファベットが混じっていてもほぼ同じ長さで改行できる関数を作ってみました。

作った関数


function mb_wordwrap( $string, $width = 35, $break = PHP_EOL ) {
	$one_char_array   = mb_str_split( $string );
	$char_point_array = array_map(
		function( $char ) {
			$point = 1; // 全角
			if ( strlen( $char ) === mb_strlen( $char ) ) { // 半角
				if ( ctype_upper( $char ) ) { // アルファベット大文字
					$point = 0.7; // 全角を基準とした大きさ
				} else { // アルファベット小文字 or 記号
					$point = 0.5; // 全角を基準とした大きさ
				}
			}

			return $point;
		},
		$one_char_array
	);

	$words_array = array();
	$point_sum   = 0;
	$start       = 0;
	foreach ( $char_point_array as $index => $point ) {
		$point_sum += $point;
		if ( $point_sum >= $width ) {
			$words_array[] = mb_substr( $string, $start, $index - $start );
			$start         = $index;
			$point_sum     = 0;
		}

		if ( $index === array_key_last( $char_point_array ) ) {
			$words_array[] = mb_substr( $string, $start, count( $one_char_array ) - $start );
		}
	}

	return implode( $break, $words_array );
}

使い方


$wrap_text = mb_wordwrap('これはSampleテキストです。【記号】やAlphabet!!を入れても大体同じ長さになっていると思います。', 10);
echo $wrap_text;
/*
これはSampleテキス
トです。【記号】やAlp
habet!!を入れても大
体同じ長さになってい
ると思います。
*/

使用する環境(フォントや文字間隔)により微妙にズレる可能性がありますので、ご自身の環境に合わせて$pointの数値を調整してみてください。