Уметь писать код - не значит уметь делать это правильно. Хороший код - это как красиво оформленный пост - его удобно читать, в нём легко ориентироваться и разработчику всегда понятно как его расширить, отладить или использовать для других целей.
Поэтому всегда важно уделять внимание оформлению кода, комментировать сложные участки кода.
Вначале немного теории. Один и тот же код можно писать разными способами. Код может быть процедурным, функциональным и объектно-ориентированным.
Процедурный подход
Процедурный подход самый простой. Под ним подразумевается скрипт, в котором сплошняком написан команды и вызваны элементарные php функции.
Например:
$a = 12; $b = 10; $c = 4; $d = $a % $b; $e = $c + $d;
Такой подход уместен, если у вас очень маленький код или он выполняет строго одну задачу(например генерирует картинку), как говорится "ни шаг вправо, ни шаг влево".
Функциональный подход
В функциональном подходе ваш код разделён на части и каждая из них помещена в свою функцию. Это позволит избежать дублирования кода, придаст коду лаконичность и его будет проще читать.
Так-же у каждой функции будет своя собственная область видимости переменных. То есть переменные, "живущие внутри неё" никогда не просочатся наружу и переменные, используемые вне функции так-же не попадут в саму функцию.
Определяя функцию вы сами можете указать какие переменные должны попасть в функцию и что она должна вернуть, то есть вы строго контролируете этот процесс.
Исключения составляют суперглобальные переменные, такие как $_SERVER, $_REQUEST, $_GET, $_POST - они доступны всегда и везде.
Перепишем процедуру на функции:
function getRemainder($a, $b) { $result = $a % $b; return $result; } function getSum($a, $b) { $result = $a + $b; return $result; } $a = 12; $b = 10; $c = 4; $d = getRemainder($a, $b); $e = getSum($c, $d);
Теперь вычисление остатка от деления $a на $b и нахождение суммы от $c и $d завёрнуто в функции getRemainder и getSum.
Функции могут быть определены как до их вызова, так и после. Наверняка вы обратили внимание, что в функции getSum "используются переменные" $a и $b, хотя складываем мы $c и $d. Это как раз и есть область видимости переменных внутри функции и они не имеют ничего общего с числовыми переменными $a и $b, определёнными вне функции. Мы могли назвать их как угодно. Оператор return в конце функции возвращает работы функции. То есть переменная $result возвращается наружу и её значение присваивается переменной $d или $e.
Если просто вызвать функцию, не присваивая никакой переменной её возвращаемого значения - то функция просто "отправит в космос" возвращаемое ей значение.
Объясню на примере:
function getValue() { $string = 'String'; return $string; } $a = getValue(); echo $a;//выведет String echo $string;//ничего не выведет, так как переменная $string существует только внутри функции getValue //А если просто вызвать функцию getValue(); echo $string;// так же ничего не выведет, так как переменная $string существует только внутри функции getValue //получается, что функция getValue "отработала вхолостую", так как никто не принял её возвращаемого значения.
Если нужно провести какую-то типовую операцию много раз(используя разные входные данные) - то её обязательно надо поместить в функцию и вызывать сколько угодно раз.
Объектно-ориентированный подход
И третий подход - объектно-ориентированный. Сокращённо ООП(объектно-ориентированное программирование).
Он так называется в связи с тем, что он представляет из себя произвольное количество объектов с определенными наборами свойств и действий, называемых методами.
В ООП так-же есть такие вещи, как наследование, полиморфизм, абстракция, интерфейсы, конструкторы, деструкторы и многое другое. Это огромная тема и раскрывать её в рамках этой статьи я не буду.
Я покажу лишь простейший пример использования класса.
class Calc { //объявление свойств(переменных) класса public $a; public $b; public $c; private $d; private $e; //метод для определения остатка от деления private function getRemainder() { $this->d = $this->a % $this->b; } //метод найдёт сумму private function getSum() { $this->e = $this->c + $this->d; } //метод вернёт результат public function getResult() { self::getRemainder(); self::getSum(); } } //создание объекта или экземпляра класса $calc = new Calc(); //задание свойств класса $calc->a = 12; $calc->b = 10; $calc->c = 4; //вызов метода класса $e = $calc->getResult(); //вывод на экран результата echo $e;
При объявлении свойств я использовал ключевые слова public и private.
public - это значит общедоступный и к этому свойству или методу можно обратиться в любом контексте.
private - к таким свойствам и методам можно получить доступ только внутри класса, в котором они определены.
Так же свойство или метод можно определить как protected. Это означает, что доступ к методу или свойству можно получить из текущего класса или из класса, который наследует свойства и методы текущего класса.
Ключевое слово self ссылается на текущий класс и через него можно обратиться к методам текущего класса.
Переменная $this используется для обращения к переменной или методу в контексте класса.
Вот вкратце и всё, можете проверить, все 3 способа будут выдавать одинаковый результат.
Теперь традиционно ставим задачу и её примере рассматриваем решения, так сказать обкатаем теорию.
Имеем 5 видов фруктов и у каждого указана стоимость(за кг).
По условиям задачи нужно посчитать сколько будет стоить 5кг, 12кг, 14кг, 16кг, 22кг, 135кг, 150кг, 200кг, 254кг, 300кг и 400кг каждого фрукта.
//исходные данные 'name' => 'Бананы', 'price' => 65, ); 'name' => 'Ананасы', 'price' => 90, ); 'name' => 'Яблоки', 'price' => 50, ); 'name' => 'Груши', 'price' => 80, ); 'name' => 'Кокосы', 'price' => 130, );
Для наглядности попробуем решить её процедурно.
foreach ($fruits as $fruit) { $price_5 = $fruit['price'] * 5; $price_12 = $fruit['price'] * 12; $price_14 = $fruit['price'] * 14; $price_16 = $fruit['price'] * 16; $price_22 = $fruit['price'] * 22; $price_135 = $fruit['price'] * 135; $price_150 = $fruit['price'] * 150; $price_200 = $fruit['price'] * 200; $price_254 = $fruit['price'] * 254; $price_300 = $fruit['price'] * 300; $price_400 = $fruit['price'] * 400; echo $fruit['name'] . ' 5кг стоят ' . $price_5 . 'руб.<br />'; echo $fruit['name'] . ' 12кг стоят ' . $price_12 . 'руб.<br />'; echo $fruit['name'] . ' 14кг стоят ' . $price_14 . 'руб.<br />'; echo $fruit['name'] . ' 16кг стоят ' . $price_16 . 'руб.<br />'; echo $fruit['name'] . ' 22кг стоят ' . $price_22 . 'руб.<br />'; echo $fruit['name'] . ' 135кг стоят ' . $price_135 . 'руб.<br />'; echo $fruit['name'] . ' 150кг стоят ' . $price_150 . 'руб.<br />'; echo $fruit['name'] . ' 200кг стоят ' . $price_200 . 'руб.<br />'; echo $fruit['name'] . ' 254кг стоят ' . $price_254 . 'руб.<br />'; echo $fruit['name'] . ' 300кг стоят ' . $price_300 . 'руб.<br />'; echo $fruit['name'] . ' 400кг стоят ' . $price_400 . 'руб.<br />'; }
Выглядит это громоздко и некрасиво. А если надо будет посчитать не 11 значений, а 500? И готов поспорить, что при копипасте вы точно не всё поправите и будете получать неверные данные.
Теперь пробуем функционально.
//вернёт стоимость function getPrice($price, $weight) { $result_price = $price * $weight; return $result_price; } //вернёт все веса function getWeights() { } //получаем веса в переменную $weights = getWeights(); //перебираем все фрукты foreach ($fruits as $fruit) { //перебираем все веса для каждого фрукта foreach ($weights as $weight) { echo $fruit['name'] . ' ' . $weight . 'кг стоят ' . getPrice($fruit['price'], $weight) . 'руб.<br />'; } }
Код вышел гораздо более читабельным. Веса указаны в функции getWeights и простым добавлением их туда посчитать сколько бы стоил другой вес каждых фруктов.
Я перебрал все фрукты и при каждом переборе перебирал все веса. Можно было сделать и наоборот.
И наконец реализация на ООП.
class Fruiting { public $fruits; public $weights; public function setData($fruits, $weights) { $this->fruits = $fruits; $this->weights = $weights; } private function getPrice($price, $weight) { $result_price = $price * $weight; return $result_price; } public function getResult() { //перебираем все фрукты foreach ($this->fruits as $fruit) { //перебираем все веса для каждого фрукта foreach ($this->weights as $weight) { echo $fruit['name'] . ' ' . $weight . 'кг стоят ' . self::getPrice($fruit['price'], $weight) . 'руб.<br />'; } } } } $fruiting = new Fruiting(); $fruiting->getResult();
Как видите - код более объёмный. При простых вычислениях можно обойтись и функциональным подходом, но все действительно большие и сложные проекты написаны с использованием ООП.
P.S. Когда пишете код - представьте, что поддерживать его будет психически неуравновешенный маньяк, который знает где вы живёте.