PHP: have a text box that allows users to enter a number, a number followed by k (or kb) or m or (mb) to denote filesize and process accordingly?
I'm actually struggling to word this properly.
What I have at the moment is a form that asks for a minimum and maximum filesize in kb but what I would like to attempt is to allow the user to decide their max and min file sizes by creating somekind of rules, e.g.:
If there are no letters in the boxes then interpret it as bytes, if there is a k or kb present, interpret at kb and likewise for mb.
The default and any errors that occur should just set to kb I think but I am just trying to figure out in my head how to achieve this and any suggestions would be very much appreciated.
<tr>
<td class="label">File Size:</td>
<td>
<input id="filesize_min" name="filesize_min" class="text" value="<?php if (isset($_POST['dosearch']))
{
echo($filesize_min);
}
elseif (isset($_POST['advancedsearchsubmit']))
{
echo($_POST['hiddenfilesize_min']);
}
else
{
echo "";
} ?>"><div id="kb">(kb min)</div>
</td>
<td>
<input id="filesize_max" name="filesize_max" class="text" value="<?php if (isset($_POST['dosearch']))
{
echo($filesize_max);
}
elseif (isset($_POST['advancedsearchsubmit']))
{
echo($_POST['hiddenfilesize_max']);
}
else
{
echo "";
}?>">
<div id="kb">(kb max)&开发者_如何学Golt;/div>
</td>
</tr>
UPDATE
Thanks for all the great answers, just gonna try some of them out just now, all have been upvoted.
My try:
<?php
function strtobytes($str) {
$result = 0;
if (preg_match('/^(\d+)(.*)$/', $str, $m)) {
list(, $intVal, $suffix) = $m;
switch (strtolower(trim($suffix))) {
case 'k': case 'kb':
$intVal *= pow(1024, 1);
break;
case 'm': case 'mb':
$intVal *= pow(1024, 2);
break;
case 'g': case 'gb':
$intVal *= pow(1024, 3);
break;
case 't': case 'tb':
$intVal *= pow(1024, 4);
break;
}
$result = $intVal;
}
return $result;
}
foreach (array('512', '512k', '512kb', '512m', '512mb', '512g', '512gb', '512t', '512tb') as $str) {
printf(
'%s = %s bytes<br />',
$str, strtobytes($str)
);
}
Converting the string into an integer (number of bytes). Then you can do whatever you like
$filesize;
if (is_numeric($filesize)) {
$filesize = (int) $filesize;
} else {
switch (true) {
case strtolower(substr($filesize, -1)) === 'k':
$filesize = substr($filesize, 0, -1) * 1024;
break;
case strtolower(substr($filesize, -2)) === 'kb':
$filesize = substr($filesize, 0, -2) * 1024;
break;
// And so on for m/mb, g/gb ...
default:
// Invalid format (?)
break;
}
}
You can make a function out of it for better reuseability.
You can of course use regular expressions or string functions to detect certain strings in your input, but wouldn't it be easier for both you and the user to just add one or two selects where the user can simply select the unit and the value gives you a multiplier, like for example for the minimum value:
<select name="unit_min">
<option value="1">bytes</option>
<option value="1000">Kb</option>
<option value="1000000">Mb</option>
</select>
Mixing of numeric values and string values in one input-box seems like the wrong way to go.
I suppose that when there's $_POST['dosearch'] you have processed the form before and set filesize_min and filesize_max. You seem to be asking about how to do that processing and set filesize_min and max properly to be always in kbytes, would be something like the following:
$_POST['filesize_min'] = trim($_POST['filesize_min']);
if (preg_match('^(\d+)\s*(k|m)b?$', $_POST['filesize_min'], $matches)) {
$filesize_min = $matches[1];
switch ($matches[2]) {
case 'k':
break;
case 'm';
filesize_min *= 1024;
break;
default:
filesize_min /= 1024;
break;
}
} else {
// Validation error
}
I haven't tested this, but i think it should work... You may do the same for filesize_max
精彩评论