Определение класса и его свойства. Соединение с базой данных

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. ()

And those on Linux Systems can use LAMP or MAMP for Mac OS users. Another way to have all this is to have a virtual web server. You can install one yourself using VMware or Oracle VM VirtualBox. For those who are advanced in web servers stuffs, I believe Vagrant will be the best for you.

At the end of the day, what matters is for you to have a running server that has php and a database that you can connect to.

Since PHP 5.5.0, the mysql extension is deprecated I will be using PDO. So if you don"t have PDO extension activated you can do it now. Or if could also use Mysqli instead. I have decided to use PDO to make the tutorial more universal because in the first version of it, many people had problems with mysql and were encounters a lot of errors.

Structure of the site

Here I will be creating a very simple website that will display a list of our recent news posts ordered by date.

For each post we"ll be displaying its title, short description, the date of publication and the author"s name. The title will be a URL that links us to another page that will display the full content of the news(See image bellow).

On the page displays the full artile, we"ll also list other articles so that the user can easily read another news without going page to the home page. We will also provide a link to go back to the home page.

Database model and structure of tables

Create a new database and name it news or something else. We will at this level have only one table in our database. The table will contain all our news. I named the table info_news ; you can name anything you want what matters is the structures.

So create your database and create following table in it.

  • Table structure for table info_news
CREATE TABLE IF NOT EXISTS "info_news" ("news_id" int(11) NOT NULL AUTO_INCREMENT, "news_title" varchar(255) NOT NULL, "news_short_description" text NOT NULL, "news_full_content" text NOT NULL, "news_author" varchar(120) NOT NULL, "news_published_on" int(46) NOT NULL, PRIMARY KEY ("news_id")) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

This is the table"s model:

You may be wondering how I got the structure of this table. The helped me understand different information I need on each news article

Files & folders structure

For this project I will be using two main files: index.php and read-news.php .

Since I want to make the project as simple as possible just to show you the concept, I won"t be using a or adopt an design pattern.

But, I want to keep my code clean; so I will be using a different file that will contain my database connection (dbconnect.php ) and another file(functions.php ) that will contain some set of functions we will create and use them in the project.

At the end, our folder structure should be like follow:

  • News/
    • config/
      • dbconnect.php
    • includes/
      • functions.php
    • design/
      • style.css
  • index.php
  • read-news.php

Check out my own folder bellow:

Files content (codes)

To start, we"ll require the db.connect.php in functions.php because we will the database instance in our functions. Then in index.php and read-news.php we"ll require the functions.php because we will need those functions in them.

  • File config/dbconnect.php

setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); return $pdo; } catch (PDOException $e){ $e->getMessage(); } }

  • File includes/functions.php

This file contains all function we will need in the project. The number of functions may increase as the project grows.

prepare(" SELECT news_id, news_title, news_short_description, news_author, news_published_on FROM info_news ORDER BY news_published_on DESC "); return $request->execute() ? $request->fetchAll() : false; } function getAnArticle($id_article, $conn) { $request = $conn->prepare(" SELECT news_id, news_title, news_full_content, news_author, news_published_on FROM info_news WHERE news_id = ? "); return $request->execute(array($id_article)) ? $request->fetchAll() : false; } function getOtherArticles($differ_id, $conn) { $request = $conn->prepare(" SELECT news_id, news_title, news_short_description, news_full_content, news_author, news_published_on FROM info_news WHERE news_id != ? "); return $request->execute(array($differ_id)) ? $request->fetchAll() : false; }

  • File index.php without PHP

Welcome to news channel

Latest news

First news title here

Second news title here

This news short description will be displayed at this particular place. This news short description will be displayed at this particular place.

published on Jan, 12th 2015 by zooboole

Thirst news title here

This news short description will be displayed at this particular place. This news short description will be displayed at this particular place.

published on Jan, 12th 2015 by zooboole

Fourth news title here

This news short description will be displayed at this particular place. This news short description will be displayed at this particular place.?= date("Y") ?> - all rights reserved.

Note: Each news has a specific URL that links it to the read-news.php page like this:

News title

where x is a number

The x represent the unique id of that particular article. So the read-news.php?newsid=x tells the read-news.php page to display a news that has the id x .

Now in this file we want the news to be fetched and displayed from the database dynamically. Let call the function fetchNews() . To do that let"s replace every thing in

...

by the following:

$article) :?>

news_id ?>">news_title) ?>

news_short_description) ?>

published on news_published_on) ?> by news_author) ?>

  • File read-news.php

Welcome to news channel

Latest news

Welcome to the demo news site. We never stop until you are aware.

return to home page
0) { // Fecth news $article = getAnArticle($id_article, $dbh); $article = $article; }else{ $article = false; echo "Wrong article!"; } $other_articles = getOtherArticles($id_article, $dbh); ?>

news_title) ?>

published on news_published_on) ?> by news_author) ?>
news_full_content) ?>

Other articles

$article) :?>

news_id ?>">news_title) ?>

news_short_description) ?>

published on news_published_on) ?> by news_author) ?> - all rights reserved.

  • The file design/style.css

Html, body { font-family: verdana; font-size: 16px; font-size: 100%; font-size: 1em; height: 100%; width: 100%; margin: 0; padding: 0; background-color: #4DDEDF; } * { box-sizing: border-box; } a{ text-decoration: none; color: #4DDED0; } .welcome { width: 800px; margin: 2em auto; padding: 10px 30px; background-color: #ffffff; } .welcome a { display: inline-block; width: 200px; border: 2px solid #0DDED0; padding: 0.5em; text-align: center; } .welcome h1 { margin: 0; color: #555; } .news-box { width: 800px; margin: 0.5em auto; padding: 30px; background-color: #ffffff; } .news-box h2 { font-size: 1.3em; padding: 0; margin-bottom: 0; color: #e45; } .news-box p { font-size: 12px; padding: 0; margin-bottom: 0.3em; color: #555; } .news-box span { font-size: 10px; color: #aaa; } .footer { font-size: 10px; color: #333; text-align: center; width: 800px; margin: 2em auto; padding: 10px 30px; }

Room for improvement

Indeed, this is a very basic way of making a news website. It doesn"t have any professional aspect like serious news sites do. But, we should know that this is a great basement to start with. The point here is mostly to show you how to retrieve data from a database and display it.

So, to make this tutorial complete, these are some functionalities one could add:

  • an admin panel to manage news (add, edit, delete,etc),
  • categorize your news,
  • inhence the design,
  • add comments system under each article we are reading,
  • news scheduling

There is lot one can do to make such system complete. It"s left with you to decide of what to add or how you can use it for other goals.

Conclusion

Voila. We are at the end of this little tutorial. We have created a simple news system that displays a list of articles and when we click on an article"s title we are taken to a reading page that uses the article"s id to retrieve dynamically the whole content of that article.

It"s a very simple system, but with it you can improve your skills in PHP/MYSQL applications. It was also an opportunity to introduce a bit how to use PDO.

So, if you have any question or you are meeting some errors, just comment down here. Check out the , and you can also file of the source code with comments

Сначала создадим файл index.php , который будет содержать скрипт клиентской части, то есть выводить страницы в браузере пользователя. Копируем ниже приведенный код и сохраняем файл в корневом каталоге нашей CMS cms.

title . " | Widget News"; require(TEMPLATE_PATH . "/viewArticle.php"); } function homepage() { $results = array(); $data = Article::getList(HOMEPAGE_NUM_ARTICLES); $results["articles"] = $data["results"]; $results["totalRows"] = $data["totalRows"]; $results["pageTitle"] = "Widget News"; require(TEMPLATE_PATH . "/homepage.php"); } ?>

Разберем код скрипта подробно.

  1. Включаем файл конфигурации

    Первая строка кода включает файл config.php , и все установки приложения становятся доступны в скрипте. Мы используем функцию require() , а не include() , так как require() генерирует ошибку в случае отсутствия подключаемого файла.

  2. Получаем параметр action

    Сохраняем параметр $_GET["action"] в переменной $action , чтобы можно было использовать значение далее в скрипте. Но прежде проверяем наличие значения $_GET["action"] с помощью функции isset() . Если его нет, устанавливаем для переменной $action пустую строку ("").

    Проверять значения, поставляемые пользователем (такие как строки, значения из форм, куки), на наличие перед использованием - хорошая практика программирования. Так не только ограничивается количество дырок в системе безопасности, но и предотвращает вывод предупреждения "undefined index" при выполнении скрипта.

  3. Блок switch проверяет параметр action в URL для определения нужного действия (вывести архив, просмотреть статью). Если параметр action отсутствует в URL, то скрипт выводит главную страницу.

  4. archive()

    Данная функция выводит список всех статей в базе данных. Для этого используется метод getList() класса Article . Функция сохраняет результат и заголовок страницы в ассоциированном массиве $results , и шаблон может вывести его на странице. В завершении включается шаблон для вывода страницы. (Мы рассмотрим шаблоны в другом уроке нашей серии.)
  5. viewArticle()

    Данная функция выводит страницу одной статьи. Она получает ID статьи для вывода из параметра URL articleId , затем вызывает метод класса Article getById() для получения объекта статьи, который сохраняется в массиве $results для использования в шаблоне. (Если нет параметра articleId или статья не может быть найдена, то функция просто выводит главную страницу.)

    Обратите внимание, что мы используем преобразование типов (int) для явного приведения параметра запроса articleId к целому типу. Такое действие предотвращает передачу отличных от чисел значений в наш код.

  6. homepage()

    Последняя функция homepage() выводит главную страницу сайта, на которой содержится список из нескольких статей, количество которых указано в параметре конфигурации HOMEPAGE_NUM_ARTICLES (по умолчанию 5). Функция очень похожа на функцию archive() за исключением передачи параметра HOMEPAGE_NUM_ARTICLES методу getList() для ограничения количества возвращаемых статей.

2. Серверная часть

Скрипт серверной части несколько сложнее, чем index.php , так как в нем реализованы функции администрирования для нашей CMS. Хотя основная структура похожа на index.php .

Создаем файл admin.php в том же каталоге, что и файл index.php . И копируем в него код:

storeFormValues($_POST); $article->insert(); header("Location: admin.php?status=changesSaved"); } elseif (isset($_POST["cancel"])) { // Пользователь сбросил результаты редактирования: возвращаемся к списку статей header("Location: admin.php"); } else { // Пользователь еще не получил форму редактирования: выводим форму $results["article"] = new Article; require(TEMPLATE_PATH . "/admin/editArticle.php"); } } function editArticle() { $results = array(); $results["pageTitle"] = "Edit Article"; $results["formAction"] = "editArticle"; if (isset($_POST["saveChanges"])) { // Пользователь получил форму редактирования статьи: сохраняем изменения if (!$article = Article::getById((int)$_POST["articleId"])) { header("Location: admin.php?error=articleNotFound"); return; } $article->storeFormValues($_POST); $article->update(); header("Location: admin.php?status=changesSaved"); } elseif (isset($_POST["cancel"])) { // Пользователь отказался от результатов редактирования: возвращаемся к списку статей header("Location: admin.php"); } else { // Пользвоатель еще не получил форму редактирования: выводим форму $results["article"] = Article::getById((int)$_GET["articleId"]); require(TEMPLATE_PATH . "/admin/editArticle.php"); } } function deleteArticle() { if (!$article = Article::getById((int)$_GET["articleId"])) { header("Location: admin.php?error=articleNotFound"); return; } $article->delete(); header("Location: admin.php?status=articleDeleted"); } function listArticles() { $results = array(); $data = Article::getList(); $results["articles"] = $data["results"]; $results["totalRows"] = $data["totalRows"]; $results["pageTitle"] = "All Articles"; if (isset($_GET["error"])) { if ($_GET["error"] == "articleNotFound") $results["errorMessage"] = "Error: Article not found."; } if (isset($_GET["status"])) { if ($_GET["status"] == "changesSaved") $results["statusMessage"] = "Your changes have been saved."; if ($_GET["status"] == "articleDeleted") $results["statusMessage"] = "Article deleted."; } require(TEMPLATE_PATH . "/admin/listArticles.php"); } ?>

Рассмотрим интересные места нашего скрипта:

  1. Старт сессии пользователя

    В начале скрипта мы вызываем функцию session_start() . Данная функция PHP запускает новую сессию пользователя, которая позволяет нам контролировать регистрацию пользователя в системе. Если сессия для пользователя уже имеется, то PHP автоматически возобновит ее и будет использовать.

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

  2. Получаем параметр action и переменную сессии username

    Затем мы сохраняем параметр $_GET["action"] в переменной $action , а переменную сессии $_SESSION["username"] в $username , чтобы затем использовать данные значения в скрипте. Перед сохранение осуществляем проверку с помощью функции isset() . Если значение не существует, устанавливаем в соответствующей переменной пустую строку ("").

  3. Проверяем, зарегистрирован ли пользователь

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

  4. Определяем действие для выполнения

    Блок switch работает так же как и в index.php: производится вызов соответствующей функции на основании значения параметра URL action . По умолчанию выводится список статей.

  5. login()

    Функция вызывается, когда нужно произвести регистрацию пользователя в системе.

    Если пользователь отправил форму регистрации (что проверяется по параметру формы login), то функция сопоставляет введенные имя и пароль со значениями параметров конфигурации ADMIN_USERNAME и ADMIN_PASSWORD . Если они соответствуют, то мы устанавливаем ключ сессии username в значение имени администратора, а затем перенаправляем обратно скрипту admin.php , который выводит список статей. Если пароль и имя пользователя неверные, то будет выведена форма регистрации с сообщением об ошибке.

    Если пользователь еще не отправил форму регистрации, то просто выводим ее.

  6. logout()

    Данная функция вызывается, когда пользователь выходит из системы. Здесь просто удаляется ключ сессии username и производится перенаправление обратно в admin.php .

  7. newArticle()

    Данная функция позволяет пользователю создавать новую статью. Если пользователь уже отправил форму для новой статьи, то функция создает новый объект Article , сохраняет данные формы в объекте с помощью вызова функции storeFormValues() , вставляет статью в базу данных с помощью функции insert() и перенаправляет обратно на список статей, выводя сообщение об успешном завершении операции.

    Если пользователь не отправил форму для новой статьи, то функция создает новый пустой объект Article без значений, затем использует шаблон editArticle.php для вывода формы редактирования статьи для только что созданного объекта.

  8. editArticle()

    Данная функция похожа на newArticle() , за исключением того, что пользователю предоставляется возможность редактировать статью. Когда пользователь сохраняет изменения, функция получает существующую статью с помощью getById() , записывает новые значения в объекте Article , затем сохраняет измененный объект с помощью функции update() . (Если статья не найдена в базе данных, функция выведет сообщение об ошибке.)

    Когда выводится форма редактирования статьи, функция использует метод getById() для загрузки текущих значений в поля формы.

    Скрипт использует один и тот же шаблон (editArticle.php) и для создания новой статьи и для редактирования имеющейся. То есть нужно создавать только одну форму HTML. Параметр formAction используется для определения операции со статьей.

  9. deleteArticle()

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

  10. listArticles()

    Последняя функция функция в скрипте admin.php выводит список статей в CMS. Используется метод getList() класса Article для получения всех статей. Затем применяем шаблон listArticles.php для вывода списка. Кроме того, функция проверяет параметры запроса URL error и status , чтобы вывести сообщения об ошибке и состоянии системы, если нужно.

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

Каждую страницу которая заканчивается на / можно открыть и через /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

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

Многих интересует вопрос, как перенести сайт и БД на новый хостинг или с тестовой локальной машины на рабочий сервер? Внимательно читаем инструкцию.

Для переноса сайта с одного хостинга на другой, или с тестовой локальной машины на рабочий сервер выполните следующие действия:
1. Копируем содержимое всех файлов XOOPS, включая xoops_lib и xoops_data. Лучше архивировать прямо на сервере (локальной машине), легче будет скачать/заливать;
2. Создаём дамп базы данных на старом/локальном сервере;
2.1. Заходим в phpMyAdmin и выбираем нужную базу данных;
2.2. Нажимаем на вкладку "Экспорт" [рис. 1]

Рис. 1

2.3. Выбираем способ экспорта "Быстрый - отображать минимум настроек" нажимаем ok и скачиваем дамп [рис. 2]. В старых версиях нужно указать "Сохранить как файл".

Рис. 2

3. Создаём на новом сервере базу данных для сайта. При создании указываем кодировку utf8. [рис. 3]

Рис. 3

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

3.1. Заходим в созданную базу данных и выбираем вкладку "Операции". Здесь мы должны указать кодировку сравнения [рис. 4 ]. Этот шаг можно пропустить, если вы указали кодировку при создании базы данных.

Рис. 4

4. Импортируем созданный на втором шаге дамп базы данных на новый хостиг.
4.1. Заходим в phpMyAdmin и выбираем созданную базу данных.
4.2. Переходим во вкладку "Импорт", выбираем дамп базы данных с локального компьютера, кодировка файла utf-8, и нажимаем ok. [рис. 5]

Рис. 5

5. Закачиваем на новый сервер архив с файлами XOOPS и распаковываем его.
6. Следующим дирректириям устанавливаем права на запись (UNIX 777):
uploads/
uploads/avatars/
uploads/images/
uploads/ranks/
uploads/smilies/
xoops_lib/modules/protector/configs/
xoops_data/caches
xoops_data/caches/xoops_cache
xoops_data/caches/smarty_cache
xoops_data/caches/smarty_compile
xoops_data/configs
xoops_data/data
7. Редактируем конфигурационные файлы;
7.1. Открываем файл /mainfile.php и редактируем следующие строки:
7.1.1. Полный путь до папки XOOPS на новом сервере: define("XOOPS_ROOT_PATH", "C:/xampp/htdocs/xoops");
7.1.2. Полный путь до папки xoops_lib на новом сервере (из соображений безопасности её необходимо вынести в не корня сайта): define("XOOPS_PATH", "C:/xampp/htdocs/xoops/xoops_lib");
7.1.3. Полный путь до папки xoops_data на новом сервере (из соображений безопасности её необходимо вынести в не корня сайта): define("XOOPS_VAR_PATH", "C:/xampp/htdocs/xoops/xoops_data");
7.1.4. HTTP адрес сайта: define("XOOPS_URL", "http://сайт");
7.2. Открываем файл /xoops_data/data/secure.php и редактируем следующие строки:
7.2.1. Хост сервера базы данных (оточняйте у хостинг провайдера): define("XOOPS_DB_HOST", "localhost");
7.2.2. Пользователь созданной базы данных: define("XOOPS_DB_USER", "xoops_user");
7.2.3. Пароль созданной базы данных: define("XOOPS_DB_PASS", "xoops_pass");
7.2.4. Имя созданной базы данных: define("XOOPS_DB_NAME", "xoops_2.5.5_new");
8. На файлы /mainfile.php и /xoops_data/data/secure.php ставьте права только для чтения (UNIX 444)
9. Открываем сайт в браузере, в нашем случае это