Перенос XOOPS на новый сервер - Lab - Новости. Включаем файл конфигурации

18.04.2019

В нашей CMS Article будет единственным классом PHP. Он будет обслуживать задачи сохранения статьи в базе данных и получения материалов для вывода на страницах проекта. Как только мы построим данный класс будет действительно легко создать другие скрипты для создания, обновления, вывода и удаления статей.

В нашей папке cms создаем каталог classes . В папке classes создаем новый файл с именем Article.php и копируем в него следующий код:

id = (int) $data["id"]; if (isset($data["publicationDate"])) $this->publicationDate = (int) $data["publicationDate"]; if (isset($data["title"])) $this->title = preg_replace ("/[^\.\,\-\_\"\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data["title"]); if (isset($data["summary"])) $this->summary = preg_replace ("/[^\.\,\-\_\"\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data["summary"]); if (isset($data["content"])) $this->content = $data["content"]; } /** * Устанавливаем свойств с помощью значений формы редактирования записи в заданном массиве * * @param assoc Значения записи формы */ public function storeFormValues ($params) { // Сохраняем все параметры $this->__construct($params); // Разбираем и сохраняем дату публикации if (isset($params["publicationDate"])) { $publicationDate = explode ("-", $params["publicationDate"]); if (count($publicationDate) == 3) { list ($y, $m, $d) = $publicationDate; $this->publicationDate = mktime (0, 0, 0, $m, $d, $y); } } } /** * Возвращаем объект статьи соответствующий заданному ID статьи * * @param int ID статьи * @return Article|false Объект статьи или false, если запись не найдена или возникли проблемы */ public static function getById($id) { $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD); $sql = "SELECT *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles WHERE id = :id"; $st = $conn->prepare($sql); $st->bindValue(":id", $id, PDO::PARAM_INT); $st->execute(); $row = $st->fetch(); $conn = null; if ($row) return new Article($row); } /** * Возвращает все (или диапазон) объектов статей в базе данных * * @param int Optional Количество строк (по умолчанию все) * @param string Optional Столбец по которому производится сортировка статей (по умолчанию "publicationDate DESC") * @return Array|false Двух элементный массив: results => массив, список объектов статей; totalRows => общее количество статей */ public static function getList($numRows=1000000, $order="publicationDate DESC") { $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD); $sql = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles ORDER BY " . mysql_escape_string($order) . " LIMIT:numRows"; $st = $conn->prepare($sql); $st->bindValue(":numRows", $numRows, PDO::PARAM_INT); $st->execute(); $list = array(); while ($row = $st->fetch()) { $article = new Article($row); $list = $article; } // Получаем общее количество статей, которые соответствуют критерию $sql = "SELECT FOUND_ROWS() AS totalRows"; $totalRows = $conn->query($sql)->fetch(); $conn = null; return (array ("results" => $list, "totalRows" => $totalRows)); } /** * Вставляем текущий объект статьи в базу данных, устанавливаем его свойства. */ public function insert() { // Есть у объекта статьи ID? if (!is_null($this->id)) trigger_error ("Article::insert(): Attempt to insert an Article object that already has its ID property set (to $this->id).", E_USER_ERROR); // Вставляем статью $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD); $sql = "INSERT INTO articles (publicationDate, title, summary, content) VALUES (FROM_UNIXTIME(:publicationDate), :title, :summary, :content)"; $st = $conn->prepare ($sql); $st->bindValue(":publicationDate", $this->publicationDate, PDO::PARAM_INT); $st->bindValue(":title", $this->title, PDO::PARAM_STR); $st->bindValue(":summary", $this->summary, PDO::PARAM_STR); $st->bindValue(":content", $this->content, PDO::PARAM_STR); $st->execute(); $this->id = $conn->lastInsertId(); $conn = null; } /** * Обновляем текущий объект статьи в базе данных */ public function update() { // Есть ли у объекта статьи ID? if (is_null($this->id)) trigger_error ("Article::update(): Attempt to update an Article object that does not have its ID property set.", E_USER_ERROR); // Обновляем статью $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD); $sql = "UPDATE articles SET publicationDate=FROM_UNIXTIME(:publicationDate), title=:title, summary=:summary, content=:content WHERE id = :id"; $st = $conn->prepare ($sql); $st->bindValue(":publicationDate", $this->publicationDate, PDO::PARAM_INT); $st->bindValue(":title", $this->title, PDO::PARAM_STR); $st->bindValue(":summary", $this->summary, PDO::PARAM_STR); $st->bindValue(":content", $this->content, PDO::PARAM_STR); $st->bindValue(":id", $this->id, PDO::PARAM_INT); $st->execute(); $conn = null; } /** * Удаляем текущий объект статьи из базы данных */ public function delete() { // Есть ли у объекта статьи ID? if (is_null($this->id)) trigger_error ("Article::delete(): Attempt to delete an Article object that does not have its ID property set.", E_USER_ERROR); // Удаляем статью $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD); $st = $conn->prepare ("DELETE FROM articles WHERE id = :id LIMIT 1"); $st->bindValue(":id", $this->id, PDO::PARAM_INT); $st->execute(); $conn = null; } } ?>

Файл получается достаточно длинным, но код очень простой. Разберем его подробно:

1. Определение класса и его свойства

Сначала определим класс Article:

Class Article {

Все, что следует за данным строками до закрывающей фигурной скобки в конце файла содержит код нашего класса Article .

После определения класса мы объявляем свойства класса: $id , $publicationDate и так далее. Каждый объект Article , который мы создаем, будет хранить данные в объявленных свойствах. Обратите внимание, что имена свойств соответствуют именам полей в таблице articles .

Технически, такой тип класса, который содержит свойства соответствующие непосредственно полям базы данных и методы для хранения и получения записей, соответствует шаблону объектно-ориентированного проектирования, известному как active record .

2. Конструктор

Затем мы создаем методы класса. Это функции, которые привязаны к классу и к объекту, создаваемому из класса. Наш основной код вызывает методы для манипулирования данными в объекте Article .

Первый метод, __construct() , является конструктором. Это специальный метод, который автоматически вызывается системой PHP каждый раз, когда создается новый объект Article . Наш конструктор получает необязательный массив $data , в котором содержатся данные для свойств нового объекта. Затем мы присваиваем данные свойствам в теле конструктора. Таким образом, получается удобный способ для создания и инициализации объекта в одно действие.

$this->propertyName означает: "Свойство объекта this с именем " $propertyName ".

Обратите внимание, что метод фильтрует данные, прежде чем присвоить их свойствам. Свойства id и publicationDate приводятся к типу int с помощью (int) , так данные значения должны быть типа int . Свойства title и summary фильтруются с помощью регулярных выражений, так как в них допускает наличие символов из определенного набора. С точки зрения безопасности фильтрация данных ввода - отличная практика. Пропускаем только допустимые значения и символы.

Однако, мы не фильтруем свойство content . Почему? Вероятно, администратор захочет использовать более широкий диапазон символов в содержании статьи - например, разметку HTML. Если мы ограничим диапазон доступных символов в содержании, то снизим полезность нашей системы для администратора.

Обычно, такие места могут оказаться дырой в системе безопасности, так как пользователь может вставить вредный код JavaScript или материалы с ошибками в содержание статьи. Однако, так как мы полагаем. что единственной персоной, которой доступно редактирование содержание, будет администратор системы, располагающий безграничным доверием, то вопрос с уязвимостью содержания остается за рамками нашего внимания. Если вы имеете дело с генерируем пользователями содержанием, например, комментариями или записями форума, то следует быть более осторожным и допускать только "безопасный" код HTML к использованию. Отличным инструментом для решения таких задач является HTML Purifier , который анализирует ввод кода HTML и удаляет все потенциальные угрозы.

Безопасность кода PHP выходит за рамки наших уроков. Вам следует посвятить определенное время для изучения данного вопроса .

3. storeFormValues()

Следующий метод storeFormValues() похож на конструктор в том, что он сохраняет полученный массив данных в свойствах объекта. Основное отличие заключается в том, что storeFormValues() может обрабатывать данные в формате, который используется в формах New Article (Новая статья) и Edit Article (Редактировать статью) (мы создадим их позже). В частности, он может обрабатывать дату публикации в формате YYYY-MM-DD , конвертировать ее в формат времени UNIX, который отлично подходит для хранения в объекте.

Формат времени UNIX представляет собой целое значение, которое содержит количество секунд от полуночи 1 января 1970 до искомой даты. Датой в таком формате легко оперировать, и ее удобно хранить.

Назначение данного метода - облегчить реализацию скрипта для хранения дат, вводимых в формах.

Все члены (то есть свойства и методы) нашего класса Article имеют ключевое слово public перед определением, что означает доступность кода вне класса. Также можно создавать частные члены (директива private) (их можно использовать только в классе) и защищенные члены (директива protected) (которые можно использовать в классе и его подклассах).

4. getById()

Теперь перейдем к методам, реализующим доступ к базе данных MySQL. Первый из них - getById() . Он принимает в качестве аргумента ID статьи ($id) и возвращает запись с указанным ID из таблицы articles , сохраняя данные в новом объекте Article .

Обычно, когда вы вызываете метод, сначала нужно создать объект, а затем вызвать метод, принадлежащий объекту. Но, так как getById() возвращает новый объект Article , будет полезно вызывать его напрямую, а не через существующий объект. Иначе придется создавать новый объект-заглушку каждый раз, когда нужно вызвать метод и получить статью.

Для разрешения вызова метода без объекта мы добавляем декларацию static к определению метода. Таким образом разрешается вызов метода непосредственно без определения объекта.

Public static function getById($id) {

Метод использует PDO для соединения с базой данных, получает запись статьи с помощью запроса SQL SELECT и сохраняет данные в новом объекте Article , который возвращается в вызывающий код. PDO — PHP Data Objects —объектно-ориентированная библиотека, встроенная в PHP, которая облегчает связь скриптов PHP с базами данных.

Разберем метод подробнее:

    Соединение с базой данных

    $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD);

    Здесь выполняется соединение с базой данных MySQL с помощью данных из файла config.php . Дескриптор соединения сохраняется в переменной $conn . Данный дескриптор используется в остальном коде для обмена данных с базой.

    Получаем запись статьи

    Выражение SELECT возвращает все поля (*) из записи в таблице articles , которые соответствуют заданному полю id . Значение поля publicationDate возвращается в формате времени UNIX, вместо формата для дат MySQL, что упрощает процесс сохранения в нашем объекте.

    Вместо того, чтобы помещать наш параметр $id непосредственно в строку SELECT , что увеличивает риск нарушения системы безопасности, мы используем:id . Такой параметр известен как placeholder (указатель места размещения) . Далее мы вызываем метод PDO для привязывания значение $id к указателю места размещения.

    Сразу после сохранения выражения SELECT в строке, мы подготавливаем его с помощью функции $conn->prepare() , сохраняя полученный дескриптор в переменной $st .

    Подготовка выражения используется для работы со многими базами данных. Она позволяет выполнять запросы быстрее и безопаснее.

    Затем мы привязываем значение переменной $id (ID нужной статьи) к указателю места размещения:id с помощью вызова метода bindValue() .

    И вызываем метод execute() для выполнения запроса. После чего используем метод fetch() для перемещения полученной записи в ассоциированный массив с именами полей и соответствующими значениями, который хранится в переменной $row .

    Закрываем соединение

    Так как нам больше не нужно соединение, мы закрываем его, присваивая значение null переменной $conn . Закрывать соединение с базой данных как можно быстрее является хорошей практикой для освобождения памяти на сервере.

    Возвращаем объект Article

    If ($row) return new Article($row); }

    Последним действием в нашем методе является создание объекта Article , который будет содержать запись из базы данных, и возвращение его вызывающему коду. Сначала проверяем наличие данных в переменной $row после вызова метода fetch() . Если данные есть, создаем новый объект Article передавая переменную ему $row . Будет вызван конструктор класса, который наполнит объект данными из массива $row . Затем возвращаем готовый объект и работа метода завершена.

5. getList()

Следующий метод getList() во многом похож на метод getById() . Основное отличие заключается в том, что метод getList() возвращает несколько статей сразу. Его используют, когда нужно вывести список статей для пользователя или администратора.

getList() принимает 2 аргумента:

$numRows Максимальное количество получаемых статей. По умолчанию установлено значение 1,000,000 (то есть, практически все статьи). Данный параметр позволяет нам получать только первые 5 статей для главной страницы. $order Порядок сортировки получаемых статей. По умолчанию используется параметр "publicationDate DESC" , который означает "сортировка по дате публикации, новые статьи первые".

Большая часть кода метода похожа на код метода getById() . Посмотрим на несколько строк:

$sql = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles ORDER BY " . mysql_escape_string($order) . " LIMIT:numRows";

Здесь запрос немного сложнее. Обратите внимание, что здесь не используется выражение WHERE , так как мы хотим получить все статьи, а не одну с заданным ID.

Также добавлено выражение ORDER BY для сортировки возвращаемых записей в определенном порядке. Используется выражение LIMIT с параметром $numRows (как указатель места размещения) для ограничения количества получаемых записей.

Специальное значение MySQL SQL_CALC_FOUND_ROWS указывает базе данных, что нужно вернуть действительное количество возвращаемых записей. Такая информация полезна для информирования пользователя и организации других функций, например, постраничного вывода списка.

Вместо передачи значения переменной $order в запрос через указатель места размещения, мы передаем его прямо в строку запроса, вызывая функцию mysql_escape_string() , чтобы отбросить любые специальные символы (для безопасности). Если использовать указатель места размещения, то PDO поместит кавычки (") вокруг строки (например, ORDER BY "publicationDate DESC"), что является ошибкой синтаксиса.

$list = array(); while ($row = $st->fetch()) { $article = new Article($row); $list = $article; }

Так как мы возвращаем несколько строк, нужно создать массив $list для размещения соответствующих объектов Article . Затем используем цикл while для получения следующей строки через fetch() , создаем новый объект Article , сохраняем строку в объекте и добавляем объект к массиву $list . Когда строк не останется, метод fetch() вернет false , и цикл остановится.

// Теперь получаем общее число статей, которые соответствуют критерию $sql = "SELECT FOUND_ROWS() AS totalRows"; $totalRows = $conn->query($sql)->fetch(); $conn = null; return (array ("results" => $list, "totalRows" => $totalRows));

В завершении мы выполняем запрос, который использует функцию MySQL FOUND_ROWS() для получения количества возвращаемых строк, вычисленного в предыдущей команде SQL_CALC_FOUND_ROWS . В этот раз используем метод PDO query() , который позволяет быстро выполнить запрос, если нет указателей места замещения. Мы вызываем метод fetch() для получения результата. Затем возвращаем оба значения - список объектов Article ($list) и общее количество строк - как ассоциированный массив.

6. insert()

Оставшиеся методы в нашем классе Article работают с добавлением, изменением и удалением записей статей в базе данных.

insert() добавляет новую статью в таблицу articles , используя значения из текущего объекта Article:

  • Сначала метод проверяет, что объект не имеет установленного свойства $id . Если у объекта есть ID, то, вероятно, статья уже имеется в базе данных и ее добавлять не нужно.
  • Затем метод выполняет запрос SQL INSERT для вставки записи в таблицу articles , используя указатели места замещения для передачи значений свойств в базу данных. Обратите внимание, что мы используем функцию MySQL FROM_UNIXTIME() для конвертации даты публикации в формат MySQL.
  • После выполнения запроса, метод возвращает ID новой статьи с помощью функции PDO lastInsertId() и сохраняет значение в свойстве $id . Мы установили в таблице articles для поля id свойство auto_increment , поэтому MySQL генерирует уникальное значение ID для каждой новой записи.

Обратите внимание, что мы используем PDO::PARAM_INT при привязке целых значений к указателям места замещения, и PDO::PARAM_STR при привязке строк. Таким образом, PDO может правильно обрабатывать значения.

7. update ()

Данный метод похож на метод insert() , за исключением того, что здесь происходит обновление записи в базе данных вместо создания новой записи.

Сначала проверяем наличие ID у объекта, так как обновить можно только запись с известным ID. Затем используем выражение SQL UPDATE для обновления полей записи. Обратите внимание на передачу ID объекта в выражение UPDATE , так как мы знаем, какую запись надо обновить.

8. delete ()

Метод delete() использует выражение SQL DELETE для удаления из таблицы articles статьи, которая хранится в объекте. Для идентификации записи задействуем свойство $id объекта. Для безопасности мы добавили LIMIT 1 к запросу, чтобы ограничиться удалением только одной записи.

В следующем уроке мы создадим скрипты для клиентской и серверной части нашего приложения.

Каждую страницу которая заканчивается на / можно открыть и через /index.php. Думаю, каждый более-менее уважаемый вебмастер это знает и вдаваться в подробности не стоит. Мы думаем, что это не сильная проблема как для людей, так и для поисковых роботов. Но все же, что-бы было на 100% правильно, давайте сделаем так, что если страница открывается через слэш, то ее нельзя было открыть через /index.php или /index.html. Естественно, везде должен отадаваться 301 редирект. чтобы ранее проставленные ссылки не теряли свой вес.


Результат работы скрипта

Как забирать окончание /index.php в Битриксе

Битрикс самая популярная коммерческая CMS, да и мы ее используем, поэтому давайте рассмотрим пример на ней. Многие вебмастера пытаются решить подобную задачу через php, записав код в init.php. но тут возникает 2 ошибки:

  • Редирект не будет работать при композите, потому что композит не грузит ядро битрикса;
  • Большая нагрузка на сервер, т.к. запускается Apache для редиректа.

Вообщем, правильно делать такой редирект исключительно через.htaccess файл. Откроем файл.htaccess, который лежит в корне битрикса и просто добавим 2 строчки кода. RewriteBase / нужно дописать после RewriteEngine On, а в конец всех правил добавим RewriteRule ^(.*)index\.php$ $1 . Естественно, все в конструкции должно лежать. Код:

Options +FollowSymLinks RewriteEngine On #Добавил RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-l RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !/bitrix/urlrewrite.php$ RewriteRule ^(.*)$ /bitrix/urlrewrite.php [L] RewriteRule .* - #Добавил RewriteRule ^(.*)index\.php$ $1

Забирать окончание /index.php через.htaccess

Если у вас не битрикс, то в корне сайта в.htaccess файле (если его нет, то создайте) нужно добавить такой код:

RewriteEngine On RewriteBase / RewriteRule ^(.*)index\.php$ $1

Надеюсь вы решили вашу задачу!

При разработке Web-приложений мы обязательно сталкиваемся с проблемами рендеринга HTML-страниц. Обычно эти проблемы решает шаблонизатор - собственно PHP или какой-нибудь парсер шаблонов. Если приложение большое и страницы содержат множество блоков, то сложность шаблонов может резко возрасти, а у разработчиков появляется желание упростить работу с ними. В ход идут разные техники, но обычно это выделение в шаблонах повторяющихся блоков и правильная их декомпозиция - включая наследование шаблонов.

Мне нравится, как сделано наследование шаблонов в Django . Идея простая - есть базовый шаблон, в нем выделены контентные блоки, которые будут меняться в зависимости от страницы. При рендеренге страницы можно указать, что за основу берется базовый шаблон и переопределить только нужные блоки. Если в проекте много однотипных страниц, то можно сделать промежуточный шаблон, наследующий от главного, а затем переопределять его данные. При умелом проектировании количество повторяющегося кода можно свести на нет, а также облегчить жизнь при изменении дизайна.

Похоже этот подход нравится не только мне и разработчикам Django, но и Fabien Potencier автору фреймворка Symfony и шаблонизатора Twig . Twig обладает множеством интересных функций, включая компиляцию шаблонов в нативные PHP-классы, фильтрацию данных, встроенными циклами и т.д. - в общем всем тем, что полагается иметь современному шаблонизатору. Но самое интересное - это то самое наследование шаблонов, о котором я говорил выше. Вот пример из официальной документации:

Базовый шаблон:

{% block head %} {% block title %}{% endblock %} - My Webpage {% endblock %}

{% block content %}{% endblock %}

Дочерний шаблон:

{% extends "base.html" %} {% block title %}Index{% endblock %} {% block head %} {{ parent() }} {% endblock %} {% block content %}

Index

Welcome on my awesome homepage.

{% endblock %}

В базовом шаблоне определены основные блоки, а в дочернем - пример их переопределения. Копания в исходных кодах показало, что реализуется это наследование также нативно - путем наследования “скомпилированных” классов. Отличная идея! Все хорошо, но меня несколько смущала необходимость изучения пусть простого, но все-таки отличного от PHP синтаксиса шаблонизатора. А моя нелюбовь к ненативным шабонам началась еще со Smarty (в котором тоже есть наследование) и до сегодняшнего дня не претерпела существенных изменений.

Совсем близко к иделу подошел разработчик из Сан-Франциско Adam Shaw . Очевидно, он также как и я не любит эксперименты с синтаксисом шаблонизаторов и придумал незамысловато названную библиотеку Template Inheritance На сайте жирным по желтому написано, что «There is no need to learn another template language», мол не нужно учить другой язык шаблонов. С этим я согласен. Что же он предлагает? Смотрим пример опять же из официальной документации:

Базовый шаблон:

Дочерний шаблон:

This is the title This is the article

Синтаксис натуральный, блоки выделены явно, подключил библиотеку в базовый шаблон и забыл. Все. Автор говорит, что сделал это с помощью буферов и стека (возможны вложенные блоки). Код действительно интересный, но пестрит наличием глобальных переменных. Чего же остается ещё желать?

Вот здесь-то мы и подходим к главной теме нашего повествования. А не сможет ли PHP сам переопределить блоки базового шаблона? Я думаю, что вполне! Смотрите:

Вот базовый шаблон:

<?php echo isset($title) ? $title: ""; ?>

Default content

Здесь в 3 блоках шаблона проверяется наличие соответствующей переменной, хранящей некоторый контент и, если она присутствует в области видимости, то ее можно выводить в шаблон, а если нет, то выводится контент по-умолчанию. Нам остается только переопределить эти переменные в дочернем шаблоне. А вот собственно и он:

Переопределенный контент

В этом примере переопределяется переменная $content, если она не была установлена заранее. Это сделано для того, чтобы была возможность наследовать этот шаблон и переопределить блок контента. Думаю, идея понятна. Не требуется никаких библиотек - просто пишите шаблоны в таком стиле и будет вам счастье.

Конечно, и здесь не обошлось без недостатков. Во-первых, это не очень лаконичный синтаксис определения и переопределения блоков: расплата за нативность. Во вторых, в дочернем шаблоне нельзя получить код родительского блока. В-третьих, при таком способе включения шаблонов перед собственно HTML-кодом может образоваться некоторое количество пробелов из-за отступов между блоками. Здесь я бы посоветовал подключать шаблон также с помощью буферов и фильтровать контент. Так делается во многих фреймворках:

Function render($pathToTemplate, $data) { extract($data); ob_start(); require $pathToTemplate; return trim(ob_get_clean()); }

Эта функция возвращает вывод шаблона из файле $pathToTemplate с подстановкой переменных, полученных из массива $data. extract - на любителя - можно и не делать, а обращаться напрямую к $data. Перед выводом из контента убираются начальные и конечные пробелы. В шаблоне можно делать все, что позволит делать ваша совесть, не нарушая принципы разделения логики и представления, и PHP. Например, в зависимости от ситуации подключать тот или иной базовый файл.

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

Hair loss medication, Propecia (finasteride) may be linked to a side effect of sexual dysfunction, a problem which may not go away after treatment has stopped , researchers from George Washington University reported in the Journal of Sexual Medicine . Propecia is a popular medication taken for male pattern hair loss .

Michael S. Irwig MD, who works at the Center for Andrology and Division of Endocrinology, The George Washington University, Washington, DC, prospectively monitored 54 adult males, average age 31, who had had three or more months of finasteride-associated sexual side effects. A side effect that continues for over three months is described as "persistent".

All the men were healthy at the start of the study, and had never had any problems with sexual functions; they had no medical or psychiatric conditions and had not used oral prescription drugs before taking Propecia for male pattern hair loss.

All the men in this study were checked and rechecked for 14 months.

96% of those who were reassessed still had persistent sexual side effects; some of them also had changes in cognition, genital sensation, and ejaculate quality.

Dr. Irwig found that 89% of the 54 men met the Arizona Sexual Experiences Scale (ASEX) of sexual dysfunction, which rates sex drive (libido), arousal, penile erection, ability to orgasm, and orgasm satisfaction.

In an Abstract in the same journal, Dr. Irwig concluded:

"In most men who developed persistent sexual side effects (≥3 months) despite the discontinuation of finasteride, the sexual dysfunction continued for many months or years.

Although several rat studies have shown detrimental changes to erectile function caused by 5 alpha reductase inhibitors, the persistent nature of these changes is an area of active research.

Prescribers of finasteride and men contemplating its use should be made aware of the potential adverse medication effects."


What is Propecia (finasteride)?

Finasteride is a synthetic 5α-reductase inhibitor. It is an inhibitor of the enzyme that coverts testosterone to DHT (dihydrotestosterone). It is produced and marketed by Merck & Co., Inc. It is known under the brand names Proscar and Propecia and has been approved by the FDA for the treatment of:
  • Male pattern baldness - hair is lost in a well defined pattern, starting above the temples and thinning at the crown of the head.

  • Benign prostatic hyperplasia - an increase in the size of the prostate
Reported side effected related to finasteride include:
  • Erectile dysfunction (impotence)
  • Abnormal ejaculation
  • Lower ejaculatory volume
  • Abnormal sexual function
  • Testicular pain
  • Gynecomastia - development of male breasts
  • Depression - Merck added this side effect in December 2010
Prostate cancer - The FDA added a warning that finasteride may raise the risk of high-grade prostate cancer . No clear link has been established between finasteride use and prostate cancer risk. Some studies have suggested it may reduce the prevalence and growth of benign prostate tumors. However, finasteride can also mask the early detection of prostate cancer.

A 2008 study found that finasteride reduces prostate cancer risk without boosting the chances of developing aggressive tumors. ()

Аннотация : В статье рассматриваются вопросы, связанные с проведением в сентябре 2014 г. референдума о независимости Шотландии. Автор освещает основные этапы деволюционного движения в Шотландии с тем, чтобы выявить предпосылки происходящих сейчас событий. Затем исследуется отношение населения региона к идеям независимости, для того чтобы попытаться спрогнозировать исход предстоящего референдума. В целях прогнозирования и понимания будущих процессов в регионе, автор представляет основные плюсы и минусы более радикального варианта развития событий - отделения Шотландии от Великобритании. В статье использованы, как теоретические методы - анализ и синтез, так и исторический (рассмотрение процессов деволюции в исторической ретроспективе), а так же практические: мониторинг и прогнозирование (попытка предсказать исход референдума с помощью наличия определенных количественных данных). Анализ возможных последствий отделения региона показал, что независимость приведет к множеству как положительных, так и негативных моментов в политической и социально-экономической сферах жизни шотландского общества. Изучив отношение населения к идеям независимости региона за последние 35 лет, автор заключает, что Шотландия останется в составе Великобритании, но с предоставлением ее институтам власти еще больших полномочий в будущем.

Ключевые слова : независимость, референдум, деволюция, отношение к независимости, плюсы отделения Шотландии, минусы отделения Шотландии, политические аспекты, социально-экономические аспекты, Шотландская Национальная партия, этнический сепаратизм

DOI : 10.7256/1812-8696.2014.7.12577

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

Библиография:
Еремина Н. В. Проблема развития региональных инноваций: фактор культурно-исторического наследия в отношениях «центр-периферия» (на примере национальных регионов Великобритании) // Политика как фактор инновационного развития. Материалы международной научной конференции / Под ред. А.Ю. Сунгурова. СПб., 2010.
Еремина Н. В. Проблема статуса Шотландии в 90-е гг. XX в. Спб.: Изд-во С.-Петерб. Ун-та, 2005.
Кагриманян А. С. Экономические факторы периферийного сепаратизма в Европе // Федерализм. – 2014.-№ 1 (73).
Curtis J., Steven M. The 2011 Scottish parliament election. The electoral reform society. London, 2011.
Keating M. The Government of Scotland: Public Policy Making After Devolution. Edinburgh, 2010.
Kellas J. G. The Scottish political system. New York, 1973.
McLean I., Gallagher J., Lodge G. Scotland"s Choices: The Referendum and what Happens Afterwards. Edinburgh, 2013.
Philips D. Government spending on benefits and state pensions in Scotland: current patterns and future issues. Institute for fiscal studies. London, 2013.
Pilkington C. Devolution in Britain today. Manchester, 2002.
Smith K. Beyond Evidence Based Policy in Public Health: The Interplay of Ideas. Basingstoke.: Palgrave Macmillan, 2013.

Правильная ссылка на статью:
просто выделите текст ссылки и скопируйте в буфер обмена
Кагриманян А.С. Независимость Шотландии: быть или не быть. // Политика и Общество. - 2014. - № 7. - C. 745-752. DOI: 10.7256/1812-8696.2014.7.12577