Написване на клас за File Upload. Част 1
Казано просто class-а е серия от функции, които работят ръка за ръка, за създаването на изходен резултат. Причината, класа да се справя блестящо с ъплоуда на файлове, е че съществуват тонове функции, които някой може да напише, като всичките са взаимозависими от изходния резултат който предлагат, преди финалния резултат да бъде определен.


Интродукция

Напоследък, наблюдавах тонове от въпроси върху таблото за съобщения, относно ъплоуд на файлове на сървъра. Изглежда, това е епидемия, която трябва да бъде излекувана. Бях написал PHP class за ъплоуд на файлове, който някои членове от таблото за съобщения, използуваха и им помогна в облекчаване на живота им. Днес, ще се опитаме да напишем наш собствен високо customizable file upload class. Преди да започнем, вземете подръка бутилка сода и нещо за хрупане, защото може да отнеме известно време. Готови ли сте....(пауза да се снабдиме с екстрите)..да започваме.

Какво е class и защо се нуждая от него?

Казано просто class-а е серия от функции, които работят ръка за ръка, за създаването на изходен резултат. Причината, класа да се справя блестящо с ъплоуда на файлове, е че съществуват тонове функции, които някой може да напише, като всичките са взаимозависими от изходния резултат който предлагат, преди финалния резултат да бъде определен. Поради тази причина пишеме клас вместо 10 функции и taking the time to validate each one.

Друга красота на класа е, че можете да извикате всяка от характеристиките(свойствата) вътре в класа, по Ваше желание. Примерно, с този class, ще има 'x' броя функции, всички играещи своята роля в изходния резултат от процеса на upload . Ако желаете да използувате класа само за да проверите file's size, без да upload-вате файла на сървъра, тогава желанието Ви е изпълнено. Ако желаете само да получите файловото разширение и да го потвърдите, то се оказва, че и това можете. Това е красотата на класа. Създаден подобаващо, класът(class) е(are) изкуство (artwork), а не само огромно количество код.

Преди да напишем клас, или каквото и да е, трябва да планираме. Нека да пресметнем(премислим), от какво се нуждаем за да направим class-а ефективен. Ще се нуждаем от аранжиране на функции, всички проверяващи(потвърждаващи)някакъв сорт процеси, смесващи тези процеси, общуващи помежду си. Да направим стъпка напред и да разгледаме, какви индивидуални функции ще напишеме днес.

Речник: validation-потвърждаване, утвърждаване, ратификация

validity-валидност, законност, обоснованост

Validation на файлово разширение
Validation на размера на файла
Намиране размера на файла
Намиране на максимално допустимия размер на файла
Validation на потребителските ъплоудвани файлове
Проверка за съществуване на файл
Определяне на upload директорията
Определяне на upload log директория
Upload процес със и без validation
Ако все още се питате, защо се нуждаете от class, отговорът е прост. Някога писали ли сте огромен код, в който всичко е взаимно свързано, с идеята да се изпълни някакъв изходен резултат? Разбира се, че сте писали и знаете в какъв досаден, къртовски труд може да се превърне това. Когато за първи път пишете клас, това си е доста трудоемко и времеемко, но след това никога няма да Ви се наложи да го пишете отново. Просто го извиквате и останалото е история. Classes заедно с functions, ще направят живота Ви по-лек. След казаното дотук, нека да започнем.

Do It With Class
<?php
class Upload_Files {

var $temp_file_name;
var $file_name;
var $upload_dir;
var $upload_log_dir;
var $max_file_size;
var $banned_array;
var $ext_array;
?>


Горният отрязък от код е началото на класа. Трябва да стартирате всички класове с думата 'class'. Директно след думата 'class' е името на класа. Можете да го кръстите, както Ви харесва, но за това упражнение, ще го кръстим 'Upload_Class'. Следваща името на класа е отварящата скоба за класа.Тя казва на PHP - "Хей класа ми започва, действай".

Веднага под началото на класа, трябва да декларираме нашите променливи за този клас. Basically това са променливите, които могат да бъдат включени извън class-а, от крайния юзер. Точно както functions могат да приемат аргументи, така могат и класовете, но с малко различен синтаксис. Тези класове казват на класа, че тези променливи могат да бъдат дефинирани от юзера. Променливите, използувани от класа, трябва първо да бъдат дефинирани като 'var $variable_name'.

Function #1 (Validation на файловото разширение)

<?php
function validate_extension() {
//SECTION #1
$file_name = trim($this->file_name);
$extension = strtolower(strrchr($file_name,"."));
$ext_array = $this->ext_array;
$ext_count = count($ext_array);

//SECTION #2
if (!$file_name) {
return false;
} else {
if (!$ext_array) {
return true;
} else {
foreach ($ext_array as $value) {
$first_char = substr($value,0,1);
if ($first_char <> ".") {
$extensions[] = ".".strtolower($value);
} else {
$extensions[] = strtolower($value);
}
}

//SECTION #3
foreach ($extensions as $value) {
if ($value == $extension) {
$valid_extension = "TRUE";
}
}

//SECTION #4
if ($valid_extension) {
return true;
} else {
return false;
}
}
}
}
?>






Тази първа функция, ще провери дали файловото разширение е валидно. Как става това? Да хвърлим по един поглед на всяка секция от кода, за да открием как. За да използувате тази функция, трябва да включите и двете: file name и един масив с допустимите разширения. Ако желаете да приемете всички файлови разширения, не се нуждаете да изпращате масив за разширенията. В края на този tutorial, ще проследиме как да извикаме целия class и всяка функция в class-а, но засега проучваме class-а, за да имаме ясна представа от това мощно средство.


<?php
//SECTION #1
$file_name = trim($this->file_name);
$extension = strtolower(strrchr($file_name,"."));
$ext_array = $this->ext_array;
$ext_count = count($ext_array);
?>


Section #1
Първата секция от тази функция, дефинира променливите, които ще бъдат използувани от тази функция.

$file_name = The actual file name декларирано от юзера upon calling the class.
$extension = Разширението, екстрактнато от името на файла. Функцията strrchr() ще открие последния срещан character и ще чете от тази точка нататък.
$ext_array = масива деклариран от юзера upon calling the class.
$ext_count = Броят на елементите във extension array(масив на разширенията).

<?php
//SECTION #2
if (!$file_name) {
return false;
} else {
if (!$ext_array) {
return true;
} else {
foreach ($ext_array as $value) {
$first_char = substr($value,0,1);
if ($first_char <> ".") {
$extensions[] = ".".strtolower($value);
} else {
$extensions[] = strtolower($value);
}
}
?>



Section #2
Тази секция от функцията стартира процеса на потвърждаване на файловото разширение. Първо проверяваме дали $file_name съществува, и ако е продължаваме, иначе затваряме функцията и върнатият резултат false, защото без file name, няма какво да изследваме. След това проверяваме дали $ext_array съществува. Ако не, се предполага, че сте възприели всички файлови разширения. След това стартираме нашият първи foreach() цикъл. Този цикъл, ще подсигури, че файловото разширение започва с period и е lowercase, а ако не е ще бъде променено за да отразява това изискване и ще бъде изпратено на друг масив кръстен $extensions. След като сме

<?php
//SECTION #3
foreach ($extensions as $value) {
if ($value == $extension) {
$valid_extension = "TRUE";
}
}
?>


Section #3
Сега стартираме още един цикъл. Използуваме новодефинирания и организиран $extensions масив, като фокус на цикъла. В цикъла if е твърдението, използувано да провери дали разширението е валидно. Основно if твърдението казва, че ако файловото разширение отговаря на някоя от стойностите екстрактната от допустимите разширения, то $valid_extension променливата приема стойност true. Това е ядрото на нашия цикъл, с което се открива дали е допустим нашия файл или не е.



<?php
//SECTION #4
if ($valid_extension) {
return true;
} else {
return false;
}
}
}
}
?>


Section #4
Последната секция от функцията е отрязък от кода, четящ дали $valid_extension променливата е present. Ако е, функцията връща true и файлът е okay, иначе функцията връща false. Откриваме (3) closing скоби в края на кода, (2) за горните if-elseif твърдения и последната за затваряне на функцията.
---------------------------

Function #2 (Validation of File Size)
<?php
function validate_size() {
$temp_file_name = trim($this->temp_file_name);
$max_file_size = trim($this->max_file_size);

if (!$temp_file_name) {
$size = filesize($temp_file_name);
if ($size > $max_file_size) {
return false;
} else {
return true;
}
} else {
return false;
}
}
?>


Функцията е значително по-малка от предишната и ще преминем през нея изцяло. Първите (2) реда дефинират $temp_file_name и $max_file_size, които трябва да са зададени от крайния юзер upon the class call. Следва if-elseif statements. Проверяваме дали $temp_file_name съществува, и ако не, функцията завършва и връща false. Ако $temp_file_name is present, екстрактваме file's size и го сравняваме с допустимия $max_file_size. Ако file's size е по-голям от max функцията връща false, иначе връща true и file size е валиден.
--------------------------

Function #3 (Дали този файл вече съществува?)

<?php
function existing_file() {
$file_name = trim($this->file_name);
$upload_dir = $this->get_upload_directory();

if ($upload_dir == "ERROR") {
return true;
} else {
$file = $upload_dir . $file_name;
if (file_exists($file)) {
return true;
} else {
return false;
}
}
}
?>




Тази функция ще провери, дали файла за upload, не съществува вече на сървъра. Тази функция е добавена upon request и няма много да се спираме на нея. По същество, би трябвало да имате някакъв вид преименуваща система, която да използувате, преди и да сте помислили за upload на сървъра. Примерно, когато допускаме юзер да upload-ва на сървъра, там някъде трябва да има запис във database, относно този файл. Така че може да вземем id номера от database и да преименуваме файла, предоставен от юзера на id номера. (т.е. юзера предоставя hello_world.php и той се променя на 452.php, защото това е 452-ят запис в DB) Това е много добра naming system, защото е изключително лесно да delete и update записите. Тук няма преименуваща функция, включена в този class, но Вие лесно бихте могли да добавите.

Първите (2) реда от тази функция, декларират $file_name и $upload_dir. След това стартираме if-elseif statement. Първо проверяваме if : имаме ли валидна upload directory. Ако нямаме, се извършва exit на функцията и връщане на true. Знам, че изглежда наопаки да връщаме true, когато файла съществува or there is an error, но за тази функция върши работа. Името на функцията е 'exisiting_file()', така че ако върне true, значи казва че file exists и не би трябвало да се ъплоудва. Ако upload directory е валидна, продължаваме към следващата секция на if-elseif statement.

Сега описваме пътя до нашия файл с the file name intact(цялостен,цял), т.е. $file = $upload_dir . $file_name. След това имаме малка част код, която използува PHP функцията file_exists(). Ако file exists, връщаме true, иначе връщаме false и файла е okay да бъде ъплоудван.

-------------------------------
Function #4 (Екстракт на File's Size)
<?php
function get_file_size() {
//SECTION #1
$temp_file_name = trim($this->temp_file_name);
$kb = 1024;
$mb = 1024 * $kb;
$gb = 1024 * $mb;
$tb = 1024 * $gb;

//SECTION #2
if ($temp_file_name) {
$size = filesize($temp_file_name);
if ($size < $kb) {
$file_size = "$size Bytes";
}
elseif ($size < $mb) {
$final = round($size/$kb,2);
$file_size = "$final KB";
}
elseif ($size < $gb) {
$final = round($size/$mb,2);
$file_size = "$final MB";
}
elseif($size < $tb) {
$final = round($size/$gb,2);
$file_size = "$final GB";
} else {
$final = round($size/$tb,2);
$file_size = "$final TB";
}
} else {
$file_size = "ERROR: NO FILE PASSED TO get_file_size()";
}
return $file_size;
}
?>


Тази функция ще изследва файла, за да екстрактне file's actual size форматиран за upload log file. Кода е разбит на (2) секции за по-лесно разбиране.

<?php
//SECTION #1
$temp_file_name = trim($this->temp_file_name);
$kb = 1024;
$mb = 1024 * $kb;
$gb = 1024 * $mb;
$tb = 1024 * $gb;
?>


Section #1
Първата секция от тази функция дефинира Вашите променливи. Приемаме temporary name за файла, както и определяме file sizes с цел сравняване. The file sizes е дефиниран в bytes.

<?php
//SECTION #2
if ($temp_file_name) {
$size = filesize($temp_file_name);
if ($size < $kb) {
$file_size = "$size Bytes";
}
elseif ($size < $mb) {
$final = round($size/$kb,2);
$file_size = "$final KB";
}
elseif ($size < $gb) {
$final = round($size/$mb,2);
$file_size = "$final MB";
}
elseif($size < $tb) {
$final = round($size/$gb,2);
$file_size = "$final GB";
} else {
$final = round($size/$tb,2);
$file_size = "$final TB";
}
} else {
$file_size = "ERROR: NO FILE PASSED TO get_file_size()";
}
return $file_size;
}
?>



Section #2
Втората секция на тази функция стртира нашия validation и output process. Първо проверяваме if $temp_file_name е валидна, if not, функцията връща error, иначе казано функцията продължава и опитва да определи file's actual size. Upon validation of the $temp_file_name, получаваме file's size във bytes от PHP функцията filesize(). Искаме да имаме readable output за нашия log file, както и за нашия юзер. Юзерите не искат 10240 bytes, а да видят 10 KB. Така че, задаваме simple statement сравняващ file's size със различни file sizes, за да върне readable file size. Кода общо взето, сам говори за себе си. ( СЛЕДВА ПРОДЪЛЖЕНИЕ )



/ Трябва да сте регистриран за да напишете коментар /