Условия в PHP
Всем привет! Вот и очередной урок по PHP подоспел. Сегодняшняя тема – одна из самых любимых у тех, кто начинает программировать. Ещё бы, ведь условия в PHP – это то, что позволяет нам составлять различные алгоритмы. Именно в зависимости от условий программа будет вести себя так или иначе. И именно благодаря им мы можем получать разный результат при разных входных данных. В PHP имеются несколько конструкций, с помощью которых можно реализовать условия. Все они используются, и имеют свои преимущества в разных ситуациях, или, если хотите – условиях. Кругом одни условия, не так ли? Так. Никто ведь не будет спорить, что в реальной жизни в зависимости от обстоятельств мы поступаем по-разному. В программировании это не менее важно и сейчас мы этому научимся.
Как вы должны помнить из прошлого урока, в PHP, в зависимости от оператора, операнды приводятся к определённому типу. Для операторов условий в PHP действуют те же правила, и здесь операнд всегда приводится к булевому значению. В случае, если это значение true, то считаем, что условие выполнено, а в случае, если false – то условие не выполнено. В зависимости от того, выполнено ли условие, мы можем делать или не делать какие-либо действия. И тут я предлагаю рассмотреть первый условный оператор – if.
Условный оператор if
Это самый простой, и самый часто используемый оператор. В общем случае конструкция выглядит следующим образом:
А в реальной жизни использование оператора if выглядит следующим образом:
Здесь мы явно передали оператору значение true. Разумеется, это абсолютно бессмысленно. Давайте с помощью условия будем определять числа больше 10. Это довольно просто:
И после запуска мы увидим результат:
Число больше 10
Конструкция if-else
А можно ли сделать так, чтобы, когда условие не выполнилось, выполнился другой код? Конечно можно! Для этого вместе с оператором if используют оператор else (по-русски — иначе). Он пишется после фигурных скобок, в которые заключается код, выполняющийся при выполненном условии. И выглядит конструкция следующим образом:
- Тест на знание основ HTML
- Тест на знание основ PHP
- Тест на знание ООП в PHP
10) < echo 'Число больше 10'; >else
Здесь опять же на экран будет выведено сообщение:
Число больше 10
Однако если мы изменим входные данные, и переменной $x в самом начале присвоим значение 8, то выведется сообщение:
Число меньше либо равно 10
Попробуйте сделать это прямо сейчас.
Конструкция if-elseif-else: несколько условий
В случае, если вам нужно проверить несколько условий, после оператора if добавляется ещё и оператор elseif. Он проверит условие, только если не выполнится первое условие. Например:
10) < echo 'Число больше 10'; >elseif ($x == 10)
В данном случае, на экран будет выведено:
Число равно 10
И да, после этого оператора можно добавить else. Код внутри него будет выполнен, если не выполнилось ни одно из условий:
10) < echo 'Число больше 10'; >elseif ($x == 10) < echo 'Число равно 10'; >else
Результат этого кода, я полагаю, объяснять не нужно. Да, кстати, возможен целый список из elseif-ов. Например, такой:
elseif ($x == 1) < echo 'Число равно 1'; >elseif ($x == 2) < echo 'Число равно 2'; >else
Приведение к boolean
Помните, в уроке про типы данных в PHP мы с вами научились явно приводить значения к какому-либо типу. Например:
Результатом будет true.
Работающее так же, только неявное преобразование, всегда происходит в условии. Например, следующее условие:
Выполнится успешно, так как число 3 будет преобразовано к true. К false будут приводиться следующие значения:
- » (пустая строка)
- 0 (число 0)
Таким образом, любое ненулевое число и ненулевая строка будут преобразованы в true и условие выполнится. Исключение – строка, состоящая из одного нуля:
Она также будет преобразована к false.
Я затронул эту тему с приведением к boolean в домашнем задании к этому уроку. Обязательно его выполните. А сейчас давайте перейдём к следующему условному оператору.
Оператор switch
Помимо конструкции if-else есть ещё один оператор условия. Это – switch. Это очень интересный оператор, требующий запоминания нескольких правил. Давайте для начала посмотрим, как он выглядит на следующем примере:
Сначала может показаться, что этот оператор довольно сложный. Однако, если разобраться, то всё становится понятно. В операнде switch указывается некоторое выражение. В нашем случае, это переменная $x, а точнее её значение — 1.
В фигурных скобках мы перечисляем операторы case, после которых указываем значение, с которым сравнивается значение операнда switch. Сравнение происходит нестрогое, то есть как будто используем оператор ==. И если условие выполнилось, то выполняется код, указанный после двоеточия. Если же ни одно из условий не выполнилось, то выполняется код из секции default, которой в общем-то может и не быть, и тогда ничего выполняться не будет. Обратите внимание, внутри каждой секции case, в конце мы прописали оператор break. Это делается для того, чтобы после выполнения кода в случае выполнения условия не продолжилась проверка условий. То есть, если бы не было break в конце секции case 1, то после того, как вывелся бы текст
Число равно 1
продолжило бы выполняться условие сравнения с 2, а затем бы выполнился и код в секции default. Не забывайте писать break!
Сравнение switch с if
Вообще, этот код можно было бы записать и с помощью конструкции if-elseif-else:
elseif ($x == 2) < echo 'Число равно 2'; >else
Но в виде конструкции switch-case код в конкретно этом случае выглядит проще. И вот почему:
- мы сразу видим, что конкретно мы сравниваем (переменную $x) и понимаем, что сравниваем в каждом условии именно это значение, а не какое-либо ещё;
- глазу удобнее воспринимать то, с чем сравниваем – секции case 1, case 2 визуально воспринимаются легче, сравниваемое значение заметнее.
И снова про switch
И я ещё не всё сказал про switch — можно писать несколько case-ов подряд, тогда код выполнится при условии, что выполнен хотя бы один из них. Например:
Согласитесь, это может быть удобно.
Хорошо, давайте пройдёмся по особенностям оператора switch, о которых нужно помнить всегда.
- break прерывает набор условий, не забывайте указывать его;
- секция default будет выполнена, если не выполнилось ни одно из условий. Она может и вовсе отсутствовать;
- несколько case-ов могуть быть записаны подряд, тогда код в секции выполнится при выполнении хотя бы одного из условий.
Немного практики
Ну что, запомнили операторы условий? Давайте закрепим на практике более реальными примерами.
Чётное или нечётное
Вот один из примеров – нужно определить, чётное ли число или нет. Для этого нам нужно проверить, что остаток от деления на 2 будет равен 0. Подробнее об операторах читайте тут. Давайте сделаем это:
else
Попробуйте самостоятельно изменить значение переменной $x. Круто, да? Оно работает!
Модуль
Давайте теперь научимся вычислять модуль числа. Если число больше или равно нулю, то нужно вывести само это число, если меньше – заменить знак с минуса на плюс.
= 0) < echo 'Модуль числа: ' . $x; >else
Модуль числа: 2
Как мы видим, всё успешно отработало.
Тернарный оператор
Помимо этого, в PHP есть ещё один оператор, который представляет собой сокращённую форму конструкции if-else. Это тернарный оператор. При этом он возвращает разные результаты, в зависимости от того, выполнено ли условие или нет. В общем виде его использование выглядит следующим образом:
условие ? результат_если_true : результат_если_false
Или на примере того же нахождения модуля:
= 0 ? $x : -$x; echo 'Модуль: ' . $mod;
Модуль: 2
Круто, да? Тернарный оператор – очень элегантно вписывается при решении таких вот простеньких задачек.
И ещё немного практики
Условия можно помещать внутрь друг друга и вообще, чего с ними только можно не делать. Например:
0) < if ($x >= 100) < echo 'Число больше либо равно 100'; >else < echo 'Число больше 0 но меньше 100'; >> else
Итог
Друзья, надеюсь вам понравился урок. Если это так – буду рад, если вы поделитесь им в социальных сетях или расскажете друзьям. Это лучшая поддержка проекта. Спасибо тем, кто это делает. Если у вас возникли какие-то вопросы или замечания – напишите об этом в комментариях. А сейчас – все быстренько делаем домашнее задание, там ещё больше интересных примеров с условиями. Всем пока!
Создание, открытие, чтение, запись, удаление и проверка наличия файла в PHP
В общем виде взаимодействие с файлами в PHP сводится к открытию файла, выполнению с ними необходимых действий и закрытию файла. При открытии файла определяется режим дальнейшей с ним работы. Это может быть открытие для чтения, записи, добавления данных. Есть так же режимы открытия файла, совмещающие в себе одновременно и чтение и запись.
Существует множество возможностей выполнять чтение из файлов – можно получить данные в разной форме – построчное считывание, получение массива строк и так далее.
Создание и запись файла
Для создания файла, необходимо выполнить открытие файла в режиме записи. Открытие файла выполняется функцией fopen. Первым параметром этой функции указывает путь к файлу. Второй параметр указывает на режим открытия файл. Для создания файла нужно указать режим записи файла — «w».
$f = fopen("myfile.txt", "w");
Если файл с таким именем уже есть, то режим записи позволит создать новый пустой файл на месте существующего, удалив все его данные.
Еще существует параметр «w+», позволяющий, открывать одновременно для чтения и записи. При этом, если файл с таким именем уже существовал, данные в нем сотрутся.
При выполнении операции открытия, функция вернет значение – дескриптора файла – специальной файловой переменная, которая будет указывать последующим функциям с каким именно файлом выполнять свои действия.
Для добавления новых данных в открытый в режиме записи файл используется функция fwrite. Первым параметром указывается дескриптор файла. Затем строка, которую нужно записать в файл. При необходимости, третьим параметром можно ограничить количество записываемых символов.
fwrite($f, "Мой текст для записи в файл.");
После записи всех строк, его необходимо закрыть. Для этого применяется функция fclose. Единственным параметром для нее служит дескриптор файла.
fclose($f);
В итоге, код создания и сохранения файла выглядит следующим образом:
$f = fopen("myfile.txt", "w");
fwrite($f, "Первая строка.\r\n");
.
fwrite($f, "Последняя строка.\r\n");
fclose($f);
Символы «\r\n» означают символ конца строки. Если не добавлять, все строки в записанном файле объединятся в одну строку.
Добавление данных в существующий файл
Для того, чтобы дописать какую-либо информацию в уже созданный файл, его нужно открыть в режиме записи, но с сохранением имеющейся информации. Т.е. файл будет открыт так же для записи, но при записи в такой файл, они будут добавляться в его конец.
$f = fopen("myfile.txt", "a"); "// Параметр "a" указывает открыть в режиме добавления"
fwrite($f, "Новая строка\r\n");
fclose($f);
Если же файла с указанным именем не существует, файл будет создан и все данные будут записаны в него.
Еще есть режим «a+», открывающий файл для чтения и записи, с переходом в конец файла.
Чтение файла
Для чтения из файла, функции fopen назначается параметр «r», что означает, что файл будет открыт только для чтения. Чтение из файла выполняет функция fgets. Первым параметром указывается дескриптор файла. Второй, необязательный, параметр определяет размер считываемой строки. Если второй параметр не указывать, текущая строка будет считана до символа конца строки.
$f = fopen("myfile.txt", "r"); // Параметр "r" указывает открыть в режиме чтения
$s = fgets($f);
echo $s;
fclose($f);
Режим «r+» открывает файл для чтения и записи.
Для считывания всех строк из файла, можно воспользоваться циклом, в котором будет считываться по одной строке до конца файла:
$f = fopen("myfile.txt", "r");
while (!feof($f)) $s = fgets($f);
echo $s;
>
fclose($f);
Функция feof используется в условии цикла для определения конца файла и завершения цикла считывания.
Кроме описанного метода получения данных из файла, PHP имеет еще множество различных функций. Иногда проще получить стразу все содержимое файла (функция readfile) или загрузить все строки в массив (функция file), и работать уже с ним. Для таких целей не придется открывать файл для чтения и закрывать его. Все эти действия будут выполнены самой функцией.
readfile("myfile.txt");
$mas = file("myfile.txt");
foreach ($mas as $m)
echo $m;
С помощью функции fgetc можно считывать содержимое файла посимвольно:
$f = fopen("myfile.txt", "r");
while (!feof($f)) $s = fgetc($f);
echo $s;
>
fclose($f);
Удаление файла
Удаление файла выполняется функцией unlink. В параметре указывается путь к удаляемому файлу.
unlink("myfile.txt");
Проверка существует ли файл
Иногда, прежде чем, выполнять какие-либо действия с файлом необходимо проверить, существует ли он. Для этого используется функция file_exists. В параметре указывается путь к файлу.
if (file_exists("myfile.txt"))
echo "Такой файл есть.";
else
echo "Файла с таким именем нет.";
OpenCart 2+ описание процесса загрузки приложения.

Для того, чтобы хорошо разбираться в том, с чем работаешь, необходимо знать процесс «изнутри». В данной статье я распишу пошагово процесс работы ядра фреймворка или CMS (кому как нравится) OpenCart версии 2+. Тем более, что OpenCart построен с учетом концепции MVC (модель-вод-контроллер), а значит имеет довольно понятную структуру с которой удобно работать и удобно расширять. Чего пока не хватает — так это документации и русскоязычных статей в интернете.
Файл index.php
Файл находится в корне сайта.
Это точка входа для всего приложения. Все запросы к серверу проходят через этот файл, который подключает нужные библиотеки и координирует дальнейшее выполнение скрипта.
Рассмотрим этапы его работы.
- Устанавливается константа с версией OC
define('VERSION', '2.3.0.2.2');
- При наличии файла config.php в корневой папке, он подключается и устанавливает ряд констант, устанавливающих пути к служебным (system) и рабочим (catalog) папкам, а так же константы доступа к базе данных.
if (is_file(‘config.php’))
- В случае отсутствия файла config.php в корневой папке, константа DIR_APPLICATION оказывается не установленной. Тогда отсылается заголовок на переадресацию в папку install, которая запускает процесс установки OC и завершает на этом этапе работу скрипта
if (!defined('DIR_APPLICATION')) < header('Location: install/index.php'); exit; >
- Если дошли до этой строки — конфигурация загружена, подключается файл из папки system/startup.php
require_once(DIR_SYSTEM . 'startup.php');
- Последняя строка файла index.php
start('catalog');
выполнится лишь после подключения файла ‘startup.php’, о чем ниже.
Файл system/startup.php
- Устанавливается протоколирование всех ошибок
error_reporting(E_ALL);
- Проверяется версия php, должна быть не ниже 5.4
if (version_compare(phpversion(), ‘5.4.0’, ‘
- Устанавливается временная зона по-умолчанию
if (!ini_get(‘date.timezone’))
- Далее устанавливаются значения суперглобального массива $_SERVER
- Объявление функции modification(), которая используется для получения пути к
function modification($filename)
При этом в начале функции прописаны проверки на область видимости от куда выполняется скрипт – админка, папка install или catalog. Каждая из этих областей видимости определяет свои константы, на основе их и построены данные проверки.
В переменную $file сохраняется путь к файлу начиная от папки system/storage/modification . Если переданный функции файл там найден, то возвращается данный путь. Если нет – значит файл не модифицировался и возвращается тот же путь к файлу, который передан функции в качестве аргумента.
- Подключение файла autoload.php, которого нет по-умолчанию в OpenCart 2.3.
// Autoloader if (is_file(DIR_SYSTEM . '../../vendor/autoload.php')) < require_once(DIR_SYSTEM . '../../vendor/autoload.php'); >
В данном файле можно подключить сторонние автозагрузчики или что-то еще.
- Далее код автозагрузки системных классов OC.
- Подключается ряд важных системных классов, нужных для работы CMS из папки system\engine .
require_once(modification(DIR_SYSTEM . 'engine/action.php')); …
- Из папки system/helper подключается несколько файлов содержащие функции-помошники
- general.php – Файл для обеспечения безопастности. Содержит функцию token() для генерации случайной строки (токена), функцию hash_equals() для сравнения хеш-строк
- utf8.php – устанавливает кодировку
- json.php – кодирует/раскодирует данные в формате json
- В конце данного файла объявление функции start(), которая должна подключить главный файл фреймворка- framework.php, реализующий дальнейшую работу приложения согласно модели MVC.
function start($application_config)
После этого, выполнение скрипта возвращается к файлу index.php в котором выполняется последняя строка, запускающая подключение к фалу framework.php
В качестве аргумента, функции передается указатель на рабочий каталог- backend(admin) или frontend(catalog)
start('catalog');
Файл system/framework.php
Не забываем, что все классы в данном файле загружаются с помощью автозагрузчика, с проверкой на модификацию (сначала поиск в папке system/storage/modification/system/… )
- Первой строкой создается объект класса Registry. Файл system\engine\registry.php
$registry = new Registry();
Это самый важный объект приложения. Данный класс используется для хранения(получения, проверки на наличие) в массиве $data служебных объектов (Config, Event, Loader, Request, Response, Database, Session, Cache, Url, Language, Document). Далее в данном файле (framework.php) создаются эти самые служебные объекты и с помощью метода set() сохраняются в закрытой переменной $data класса Registry. Так же, многие из этих объектов, получают Registry в качестве аргумента конструктора, при их создании, для получения доступа из них к реестру, а из него к другим служебным объектам.
Пример.
Любой контроллер наследует от абстрактного класса Controller, который получает объект Registry при создании:
abstract class Controller < protected $registry; public function __construct($registry) < $this->registry = $registry; > .
так же есть магические методы
public function __get($key) < return $this->registry->get($key); > public function __set($key, $value) < $this->registry->set($key, $value); >
Таким образом, при запросе свойства класса, которое у него отсутствует, идет передача вызова на объект Registry (который был передан в protected $registry).
Таким образом, при вызове в контроллере
$this->load->model('. ');
после того, как не будет найдено свойство load контроллера, будет вызвано $registry->load.
То есть, объект Registry используется, в последствии, многими другими объектами для получения доступа к хранимым в нем служебным объектам (их свойствам и методам).
- Config. Файл system\library\config.php
$config->load('default');
в данном файле хранятся настройки по умолчанию касающиеся БД, эл.почты, вывода ошибок, сессии, кэша, кодировки и др. (см. файл system\config\default.php )
Следующей строкой в массив настроек добавляются настройки из файла
— system\config\catalog.php (если фреймворк запущен из frontend – в index.php строкой start(‘catalog’);)
или
— system\config\admin.php (для админки)
Затем, экземпляр класса Config сохраняется в массив $data класса Registry
Данные одного из этих файлов (который загрузится) дополняет и где-то меняет настройки по-умолчанию из файла default.php
- Event. Файл system\engine\event.php
$event = new Event($registry);
передается объект Registry в конструктор класса Event, для использования в методе trigger() при вызове нужных функций.
— Event Register. Регистрируюся все события, которые были получены объектом Config и сохранены в массиве action_event. Они записываются в массив data[$trigger] объекта Event.
if ($config->has('action_event')) < foreach ($config->get('action_event') as $key => $value) < $event->register($key, new Action($value)); > >
- Loader. Файл system\engine\loader.php
$this->load->model('account/custom_field');
Делает он это, опять таки, с помощью переданного ему, в качестве аргумента для конструктора, объекта Registry, хранящему все служебные объекты с их свойствами (читать выше).
- Request (запрос браузера на сервер). Файл system\library\request.php
$this->request->post['address_id']
в результате будет получено значение массива $_POST по ключу ‘address_id’.
- Response (ответ сервера браузеру). Файл system\library\response.php
$response->addHeader('Content-Type: text/html; charset=utf-8');
В данный объект можно сохранять свои заголовки методом addHeader($header), которые будут добавляться в private $headers.
Есть так же метод для переадресации redirect($url, $status = 302), метод для сжатия страницы сервером перед отправкой браузеру compress().
Метод setOutput($output) вызывается во многих контроллерах для сохранения страницы (после формирования файла представления) в private $output объекта Response, для последующего вывода:
$this->response->setOutput($this->load->view('checkout/checkout', $data));
Метод output() – передает браузеру для вывода заголовки и все содержимое страницы. Он выполняется в самом конце файла framework.php
- DB. Класс для работы с базой данных. Файл system\library\db.php
$this->db->query("INSERT INTO…
- Session. Класс для работы с сессиями. Файл system\library\session.php
- класс Session\DB из файла system\library\session\db.php который сохраняет определенные данные в БД устанавливая в одно из полей идентификатор текущей сессии (нужно предварительно раскомментировать код создания таблицы session в начале файла);
- класс Session\File из файла system\library\session\file.php который создает файл имеющий название ‘/sess_’ + идентификатор сессии и сохраняет в него данные.
- Cache. Класс для работы с кэшем. Файл system\library\cache.php
- APC (system\library\cache\apc.php)
- Файл (system\library\cache\file.php)
- Оперативная память (system\library\cache\mem.php)
- Url. Объект данного класса генерирует URL (ссылки). Файл system\library\url.php
$data['customlink'] = $this->url->link('custom/custom');
- Language. Файл подключающий языковые файлы и получающий из них запрашиваемую строку. Файл system\library\language.php
$_['language_default'] = 'en-gb';
Метод load данного класса, принимает, в качестве первого аргумента путь к файлу перевода, который подключается:
$this->load->language('checkout/checkout');
В данной строке, load является не методом класса language, а объектом класса Loader, который содержит метод language(), вызывающий (через регистратор объектов- Registry) метод load уже объекта language, передавая ему параметры в скобках.
Получение данных из массива подключаемого языкового файла осуществляется с помощью метода get():
$this->language->get('heading_title')
- Document. Объект данного класса содержит данные (собирает и возвращает) выводимые в основном в шапке HTML документа, такие как заголовок страницы, описание, ключевые слова, стили, js скрипты и др. Файл system\library\document.php
$this->document->addStyle('catalog/view/mystyle.css');
далее, в контроллере получаем все стили и передаем в представление (header.tpl), где в цикле они извлекаются.
- Config Autoload. Производится автозагрузка конфигурационных файлов, которые можно добавить в system\config\admin.php
// Autoload Configs $_['config_autoload'] = array();
- Language Autoload. Загружает автоматически языковые файлы, указанные в system\config\default.php
$_['language_autoload'] = array('en-gb');
- Library Autoload. Позволяет автоматически загрузить указанные классы библиотек. Например для frontend загружается дополнительно библиотека openbay, указанная в файле system\config\catalog.php
$_['library_autoload'] = array( 'openbay' );
- Model Autoload. Позволяет автоматически загрузить модель из списка указанном в конфигурационных файлах, например в system\config\default.php
$_['model_autoload'] = array();
- Front Controller. Объект используется для выполнения переданных ему действий (вызов определенного метода нужного контроллера) до выполнения метода контроллера переданного в route (полученного из URL).
$controller = new Front($registry);
Создается объект класса Front хранящий обработчики событий в массиве (private $pre_action) и вызывающий для их обработки метод execute объекта Action. Файл system\engine\front.php
Метод addPreAction() формирует массив объектов класса Action для последующего выполнения.
Метод dispatch() сначала выполняет все элементы из массива $pre_action, а затем переданный в качестве аргумента Action $action. Для выполнения он передает объекты методу execute(), где вызывается одноименный метод объекта Action, который и выполняет метод (по-умолчанию index) переданного ему контроллера.
- Pre Actions. В данном блоке, в фронт-контроллер устанавливаются действия, которые должны выполняться до выполнения любых других действий.
if ($config->has('action_pre_action')) < foreach ($config->get('action_pre_action') as $value) < $controller->addPreAction(new Action($value)); > >
В конфигурационном файле проверяется наличие действий (контроллеров), методы (index) которых нужно выполнить сразу же. Например в system\config\catalog.php :
$_['action_pre_action'] = array( 'startup/session', 'startup/startup', 'startup/error', 'startup/event', 'startup/maintenance', 'startup/'.$seo_type );
В цикле, данные массива передаются в метод addPreAction() объекта Front, где они сохраняются в массив $pre_action для дальнейшего выполнения.
$controller->dispatch(new Action($config->get('action_router')), new Action($config->get('action_error')));
отправляет на выполнение объект Action с аргументом из конфигурационного файла (startup/router.php) и вторым аргументом объект с указанием файла который должен обработать ошибки, если будут. В данном случае это «error/not_found»
То есть вызов метода $controller->dispatch() в OC начинает процесс работы контроллера/метода указанных в route в данный момент (из URL), перед этим выполнив методы (index по-умолчанию если не указаны другие) данных классов (из ‘action_pre_action’):
'startup/session', 'startup/startup', 'startup/error', 'startup/event', 'startup/maintenance', 'startup/'.$seo_type
Указанные контроллеры находятся в папке catalog\controller\startup
Выполнив предварительные методы из списка, последним в списке вызывается catalog\controller\startup\router.php
он из URL отбирает только значение «route»- контроллер/действие и создает объект класса Action передав ему их в качестве аргумента для конструктора. Далее вызывается метод execute() объекта Action, который и выполняет переданные ему контроллер/метод. Остальные GET параметры используются уже в этих контроллерах.
$response->setCompression($config->get('config_compression'));
Считывается из конфигурации и сохраняется в свойстве объекта Response уровень сжатия для функции gzencode(). По умолчанию – 0 (без сжатия).
Завершающая строка выполняемая фреймворком
$response->output();
Вызывает метод output() объекта Response, в котором производится вызов метода сжатия compress() если до этого был выбран уровень сжатия, затем отсылаются заголовки и выводится контент строкой echo $output;
Стоит еще вспомнить класс Action, который был подключен в файле system/startup.php. Файл system\engine\action.php
Объект его создается в основном в данном файле (framework.php) когда нужно выполнить какой-то метод определенного контроллера. При создании его объекта, конструктору передается $route – путь к выполняемому контроллеру/метод. Если метод не передан – будет выполняться метод index.
В файле framework.php объект класса Action передается
— для выполнения методов служебных объектов (предзагрузки) массива ‘action_pre_action‘ файла конфигурации
— методу dispatch() объекта Front Controller, который сначала в цикле выполняет действия добавленные в предзагрузку и затем действие(контроллер) startup/router, который разбирает текущий URL и выполняет указанный там контроллер/действие.
Автор: Сергей Дата публикации: 18.04.2017
- Процесс вывода страницы в OpenCart согласно полученного URL.
- События в OpenCart 2.2+
- Модуль вывода категорий для OpenCart 2.3. Процесс создания модуля.
- Класс Action в OpenCart 2.
- Регистратор объектов в OpenCart 2. Класс Registry.
PhpStorm. Почти все, что вы хотели знать об интеграции с Git.

Давно не писал про phpstorm. Да и чего тут писать, казалось бы. Документация в публичном доступе, бесплатная версия доступна для скачивания, да и лицензия стоит не так дорого. Полно уже информации о том, что это наикрутейший инструмент, который есть сейчас на рынке для разработки приложений на php. Но все еще много сомневающихся, многих отталкивает его «монструозность», «тормознутость» (все познается в сравнении). Лично мне кажется, что дело не в перечисленных выше факторах, а в непонимании, как им пользоваться. Читать огромную доку — лень, изучать что-то новое — лень. Программисты — они вообще люди ленивые в большинстве своем.
Многие приходят ко мне на сайт в поисках информации о phpstorm. И этим постом я хочу начать новый цикл статей о phpstorm, который будет раскрывать наиболее полезные фичи этого наикрутейшего инструмента. В этой статье поговорим об интеграции с git.
Осторожно, под катом очень много картинок, гифок, и … текста …
Дисклеймер
Давайте сразу договоримся — есть крутые гуру, которые не признают GUI-вариант управления git репозиторием. Нравится — пользуйтесь дальше. Я понимаю, что в CLI возможности git’а раскрываются на 100%. Но есть такие сценарии, когда с git гораздо удобнее работать именно в GUI. Мы все это понимаем и осознаем, и спор об этом выходит за рамки данной статьи.
Информация о том, что такое git, зачем он нужен, как его установить, как им пользоваться в целом — все это тоже остается за пределами данного материала.
Еще я пишу все это на Maс, поэтому может возникнуть путаница с расположением пунктов меню и хоткеями. Но я постараюсь отдельно прописать это и для Windows, главное не забыть.
Для кого эта статья.
- для начинающих разработчиков, которые сели за phpstorm и не знают с какой стороны к нему подступиться
- для прожжёных старпёров, которые пользуются Notepad++/Sublime Text/Atom/Coda и иже с ними, а также используют git через cli на постоянной основе
- для любителей Tortoise Git или SourceTree, или каких-то иных GUI; материал позволит вам сравнить ваш инструментарий с возможностями, предлагаемыми PhpStorm
- для всех тех, кто хочет перейти на PhpStorm и кому еще недостаточно поводов это сделать
- для меня, чтобы систематизировать и упорядочить, а также приумножить знания об этой замечательной IDE
Начало
После того, как git установлен в вашей ОС, нужно подключить его к PhpStorm. Сделать это можно в настройках IDE по адресу File | Default Settings… | Version Control | Git. Тут есть опция Path to Git executable, в которой нужно задать путь до исполняемого файла git. В 99% случаев он определится автоматически, но если вдруг у вас какой-то специфичный случай, нужно тут указать путь до бинарника с git. После указания нужно нажать на кнопочку Test, чтобы убедиться, что все ок.
Если вдруг вы не нашли этот пункт меню, то вероятно у вас не установлен плагин «Git Integration». Обычно он установлен и включен по-умолчанию в стартовой инсталляции PhpStorm, но мало ли.
Кстати, тут сразу можно обратить внимание, что PhpStorm даст фору любому GUI по количеству опций, которые можно настроить. Одних только дефолтных настроек 9 вкладок (которые будут работать во всех системах контроля версий, а не только в git). А есть еще специфичные для каждого проекта и vcs опции. А еще опции для разных частей интерфейса … впрочем, обо всем по порядку.
Подключение репозитория к проекту
Мне встречалось, как минимум, 3 способа подключения репозитория к проекту. Я разделяю их на основной и вспомогательные. Я считаю, надо описать основной, чтобы иметь возможность создать репозиторий всегда, а про вспомогательные я напишу мельком.
По-дефолту, PhpStorm ассоциирует корень репозитория с корнем проекта. Если ваш проект еще не содержит репозитория, то нужно зайти в меню VCS | Enable Version Control Integration, из него вывалится всплывашка, предлагающая выбрать систему контроля версий. Выбираем git и жмем Ok.

Подтверждение этого диалога равносильно команде git init. После выполнения этих действий в меню VCS появятся дополнительные действия, доступные при работе с системами контроля версий, а также специфичные именно для git операции.
Если у вас уже есть репозиторий, то нужно его подключить к проекту. Для этого нужно проследовать в настройки проекта PhpStorm | Preferences | Version Control. При входе в это меню можно будет увидеть окно, которое показывает список соответствий между директориями проекта и репозиториями. PhpStorm использует модель версионирования на основе директорий, поэтому каждый репозиторий должен быть связан с какой-то директорией.
PhpStorm довольно умный, и если он нашел репозитории внутри вашего проекта, он покажет их все. Вам останется только выбрать нужный репозиторий. Кроме этого он покажет отдельной строкой директорию , которая ассоциирована с корнем вашего проекта. Если ваш репозиторий находится в корне проекта, то просто ассоциируем с типом VCS — Git:
Если же ваш репозиторий находится глубже по уровню — выбираем найденный phpstorm’ом репозиторий и также нажимаем на плюсик.
Если же ваш репозиторий находится за пределами проекта, то это тоже не беда, на этот случай можно добавить репозиторий, указав полный путь к нему с помощью диалогового окна добавления, которое вызывается при нажатии на плюсик без выбранного репозитория в списке.

Тут есть киллер фича, можно привязать несколько репозиториев к одному проекту, в том числе и с разными системами контроля версий. О нескольких репозиториях я расскажу позже.
Есть и другие способы прилепить репозиторий к проекту. Например, вы можете создать новый проект сразу же из репозитория, который у вас уже хранится где-нибудь на гитхабе. Для этого идем в VCS | Checkout from Version Control | Git (или Github). На стартовом экране PhpStorm тоже есть кнопка, которая вызывает аналогичное диалоговое окно.
Тут достаточно указать путь до репозитория, директорию для нового проекта и его имя. Запустится процесс создания проекта и репозиторий будет автоматом прицеплен к нему.
Еще бывает при входе в проект phpstorm может найти репозиторий, который находится внутри проекта, и может предложить сразу же его ассоциировать с проектом.
В общем, способов масса, нужно лишь выбрать наиболее удобный. В целом, phpstorm так и норовит сам все за вас сделать, поэтому просто не стоит ему сопротивляться.
Инструменты работы с Git.
Чем чаще всего пользуются разработчики? git status/add/rm/commit/checkout/branch/merge/rebase/log/fetch/pull/push и т.д. Для всех этих консольных команд в PhpStorm есть отдельные инструменты, которые делают их работу более наглядной, а значит, и более эффективной.
Основная панель инструментов. Состояние файлов, git status
Примерно 50% времени всей работы с репозиторием в PhpStorm происходит внутри панели инструментов Version Control, которая включается в меню View | Tool Windows | Version Control (или по хоткею Command + 9). Эта панелька содержит 3 вкладки — Local Changes, Log и Console. Последняя показывает просто список всех консольных команд, которые были выполнены самим PhpStorm’ом со всеми параметрами. А вот на первых двух остановимся поподробнее.
Local changes
Если сравнивать gui и cli, то это прям «git status на стероидах». Основой работы этой вкладки являются Change-листы. Это такая небольшая абстракция поверх версионного контроля, которая позволяет прикрепить набор редактируемых файлов к какому-то списку, что помогает изолировать код, относящийся к разным фичам друг от друга. Вообще говоря, сценариев использования change-листов огромное множество. В phpstorm поддержка этих change-листов довольно широка. Например, он может формировать чейнжлисты на основе задач из багтрекера сам, а при переключении веток сохранять состояние чейнжлиста и переходить к другому чейнжлисту. Вы можете сами управлять чейнжлистами, создавать свои, перекидывать файлы из одного листа в другой, коммитить эти листы отдельно друг от друга и т.д. и т.п. Если углубляться в эту тему, можно написать не одну статью в этом блоге Поэтому я буду рассматривать работу только с одним-двумя чейнжлистами для упрощения.
По-умолчанию в PhpStorm уже есть один чейнжлист, который нельзя удалить, называется он Default. В этот лист попадают все те файлы, которые вы правите в рамках текущего репозитория. Хотя нет, на самом деле дефолтных листа — два, постараюсь показать на примере.
Если вспоминать теорию по git, то каждый файл может находиться в одном из нескольких состояний: untracked, unstaged, staged или commited. Узнать о том, в каком состоянии какой файл находится в данный момент, можно с помощью команды git status. Она покажет все те файлы, которые не являются commited. Для примера я взял три файла из тестового репозитория и ввел каждый из них в разное состояние, а на скрине ниже показал разницу между выводом cli и gui интерфейсов:

Слева в cli мы видим следующую картину:
- файл app/basic.html находится в состоянии staged и если выполнить git commit, то он попадет в коммит
- файл app/index.html находится в состоянии unstaged, на нем нужно сделать git add, чтобы перевести в состояние staged
- файл inner.html находится в состоянии untracked, и нужно использовать команду git add, чтобы перевести его в состояние staged
Справа в gui мы видим только две категории (а точнее — два чейнжлиста). Если с листом Unversioned Files все относительно понятно — слова untracked и unversioned являются синонимами в контексте git, а значит в этом листе показываются те файлы, которые являются не добавленными в репозиторий. А вот с листом Default не понятно, там отображаются файлы, которые находятся в состоянии staged и unstaged, и никак не разделены между собой.
WAT?
Тут надо понимать, что отображаемые два чейнжлиста — это дефолтные листы. Поэтому следует принимать то поведение, которое было в них заложено. Если подумать, то так ли нам важно, находится файл в состоянии staged или unstaged? Очень часто бывает так, что после выполнения команды «git add .» которая помечает все файлы репозитория меткой staged, приходится еще что-то подправлять. После таких правок очень легко забыть повторно добавить файлы в индекс (вызвав команду git add . снова, или применив её на какой-то конкретный файл). Чаще всего нам важно понимать лишь разницу между теми файлами, которые мы хотим добавлять в репозиторий, и теми, которые не хотим добавлять.
Так вот PhpStorm старается по-умолчанию разделять файлы на те, которые есть в репозитории и те, которых нет в репозитории. А те файлы, которые есть в репозитории он делит только на измененные и не измененные. Если вы изменили какой-то файл, находящийся под контролем версий, он просто показывается в чейнжлисте Default (или в том чейнжлисте, с которым вы этот файл ассоциировали) и он же автоматически будет готов к коммиту. На уровне git все файлы, которые вы меняете с помощью phpstorm, будут находиться в состоянии unstaged. Этого достаточно, чтобы понять, что файл изменен. А уже когда вы фиксируете правки, phpstorm сам добавляет их в индекс (git add).
На мой взгляд, такая система на порядок проще для начинающих. Когда я учился, мне было тяжело поначалу ориентироваться в состояниях файлов. Чем меньше состояний — тем проще для освоения. Так вот в phpstorm этих состояний минимум, а значит и начать с этим работать — проще, имхо.
Основные возможности вкладки Local Changes

Помимо просмотра статуса репозитория и работы с change-листами, панель имеет ряд дополнительных возможностей. Стоит обратить внимание на панельку инструментов с иконками слева от списка измененных файлов.
При наведении на каждую иконку показывается название инструмента, хоткей. Тут есть такие полезные штуки, как сворачивание/разворачивание списка файлов и чейнжлистов (очень полезно, когда измененных файлов очень много). Есть возможность группировки файлов по директориям — в чейнжлистах будет светиться не просто список файлов, но и директории, в которых эти файлы находятся.
Довольно удобной фичей тут является возможность предпросмотра diff для каждого файла сразу же после выбора их в спике. После включения вся панель инструментов делится на две части, слева будет оставаться также список файлов, а справа — diff файла, выбранного слева. И в нем можно даже сразу редактировать. Diff можно открыть в отдельном всплывающем окне, если неудобно смотреть его в маленьком окошке.
Также тут присутствуют кнопки для управления чейнжлистами, которые позволяют добавлять/удалять их, выбирать активный чейнжлист, перемещать файл между чейнжлистами (что можно делать и с помощью Drag’n’Drop).
Отсюда же можно произвести отмену сделанных изменений в файле (операция Revert). Если вы изменили файл, который уже был в репозитории, то PhpStorm отменит все сделанные в нем изменения и приведет его к состоянию в HEAD метке репозитория, выполнив команду git checkout HEAD — file. Если же файла нет в репозитории, то команда вернет файл в список Untracked.
В общем — пробуйте. Возможностей у этой панельки — хоть отбавляй.
Фиксация правок, git commit
Сделать коммит можно тоже множеством способов. Есть хоткеи (Command + K или Ctrl + K), есть кнопочки в интерфейсе и контекстных меню — используйте любой удобный. Самое важное тут понимать — в коммит попадет только то, что вы непосредственно укажете, независимо от того, что сейчас находится в индексе гита. Выбрали только один файл, в коммит попадет только он. Выбрали директорию — попадут все измененные файлы этой директории. Выбрали чейнжлист — попадут файлы из него. Ну вы поняли
По-дефолту, в коммит попадают только те правки, которые находятся в листе Default. Когда вы запускаете операцию коммита, PhpStorm показывает вам большущее диалоговое окно, в котором можно очень много всего сделать.

Тут можно еще раз проверить, какие именно файлы попадут в коммит. Будет выведено все дерево измененых файлов с группировкой по директориям и деревом вложенности (если выбран этот режим отображения). Также тут можно нужно задать сообщение для коммита и на всякий случай проверить diff.
Помимо таких типовых операций можно попросить PhpStorm сделать такие вещи, как проверка синтаксиса на корректность, или проверить TODO в файлах, предназначенных для коммита. Если будут найдены проблемы, то он любезно сообщит о них и предложит либо исправить, либо закоммитить так как есть.
Просмотр истории репозитория, git log
В любом инструменте для работы с репозиториями через gui обязательно должно быть дерево коммитов. PhpStorm — не исключение. Найти его можно во вкладке Log панели Version Control. На первый взгляд — ничего необычного. Однако чем больше с ним работаешь, тем больше понимаешь, насколько это серьезный инструмент. Да, я согласен, тут может быть есть не все то, что нужно иногда (редко), но тем не менее, на мой взгляд, этот лог гораздо более функционален, чем лог в других gui’яx (слово-то какое!).

В верхней части находятся возможности по фильтрации дерева. Можно показать только те коммиты, которые в тексте описания содержат какую-то строку или регулярку. Можно показать коммиты конкретной ветки/тега. Можно показать коммиты конкретного пользователя, или показать коммиты с фильтром по дате. Что очень интересно — можно показать дерево одного репозитория, или же нескольких репозиториев сразу (на скрине как раз показано несколько деревьев сразу, выбранные в фильтре Paths)!
Само по себе дерево является интерактивным. Можно свернуть историю, если она линейна, нажав на ветвь истории. Каждый коммит в дереве кликабелен и имеет контекстное меню, через которое можно выполнить все базовые операциями над коммитами в истории. Например, если вы хотите отменить сделанный коммит, через контекстное меню надо нажать на Reset Current branch to here …, после чего будет вызван диалог, предлагающий выбрать тип reset’а — hard, soft или mixed с пояснением каждого из вариантов.

А еще можно назначать теги, переходить к коммиту на github, делать cherry-pick, создавать новые ветки из коммита, и даже менять сообщение коммита. В общем много всего.
Клик по коммиту приводит к тому, что в правой части дерева появляется расширенная информация об этом коммите, а также об измененных в нем файлах с возможностью просмотра diff, перехода к редактированию файла, или просмотра истории конкретного файла.
В дополнение ко всему вышесказанному можно добавить приятную мелочь — интеграцию лога с таск-трекером. Для того, чтобы её настроить, нужно пойти в настройки по адресу Version Control > Issue Navigation, где добавить свои настройки для своего таск-трекера. В нашем случае оно выглядит вот так:

После сохранения этих настроек в логе коммитов гита (а на самом деле не только там, а много где) все подходящие под регулярку строки будут преобразованы в ссылки.

Просмотр изменений, git diff
В phpstorm ну очень много функциональности по части интеграции с гитом. Наверно самой удобной и нужной его частью является diff-viewer, который встроен в текстовый редактор phpstorm. Кстати, если у вас на примете уже есть какой-то другой diff-viewer, и вы им давно успешно пользуетесь, phpstorm дает возможность использовать его прямо в IDE (правда эта тема выходит за рамки статьи).
Сам по себе diff-viewer не является частью интеграции git в phpstorm. Это вполне обособленный инструмент, который можно использовать и в других сценариях. Например, можно сравнить содержимое двух файлов между собой (выделяем в дереве оба файла и жмем Ctrl+D или Command + D).
Этот инструмент разработчики JetBrains используют во всех своих IDE, поэтому он вылизан до безупречности, и его стараются использовать везде. Я уже писал выше, что при просмотре списка измененных файлов доступен предпросмотр diff, но полные его возможности раскрываются тогда, когда мы раскрываем полную его версию, либо занимаемся слиянием конфликтующих правок.
Если вам нужно просмотреть историю изменения какого-то файла и сравнить его с предыдущей версией этого же файла, то можно сделать следующее: достаточно вызвать контекстное меню конкретного файла (в дереве файлов или в редакторе) и выбрать опцию Git | Show History. В основной панели инструментов Version Control появится новая вкладка — History, в которой будут отражены все зафиксированные коммиты, в которых присутствовал этот файл. И вот тут как раз можно просмотреть разницу между разными версиями этого же файла с помощью соответствующей кнопки на панели (или шортката Ctrl + D или Command + D)

Нажав на эту кнопку вы увидите те правки, которые были сделаны в рамках этого коммита.
При просмотре diff’а можно настроить отображение окошка так, как душе угодно — можно просматривать в одной колонке, можно в двух; можно выделить изменения, которые были сделаны в рамках одной строки; можно показать файл целиком или показать только изменения + 5 строк сверху и снизу (при этом остальные строки файла будут просто в свернутом состоянии и к ним можно будет получить доступ, просто нажав на «плюсик» разворачивания кодового блока)

Ветки и состояние, git branch и снова git status
Все, что нужно знать о ветках, а также дополнительные сведения о текущем состоянии вашего репозитория (помимо файлов, о которых была речь чуть выше), находится в правом нижнем углу phpstorm. Если вы в данный момент находитесь на какой-то ветке, то будет отображено название ветки. Если вы «оторвались от головы» репозитория и перешли на какой-то коммит, то там будет короткий хеш коммита. Если вы находитесь в каком-то особом состоянии типа merge или rebase, то оно тоже будет там показано

При нажатии на эту область вылезает список всех ваших репозиториев, всех их веток (локальных и удаленных), а также опции для работы с ними. Можно переключиться на другую ветку, создать новую, переименовать. Кстати, очень полезная функция — сравнить текущую ветку с одной из выбранных — очень помогает при Code Review

Откроется уже знакомый нам diff-viewer, который позволит просмотреть всю разницу между коммитами.
Слияние веток, git merge
Но это лишь возможности просмотра в diff-viewer’е. Настоящий бум начинается в те моменты, когда происходит слияние, или работа с откатом сделанных изменений.
Как известно, слияние может производиться с помощью разных стратегий и в разных ситуациях оно будет работать по разному. В случае слияния с fast-forward phpstorm ничего не предложит (вполне ожидаемо). А вот если назревает какой-то конфликт, то phpstorm любезно покажет вам диалоговое окно со всеми конфликтующими файлами:

Как и в cli, тут есть возможность принять чужие или свои изменения в приоритете. А есть кнопка Merge… открывающая diff-viewer, который поможет разрешить конфликт

На этот раз представлен трехсторонний diff. В левом окне — ваши правки. В правом — конфликтующие ветки. В середине — результат слияния. Красным помечены конфликтующие строки, изменения в которых были внесены с обоих сторон. Серым помечены удаления строк, а зеленым — добавления.
С помощью стрелок между окнами можно перемещать код из разных вариантов кода в результирующий вариант.
Все, что не является красным — phpstorm может обработать автоматически. Достаточно нажать кнопку Apply All Non-Conflicting Changes на верхней панели инструментов. Эта кнопка решает в ситуациях, когда изменений ну очень много, но при этом diff-viewer оставляет просмотр правок на ваше усмотрение.
Красные конфликты, как правило, нужно разруливать уже руками. В некоторых случаях phpstorm может предложить автоматически разрешить и эти виды конфликтов, если ситуация уж совсем очевидная. Напротив такой строки он покажет символ волшебной палочки.
Перебазирование, git rebase
Для того, чтобы начать rebase, нужно пойти в меню VCS | Git | Rebase … Откроется диалоговое окно, которое позволит задать параметры для перебазирования одной ветки на другую. Все довольно очевидно и понятно:

Выбираем репозиторий, ветку для перебазирования, новую базу и жмем Rebase. Если был выбран интерактивный режим, то откроется окошко со списком всех перебазируемых коммитов и всеми опциями изменения истории. В общем все так же, как в cli, только в одном месте

После запуска перебазирования phpstorm начнет по одному перекидывать коммиты. В зависимости от того, какие опции перебазирования были выбраны для веток, будут происходить разные действия. Например, если вы выбрали редактирование файлов в каком-то коммите, то phpstorm остановит процесс rebase’а на этом коммите и предложит вам отредактировать файлы, после чего — продолжить:

Если делаете слияние нескольких коммитов в один, то phpstorm любезно предложит ввести новое сообщение о коммите

По окончании операции будет сообщение об успешно завершенной операции

Если же был выбран не интерактивный rebase, то он будет произведен точно так же, как и в cli.
Работа с удаленными репозиториями, git fetch, pull, push & clone
Сделать fetch можно с помощью меню VCS | Git | Fetch. Возможно где-то в недрах конфигурации есть опция, которая бы автоматически выполняла эту команду, но мне удалось найти эту функцию только в стороннем плагине — GitToolbox,
Сделать pull можно с помощью меню VCS | Git | Pull… Откроется диалоговое окно, которое предложит выбрать репозиторий и ветку/ветки для слияния. Там же есть ряд наиболее часто используемых опций при слиянии

Если вдруг в процессе слияния обнаружатся конфликты, то будет предложено их слить с помощью diff-viewer’а, как и при обычном merge.
Для выполнения push нужно выбрать меню VCS | Git | Push … или воспользоваться хоткеем Command + Shift + K или Ctrl + Shift + K. Это тоже диалоговое окно, в котором нужно выбрать репозитории и ветки, в которые выполнить отправку новых коммитов

Прочее
Конечно же, это не все. Причем далеко не все. Я описал тут только те функции, которые наиболее часто востребованы, и немного коснулся менее используемых вещей. В phpstorm продуманы очень многие мелочи, которые в повседневной жизни упрощают работу с репозиторием многократно. Конечно же тут есть и cherry pick, и revert, и разные стратегии слияния веток, и много чего еще. Статья и без них уже получилась огромной, а если вы разберетесь с материалом этой статьи, то использовать все остальные фишки шторма не составит никакого труда.
Да, конечно, не все операции phpstorm позволит сделать с помощью GUI. Но подавляющее большинство операций — доступно. Да — это медленнее, чем через cli. Да — может быть это не «труъ». Но факт остается фактом — работать с гитом через GUI в шторме удобно и приятно, и что самое главное — продуктивно! Пользуйтесь дарами человечества и изучайте инструменты, с которыми работаете. Всем благ.
