Конструкция switch в PHP, массивы (array) и константы | Механизмы защиты Joomla

"Все аспекты самостоятельного создания и продвижения сайтов
от практика с многолетним опытом." — блог Рудь Сергея
info@site-on.net
Заметка: активирована адаптивная версия сайта, которая автоматически подстраивается под небольшой размер Вашего браузера и скрывает некоторые детали сайта для удобства чтения. Приятного просмотра!
26.04.2013

Здравствуйте уважаемые читатели портала о создании и продвижении сайтов - Site on! Как и обещал, сегодня я напишу вам решение предыдущей задачи, также мы продолжим тему операторов условия в PHP и познакомимся с конструкцией switch. Затем мы изучим такой тип переменных как массив (array) и узнаем о константах, кстати, благодаря которым во всех версиях Joomla реализована защита от прямого обращения к файлам ядра. Скажу вам по секрету, что на этом блоге я сделал точно также, так как считаю эту идею весьма неплохой, и раз уж вспомнил об этом, то обязательно расскажу, как работает данная защита и для чего она вообще нужна.

Конструкция switch в PHP

Конструкция switch может стать альтернативой использования if, else, elseif. Лично я в своих проектах использую и switch и if, else, elseif, смотря по ситуации, что будет уместней. Итак, как это работает:

<?php
switch (переменная) {
    case 'возможное значение1' : 'выполнить что-то'; break;
    case 'возможное значение2' : 'выполнить что-то другое'; break;
    case 'возможное значение3' : 'выполнить ещё что-то'; break;
    default: echo 'ничего не подошло :('; // default не обязателен
}
?>

break как и default ставить не обязательно, но если не ставить в конце каждого кейса (case) break, то после того как PHP найдёт нужный кейс, он выполнит все остальные инструкции ниже по коду, вне зависимости от того, подходят остальные кейсы или не подходят. Пример:

 <?php
header('Content-Type: text/html; charset=utf-8');

$color = 'зелёный'; switch ($color) { case 'красный' : echo 'Ваш любимый цвет красный <br />'; case 'зелёный' : echo 'Ваш любимый цвет зелёный <br />'; case 'жёлтый'  : echo 'Ваш любимый цвет жёлтый <br />'; case 'серый'   : echo 'Ваш любимый цвет серый <br />'; default: echo '<span style="color:red;font-weight:900">Мы не знаем какой у вас любимый цвет</span>'; } ?>

Результат:

Switch в PHP

Нужно вам такое поведение (без break) или не нужно зависит от конкретной ситуации, чаще всего не нужно. Ещё раз обращаю ваше внимание, что всё то же самое можно было сделать с помощью if, else и тд., но в данном случае применение свича гораздо наглядней, чем громоздить кучу if – else, if – else, if – else. В общем, смотрим по ситуации.

Массивы в PHP (array)

Массив – это один из типов переменных в PHP, который обозначает множество переменных внутри одной общей. Обозначается как обычная переменная, после которой идут квадратные скобочки, в которых мы можем указывать название (индекс) ячейки:

<?php
$product[0] = "ball"; // индекс 0
$product[1] = "leather ball"; // индекс 1
$product[2] = "silk"; // индекс 2
?>

А можем и не указывать индекс:

<?php
$product[] = "ball"; // индекс 0
$product[] = "leather ball"; // индекс 1
$product[] = "silk"; // индекс 2
?>

Как видите, индексы автоматически расставятся, начиная счёт с нуля.

Если вы где-то забудете указать индекс, хотя перед этим его указывали, то в индекс этой ячейки автоматически присвоится число, которое будет равно наибольшему из предыдущих индексов +1. Смотрим пример:

<?php
$product[34] = "ball"; // индекс 34
$product[6] = "leather ball"; // индекс 6
$product[] = "silk"; // индекс 35
$product[88] = "silk2"; // индекс 88
$product[] = "silk3"; // индекс 89
?>

Как узнать количество ячеек в массиве?

Чтобы посчитать (узнать) количество ячеек в массиве используется функция count():

<?php
$product[34] = "ball";
$product[6] = "leather ball";
$product[] = "silk";
$product[88] = "silk2";
$product[] = "silk3";

echo count($product); // выведет в браузер число 5 ?>

Как обратится к конкретной ячейке в массиве?

Для того чтобы выполнить какое-либо действие с нужной нам ячейкой, мы должны написать имя массива (не забыв про знак доллара) и указать индекс нужной нам ячейки:

 <?php
echo $product[89]; // silk3
?>

Как посмотреть содержимое массива?

Для того чтобы посмотреть содержимое массива вы можете использовать функцию prin_r():

<?php
echo '<pre>'; // HTML тег для удобства чтения
print_r ($product);
echo '</pre>';
?>

Результат:

содержимое массива

Также очень удобной является функция для просмотра массивов (и не только) var_dump ():

<?php
echo '<pre>';
var_dump ($product);
echo '</pre>';
?>

Результат:

тип array

В отличие от предыдущей функции, функция var_dump () сразу считает общее количество ячеек и показывает тип каждой из них.

Второй способ создать массив

Итак, с массивами в PHP мы уже немного знакомы, давайте теперь рассмотрим другой способ их создания, который будет гораздо компактней:

<?php
$product = array("silk", "ball", "leather");
//тоже, что и
$product = array(0=>"silk1", 1=>"ball", 2=>"leather"); // задаём индексы вручную
?>

Вариант создания массива, рассмотренный в начале статьи, и данный вариант полностью идентичны, отличаются лишь синтаксисом написания.

Ассоциативные массивы

Ассоциативные массивы – это те же самые массивы, только с одним отличием – их индексы вместо цифр содержат слова (строки). Пример:

<?php
$sport['basketball'] = '78:95';
$sport['football'] = '3:2';
$sport['handball'] = '24:15';

echo $sport['handball']; // получим 24:15 ?>

Их используют для построения удобно читаемых массивов, в которых каждая ячейка содержит осознанное название (ассоциацию), а не просто число. То же самое можно было записать и так:

<?php
$sport = array('basketball'=>'78:95', 'football'=>'3:2', 'handball'=>'24:15'); 
?>

Как правильно записывать индексы ячеек и значения ячеек: в одинарных или двойных кавычках? О разнице двойных и одинарных кавычек я подробно писал в статье об экранировании и спецсимволах PHP. Для тех, кому не хочется переходить по ссылке, коротко отвечу: лучше в одинарных кавычках, но и так и так правильно.

Также обращаю ваше внимание на то, что вы можете делать и смешанные массивы, где в индексах ячеек будут встречаться как числа, так и строки.

Многомерные массивы (array)

Многомерный массив – это обыкновенный массив, в одной или более ячеек которого содержится ещё один массив. То есть когда внутри массива среди прочих ячеек есть ячейка с массивом, это и называется многомерным массивом. Пример:

<?php
$users = array(
    0 => array(
        "login" => "Admin",
        "password" => "fdg4gfd"
    ),
    1 => array(
        "login" => "Arnold",
        "password" => "ef4mgj5"
    )
);

echo $users[0]["login"]; // "Admin" ?>

Вас мог смутить такой стиль записи, до этого я писал массив в одну строку, но если вы читали вводную статью о PHP, то знаете, что в PHP инструкции можно разрывать и ставить Enter столько раз, сколько вам захочется. Это сделано с целью, чтобы можно было гибко форматировать код и делать его более структурированным и читабельным. Реальным примером применения массивов на практике может послужить мой кейс по созданию ротации баннеров для любого сайта.

Константы в PHP

Константы в PHP объявляются с помощью функции define(), где в круглых скобках сначала указывается имя константы, далее через запятую её значение. В PHP константы принято записывать заглавными буквами, однако это лишь условность, а не правило, то есть вы можете называть константу и маленькими буквами, всё прекрасно работает и так и так. Но я вам рекомендую придерживаться общепринятого тона и писать константы БОЛЬШИМИ буквами, так они сразу выделяются в коде. И ещё, естественно, значение константы не может быть переменной. Пример:

<?php
define('NAME','Sergey');
echo NAME; // выводим значение константы в браузер. Напишет: Sergey
?>

Отличия констант и переменных

В отличие от переменных:

Как тогда использовать константы? В них можно хранить важные данные, которые часто повторяются, чтобы их никто по ошибке, включая вас, не переписал. Например, в константе можно хранить пути до часто используемых файлов. Также PHP имеет множество встроенных констант, которые удобно использовать, например, константа E_ALL при выборе типов ошибок, которые мы хотим выводить:

 <?php
error_reporting(E_ALL); // вывод абсолютно всех ошибок, даже самых мелких
?>

Если вы хотите проверить, существует ли уже какая-нибудь константа, вы можете использовать функцию defined() (перед этим была define(), не запутайтесь):

<?php
define('NAME','Sergey');
echo defined('NAME'); // выведет 1, так как константа существует, либо пустоту (true или false)
?>

Важно! При использовании defined() не забывайте заключать имя константы в кавычки. Стоит также отметить, что константы, так же как и переменные регистро-зависимы! Однако для констант это правило можно отключать при их создании, чего я не советую и даже не вижу смысла, только запутаете себя. Но возможно вам это пригодится, поэтому чтобы отключить регистро-зависимость констант, нужно при их создании указать третий параметр true:

 <?php
define('NAME','Sergey',true);
echo naMe; // выведет Sergey, так как мы отключили регистро-зависимость.
?>

Механизм защиты Joomla с помощью констант

Ещё одним прекрасным примером использования констант послужит система защиты от прямого обращения к файлам в Joomla. Что вообще означает эта фраза? Представьте Joomla (или любой другой движок), в ней есть множество файлов с расширением .php, которые при необходимости подключаются на лету в главный файл – index.php. На этом взаимодействии и строится основной принцип динамических сайтов на PHP: у нас существует один единственный файл (index.php), который в зависимости от ситуации подключает другие файлы, образуя тем самым разные страницы сайта и всевозможную остальную функциональность.

А теперь представьте ситуацию, когда один из файлов отвечает за отправку почты, то есть каждый раз когда мы его подключаем он отправляет письмо о новом комментарии на вашем сайте. В случае Joomla и других Open Source (бесплатных) CMS (Wordpress, Magenta, Monstra и тд.) я могу взять и посмотреть, где именно находится этот файл, то есть узнать его путь.

Что мне это даёт? Зная путь к файлу, я могу написать его прямо в адресную строку, тем самым заставлю его отработать (проиграть свой код). К примеру, путь к моей карте сайта находится по адресу:

корень сайта/maps/sitemap1.xml

Значит, в адресную строку мне нужно написать:

http://site-on.net/maps/sitemap1.xml

И вы увидите мою карту сайта, если бы она там была :) Так вот зная путь к файлу отправки писем, каждый раз, когда я буду вбивать его адрес в строку браузера вам будет приходить письмо якобы о новом комментарии. Обновлю страницу 10 раз, письмо придёт 10 раз, хотя комментарий никто и нигде не оставлял. Напишу скрипт, который будет автоматически обновлять страницу, и пойду по делам, или спать. А в это время на ваш сайт и почтовый сервер будет создаваться постоянная нагрузка.

Это был слегка идеализированный пример, но на практике всё почти что так и есть. И таких бед можно придумать и создать до бесконечности. Даже если вы делали сайт на собственном движке, о котором не знают даже ваши родные и близкие, то продвинутым людям всё равно не составит труда узнать пути ко всем вашим файлам.

Как же нам запретить обращаться ко всем .php файлам из строки браузера (запретить прямой доступ к файлам)? Вы можете придумать разные изощрения, а можете поступить так же, как сделали разработчики Joomla и я на своём блоге.

На самом деле это гениально и очень просто: в главном файле нашего сайта – index.php нужно создать константу с любым значением и названием, например, числом 1, как это сделали разработчики Joomla или логическим значением TRUE, как это сделал я на этом блоге:

В Joomla:

PHP константы

На моём блоге:

защита Joomla

Как видите, это делается преимущественно в начале index.php, а главное ДО первого подключения внешнего PHP скрипта.

Затем первой строчкой КАЖДОГО подключаемого файла мы должны писать следующую проверку:

 defined('_JEXEC') or die;

в случае Joomla и:

 defined('SECURE') or die;

в моём случае.

Мы проверяем, существует ли данная константа, если существует, то продолжаем работу, а если нет – прекращаем работу всех скриптов и отдаём злоумышленнику пустую белую страницу. Вот и всё, единственный минус данного метода заключается в том, что если у вас уже есть сотня другая php файлов, вам придётся заходить в каждый файл и дописывать эту строку.

Кстати, если вы ещё не знаете, как навсегда избавиться от проблемы дублей страниц в Joomla, VirtueMart, Wordpress или любой другой CMS, то предлагаю вам прочесть мой метод по ссылке выше.

Решение предыдущей задачи

А теперь пришло время решения задачи из предыдущей статьи:

<?php
$b = 16; // заданные значения
$chis = 14+$b-86*2; // числитель
$znam = 100+$b; // знаменатель

$otvet = $chis/$znam; // ответ echo $otvet.'<br />'; // Для отладки, чтобы следить за правильной работой $str_otvet = "'$otvet'"; // Приводим число к строке, так как мы пока ещё не умеем по-другому.
if ($otvet == -2 and $chis!=$znam and $chis!=$b and $znam!=$b){ echo $otvet; } elseif ($str_otvet{3} + $str_otvet{4} != 5){ echo $str_otvet{4}; } ?>

Решили по-другому? Замечательно! Можете поделиться своим вариантом в комментариях ниже. Всем спасибо за внимание, до встречи в новых статьях!

С уважением, .
Пожалуйста, оцените эту статью
Средняя оценка: 5 из 5 (проголосовало: 4)
Статья оказалась вам полезной? Подпишитесь, чтобы не пропустить новые!

Ваш email:
Вы можете помочь развитию проекта, сделав всего 1 клик:
Спасибо!
Пожалуйста, прокомментируйте, как Вам моя статья?
Имя:
Комментарий:

Если Вы хотите вставить код, пожалуйста, заключайте его в [code][/code]

Подписаться на новые комментарии:

E-mail:


Защита от спама: у треугольника три...
Ответ:
Подписаться на новые комментарии без комментирования - Email:
Защита от спама: у треугольника три...
Ответ:

21.08.2013 13:36:25 Никита:
Подскажите, а как использовать defined('SECURE') or die; при подгрузке файлов с помощью javascript, ну например $(#forms').load('form.php'); ? Они ведь не обрабатывают предыдущий код...

Ответить на комментарий


09.09.2013 15:44:22 Anna:
Напишите пожалуйста статью по защите самописного сайта с помощью PDO. Заранее спасибо!

Ответить на комментарий


29.09.2014 23:56:05 nastya:
Отличные уроки! Спасибо. Задача сформулированна, на мой взгляд, не очень понятно. "если решение выражения противоположно числу 2" - для меня это скорее $x != 2, то есть не равно числу два, а не равно минус два $otvet == -2, как написано у Вас. И то, что ответ надо в набор символов превести тоже не с первого раза ясно. А так отличный урок!
01.10.2014 21:09:46 Сергей отвечает:
Спасибо за отзыв. Возможно, Вы правы.

Ответить на комментарий


27.01.2015 14:49:31 Иван:

<?php
$b = 16;
$a = (14+$b-86*2)/(100+$b);
if ((14+$b-86*2)/(100+$b)== -2 and (14+$b-86*2)!= (100+$b) and (14+$b-86*2)!=$b and (100+$b)!=$b){
echo (14+$b-86*2)/(100+$b);
} elseif ($a{4}+$a{5}!=5) {
echo $a{5}, "<br/>";
echo (14+$b-86*2)/(100+$b);
}
?>

Соглашусь с комментарием ниже, что слова "противоположное 2" можно интерпретировать, как $x!=2, что я, собственно и сделал, но, посмотрев в решение задачи, исправил на "-2". По-поводу остального не знаю - правильно или нет. Был очень благодарен, если бы кто-то указал на ошибки, если они есть!

Ответить на комментарий


06.05.2015 16:17:18 Славик:
У меня получилось, но преобразовал к строке путем конкатенации. Еще не понятен фрагмент условия "3 и 4 символов". Это как считаем мы или PHP?

echo'для b=20'. '<br>';
$b=20;
$c=14+$b-86*2;
$z=100+$b;
$v=$c/$z;
$vs=$v.'string';
$ss=$vs{4}+$vs{5};
if ($v==-2 and $z!=$c=!$b)
{echo 'Решение выражения:'. $v. '<br>';}
elseif($ss!=5)
{echo $vs{5};}
else{echo 'все ни о чем!'.'<br>';}

echo 'для b=-14'. '<br>';
$b=-14;
$c=14+$b-86*2;
$z=100+$b;
$v=$c/$z;
$vs=$v.'string';
$ss=$vs{4}+$vs{5};
if ($v==-2 and $z!=$c=!$b)
{echo 'Решение выражения:'. $v. '<br>';}
elseif($ss!=5)
{echo $vs{5};}
else{echo 'все ни о чем!'.'<br>';}

echo'для b=16'. '<br>';
$b=16;
$c=14+$b-86*2;
$z=100+$b;
$v=$c/$z;
$vs=$v.'string';
$ss=$vs{4}+$vs{5};
if ($v==-2 and $z!=$c=!$b)
{echo 'Решение выражения:'. $v. '<br>';}
elseif($ss!=5)
{echo $vs{5};}
else{echo 'все ни о чем!'.'<br>';}

Ответить на комментарий


24.01.2016 19:30:13 radik:
<?php
header('Content-Type: text/html; charset=utf-8');
$b = 20;
$a = (14+$b-86*2)/(100+$b);
$c = (14+$b-86*2);
$d = (100+$b);
if ($a !=2 and $c != $d and $d != $b) {
echo $a ;
}
echo '<br />Остальная часть страницы, она вне условия';
?>

Ответить на комментарий

Использую для работы
Мои расширения
Свежие статьи
Рекомендую
Горячо обсуждаемые
Подписка
  • Следовать в twitter:
  • Подписаться по RSS:
  • Подписаться по E-mail:
  • Следить ВКонтакте:
  • Следить на Facebook:
Пользовательское соглашение об условиях использования сайта и Политика конфиденциальности
Перепечатывание или копирование материалов сайта (текста, изображений и другого содержимого) для их публичного или коммерческого использования в сети Интернет, либо в печатных изданиях строго запрещены. При нарушении данного правила, с нашей стороны будут предприняты соответствующие меры, вплоть до судебной жалобы.
© site-on.net
Шрифт: +стандартно-