Комментарии

Присваивание и передача объектов по ссылке
( 0 Голосов )

Для версии Joomla 2.5 требуется РНР 5.2 или более поздняя версия этого языка, тогда как версия Joomla 1.6 могла вполне работать и с РНР 4.0. В версии РНР 5 было изменено исходное поведение объектов, когда они присваиваются переменным. А в версии 4.0 при наличии переменной ссылки на объект, например, $myObject, выполнялась следующая операция присваивания:

$х = $myObject;

Переменная $х создавалась как копия переменной $myObject. Поэтому если переменная $myObject изменялась далее в коде, это не оказывало никакого влияния на переменную $х. Но если выполнялась следующая операция присваивания:

$х = &$myObject;

то знак & указывал на необходимость создать в коде РНР переменную $х в качестве еще одной ссылки на переменную $myObject. Такая операция называется присваиванием по ссылке, и в данном примере обе переменные, $х и $myObject, ссылаются на один и тот же объект. Если впоследствии изменится переменная $myObject, это отразится и на переменной $х, поскольку обе они, по существу, обозначают один и тот же объект.

Это же справедливо и для ссылок на объекты в сигнатурах методов, как показано в приведенном ниже примере.

function onUserAuthenticate($credentials, $options, &$response)

В данном случае знак & указывает на то, что методу передается ссылка на объект $ response. Если переменная $response изменяется в ходе выполнения метода, то фактически изменяется один и тот же объект, передаваемый по ссылке. Это означает, что при выходе из вызываемого метода и возврате в вызывающий метод любые изменения в переменной $response отразятся на состоянии той же самой переменной в вызывающем методе.

С версии РНР 5 необходимость указывать знак & в первом рассмотренном здесь примере отпала. Так, при выполнении следующей операции:

$х = $myObject;

присваивание в РНР 5 выполняется по ссылке. Если же требуется создать новый объект, для этого необходимо выполнить следующую команду:

$х = clone $myObject;

и в результате создается копия объекта.

Если проанализировать исходный код версии Joomla 1.5, то во многих его местах можно обнаружить операторы присваивания по ссылке со знаком &, как того требовала спецификация РНР 4.0. А в версии Joomla 2.5 эти знаки были удалены, поскольку необходимость в них отпала.

Совсем иначе обстоит дело с передачей объектов по ссылке в сигнатурах методов. В этом случае рекомендуется по-прежнему пользоваться знаком &. Во-первых, этот знак указывает на то, что любые изменения в объекте во время выполнения вызываемого метода будут доступны и в вызывающем методе. И во-вторых, в силу упомянутых выше отличий в версиях языка РНР знак & явно указывает на передачу объекта по ссылке.

До появления версии Joomla 2.5 для импорта пользовательского вспомогательного класса требовалась команда jimport. Этот класс требуется для последующего шифрования проверочного пароля. Начиная с версии Joomla 2.5 этот класс загружается автозагрузчиком.

Перейдем к анализу следующей строки кода:

$response->type = 'Joomla'

В этой строке кода устанавливается строковое значение 'Joomla' в поле type объекта $ response. Это поле служит для указания на тот подключаемый модуль аутентификации, который использовался для проверки подлинности пользователя.

Далее следует приведенный ниже кодовый блок.

//В Joomla! пустые пароли не допускаются if (empty($credentials['password'])) {
$response->status = JAUTHENTICATE_STATUS_FAILURE;
$response->error_message = JText::_(
'JGLOBAL_AUTH_EMPTY_PASS_NOT_ALLOWED'); return false;
}

Этот кодовый блок содержит условный оператор i f для проверки ввода пароля. Если пароль не введен, произвести аутентификацию не удастся. Для указания на это устанавливаются соответствующие значения в полях status и error_message объекта $ response, а из рассматриваемого здесь метода возвращается логическое значение false.

В следующем кодовом блоке выполняется простой запрос базы данных Joomla с целью получить из нее идентификатор пользователя и пароль. Это первый пример запроса базы данных, в котором используется класс JDatabaseQuery, внедренный в версии Joomla 1.6. В строке кода

$db = JFactory::getDbo();

создается объекта типа JDatabase. Как правило, это первая стадия формирования любого запроса базы данных. В следующей строке кода

$query = $db->getQuery(true);

создается объект типа JDatabaseQuery. А в следующей далее строке кода

$query->select('id, password');

в оператор SELECT запроса вводятся идентификатор столбцов таблицы в базе данных и пароль. Далее следует строка кода, где в запрос вводится таблица # users:

$query->from('# users');

Обратите внимание на то, что доступ к таблице осуществляется с префиксом # в виде знака денежной единицы и двух последующих символов подчеркивания. До выполнения запроса этот префикс заменяется префиксом таблицы, выбираемым при установке Joomla (например, префиксом jos_).

В следующей строке кода

$query->where('username=' . $db->Quote($credentials['username']));

вводится оператор WHERE, ограничивающий запрос теми строками таблицы, где столбец username совпадает с элементом username массива $ credential s. А поскольку столбец username должен быть единственным в таблице базы данных, то по данному запросу будет получена лишь одна строка.

Метод $db->Quote () играет очень важную роль в обеспечении безопасности. Значение его аргумента username заключается в одинарные кавычки и "экранирует" любые символы, имеющие особое значение в запросах SQL, например, в тех случаях, если одинарные или двойные кавычки завершают один оператор SQL и начинают другой.

Во избежание подобных недоразумений они преобразуются в управляющие последовательности символов \\' и \\". В итоге специальное значение этих символов игнорируется в базе данных, защищая от случайного их ввода в поле имени пользователя, а следовательно, и в команде SQL.

Предупреждение в целях безопасности: пользуйтесь методом $db->Quote() и операторами (int) и (float) во избежание умышленного внесения зanpocoв SQL

В рассматриваемом здесь примере аргумент $credentials ['username' ] метода $db-> Quote () введен пользователем веб-сайта. Как пояснялось ранее, вводимые данные должны быть защищены от попыток злоумышленников ввести злонамеренные команды SQL в полях ввода данных. Подобного рода хакерская атака или попытка взлома называется умышленным внесением запросов SQL.

Предотвратить умышленное внесение запросов SQL можно, соблюдая два простых правила.

1. Если вводимое значение предполагается целочисленным (например, -1 или 1234) или с плавающей точкой либо запятой (вроде 12.3456 или -2,3), воспользуйтесь операторами (int) и (float) языка РНР для преобразования (или приведения) этого значения к нужному типу. Например, в следующей строке кода

$query->where(' id =* . (int) $id);

оператор (int) выполняет преобразование исходного значения аргумента $ id в целое. Этим гарантируется, что в команде формируемого запроса SQL не появится ничего, кроме целочисленного значения и знака "минус", а все остальное будет отброшено. Благодаря этому исключается возможность ввести любые команды SQL в переменных и аргументах методов.

2. Для указания переменных и аргументов любых типов, кроме целочисленных и с плавающей точкой (например, текста и дат), пользуйтесь методом $db->Quote (), чтобы гарантировать надежность значений, указываемых в запросе, как показано в приведенном ниже примере.

$query->where('title = ' . $db->quote($myTitle);

3. Если аргумент $myTitle содержит кавычки или другие символы, имеющие особое значение в командах SQL, они экранируются. В итоге их особое значение будет проигнорировано в базе данных, где они будут интерпретированы как обычный текст.

Следуя приведенным выше правилам, вы сможете защитить свои данные и воспрепятствовать попыткам злоумышленников выполнить несанкционированные запросы.

Итак, запрос базы данных сформирован и все готово для его выполнения. Это делается в следующем фрагменте кода:

$db->setQuery($query);
$result = $db->loadObject();

В первой строке приведенного выше фрагмента кода запрос передается объекту базы данных, тогда как во второй строке — выполняется сам запрос базы данных, а результаты сохраняются в переменной $ result. Если по какой-нибудь причине выполнение запроса завершится неудачно, переменная $ result окажется пустой или с логическим значением false.

Остальная часть рассматриваемого здесь метода представляет собой кодовый блок условных операторов if /then/else, начинающийся следующим образом:

if ($result) {
$parts = explode(':', $result->password);
$crypt = $parts[0];
$salt = @$parts[l];
$testcrypt = JUserHelper::getCryptedPassword($credentials['password'], <*>$salt) ;

В первой строке кода переменная $ result проверяется на наличие логического значения true. Если она не содержит это логическое значение, осуществляется переход к кодовому блоку внешнего оператора else, как показано ниже.

} else {
$response->status = JAUTHENTICATE_STATUS_FAILURE;
$response->error_message = JTextJGLOBAL_AUTH_NO_USER');
}

В итоге пользователь получает сообщение об ошибке, уведомляющее о том, что его регистрация на веб-сайте не состоялась.


Понравился материал? Пригодилась информация? Плюсани в социалки!


 
Похожие новости