初心者(そうではない)の開発者は、多くの場合、ユーザーコンテンツ、具体的には写真の操作方法について質問があります。 このトピックには多くの側面と複数のソリューションがあります。 ここでは、長所と短所がある、可能なオプションの1つのみが考慮されます。 また、静的とコードは1つのサーバーに保存され、ファイルは1つずつダウンロードされると想定しています。
システムによって解決されるタスク:
-便利なファイルのダウンロード;
-非同期画像処理の可能性;
-プレビューで簡単に作業できます。
-設定と実行の分離。
行こう
最初に、次のフィールドを使用してデータベースにファイルテーブルを作成します。id、name、size、width、height、is_deleted、is_ready、updated、created。
ファイルをダウンロードすると、まず、ファイルテーブルにエントリが作成されます。 さらに、idに基づいて、保存する必要があるパスが計算されます。
$number = sprintf('%08d', $id);
$uri = '/' .
substr($number, 0, 2) . '/' .
substr($number, 2, 2) . '/' .
substr($number, 4, 2) . '/' .
$number;
出力では、次のようになります:/ 00/47/31/00473161
upd1 Arkadiy_Kulevは、ディレクトリの深さを2レベルに制限する必要があることを示しました。
upd2実際、フォルダ内の写真をより適切に配布するため
に、パスを逆の順序で配置する方が適切です。 これは、そのような/ 161/473/00473161を受け取るURLです。 ありがとう
atd
なぜこれが行われるのですか?
- file_idは、写真が必要なエンティティテーブルのフィールドになります($ user-> avatar_file_id)。 このアプローチにより、1つのfile_idに基づいて、データベースへの追加クエリなしで画像へのフルパスを決定できます。
- 管理パネルを介して、ユーザーとダウンロード可能なオペレーターの両方のすべての写真を統一的に操作できます。
- フォルダー構造はディスク上に作成されるため、1つのフォルダーに100個を超えるサブフォルダーやファイルはありません。 この数は最大1000個のフォルダーに増やすことができますが、それより大きい数の場合、FSでの作業が困難になる場合があります。
- ファイルテーブルは、非同期のファイル処理に役立ちます。 突然すべての画像を別の形式に変換したり、他の操作を実行したりする必要がある場合は、is_readyフィールドを使用して(または独自のフィールドを追加して)既に処理済みで処理が残っている画像を特定できます。
- is_deletedフィールドのおかげで、画像の削除は非同期で実行できます。 コードは単純にtrueに設定する必要があり(トリガーに実装する方が便利です)、特別なコレクターによって削除されます(もちろん、作成する必要があります)。 これはトリガーに実装できます。
例 "00/47/31/00473161"からわかるように、このアプローチで可能な画像のダウンロード数は10億に制限されています。 当然、これは実装段階で変更することは難しくありません。
上記の機能を実装するには、receiveメソッドでImage_Managerクラスを作成する必要があります。 このクラスは、データベースにレコードを作成し、ファイルをFSの適切なディレクトリに移動し、不足しているディレクトリを作成します。
...
if ($form->isValid()) {
// , Image_Manager
// $_FILE .
...
$im = new Image_Manager($options); //
// 'avatar' ,
$file_id = $im->receive('avatar'); //
$user->avatar_file_id = $file_id;
$user->save()
}
元の画像を保存し、そのIDをユーザーに渡しました。 ただし、処理する必要があり、サイトに表示するためにいくつかのプレビューサイズを作成することができます。 いくつかの方法でさらに進んで、一度に画像を作成するか、遅延読み込みを使用できます。 2番目の方法にもいくつかの開発オプションがあり、この記事の範囲を超えています(記事の最後に、このメソッドの実装の例を示すリンクのリストが記載されています)。 最初の道を行きます。 そして、このためだけに、$ options配列がimage_managerコンストラクターに渡され、文字列「avatar」がreciveメソッドに送信されます。
サムネイルを作成するには、サイトにアップロードされた画像の種類とそのパラメーターの説明を含む構成ファイルが必要です。 例(Zend_Config_Ini形式を使用):
...
[avatar] ; big, medium small
resize.big.OutputFileFormat = jpg
resize.big.keepFrame = true
resize.big.backgroundColor = 240.240.240
resize.big.width = 236
resize.big.height = 177
resize.medium.keepFrame = true
resize.medium.backgroundColor = 240.240.240
resize.medium.width = 144
resize.medium.height = 108
resize.small.keepFrame = true
resize.small.width = 72
resize.small.height = 54
resize.small.roundCorners = false
[user_album_photo]
...
この構成ファイルは、Image_Managerコンストラクターに渡されます。 reciveメソッドを呼び出すことにより、構成ファイルのセクションを指定し、実際にこの画像の処理方法と作成されるプレビューの数を決定します。 画像処理の場合、Image_Managerがそれ自体の内部で対話する別のライブラリを持つことが望ましいです。
プレビューを保存するために、ソースファイル「00/47/31/00473161」を保存するための同じ形式が使用されますが、最後に特別なハッシュが追加され、このプレビューのパラメーターに基づいて計算されます。その結果、パスは次のようになります。 .jpg "(これも単なる例であり、別の方法で行うことができます)。 このハッシュは、パラメーターが変更された写真のプレビューの存在を判断し、変更されていない場合は、要求に応じて写真を生成するのに役立ちます。
結論に対処するために残っています。 最も簡単なオプションは、URLヘルパーのように機能する特別な画像ヘルパーを作成することです。
// url
$this->image($user->avatar_file_id, 'small', 'avatar')
画像ヘルパーは、パラメーター、セクション、プレビュータイトルを考慮して、現在の画像へのパスを作成する方法を知っているオブジェクト(おそらくImage_Manager)を参照します。 写真が別のホストにある場合は、それを置き換えます。 必要なプレビューがない場合、ヘルパーはそれを生成したり(物議を醸す瞬間、多数の画像が欠落したり、メモリやタイムアウトが終了する可能性があります)、このタイプのファイルの特別なスタブへのパスを提供できます。
その結果、便利な構成ファイルを取得し、ファイルを1行でアップロードし、ユーザー定義の写真を含むサイトのすべての写真を操作する統一された方法を取得しました。
関連リンク:
http://habrahabr.ru/blogs/nginx/77873/-ここに非常に貴重なコメントがあります
http://habrahabr.ru/blogs/nginx/94435/
http://ru.wikipedia.org/wiki/WebDAV-静的を別のサーバーに移動する場合