ホームページ  >  記事  >  バックエンド開発  >  PHP_PHP チュートリアルでアップロードされた画像の名前を変更する方法の 6 つの例

PHP_PHP チュートリアルでアップロードされた画像の名前を変更する方法の 6 つの例

WBOY
WBOYオリジナル
2016-07-13 10:25:33643ブラウズ

1. 該当するシナリオ:
データベースから返された自己増加する番号を使用して、アップロードされた画像の名前を変更することはできません。
これは、画像またはファイルをアップロードするプロセスによって決まります。
一般的な画像アップロード プロセスでは、まず画像をサーバーにアップロードし、名前を変更してからデータベースに挿入します。
つまり、データベース内で非常に簡単に取得できる自己増加IDは、ファイル名の重複を避けるためにアップロードされた写真の名前を変更するのに使用できません
データベースから最大のIDを取得して1を加算する方法が使用されます。データベースを増やす
2. 従来の解決策:
1、guid: 32 文字の 16 進数。
形式: GUID の形式は「xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx」です。各 x は、0 ~ 9 または a ~ f の範囲の 32 桁の 16 進数です。たとえば、6F9619FF-8B86-D011-B42D-00C04FC964FF は有効な GUID 値です。
利点: 重複はほとんどありません。
欠点: アップロードされた画像の名前を変更するにはまだ時間がかかります。
使用法:

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

/*
com_create_guid() は、php5 バージョンでサポートされている関数です。サポートされていないバージョンの場合は、自分で定義できます。 function guid(){
if (function_exists('com_create_guid')){
return com_create_guid();
}else{
mt_srand((double)microtime()*10000);//php 4.2.0 以降ではオプション。
echo(m t_rand( ));
$charid = strtoupper(md5(uniqid(rand(), true)));
$hyphen = chr(45);// "-"
$uuid = chr(123) // "{"
.substr($charid, 0, 8).$hyphen
.substr($charid, 8, 4).$hyphen
.substr($charid,12, 4).$hyphen
.substr ($charid, 16, 4).$hyphen
.substr($charid,20,12)
.chr(125);// "}"

guid と同じ 32 文字の 16 進数が出力されます。違いは、guid がランダムに生成されるのに対し、md5 は入力データに基づいて生成される必要があることです。
例:


コードをコピーします

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

$str = "Hello";echo md5($str);?>
出力
8b1a9953c4611296a 827abf8c47804d7
利点: 入力シード データに基づいて出力値を制御できます。シード データが規則的で反復しない場合、データは md5 によって保護できますが、これは大きな混乱を引き起こします。
欠点: 32 ビット文字は長すぎます。重複しないシード データを提供する必要があります。
使用法: シード データとして秒を使用すると、依然として重複が発生します。


コードをコピーします

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

/** time() 関数と組み合わせて使用​​され、1970 年から現在時刻までの秒数を使用します。シード番号。 */$str=time();
echo md5($str);
?>


3, uniqid(): 13 ビットまたは 23 ビットの文字列を返します
ここでの目的では、uniqid() は次のようになりますこれは md5() の改良版であり、特に、差分識別子を文字列プレフィックスとして使用できるため、名前が重複する可能性を減らすことができます。
同時実行性が高くないなどの極端な状況では、すでに一般的なニーズを満たすことができるこの関数を使用することをお勧めします。
詳細、
定義: uniqid() 関数は、マイクロ秒単位の現在時刻に基づいて一意の ID を生成します。
使用法: uniqid(prefix,more_entropy)
説明: prefix は出力文字列にプレフィックスを追加できます。 more_entropy パラメーターが true の場合、23 ビットの文字列が出力されます。



コードをコピーします

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

var_dump(uniqid());var_dump(uniqid("a"));?>

出力結果は次のとおりです:
string(13) "51734aa562254" string(14) "a51734aa562257"
利点: 13 桁の文字列長は、追加できるファイル名プレフィックスの長さであり、結果にはデータの混乱が含まれる可能性があります。逆推論を避ける 生データ。
欠点: md5 と同様、同時実行性が高く、シード データとして秒を使用するため、やはり重複が発生します。
3. バージョンアップ計画:
1, fast_uuid: 17 桁の数値を返します
この関数に登場する「シード番号の開始時刻」の概念は、uniqid() の不完全なカスタマイズ版に似ています。とても啓発的です。
time() と uniqid() で使用されるデフォルトの時刻は 1970 年から計算され、長さは 10 桁 (1366512439) です。「シード番号開始時刻」を使用すると、実際には必要なため、この値を減らすことができます。これは単なる値です。自動的に成長する可能性があります。
開始時間をカスタマイズすると、長さが短縮されるだけでなく、混乱を招く可能性もあります。
コードをコピーします コードは次のとおりです:

/*
* パラメータ suffix_len は、生成された ID 値に追加されるランダムな桁の数を指定します。デフォルト値は 3 です。
* アルゴリズムを提供してくれた「Ivan Tan| Tan Junqing DrinChing (at) Gmail.com」に感謝します。
* @param int suffix_len
* @return string
*/
function fast_uuid($suffix_len=3){
//! シード番号の計算開始時刻
$being_timestamp = strtotime('2013-3-21') ;

$time =explode(' ', microtime());
$id = ($time[1] - $being_timestamp) . sprintf('%06u', substr($time[0], 2, 6) );
if ($suffix_len > 0)
{
$id .= substr(sprintf('010u', mt_rand()), 0, $suffix_len);
}
return $id;
}

出力,
29832412631099013
2, time()+乱数:
1 秒間に発生する複数のリクエストを解決するために、乱数の使用は上記の例ですでに登場しています。次のように 2 つの関数を提供します。
コードをコピーします コードは次のとおりです:

function random($length) {
$hash = '';
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijk lm nopqrstuvwxyz ';
$max = strlen($chars) - 1;
PHP_VERSION < '4.2.0' && mt_srand((double)microtime() * 1000000);
for($i = 0; $i < $length ; $i++) {
.= $chars[mt_rand(0, $max)];
}
return $hash;
}
function random2($length, $numeric = 0) {
PHP_VERSION < ' ? mt_srand ((double)microtime() * 1000000) : mt_srand();
$seed = Base_convert(md5(print_r($_SERVER, 1).microtime()), 16, $numeric ? 10 : 35);
$seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
$hash = '';
$max = strlen( $seed) - 1;
for($i = 0; $i < $length; $i++) {
}
?>



4. 最終的な解決策
:
アイデア: ユーザー ID+秒+乱数。このうち、「userid+秒」は 10 進数から 64 桁に変換され、桁数が減ります。 説明: userid: 64 桁の最大値「ZZZZ」が 10 進数に変換され、「16777215」となります。 "ZZZ" を 10 進数に変換した値は、"262143" ";
秒: 独自の時間の開始点を設定します。
$less=time()-strtotime('2012-4-21'); 16進数の「1SpRe」、5桁に変換します
$less=time()-strtotime('2013-3-21'); 16 進数の "_jHY"; 4 桁の乱数:random(3) を使用して 3 桁の乱数を生成します。
最終結果: 4 桁のユーザー ID + 4 桁の 2 桁 + 3 桁の乱数 = 11 桁の文字列。 。結果は uniqid() と似ていますが、堅牢性が向上しています。

5. 10 進数を 16 進数に変換するアルゴリズム:

アルゴリズム 1:


コードをコピーします

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

const KeyCode = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$';
/**
* 64 進数の数値文字列を 10 進数の数値文字列に変換します
* @param $m string 64 進数の数値文字列
* @param $len integer 文字列の長さを返します。長さが十分でない場合は、0 パディングを使用します, 0はパディングなしを意味します
* @return string
* @author 野马
*/
function hex64to10($m, $len = 0) {
$m = (文字列)$m;
$hex2 = '';
$Code = KeyCode;
for($i = 0, $l = strlen($Code); $i < $l; $i++) {
$KeyCode[] = $Code[$i];
}
$ KeyCode = array_flip($KeyCode);

for($i = 0, $l = strlen($m); $i < $l; $i++) {
$one = $m[$i];
$ hex2 .= str_pad(decbin($KeyCode[$one]), 6, '0', STR_PAD_LEFT);
}
$return = binding($hex2);

if($len) {
$clen = strlen( $return);
if($clen >= $len) {
return $return;
}
else {
return str_pad($return, $len, ' 0', STR_PAD_LEFT);
}
}
return $ return;
}

/**
* 10進数の数値文字列を64ベースの数値文字列に変換します
* @param $m string 10進数の数値文字列
* @param $len integer 文字列の長さを返します。長さが十分でない場合は、0パディング、0を使用します。パディングなしを意味します
* @return string
* @author 野马
*/
function hex10to64($m, $len = 0) {
$KeyCode = KeyCode;
$hex2 = decbin($m);
$hex2 = str_rsplit($ hex2, 6);
$hex64 = array();
foreach($hex2 as $one) {
$t = binding($one);
$hex64[] = $KeyCode[$t];
}
$ return = preg_replace('/^0*/', '', implode('', $hex64));
if($len) {
$clen = strlen($return);
if($clen >= $len) {
return $return;
}
else {
return str_pad($return, $len, '0', STR_PAD_LEFT);
}
}
return $return;
}

/**
* 16進数の数値文字列を16進数の数値文字列に変換します
* @param $m string 16進数の数値文字列
* @param $len integer 文字列の長さを返します。長さが十分でない場合は、0パディングを使用します。0はパディングなしを意味します
* @return string
* @author 野马
*/
function hex16to64($m, $len = 0) {
$KeyCode = KeyCode;
$hex2 = array();
for($i = 0, $j = strlen( $m); $i < $j; ++$i) {
$hex2[] = str_pad($m[$i], 16, 2), '0', STR_PAD_LEFT);

$hex2 = implode('', $hex2);
$hex2 = str_rsplit($hex2, 6);
foreach($hex2 as $one) {
$hex64[] = $KeyCode[bindec($one)] ;
}
$return = preg_replace('/^0*/', '', implode('', $hex64));
if($len) {
$clen = strlen($return);
if( $clen >= $len) {
return $return;
}
else {
return str_pad($return, $len, '0',
}
}
return $return;
}

/ **
* この関数は PHP ネイティブ関数 str_split に似ていますが、切断が末尾から始まる点が異なります
* @param $str string 切断する必要がある文字列
* @param $len integer 各文字列の長さ
* @配列を返す
マスタング
*/
function str_rsplit($str, $len = 1) {
if($str == null || $str == false || $str == '') return false;
$strlen = strlen($str);
if($strlen $headlen = $strlen % $len;
if($headlen == 0) {
return str_split($ str, $len);
}
$return = array(substr($str, 0, $headlen));
return array_merge($return, str_split(substr($str, $headlen), $len));
}

$a=idate("U");
echo "rn
e:" 。 hex10to64($a);
echo "rn
e:" 。 hex64to10(hex10to64($a));

算法2:
复制代码代码如下:

function dec2s4($dec) {
$base = '0123456789_$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$result = '';

do {
$base[ $dec %64] 。 $result;
$dec = intval($dec / 64);
} while ($dec != 0);

return $result;
}

function s42dec($sixty_four) {
$base_map = array ( ' 0' => 0、 '1' => 1、 '3' => 4、 '5' => => 6、 '7' => 8、 '9' => 10、 '$' => ; 12、「b」 => 14、「e」 => 17、「g」 => 18 、 'h' => 19、 'j' => 21、 'l' => 24、 ' n' => 25、 'o' => 26、 'q' => 29、 's' => 30 => 31、 'u' => 32、 'w' => 35、 'z' => ; 37、「A」 => 39、「C」 => 41、「F」 => ; 、「G」 => 45、「I」 => 47、「L」 => 49 M' => 50、 'N' => 51、 'O' => 52、 'P' => 53、 'Q' => 54、 'R' => 55、 'S' => 56、 'T' => 57、 'U' => 58、 'V' => 59、 'W' => 60、 'X' => 61、 'Y' => 62、 'Z' => 63, );
$result = 0;
$len = strlen($sixty_four);

for ($n = 0; $n < $len; $n++) {
$result *= 64;
$result += $base_map[$sixty_four{$n}];
}

return $result;
}

$a=idate("U");
var_dump(dec2s4($a));
var_dump(s42dec( dec2s4($a)));

算法效率测试:
复制代代码如下:

$strarr = array();
$time1 = microtime(true);
for($i = 0; $i $str = idate("U")+$i;
$strarr[] = "{$i}->$strrn
";
}
$time2 = microtime(true);
$time3 = $time2 - $time1;

$time1 = microtime(true);
for($i = 0; $i $str = dec2s4(idate("U")+$i);
$strarr[] = "{$i}->$strrn
";
}
$time2 = microtime(true);
echo "rn
运行10000回使用時間(秒):" . ($time2 - $time1 - $time3);
テスト結果
アルゴリズム1:0.1687250137329Algorithm 2:0.044965028762817
Concrusion:Algorithm 1は効率が低くなりますが、MD5によって生成された16進数を六量体に変換でき、

6. まとめ
この記事では、アップロードされた画像の名前を変更するために使用できるいくつかの方法について説明します。重要な点は、文字列を減らすために 10 進数を 16 進数に変更することです。
例えば、fast_uuid で生成された 17 桁の数値は、たった 7 文字の 16 進数に変換されます。
具体的な使い方は、状況に応じて柔軟に使用できます。

http://www.bkjia.com/PHPjc/825004.html

tru​​ehttp://www.bkjia.com/PHPjc/825004.html技術記事 1. 該当するシナリオ: データベースから返された自己増加する番号を使用して、アップロードされた画像の名前を変更することはできません。 これは、画像またはファイルをアップロードするプロセスによって決まります。 一般的な画像アップロード処理プロセス...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。