検索
ホームページphp教程php手册discuz と ecshop インターセプト文字列関数の PHP バージョンを比較する

discuz と ecshop インターセプト文字列関数の PHP バージョンを比較する

Jun 13, 2016 am 11:58 AM
discuzecshopphp関数そしてインターセプト比較するソースコードバージョンバージョン

次に、最初にソース コードと 2 つのバージョンの関数の簡単なテストを示します。最後に、より実用的な文字列インターセプト関数を示します。ここで説明する文字列インターセプトの問題はすべて、UTF-8 でエンコードされた中国語文字列に関するものであることに注意してください。
ディスクバージョン

コードをコピー コードは次のとおりです:


/**
* [discuz] mb_substr やその他の拡張機能がインストールされていない PHP に基づくインターセプト文字列。中国語文字がインターセプトされた場合、2 文字として計算されます。
* @param $string インターセプトされる文字列
* @ param $length to be インターセプトされた文字数
* @param $dot 切り捨てられた部分の終了文字列を置き換えます
* @return インターセプトされた文字列を返します
* /
function Cutstr($string, $length, $dot = '...') {
// 文字列がインターセプトする長さより短い場合は、直接戻ります
//ここで strlen を使用して文字を取得します。 文字列の長さには大きな欠点があります。たとえば、文字列「Happy New Year」
// から 4 つの中国語文字をインターセプトしたい場合は、これら 4 つの中国語のバイト数を知る必要があります。それ以外の場合、返される文字列は「Happy New Year...」になります。
if (strlen($string) return $string
}
// 変換元の文字列の htmlspecialchars
$pre = chr(1);
$string = str_replace (array ('&', '"', '' )、配列 ($pre . '&' . $end, $pre . '"' . $end, $pre . '' . $end ) , $string );
$strcut = ''; // 初期化戻り値
// utf-8エンコードの場合(この判定はちょっと不完全なのでutf8の可能性があります)
if (strto lower) ( CHARSET ) == 'utf-8') {
//初期連続ループポインタ $n、最後の文字数 $tn、インターセプトされた文字数 $noc
$n = $tn = $noc = 0;
while ( $n $t = ord ( $string [$n] );
if ($t == 9 || $t = = 10 || (32 // 英語の半角記号などの場合は $n ポインタが 1 桁戻り、 $tn の最後の単語は 1 桁です
$tn = 1;
$noc ;
} elseif (194 // 2 バイト文字の場合、$n ポインタは 2 ビット戻り、$tn の最後のワードは 2 ビットになります
$tn = 2; ;
$noc = 2;
} elseif (224 / / 3 バイトの場合 (中国語の単語として理解できます) $n は 3 桁シフトされ、$tn の最後のワードは 3 桁になります。
$n = 3;
$noc = 2; $tn = 4;
$noc = 2; && $t $tn = 5;
$noc = 2;
} elseif ($ t == 252 || $t == 253) {
$tn = 6;
$n = 2;
} else {
}
//取得する数を超えた場合の連続ループの
if ($noc >= $length) {
break;
}
}
// ここは、 $dot を追加する準備中の最後の単語
if ($noc > $length) {
$n -= $tn;
}
$strcut = substr ( $ string, 0, $n );
} else {
// utf-8 ではない全角エンコーディングは 2 ビットだけシフトバックされます
for ($i = 0; $i $strcut .= ord ( $string [$i] ) > $string [$i] : $string [$i];
// 元の htmlspecialchars を復元します
$strcut = str_replace( array ($pre . '&' . $end, $pre . '"' . $end, $pre . '$end )、array ('&'、'"'、'' )、$strcut );
$pos = strrpos ( 1 ) );
if ($pos !== false) {
$strcut = substr ( $strcut, 0, $pos );
return $strcut ;最後に、インターセプトを $dot 出力に追加します
}


discuz バージョンの最大の欠陥は、strlen を使用して元の文字列の長さを取得し、それを受信長パラメーターで使用することです。 UTF-8 の中国語文字のバイト数は固定されていないため、次のジレンマに直面します。4 つの中国語文字をインターセプトしたい場合、どのくらいのインターセプト長を指定する必要がありますか? 8バイトですか、それとも12バイトですか? 。 。 。これは予測不可能であり、次のテスト結果からわかるように、この問題が原因で discuz の Cutstr には実際にはバグがあります:



Copy code

コードは次のとおりです:


$str1 = "貧乏になりたい";
echo my_cutstr($str1, 10, "...")."n";出力: 貧乏になりたいという願望 Qianmile... [これはバグです。原因を考えてください。 ]
echo my_cutstr($str1, 15, "...")."n"; // 出力: Yuqiongqianlimu



上記のバグの理由は、 Cutstr 関数は、文字をインターセプトするときに、中国語の文字は 2 文字としてカウントされるため、5 つの中国語の文字は 10 文字となり、元の文字列の長さは 15 バイトであるため、cutstr は 15 文字の文字列から「正常に」インターセプトされたとみなします。 10文字に「しっぽ」を追加しました。このバグを解決するには、返された部分文字列が元の文字列と同じかどうかを確認するだけです。同じである場合は、「末尾」を追加しないでください。

ecshop バージョン

コードをコピー

コードは次のとおりです:


/**
* [ecshop] PHP の mb_substr および iconv_substr 拡張機能に基づいて、これら 2 つの拡張機能は文字列をインターセプトするために使用されます。
* この関数は、utf-8 でエンコードされた中国語文字列にのみ適用されます。 。
*
* @param $str 元の文字列
* @param $length インターセプトされた文字数
* @param $append 終了文字列を切り詰められた部分に置き換えます
* @return Returnインターセプトされた文字列
*/
function sub_str($str, $length = 0, $append = '...') {
$str =trim($str);
$strlength = strlen($str);
if ($length == 0 || $length >= $strlength) {
return $str>} elseif ($length $length = $strlength $length;
if ($length $length = $strlength;
}
}
if ( function_exists( 'mb_substr') ) {
$newstr = mb_substr($str, 0, $length, 'utf-8')
} elseif ( function_exists('iconv_substr') ) {
$newstr = iconv_substr ($str, 0, $length, 'utf-8');
} else {
//$newstr = trim_right(substr($str, 0, $length)); substr($str, 0, $length);
}
if ($append && $str != $newstr) {
$newsstr .= $append;
return $ newstr;
}


ecshop 版の特徴と欠点は、元の文字列に中国語が含まれていない場合 (例: abcd1234)、中国語の文字が 1 文字としてカウントされることです。 4 つの中国語文字または 8 つの英語文字をインターセプトすることを目的としている場合、ecshop バージョンを使用すると、期待される結果が得られません: abcd。以下は簡単なテスト結果です:



コードをコピー

コードは次のとおりです: $str1 = "太陽は山を越え、黄河は海へ";

echo $str1."n";

echo my_sub_str($str1, 4, "...")."n"; //出力: 山には太陽が輝いています...
$str2 = "白1日2伊3山4";
echo $str2."n"; , "...")."n"; // 出力: White 1st 2...



最適化バージョン

中国語の文字列をインターセプトするほとんどのアプリケーション シナリオは次のとおりです。 「元の文字列は中国語、英語、数字の混合にすることができます。中国語の文字は 2 文字としてカウントされ、英語の数字は 1 文字としてカウントされます。」 この要件の実装バージョンは以下に示されています:

コードをコピー

コードは次のとおりです: /*** 文字列インターセプト、中国語の文字は 2 文字として計算され、GBK と UTF-8 エンコーディングの両方がサポートされています

* @param $string インターセプトされる文字列

* @param $length 文字数インターセプトされる
* @param $append 部分文字列に追加された末尾
* @return インターセプトされた文字列を返します
*/
function substring($string, $length, $append = false) {
if ( $length return '';
}
// 元の文字列が UTF-8 でエンコードされているかどうかを確認します
$is_utf8 = false;
$str1 = @iconv("UTF-8", "GBK", $string);
$str2 = @iconv("GBK", "UTF-8", $str1); ( $string == $str2 ) {
$is_utf8 = true;
// UTF-8 エンコードの場合は、GBK エンコードを使用します
$string = $str1>}
$ newstr = '';
for ($i = 0 ; $i $newstr .= ord ($string[$i]) > 127 ? i] . $string[ $i] : $string[$ i];
}
if ( $is_utf8 ) {
$newstr = @iconv("GBK", "UTF-8", $ newstr);
}
if ($append && $newstr != $string) {
$newstr .= $append;
}
return $newstr; >

テスト結果を以下に示します (GBK と UTF-8 の結果は一致しています):



コードをコピー

コードは次のとおりです



$str1 = "太陽は山を越え、黄河は海に流れ込みます。"

echo substring($str1, 4, "..."); n"; // 出力: 昼間... echo substring($str1, 5, ".. .")."n"; // 出力: Bai Riyi... $str2 = "12白 34 位 56 易 78 山"; echo substring($str2, 4, "... ")."n"; // 出力: 12 白... echo substring($str2, 5, "...")."n"; // 出力: 12 白 3...


著者: edwardlost のブログ

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター