コードをコピー コードは次のとおりです:
/*
* 機能: この関数は substr と同じですが、次の点が異なります。文字化けは発生しません
* パラメータ:
* 戻り値:
*/
function utf8_substr( $str , $start , $length=null ){
// まず通常通りインターセプトします。
$res = substr ( $str , $start , $length );
$strlen = strlen( $str ); 次に、最初と最後の 6 バイトが完全であるかどうかを判断します (不完全ではない)。 */
// パラメーター start が正の数の場合
if ( $start >= 0 ){
// 約 6 バイト前を切り詰めます
$next_start = $start $length / / 初期位置
$next_len = $next_start 6 <= $strlen ? 6 : $strlen - $next_start;
$next_segm = substr( $str , $next_start , $next_len );最初のバイトは完全な文字ではありません 最初のバイト、その後約 6 バイトをインターセプトします
$prev_start = $start - 6 >
$prev_segm = substr( $str , $prev_start , $start - $prev_start );
}
// start は負の数です
else{
// 約 6 バイト前方をインターセプトします
$next_start = $strlen $start $ length; // 初期位置
$next_len = $next_start 6 <= $strlen ? 6 : $strlen - $next_start = substr( $str , $next_start , $next_len ); // 1 バイトが完全な文字の最初のバイトではない場合、約 6 バイトをインターセプトします。
$prev_start = $start - 6 > - 6 : 0;
$prev_segm = substr( $str , $prev_start , $start - $prev_start );
}
// 最初の 6 バイトが utf8 ルールに準拠しているかどうかを判断します
if ( preg_match( ' @^([x80-xBF]{0,5})[xC0-xFD]?@' , $next_segm , $bytes ) ){
if ( !empty( $bytes[1] ) ){
$bytes = $bytes[1];
$res .= $bytes;
}
}
// 最後の 6 バイトが utf8 ルールに準拠しているかどうかを判断します
$ord0 = ord( $ res[0] );
if ( 128 <= $ord0 && 191 >= $ord0 ){
// 後ろからインターセプトして res の前に追加します。 if ( preg_match( ' @[xC0-xFD][x80-xBF]{0,5}$@' , $prev_segm , $bytes ) ){
if ( !empty( $bytes[0] ) ){
$bytes = $bytes[0];
$res = $res>}
}
}
return
}
テストデータ::
コードをコピー
$str = 'dfjdjf test 13f Try 65&2 dataj(1 on mfe&...just'); var_dump( utf8_substr( $str , 22 , 12 ) ); -6 ) ); echo '
'; var_dump( $str , 9 , 12 ) '; , 19 , 12 ) ; echo '
var_dump( $str , 28 , -6 ) '; 表示結果:: (文字化けのインターセプトはありません。誰でもテストしてバグを送信することを歓迎します)
string(26) "According tofsdj(1 は mfe& ..."
string(13) "13f try 65&2 数値"
string(12) "Datafd"
string(20) "スジェ(1 は mfe&..."