我几乎设法让这个上传代码正常工作,但需要帮助(希望!)最后一部分。
目前图片上传,调整大小&正确压缩,但它们最终在一个文件夹中,我需要根据我的数据库中的名称将它们放在具有特定文件名的特定位置。
目前他们上传到/images/events/wer34ret.jpg,但我希望他们上传到编号的文件夹,例如/images/events/1045/filename.jpg
它使用2页,resizer.php& uploader.php,我一直在玩session&全局变量尝试将ID输入文件夹路径,但它不起作用。
我以为我可以像这样添加一个变量:
if(strtolower($type) == "standard") {
$path = $location.'/' . $VARIABLE . '/' .$filename;
imagejpeg($tmp, $path.'.jpg', 90);
但代码忽略了变量。然后我用会话和全局变量尝试了它,但我明显遗漏了一些重要的东西。
以下是我正在使用的代码:
resizer.php:
function resize ($type,$width,$height,$location,$filename,$key) {
// Get dimensions from uploaded file
list($w, $h) = getimagesize($_FILES['uploader']['tmp_name'][$key]);
// Calculate new size/ratio
$ratio = max($width/$w, $height/$h);
$h = ceil($height / $ratio);
$x = ($w - $width / $ratio) / 2;
$w = ceil($width / $ratio);
// Read the binary and create image file
$imgString = file_get_contents($_FILES['uploader']['tmp_name'][$key]);
$image = imagecreatefromstring($imgString);
$tmp = imagecreatetruecolor($width, $height);
imagecopyresampled($tmp, $image, 0, 0, $x, 0, $width, $height, $w, $h);
// Create the path and save the image
if(strtolower($type) == "standard") {
$path = $location.'/' .$filename;
imagejpeg($tmp, $path.'.jpg', 90);
} elseif (strtolower($type) == "retina") {
// '@2x' is used at the end of file names to indicate which files are for retina devices
$path = $location.'/' . $intId .'/' .$filename.'@2x';
imagejpeg($tmp, $path.'.jpg', 80);
}
// Clean up the mess
imagedestroy($image);
imagedestroy($tmp);
}
uploader.php
// Configure the uploader's settings
$settings = array (
'maxFileSize' => 1024*3000, // 3mb
'allowedExtensions' => array ('jpeg','jpg','png','gif'),
'variations' => array (
// thumbnail
'small' => array(
'standard' => array(
'width' => 224,
'height' => 83,
'location' => '../../../images/events/'
),
'retina' => array(
'width' => 448,
'height' => 166,
'location' => 'uploads/small'
)
),
// preview image
'large' => array(
'standard' => array(
'width' => 700,
'height' => 260,
'location' => 'uploads/large'
),
'retina' => array(
'width' => 1400,
'height' => 520,
'location' => 'uploads/large'
)
)
)
);
// Include resizer function
require 'resizer.php';
// Create an array to hold the complete upload report
$uploadReport = array();
// Loop through one or more uploaded files
// Currently the HTML file input is restricted to single files but this upload script can handle multiple
// Each uploaded file has an error value, regardless of its success, so we can loop through the errors
foreach ($_FILES["uploader"]["error"] as $key => $error) {
// Create a report for this file
$fileReport = array();
// Determine which error code was produced
switch ($error) {
case UPLOAD_ERR_OK:
$errorInfo = 'File uploaded successfully';
break;
case UPLOAD_ERR_INI_SIZE:
$errorInfo = 'The uploaded file exceeds the upload_max_filesize directive in php.ini.';
break;
case UPLOAD_ERR_FORM_SIZE:
$errorInfo = 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.';
break;
case UPLOAD_ERR_PARTIAL:
$errorInfo = 'The uploaded file was only partially uploaded.';
break;
case UPLOAD_ERR_NO_FILE:
$errorInfo = 'No file was uploaded.';
break;
case UPLOAD_ERR_NO_TMP_DIR:
$errorInfo = 'Missing a temporary folder.';
break;
case UPLOAD_ERR_CANT_WRITE:
$errorInfo = 'Failed to write file to disk.';
break;
case UPLOAD_ERR_EXTENSION:
$errorInfo = 'File upload stopped by extension.';
break;
default:
$errorInfo = 'Unknown upload error';
break;
}
// Get file details from upload
$fileName = $_FILES["uploader"]["name"][$key];
$fileType = strtolower(exif_imagetype($_FILES["uploader"]["tmp_name"][$key]));
$fileType = getFileTypeString($fileType);
$fileSize = round(filesize($_FILES["uploader"]["tmp_name"][$key]) / 1000, 2);
if (!$error === UPLOAD_ERR_OK) {
// Upload error detected for this file
// Store the details in its report
buildFileReport($fileName,null,$fileType,$fileSize,1,$errorInfo);
} else {
// No upload error detected, continue
// Validate file type
if (in_array(strtolower($fileType), $settings['allowedExtensions'])) {
// Validate file size
if ($fileSize < $settings['maxFileSize']) {
// Create a unique ID for new filename
$uniqueFilename = uniqid();
// Loop through my size variations in settings
foreach ($settings['variations'] as $variation) {
// Loop through the different image types required (retina or standard)
foreach ($variation as $type => $item) {
// Resize the image and save
$strLocation = $item['location'].'/';
resize($type,$item['width'],$item['height'],$strLocation,$uniqueFilename,$key);
}
}
buildFileReport($fileName,$uniqueFilename,$fileType,$fileSize,0,"File uploaded successfully.");
// Return one or the other, or none if you don't want any feedback
// The first is to return a JSON upload report to the AJAX uploader
// Use JS to show the report at the AJAX end
// echo json_encode($uploadReport);
// This one returns just the unique filename to the AJAX uploader
// For this demo, we use the filename on the uploader page to show the preview images
echo $uniqueFilename;
} else {
buildFileReport($fileName,null,$fileType,$fileSize,1,"File size too big.");
}
} else {
buildFileReport($fileName,null,$fileType,$fileSize,1,"Invalid file type.");
}
}
}
// Function to push each fileReport to the uploadReport array
function buildFileReport($name,$newName,$type,$size,$errors,$errorInfo) {
global $uploadReport;
$fileReport['name'] = $name;
$fileReport['newName'] = $newName;
$fileReport['type'] = $type;
$fileReport['size'] = $size;
$fileReport['errors'] = $errors;
$fileReport['errorInfo'] = $errorInfo;
array_push($uploadReport, $fileReport);
}
// Function to convert file type codes to strings
function getFileTypeString($fileType) {
switch($fileType) {
case "1":
$fileType = "GIF";
break;
case "2":
$fileType = "JPG";
break;
case "3":
$fileType = "PNG";
break;
}
return $fileType;
}
它在页面上使用JQuery:
$(document).ready(function() {
// Clear previews on new upload
// For demo use
$('.upload-button').on('click', function() {
$('#standard-preview').html('');
$('#retina-preview').html('');
$('h6').hide();
$('#srcset-usage').hide();
});
// Uploader starts here
var formData = false;
// When file input changes (files chosen), automatically start
$('#uploader').on('change', function(e) {
if (window.FormData) {
// User's browser has XHR2 FormData for AJAX uploads
// So stop the default behaviour of form submission and AJAX it instead
e.preventDefault();
formData = new FormData();
// When uploader function with AJAX finishes, do stuff with the response
// For this demo, the response is the new file name (url) so we can show the examples on this page
// We can have a JSON response with details of the uploads instead or nothing if you wish
// I've passed 'this' to the function which is the file input object
$.when(newUploader(this)).done(function(url) {
// This is for this demo.
// It shows the example images and resets the progress bar
$('h6').show();
$('#upload-progress').find('.status').text('');
$('#retina-preview').html('<img src="uploads/large/'+url+'@2x.jpg" width="100%">');
$('#upload-progress').find('.bar').css('width','0');
$('#srcset-usage').find('span').text(url).end().show();
});
} else {
// XHR2 FormData is not available on the user's browser
// Se we just trigger a standard form submission instead
// Here I ask the user if they want to use the old version but pretty useless really
// Just added it for demo purposes to let you know that feature is not available
var confirmOld = confirm("Sorry, your browser does not support the latest uploader. " +
"Would you like to use the old uploader instead?");
if (confirmOld) {
$(this).parent('form').submit();
} alert("Upload cancelled.");
}
});
var newUploader = function(fileInput) {
// I need to finish this part, as it wasn't required for this demo
var i = 0,
filesInReader = fileInput.files.length, // this is how many files the user selected
img, reader, file;
// Loop through files in file input
for (i; i < filesInReader; i++) {
file = fileInput.files[i];
// Make sure it's an image file of some kind
if (!!file.type.match(/image.*/)) {
// This part needs finishing
// It allows us to get the filename and size from the user's computer
// Handy for showing a list of files being uploaded and a little thumbnail of the file
// It's also a fairly new feature, so we check if it's available first
if (window.FileReader) {
reader = new FileReader();
reader.onloadend = function(e) {
// This could call a function that outputs a pretty table of uploading files
//showUploadedItem(e.target.result, file.fileName);
};
reader.readAsDataURL(file);
}
// Append the current file in the loop to FormData
// uploader[] is the name of my file input
if (formData) formData.append('uploader[]', file);
}
}
// Here we return the response from the AJAX call to our $.when().done() function above
return $.ajax({
url: 'uploader.php',
type: 'POST',
data: formData,
processData: false,
contentType: false,
cache: false,
// This is the function that listens for AJAX progress and calls our renderProgress function
xhr: function() {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) myXhr.upload.addEventListener('progress', renderProgress, false);
return myXhr;
}
});
};
// Render the progress of our AJAX uploader
var renderProgress = function(e) {
if (e.lengthComputable) {
// Find the progress bar
var $bar = $('#upload-progress').find('.bar'),
progress = Math.round((e.loaded/e.total)*100);
// Set the bar with real-time progress
$bar.css('width', progress+'%');
// This is just making the progress more user-friendly.
// As the upload progress finishes when the upload stops,
// not when the images have been resized
if (progress <= 95) {
// If progress less than 95%, show uploading status
$('#upload-progress').find('.status').html(
'<i class="fa fa-refresh fa-spin"></i> Uploading... '+progress+'%'
);
} else {
// If progress greater than 95%, show resizing status
$('#upload-progress').find('.status').html(
'<i class="fa fa-refresh fa-spin"></i> Resizing images... 99%'
);
}
}
};
});