Php 递归上载文件夹及其内容,但使其结构符合逻辑
目标目标: a) 上载.zip文件,在我的服务器上的临时目录中提取其组件 b) 在一个位置复制/移动所有文件,但对所有文件进行唯一重命名,以便两个文件的名称(在物理位置)不相同 c) 在数据库中开发一个逻辑文件夹树结构(在复制并存储到数据库中时注意文件夹名称,同时存储其内容文件,以便所有文件都具有其所属文件夹的父id) 解释: 压缩文件上载到common/uploads/directories/FolderName.zip,解压缩到common/uploads/directories/ExtractedArchive/FolderName,然后根据定义的文件规则验证每个文件,如果验证,则复制到common/uploads/files位置/ 这些文件共享相同的物理位置,但在db中,它们以下面的方式连接(递归,无限深度)Php 递归上载文件夹及其内容,但使其结构符合逻辑,php,file-upload,yii2,directory,directory-upload,Php,File Upload,Yii2,Directory,Directory Upload,目标目标: a) 上载.zip文件,在我的服务器上的临时目录中提取其组件 b) 在一个位置复制/移动所有文件,但对所有文件进行唯一重命名,以便两个文件的名称(在物理位置)不相同 c) 在数据库中开发一个逻辑文件夹树结构(在复制并存储到数据库中时注意文件夹名称,同时存储其内容文件,以便所有文件都具有其所属文件夹的父id) 解释: 压缩文件上载到common/uploads/directories/FolderName.zip,解压缩到common/uploads/directories/Extra
- 文件夹名
- File1.html
- File2.txt
- 测试文件夹
- 文件3.pdf
- File4.doc
- 另一个测试文件夹
- docx file.docx
- 文档文件.pdf
- file5.jpg
- 李>
- 李>
fileId | filename | type | parent
1 | FolderName | folder | null
2 | File1.html | file | 1
3 | File2.txt | file | 1
4 | TestFolder | folder | 1
5 | File3.doc | file | 4
6 | file4.pdf | file | 4
7 | Another Test Folder | folder | 4
8 | docx file.docx | file | 7
9 | document file.pdf | file | 7
10 | file5.jpg | file | 4
等等
以下是我编写的任务的相关代码段:
view.php文件
<div class="modmgt-module-create">
<div class="panel panel-default">
<div class="panel-heading h4"><?php echo Html::encode($this->title); ?></div>
<div class="panel-body">
<div class="modmgt-module-form">
<?php $form = ActiveForm::begin(); ?>
<?php echo $form->field($model, 'uploadedFile')->fileInput(); ?>
<?php echo $form->field($model, 'description')->textarea(['class'=>'form-control', 'style'=>'max-width:100%; min-height:150px;']); ?>
<?php echo $form->field($model, 'idcategory')->dropDownList($categories, ['prompt'=>Yii::t('main', 'Please Select')]); ?>
<div class="form-group">
<?php echo Html::submitButton(Yii::t('main', 'Upload Folder'), ['class' => 'btn btn-primary']); ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
</div>
public function actionUploadDirectory($pid = null)
{
$model = new DirectoryUploadForm();
$model->parent = $pid; // The ID of parent Directory (coming from the get request)
if($model->load(Yii::$app->request->post()))
{
$UploadedZipFile = \yii\web\UploadedFile::getInstance($model, 'uploadedFile');
if(null != $UploadedZipFile)
{
// Step - 01 - Upload File on my Server (Works fine)
// Step - 02 - Extract that .zip file at my server (works fine)
//$zipExtractDir = Yii::getAlias('@common/uploads/directories/ExtractedArchive/').$UploadedZipFile->baseName;
// Step - 03 - Visit the Directory Recursively and add files in db if meet the requirements
$model->name = $UploadedZipFile->baseName;
$status = DirectoryUploadForm::addFilesfromDirectory($zipExtractDir, $model); // now this is where I get the problem
if(!$status)
{
Yii::$app->session->addFlash("error", Yii::t("main","Contents could not be added in db and Server"));
}
// Step - 04 - Delete the uploaded .zip file and its extracted directory (works fine)
return $this->redirect(['index', 'parent'=>$pid]);
}
else
{
Yii::$app->session->addFlash("error", Yii::t("main","Please upload a file"));
return $this->redirect(['index', 'parent'=>$pid]);
}
}
else
{
return $this->render('upload_directory', ['model' => $model]);
}
}
const TYPE_FOLDER = 1;
const TYPE_FILE = 2;
public function rules()
{
return [
[['name', 'uid', 'idstatus', 'type', 'idcategory', 'author', 'created'], 'required'],
[['description'], 'string'],
[['idstatus', 'type', 'parent', 'rating', 'views', 'idcategory', 'author'], 'integer'],
[['created', 'updated'], 'safe'],
[['name'], 'string', 'max' => 64],
[['extension', 'uid'], 'string', 'max' => 45],
[['idstatus'], 'exist', 'skipOnError' => true, 'targetClass' => FilemgtStatus::className(), 'targetAttribute' => ['idstatus' => 'idstatus']],
[['idcategory'], 'exist', 'skipOnError' => true, 'targetClass' => FilemgtCategory::className(), 'targetAttribute' => ['idcategory' => 'idcategory']],
[['parent'], 'exist', 'skipOnError' => true, 'targetClass' => FilemgtFile::className(), 'targetAttribute' => ['parent' => 'idfile']],
];
}
public function addFilesFromDirectory($dirname, $currentModel, $depth = 0, $status = true )
{
// Step - 01 - Add a Directory of name given as $direname
$temp = explode('/', $dirname);
$name = end($temp);
// $name = $currentModel->name;
$parent = $currentModel->parent;
$description = $currentModel->description;
$idcategory = $currentModel->idcategory;
$extension = '0'; // 0 is for No Extension at all
$uid = md5($name.time());
$type = FilemgtFile::TYPE_FOLDER;
$currentModelId = // add this as directory-structure-model and get its PK // works fine
if(0 == (int)$currentModelId) // means we were unable to create a db record for it
{
Yii::$app->session->addFlash("error", Yii::t("main", "Directory with name: {$name} could not be added in db"));
return false;
}
else
{
Yii::$app->session->addFlash("success", Yii::t("main", "Directory with name: {$name} has been added successfully. . ."));
$status &= true;
}
// Step - 02 - Traverse the newly created directeory ($direname)
$dir = new \RecursiveDirectoryIterator(Yii::getAlias($dirname.DIRECTORY_SEPARATOR));
while ($dir->valid())
{
if(!$dir->isDot()) // To skip the items with . and ..
{
if($dir->isFile()) // It is a file
{
$file = $dir->current();
$name = $file->getFilename();
$parent = $currentModel->parent;
$description = $currentModel->description;
$idcategory = $currentModel->idcategory;
$extension = $file->getExtension();
$uid = md5($name.'_'.time()).'.'.$extension;
$type = FilemgtFile::TYPE_FILE;
$lastInsertId = // add this file-model in database
if(0 == (int)$lastInsertId) // case: the db Insertion failed for the file
{
Yii::$app->session->addFlash("error", Yii::t("main", "File with name: {$name} could not be added in db"));
return false;
}
else
{
// Copy Files from main location to new one
$status &= self::copyFilesFromFolder(Yii::getAlias($dirname.DIRECTORY_SEPARATOR.$name), $uid); // works fine
// Create Thumbnails for Image files
$status &= self::createThumbnails(Yii::getAlias($dirname.DIRECTORY_SEPARATOR.$name), $file); // works fine
}
}
else if($dir->isDir()) // It is a directory
{
$subDir = Yii::getAlias($dir->current());
$childModel = new DirectoryUploadForm();
$childModel->parent = $currentModelId;
$childModel->description = $currentModel->description;
$childModel->idcategory = $currentModel->idcategory;
$status &= self::addFilesFromDirectory($subDir, $childModel, $depth++, $status);
if(!$status)
{
Yii::$app->session->addFlash("error", Yii::t("main", "Directory (and contents) with name: {$name} could not be added in db"));
}
}
}
$dir->next();
}
return $status;
}
FilemgtFile.php文件
<div class="modmgt-module-create">
<div class="panel panel-default">
<div class="panel-heading h4"><?php echo Html::encode($this->title); ?></div>
<div class="panel-body">
<div class="modmgt-module-form">
<?php $form = ActiveForm::begin(); ?>
<?php echo $form->field($model, 'uploadedFile')->fileInput(); ?>
<?php echo $form->field($model, 'description')->textarea(['class'=>'form-control', 'style'=>'max-width:100%; min-height:150px;']); ?>
<?php echo $form->field($model, 'idcategory')->dropDownList($categories, ['prompt'=>Yii::t('main', 'Please Select')]); ?>
<div class="form-group">
<?php echo Html::submitButton(Yii::t('main', 'Upload Folder'), ['class' => 'btn btn-primary']); ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
</div>
public function actionUploadDirectory($pid = null)
{
$model = new DirectoryUploadForm();
$model->parent = $pid; // The ID of parent Directory (coming from the get request)
if($model->load(Yii::$app->request->post()))
{
$UploadedZipFile = \yii\web\UploadedFile::getInstance($model, 'uploadedFile');
if(null != $UploadedZipFile)
{
// Step - 01 - Upload File on my Server (Works fine)
// Step - 02 - Extract that .zip file at my server (works fine)
//$zipExtractDir = Yii::getAlias('@common/uploads/directories/ExtractedArchive/').$UploadedZipFile->baseName;
// Step - 03 - Visit the Directory Recursively and add files in db if meet the requirements
$model->name = $UploadedZipFile->baseName;
$status = DirectoryUploadForm::addFilesfromDirectory($zipExtractDir, $model); // now this is where I get the problem
if(!$status)
{
Yii::$app->session->addFlash("error", Yii::t("main","Contents could not be added in db and Server"));
}
// Step - 04 - Delete the uploaded .zip file and its extracted directory (works fine)
return $this->redirect(['index', 'parent'=>$pid]);
}
else
{
Yii::$app->session->addFlash("error", Yii::t("main","Please upload a file"));
return $this->redirect(['index', 'parent'=>$pid]);
}
}
else
{
return $this->render('upload_directory', ['model' => $model]);
}
}
const TYPE_FOLDER = 1;
const TYPE_FILE = 2;
public function rules()
{
return [
[['name', 'uid', 'idstatus', 'type', 'idcategory', 'author', 'created'], 'required'],
[['description'], 'string'],
[['idstatus', 'type', 'parent', 'rating', 'views', 'idcategory', 'author'], 'integer'],
[['created', 'updated'], 'safe'],
[['name'], 'string', 'max' => 64],
[['extension', 'uid'], 'string', 'max' => 45],
[['idstatus'], 'exist', 'skipOnError' => true, 'targetClass' => FilemgtStatus::className(), 'targetAttribute' => ['idstatus' => 'idstatus']],
[['idcategory'], 'exist', 'skipOnError' => true, 'targetClass' => FilemgtCategory::className(), 'targetAttribute' => ['idcategory' => 'idcategory']],
[['parent'], 'exist', 'skipOnError' => true, 'targetClass' => FilemgtFile::className(), 'targetAttribute' => ['parent' => 'idfile']],
];
}
public function addFilesFromDirectory($dirname, $currentModel, $depth = 0, $status = true )
{
// Step - 01 - Add a Directory of name given as $direname
$temp = explode('/', $dirname);
$name = end($temp);
// $name = $currentModel->name;
$parent = $currentModel->parent;
$description = $currentModel->description;
$idcategory = $currentModel->idcategory;
$extension = '0'; // 0 is for No Extension at all
$uid = md5($name.time());
$type = FilemgtFile::TYPE_FOLDER;
$currentModelId = // add this as directory-structure-model and get its PK // works fine
if(0 == (int)$currentModelId) // means we were unable to create a db record for it
{
Yii::$app->session->addFlash("error", Yii::t("main", "Directory with name: {$name} could not be added in db"));
return false;
}
else
{
Yii::$app->session->addFlash("success", Yii::t("main", "Directory with name: {$name} has been added successfully. . ."));
$status &= true;
}
// Step - 02 - Traverse the newly created directeory ($direname)
$dir = new \RecursiveDirectoryIterator(Yii::getAlias($dirname.DIRECTORY_SEPARATOR));
while ($dir->valid())
{
if(!$dir->isDot()) // To skip the items with . and ..
{
if($dir->isFile()) // It is a file
{
$file = $dir->current();
$name = $file->getFilename();
$parent = $currentModel->parent;
$description = $currentModel->description;
$idcategory = $currentModel->idcategory;
$extension = $file->getExtension();
$uid = md5($name.'_'.time()).'.'.$extension;
$type = FilemgtFile::TYPE_FILE;
$lastInsertId = // add this file-model in database
if(0 == (int)$lastInsertId) // case: the db Insertion failed for the file
{
Yii::$app->session->addFlash("error", Yii::t("main", "File with name: {$name} could not be added in db"));
return false;
}
else
{
// Copy Files from main location to new one
$status &= self::copyFilesFromFolder(Yii::getAlias($dirname.DIRECTORY_SEPARATOR.$name), $uid); // works fine
// Create Thumbnails for Image files
$status &= self::createThumbnails(Yii::getAlias($dirname.DIRECTORY_SEPARATOR.$name), $file); // works fine
}
}
else if($dir->isDir()) // It is a directory
{
$subDir = Yii::getAlias($dir->current());
$childModel = new DirectoryUploadForm();
$childModel->parent = $currentModelId;
$childModel->description = $currentModel->description;
$childModel->idcategory = $currentModel->idcategory;
$status &= self::addFilesFromDirectory($subDir, $childModel, $depth++, $status);
if(!$status)
{
Yii::$app->session->addFlash("error", Yii::t("main", "Directory (and contents) with name: {$name} could not be added in db"));
}
}
}
$dir->next();
}
return $status;
}
DirectoryUploadForm.php文件
<div class="modmgt-module-create">
<div class="panel panel-default">
<div class="panel-heading h4"><?php echo Html::encode($this->title); ?></div>
<div class="panel-body">
<div class="modmgt-module-form">
<?php $form = ActiveForm::begin(); ?>
<?php echo $form->field($model, 'uploadedFile')->fileInput(); ?>
<?php echo $form->field($model, 'description')->textarea(['class'=>'form-control', 'style'=>'max-width:100%; min-height:150px;']); ?>
<?php echo $form->field($model, 'idcategory')->dropDownList($categories, ['prompt'=>Yii::t('main', 'Please Select')]); ?>
<div class="form-group">
<?php echo Html::submitButton(Yii::t('main', 'Upload Folder'), ['class' => 'btn btn-primary']); ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
</div>
public function actionUploadDirectory($pid = null)
{
$model = new DirectoryUploadForm();
$model->parent = $pid; // The ID of parent Directory (coming from the get request)
if($model->load(Yii::$app->request->post()))
{
$UploadedZipFile = \yii\web\UploadedFile::getInstance($model, 'uploadedFile');
if(null != $UploadedZipFile)
{
// Step - 01 - Upload File on my Server (Works fine)
// Step - 02 - Extract that .zip file at my server (works fine)
//$zipExtractDir = Yii::getAlias('@common/uploads/directories/ExtractedArchive/').$UploadedZipFile->baseName;
// Step - 03 - Visit the Directory Recursively and add files in db if meet the requirements
$model->name = $UploadedZipFile->baseName;
$status = DirectoryUploadForm::addFilesfromDirectory($zipExtractDir, $model); // now this is where I get the problem
if(!$status)
{
Yii::$app->session->addFlash("error", Yii::t("main","Contents could not be added in db and Server"));
}
// Step - 04 - Delete the uploaded .zip file and its extracted directory (works fine)
return $this->redirect(['index', 'parent'=>$pid]);
}
else
{
Yii::$app->session->addFlash("error", Yii::t("main","Please upload a file"));
return $this->redirect(['index', 'parent'=>$pid]);
}
}
else
{
return $this->render('upload_directory', ['model' => $model]);
}
}
const TYPE_FOLDER = 1;
const TYPE_FILE = 2;
public function rules()
{
return [
[['name', 'uid', 'idstatus', 'type', 'idcategory', 'author', 'created'], 'required'],
[['description'], 'string'],
[['idstatus', 'type', 'parent', 'rating', 'views', 'idcategory', 'author'], 'integer'],
[['created', 'updated'], 'safe'],
[['name'], 'string', 'max' => 64],
[['extension', 'uid'], 'string', 'max' => 45],
[['idstatus'], 'exist', 'skipOnError' => true, 'targetClass' => FilemgtStatus::className(), 'targetAttribute' => ['idstatus' => 'idstatus']],
[['idcategory'], 'exist', 'skipOnError' => true, 'targetClass' => FilemgtCategory::className(), 'targetAttribute' => ['idcategory' => 'idcategory']],
[['parent'], 'exist', 'skipOnError' => true, 'targetClass' => FilemgtFile::className(), 'targetAttribute' => ['parent' => 'idfile']],
];
}
public function addFilesFromDirectory($dirname, $currentModel, $depth = 0, $status = true )
{
// Step - 01 - Add a Directory of name given as $direname
$temp = explode('/', $dirname);
$name = end($temp);
// $name = $currentModel->name;
$parent = $currentModel->parent;
$description = $currentModel->description;
$idcategory = $currentModel->idcategory;
$extension = '0'; // 0 is for No Extension at all
$uid = md5($name.time());
$type = FilemgtFile::TYPE_FOLDER;
$currentModelId = // add this as directory-structure-model and get its PK // works fine
if(0 == (int)$currentModelId) // means we were unable to create a db record for it
{
Yii::$app->session->addFlash("error", Yii::t("main", "Directory with name: {$name} could not be added in db"));
return false;
}
else
{
Yii::$app->session->addFlash("success", Yii::t("main", "Directory with name: {$name} has been added successfully. . ."));
$status &= true;
}
// Step - 02 - Traverse the newly created directeory ($direname)
$dir = new \RecursiveDirectoryIterator(Yii::getAlias($dirname.DIRECTORY_SEPARATOR));
while ($dir->valid())
{
if(!$dir->isDot()) // To skip the items with . and ..
{
if($dir->isFile()) // It is a file
{
$file = $dir->current();
$name = $file->getFilename();
$parent = $currentModel->parent;
$description = $currentModel->description;
$idcategory = $currentModel->idcategory;
$extension = $file->getExtension();
$uid = md5($name.'_'.time()).'.'.$extension;
$type = FilemgtFile::TYPE_FILE;
$lastInsertId = // add this file-model in database
if(0 == (int)$lastInsertId) // case: the db Insertion failed for the file
{
Yii::$app->session->addFlash("error", Yii::t("main", "File with name: {$name} could not be added in db"));
return false;
}
else
{
// Copy Files from main location to new one
$status &= self::copyFilesFromFolder(Yii::getAlias($dirname.DIRECTORY_SEPARATOR.$name), $uid); // works fine
// Create Thumbnails for Image files
$status &= self::createThumbnails(Yii::getAlias($dirname.DIRECTORY_SEPARATOR.$name), $file); // works fine
}
}
else if($dir->isDir()) // It is a directory
{
$subDir = Yii::getAlias($dir->current());
$childModel = new DirectoryUploadForm();
$childModel->parent = $currentModelId;
$childModel->description = $currentModel->description;
$childModel->idcategory = $currentModel->idcategory;
$status &= self::addFilesFromDirectory($subDir, $childModel, $depth++, $status);
if(!$status)
{
Yii::$app->session->addFlash("error", Yii::t("main", "Directory (and contents) with name: {$name} could not be added in db"));
}
}
}
$dir->next();
}
return $status;
}
问题 上载结构未得到维护。我得到的结构是这样出现的:父目录得到的文件实际上属于它的子目录模型。然而,创建子目录模型时也没有包含任何内容。一切都搞砸了 我已经删除了这里没有用的代码,这样你就不必阅读不必要的代码来解决问题;但是如果你需要查看我机器上的完整代码,请告诉我 感谢您的帮助。提前谢谢各位。 保持幸福