引用: 前回の記事で述べたように、ページ内で隠しメソッドを使用すると、アップロード ページを美しく見せることができます。でもこれでは性能的には何の役にも立たないので、バックグラウンド処理に何か処理テクニックはないものでしょうか?いわゆるバックグラウンド スキルには、より高速なアップロードと、より大きなファイルのアップロードが含まれる必要があります。そこで今回はバックエンド処理にはどのようなスキルがあるのかについてお話しします!
ビジネス シナリオ 1. アップロードするファイルを 1 つだけ選択します。すぐに検証作業を行う必要はありません。その場合、最適化はまったく行われない可能性があります。最終的にしなければならないことは、このファイルをフォームに入力して一緒に送信し、直接処理することだけだからです。
ビジネス シナリオ 2: 複数のファイルをアップロードする必要があり、ファイルの内部コンテンツを随時検証して、対応するページに表示する必要があります。この場合、ユーザーがファイルのアップロードを選択した後、ファイル内の情報を読み取る必要があるため、ファイルをすぐにアップロードする必要があり、最後に送信するときにもファイルを一度送信する必要があります。明らかに、ここには反復的なアップロード タスクがあり、1 つはユーザーの時間を消費し、もう 1 つはサーバーの帯域幅リソースを消費します。最適化の方法としては、初回にファイルをアップロードした後、そのファイルをサーバー上に保持しておき、実際にフォームを送信するときに、アップロードされた一時ファイルを読み取るだけでよいという方法も考えられます。はい、これが私たちのアプローチです!
ビジネス シナリオ 3 はシナリオ 2 と似ており、複数のファイルをアップロードする必要がありますが、複数のファイルを個別にアップロードすることもできます。つまり、最初に 10M、2 回目に 10M、合計 10 回アップロードした可能性があります。そうすると、サーバー側では 1 回の送信がアップロード サイズの制限を超えたはずですが、もしそうなら。毎回アップロードしても大丈夫、最後に送信するときも短いテキストメッセージをアップロードするだけです!
確かに考え方はシンプルで問題なさそうですが、私の能力では限界があるのか、これに対処するのに本当に時間がかかりました。以下にサンプルコードを記載しますので、参考にしてください。
ファイルアップロード手法 (アップロードした単一ファイルをサーバー側に一時ファイルとして存在させる) サンプルコード:
1. ページjs 処理
//点击选择完成文件后,触发上传文件操作,将文件上传至服务器临时目录 $('.upload-real-file').off().on('change', function(){ if(!$(this).val()){ return false; } var responseObjId = $(this).attr('response-id'); var responseObj = $('#' + responseObjId); $('#Form').ajaxSubmit({ url:'/aa/bb/uploadTmpApkTool', resetForm: false, dataType: 'json', beforeSubmit: function(option){ window.loading = layer.load(2); }, success: function(data, statusText){ layer.close(window.loading); if(data.status == 1){ responseObj.html(data.apkInfoHtml); var parentContainer = responseObj.parent().parent(), nameContainer = parentContainer.find('.file-name-container'); nameContainer.html(data.apkName); nameContainer.attr('title', data.apkName); responseObj.find('.file-tmp').html(data.fileInfo); //将文件信息存放于隐藏域中,以便在提交时能找到 $(submitId).removeAttr('disabled'); }else{ layer.alert(data.info); } }, error: function(data){ layer.close(window.loading); layer.alert('未知错误,请稍后再试!'); } }); return false;//防止dialog 自动关闭 });
2. 明らかに、ページはファイル情報とバックグラウンド処理コード (PHP) を取得する必要があります
$apkConfig = $this->_getApkConfig(); $params = $this->getFilteredParam('get'); $subFile = $_FILES['apkToolFiles']; $apkName = $apkInfoHtml = ""; if(empty($subFile)) { $this->ajaxReturn(array('status' => -4, 'info' => '请选择要上传的文件')); } foreach ($subFile['name'] as $subKey => $subVal) { if ($subFile['name'][$subKey]) { $fileData = $this->_getFileData($subFile, $subKey); $checkData = array( 'maxSize' => $apkConfig['FILE_MAX_SIZE'], 'savePath' => $apkConfig['TMP_CHILD_PATH'], 'extArr' => array('apk'), 'releaseName' => str_replace('.apk', '', $fileData['fileName']), //特有 ); $checkResult = $this->_checkFileData($fileData, $checkData); if ($checkResult['status'] != 1) { $this->ajaxReturn($checkResult); } //移动文件 $filePath = $checkData['savePath'] . '/' . $fileData['fileName'] . '.tmp' . genRandStr(6);; $this->_moveUploadedFile($fileData['tmpName'], $filePath); $apkInfo = $this->_apkParser($filePath); //解析 if($apkInfo['UMENG_CHANNEL'] != 'UMENG_CHANNEL_VALUE') { @unlink($filePath); //删除无效文件 $this->ajaxReturn(array('status' => 0, 'info' => "UMENG_CHANNEL的值要是 UMENG_CHANNEL_VALUE才行")); } $tmpFileArr['file_info'] = array( 'name' => $subFile['name'][$subKey], 'type' => $subFile['type'][$subKey], 'tmp_name' => str_replace($apkConfig['TMP_CHILD_PATH'] . '/', '', $filePath), 'error' => $subFile['error'][$subKey], 'size' => $subFile['size'][$subKey], ); //转存该值,不再重复上传文件 } else { $this->ajaxReturn(array('status' => 0, 'info' => "文件不能为空")); } foreach ($apkInfo as $key => $val) { $apkInfoHtml .= "{$key}:{$val} \r\n"; } $apkName = $fileData['fileName']; $version = $apkInfo['versionName']; } $fileInfo = htmlspecialchars(json_encode($tmpFileArr['file_info'])); $fileInfoHtml = "<input name=\"apkToolFileTmp[]\" value='{$fileInfo}' type=\"hidden\"/>"; //一定要输出前使用htmlspecialchars, 否则不能正确显示页面值和获取至正确的文件信息 $this->ajaxReturn(array('status' => 1, 'info' => "上传成功", 'version' => $version, 'item' => $item, 'apkName' => $apkName, 'apkInfoHtml' => $apkInfoHtml, 'fileInfo' => $fileInfoHtml)); }
3. 2 つの部分を使用して協力コードの最後にフォームを送信するときに、ファイルをサーバーに送信する必要はなく、アップロードされた一時ファイルを移動するだけで済みます。前に、それで終わりです!
$('.upload-file-real').attr('disabled', 'disabled'); //提交表单前,禁用上传文件
4. フォローアップ作業
一時ファイルをサーバーにアップロードした後、ユーザーが現在の操作をキャンセルしたかどうかを判断する方法はありません。キャンセルされた場合、一時ファイルは削除されます。は常にサーバー上に存在するため、一時ディレクトリを定期的にクリーンアップするスクリプトが必要です。もちろん、これは非常に簡単です。たとえば、1 日より古いファイルは削除されます。掃除の頻度をコントロールすることに注意してください。
5. 余談
ログは非常に重要です。問題が発生した場所、ファイルが削除された場所、データベースがクリーンアップされた場所を記録しておく必要があります。理由は、助けを求めて叫ぶ場所です。
ファイルをサーバーの一時ディレクトリにアップロードする バックエンドの処理原理は非常に単純に見えますが、少なくともこの小さな関数を実行していたときは、かなりの時間がかかりました。それを理解するための努力の!