Уметь писать код - не значит уметь делать это правильно. Хороший код - это как красиво оформленный пост - его удобно читать, в нём легко ориентироваться и разработчику всегда понятно как его расширить, отладить или использовать для других целей.
Поэтому всегда важно уделять внимание оформлению кода, комментировать сложные участки кода.
Картинка с сайта www.jclassified.in
Вначале немного теории. Один и тот же код можно писать разными способами. Код может быть процедурным, функциональным и объектно-ориентированным.
Процедурный подход
Процедурный подход самый простой. Под ним подразумевается скрипт, в котором сплошняком написан команды и вызваны элементарные php функции.
Например:
<?php
$a = 12;
$b = 10;
$c = 4;
$d = $a % $b;
$e = $c + $d;
echo round($e);
?>
Такой подход уместен, если у вас очень маленький код или он выполняет строго одну задачу(например генерирует картинку), как говорится "ни шаг вправо, ни шаг влево".
Функциональный подход
В функциональном подходе ваш код разделён на части и каждая из них помещена в свою функцию. Это позволит избежать дублирования кода, придаст коду лаконичность и его будет проще читать.
Так-же у каждой функции будет своя собственная область видимости переменных. То есть переменные, "живущие внутри неё" никогда не просочатся наружу и переменные, используемые вне функции так-же не попадут в саму функцию.
Определяя функцию вы сами можете указать какие переменные должны попасть в функцию и что она должна вернуть, то есть вы строго контролируете этот процесс.
Исключения составляют суперглобальные переменные, такие как $_SERVER, $_REQUEST, $_GET, $_POST - они доступны всегда и везде.
Перепишем процедуру на функции:
<?php
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);
echo round($e);
?>
Теперь вычисление остатка от деления $a на $b и нахождение суммы от $c и $d завёрнуто в функции getRemainder и getSum.
Функции могут быть определены как до их вызова, так и после. Наверняка вы обратили внимание, что в функции getSum "используются переменные" $a и $b, хотя складываем мы $c и $d.
Это как раз и есть область видимости переменных внутри функции и они не имеют ничего общего с числовыми переменными $a и $b, определёнными вне функции. Мы могли назвать их как угодно.
Оператор return в конце функции возвращает работы функции. То есть переменная $result возвращается наружу и её значение присваивается переменной $d или $e.
Если просто вызвать функцию, не присваивая никакой переменной её возвращаемого значения - то функция просто "отправит в космос" возвращаемое ей значение.
Объясню на примере:
<?php
function getValue() {
$string = 'String';
return $string;
}
$a = getValue();
echo $a;//выведет String
echo $string;//ничего не выведет, так как переменная $string существует только внутри функции getValue
//А если просто вызвать функцию
getValue();
echo $string;// так же ничего не выведет, так как переменная $string существует только внутри функции getValue
//получается, что функция getValue "отработала вхолостую", так как никто не принял её возвращаемого значения.
?>
Если нужно провести какую-то типовую операцию много раз(используя разные входные данные) - то её обязательно надо поместить в функцию и вызывать сколько угодно раз.
Объектно-ориентированный подход
И третий подход - объектно-ориентированный. Сокращённо ООП(объектно-ориентированное программирование).
Он так называется в связи с тем, что он представляет из себя произвольное количество объектов с определенными наборами свойств и действий, называемых методами.
В ООП так-же есть такие вещи, как наследование, полиморфизм, абстракция, интерфейсы, конструкторы, деструкторы и многое другое. Это огромная тема и раскрывать её в рамках этой статьи я не буду.
Я покажу лишь простейший пример использования класса.
<?php
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();
return round($this->e);
}
}
//создание объекта или экземпляра класса
$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кг каждого фрукта.
Что такое массивы и как с ними работать я уже рассказывал ранее.
<?php
//исходные данные
$fruits = array();
$fruits[] = array(
'name' => 'Бананы',
'price' => 65,
);
$fruits[] = array(
'name' => 'Ананасы',
'price' => 90,
);
$fruits[] = array(
'name' => 'Яблоки',
'price' => 50,
);
$fruits[] = array(
'name' => 'Груши',
'price' => 80,
);
$fruits[] = array(
'name' => 'Кокосы',
'price' => 130,
);
?>
Для наглядности попробуем решить её процедурно.
<?php
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? И готов поспорить, что при копипасте вы точно не всё поправите и будете получать неверные данные.
Исходник на pastebin http://pastebin.com/ZP91uX8R
Теперь пробуем функционально.
<?php
//вернёт стоимость
function getPrice($price, $weight) {
$result_price = $price * $weight;
return $result_price;
}
//вернёт все веса
function getWeights() {
return array(5, 12, 14, 16, 22, 135, 150, 200, 254, 300, 400);
}
//получаем веса в переменную
$weights = getWeights();
//перебираем все фрукты
foreach ($fruits as $fruit) {
//перебираем все веса для каждого фрукта
foreach ($weights as $weight) {
echo $fruit['name'] . ' ' . $weight . 'кг стоят ' . getPrice($fruit['price'], $weight) . 'руб.<br />';
}
}
?>
Код вышел гораздо более читабельным. Веса указаны в функции getWeights и простым добавлением их туда посчитать сколько бы стоил другой вес каждых фруктов.
Я перебрал все фрукты и при каждом переборе перебирал все веса. Можно было сделать и наоборот.
Исходник на pastebin http://pastebin.com/07QTBihX
И наконец реализация на ООП.
<?php
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->setData($fruits, array(5, 12, 14, 16, 22, 135, 150, 200, 254, 300, 400));
$fruiting->getResult();
?>
Исходник на pastebin http://pastebin.com/2dBEQFtK
Как видите - код более объёмный. При простых вычислениях можно обойтись и функциональным подходом, но все действительно большие и сложные проекты написаны с использованием ООП.
Подробнее о классах можно почитать в официальной документации
При написании материала старался следовать советам @ontofractal :)
P.S. Когда пишете код - представьте, что поддерживать его будет психически неуравновешенный маньяк, который знает где вы живёте.
Озвучил Ваш постскриптум коллегам на работе. Двое из них нервно хихикнули, третий задумался. К чему бы это... Оо
Привет!
Этот пост был выбран Академией Голоса и попал в список программы поддержки качественных образовательных постов.
Ссылка на твой пост будет опубликована в отчете Академии.
Спасибо за полезный контент (ノ◕ヮ◕)ノ*:・゚✧
Спасибо, значит не зря старался. Вот теперь можно с чистой совестью и домой))
Совет о представлении кода при его написании супер!))
Не понял что вы имеете ввиду))
P. S. ваш.
Постскриптум -)