前段时间,接触到了一个这样的需求:一个微信端的动态查询需要在移动端根据不同的条件搜索可以展示相应的数据及图片信息(包括名称,图片会有多张),对应后台的需求很多,其中有一个则是可以手动配置信息(包括但不仅限于批量处理数万张图片,然后动态匹配查询结果,最终实现在移动端展示......
关于图片处理这部分有很多种解决思路,我这里只写一下我自己最终选择的一种处理方式(仅供参考),勿喷~~~
1:确定后台图片处理规则;
2:将文件按照规则处理保存对应的服务器目录;
3:PHP解压linux文件
function __construct($app)
{
$this->app = $app;
$this->targetDir = 'files/upload_tmp';
$this->_targetDir = 'files/upload_tmp/yq';
$this->uploadDir = 'files/upload';
}
处理图片文件:根据对应的ID保存文件目录
public function batchfile()
{
if (isset($_REQUEST["name"])) {
$fileName = $_REQUEST["name"];
} elseif (!empty($_FILES)) {
$fileName = $_FILES["file"]["name"];
} else {
$fileName = uniqid("file_");
}
if (empty($_REQUEST["file_id"])) exit;
kernel::single("modelsmatch_upload_files")->foldfile($_REQUEST["file_id"], $fileName,
'images/qcj/folder');
}
文件服务器处理:
public function foldfile($file_id, $fileName, $uploadDir1 = 'files/qcj')
{
@set_time_limit(5 * 60);
usleep(5000);
$cleanupTargetDir = true; // Remove old files
$maxFileAge = 5 * 3600; // Temp file age in seconds
$file_array = explode('.', $fileName);
$old_file_name = $file_array[0];
$ext_name = end($file_array);
$targetDir = $this->targetDir;
$uploadDir = $uploadDir1;
// Create target dir
if (!file_exists($targetDir)) {
$this->mkdir_p($targetDir);
}
// Create target dir
if (!file_exists($uploadDir)) {
$this->mkdir_p($uploadDir);
}
$filePath = $targetDir . '/' . $file_id . "." . $ext_name;
$uploadPath = $uploadDir . '/' . $file_id . "." . $ext_name;
// Chunking might be enabled
$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 1;
// Remove old temp files
if ($cleanupTargetDir) {
if (!is_dir($targetDir) || !$dir = opendir($targetDir)) {
die('{"jsonrpc" : "23.0", "error" : {"code": 100, "message": "Failed to open
temp directory."}, "file_id" : "' . $file_id . '"}');
}
while (($file = readdir($dir)) !== false) {
$tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
// If temp file is current file proceed to the next
if ($tmpfilePath == "{$filePath}_{$chunk}.part" || $tmpfilePath ==
"{$filePath}_{$chunk}.parttmp") {
continue;
}
// Remove temp file if it is older than the max age and is not the current file
if (preg_match('/\.(part|parttmp)$/', $file) && (@filemtime($tmpfilePath) <
time() - $maxFileAge)) {
@unlink($tmpfilePath);
}
}
closedir($dir);
}
// Open temp file
if (!$out = @fopen("{$filePath}_{$chunk}.parttmp", "wb")) {
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}
, "file_id" : "' . $file_id . '"}');
}
if (!empty($_FILES)) {
if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) {
die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move
uploaded file."}, "file_id" : "' . $file_id . '"}');
}
// Read binary input stream and append it to temp file
if (!$in = @fopen($_FILES["file"]["tmp_name"], "rb")) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open
input stream."}, "file_id" : "' . $file_id . '"}');
}
} else {
if (!$in = @fopen("php://input", "rb")) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open
input stream."}, "file_id" : "' . $file_id . '"}');
}
}
while ($buff = fread($in, 4096)) {
fwrite($out, $buff);
}
@fclose($out);
@fclose($in);
rename("{$filePath}_{$chunk}.parttmp", "{$filePath}_{$chunk}.part");
$index = 0;
$done = true;
for ($index = 0; $index < $chunks; $index++) {
if (!file_exists("{$filePath}_{$index}.part")) {
$done = false;
break;
}
}
if ($done) {
if (!$out = @fopen($uploadPath, "wb")) {
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open
output stream."}, "file_id" : "' . $file_id . '"}');
}
if (flock($out, LOCK_EX)) {
for ($index = 0; $index < $chunks; $index++) {
if (!$in = @fopen("{$filePath}_{$index}.part", "rb")) {
break;
}
while ($buff = fread($in, 4096)) {
fwrite($out, $buff);
}
@fclose($in);
@unlink("{$filePath}_{$index}.part");
}
flock($out, LOCK_UN);
}
@fclose($out);
}
//解压rar文件
$this->unrar($uploadPath, './images/qcj/', true, false);
// Return Success JSON-RPC response
die('{"jsonrpc" : "2.0", "result" : "success", "file_id" : "' . $file_id . '",
"file_name":"' . $fileName . '"}');
}
生成文件目录:
private function mkdir_p($dir, $dirmode = 0755)
{
$path = explode('/', str_replace('\\', '/', $dir));
$depth = count($path);
for ($i = $depth; $i > 0; $i--) {
if (file_exists(implode('/', array_slice($path, 0, $i)))) {
break;
}
}
for ($i; $i < $depth; $i++) {
if ($d = implode('/', array_slice($path, 0, $i + 1))) {
mkdir($d, $dirmode);
}
}
return is_dir($dir);
}
PHP在linux解压方式有很多种,这里只写常用的zip/rar格式
rar格式:
public function unrar($src_file, $dest_dir = false, $create_zip_name_dir = true, $overwrite = false)
{
if ($rar = rar_open($src_file)) {//$src_file压缩文件
if ($rar) {
$splitter = ($create_zip_name_dir === true) ? "." : "/";
if ($dest_dir === false) {
$dest_dir = substr($src_file, 0, strrpos($src_file, $splitter)) . "/";
}
// 如果不存在 创建目标解压目录
$this->create_dirs($dest_dir);//$dest_dir解压文件
$list = rar_list($rar) or die('could not get list');
foreach($list as $file) {
$pattern = '/\".*\"/';
preg_match($pattern, $file, $matches, PREG_OFFSET_CAPTURE);
$pathStr=$matches[0][0];
$pathStr=str_replace("\"",'',$pathStr);
$entry = rar_entry_get($rar, $pathStr) or die('</br>entry not found');
$entry->extract($dest_dir);
}
//关闭压缩包文件
rar_close($rar);
}
} else {
return false;
}
return true;
}
zip格式:
public function unzip($src_file, $dest_dir = false, $create_zip_name_dir = true, $overwrite = true)
{
if ($zip = zip_open($src_file)) {
if ($zip) {
$splitter = ($create_zip_name_dir === true) ? "." : "/";
if ($dest_dir === false) {
$dest_dir = substr($src_file, 0, strrpos($src_file, $splitter)) . "/";
}
// 如果不存在 创建目标解压目录
$this->create_dirs($dest_dir);
// 对每个文件进行解压
while ($zip_entry = zip_read($zip)) {
// 文件不在根目录
$pos_last_slash = strrpos(zip_entry_name($zip_entry), "/");
if ($pos_last_slash !== false) {
// 创建目录 在末尾带 /
$this->create_dirs($dest_dir . substr(zip_entry_name($zip_entry), 0,
$pos_last_slash + 1));
}
// 打开包
if (zip_entry_open($zip, $zip_entry, "r")) {
// 文件名保存在磁盘上
$file_name = $dest_dir . zip_entry_name($zip_entry);
// 检查文件是否需要重写
if ($overwrite === true || $overwrite === false && !is_file($file_name)) {
// 读取压缩文件的内容
$fstream = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
//@unlink(iconv("utf-8","gb2312",$file_name));
print_r($fstream);
@file_put_contents($file_name, $fstream);
// 设置权限
chmod($file_name, 0777);
// echo "save: ".$file_name."<br />";
}
// 关闭入口
zip_entry_close($zip_entry);
}
}
// 关闭压缩包
zip_close($zip);
}
} else {
return false;
}
return true;
}
创建解压目录:
public function create_dirs($path)
{
if (!is_dir($path)) {
$directory_path = "";
$directories = explode("/", $path);
array_pop($directories);
foreach ($directories as $directory) {
$directory_path .= $directory . "/";
if (!is_dir($directory_path)) {
mkdir($directory_path);
chmod($directory_path, 0777);
}
}
}
}
读取目录下所有内容:
public function get_dir_files($dir = "")
{
if (empty($dir)) return array();
//打开目录
$fp = opendir($dir);
//阅读目录
while (false != ($file = readdir($fp))) {
//$file = iconv("gb2312", "utf-8", $file);
//列出所有文件并去掉'.'和'..'
if ($file == '.' || $file == '..') continue;
$fileName = $file;
$fileId = md5($file);
$imgdir = $dir . $fileName;
$url = kernel::base_url(1) . '/' . $imgdir;
$arr_file[] = $fileId . '|' . $fileName . '|' . $imgdir . '|' . $url;
}
closedir($fp);
return $arr_file;
}
注意的几个地方:
1:需要在linux安装扩展;
2:Linux中文编码问题;
欢迎大家指正~~