Створення алиасов і редиректів. Apache

Створення алиасов і редиректів. Apache

Привіт всім читачам!

Сьогодні ми розглянемо досить важливу тему, яка висувається багатьма роботодавцями, а саме багатомовність.

Що ж я мав на увазі, кажучи про багатомовності. Ну, напевно кожен із моїх високоповажних читачів не раз бачили круті портали і між усім сбродом інформації знаходили дві маленькі іконки, переважно з усім відомим зоряно-смугастим і рідним біло-синьо-червоним прапорами. Безумовно, після натискання на одну з них звична нам російська мова перетворювалася в буржуйський language (), або навпаки. Але задавали ви собі коли-небудь питання про те, як це все робиться. Що ж, саме про це я і буду вести мову.

Відразу скажу, що для роботи з тим матеріалом, який буде тут викладено вам знадобитися підтримка РНР не нижче 4.39.

Отже, як ви знаєте, зміст нашого сайту розділяється на динамічне і статичне. До статичному змістом ми віднесемо те, що не змінюватиме своє значення в процесі роботи (ключові слова, текст помилок, і інша нісенітниця). З цього ми і почнемо. Але давайте проаналізуємо, як саме ми будемо змінювати мову даного текстового значення. Сподіваюся, ніхто не запропонував скористатися винятками, бо це настільки нераціонально, що нераціонально і бути не може. Замість цього я пропоную скористатися константами (про тип даних читайте на php.net). Ми просто будемо оголошувати службове слово, яке в залежності від значення мови відповідно буде міняти і своє значення. Як ми це зробимо? Так як і всі, створимо два (наприклад) різних файлу, імена яких будуть носити такий шаблон:

Язик_map.php;

Як ви вже зрозуміли замість слова `язик` ми підставимо значення, що характеризує даний мову. У нашому випадку ми будемо використовувати однорядкове резюме код мови (ru, en, ua, pl і т.д.).

Що ж теорію з'ясували тепер давайте, застосуємо наші знання на практиці. Створюємо два файли. Я створив файли з англійським перекладом і російським, а як створите ви це вже на ваш смак.

Файл: en_map.php

Файл: ru_map.php

Отже, на мій погляд, нічого складного немає, і все написане підпорядковується самим банальним законам РНР. Спочатку ми робимо перевірку, чи не були константи вже оголошені, якщо були, то чи не оголошуємо, в іншому ж випадку оголошуємо.

Це була легка частина, тепер давайте перейдемо до більш складної теми - до переведення динамічної частини.

Припустимо, у вас є велика портальна система або простий сайт, але ви, талановитий програміст знає всі аспекти РНР, не є його власником, а зробили його під замовлення. Власником же є повним дизайнером (), яка не слухом, що не духом про якісь там програмістів тонкощах, але у нього є одне лише бажання, щоб все працювало, і він міг змінювати все. Щодо всього, це вже інша історія, а ось мовні параметри сайту ми йому все-таки дозволимо змінити (та що там, чим би дитя не тішилося).

Але знову повертаючись до проблеми про "дизайнерів і програмістів" потрібно знову згадати що такий сайт повинен повністю бути, так би мовити "Що Бачиш Те І Отримаєш", інакше не можна. Тому я постараюся зробити все так, щоб воно не викликало нервового тику у програмістів, і могло задовольнити дизайнерів (мається на увазі юзабіліті).

Отже, геть порожні слова і вперед на Берлін. Ми почнемо з теорії. Отже, як же ми будемо розрізняти мови у динамічного змісту, яке в кращому випадку видаляється, змінюється, а то і чого хорошого взагалі накриється. Константами тут ніяк не обійтися, що ж робити?

Я вже чую витають навколо вас думки.

Особисто коли я намагався втілити це в життя, то спочатку я це зробив самим нераціональним способом, а саме для перекладу статей розділив поля в таблиці, які підлягали переведенню надвоє (тобто, створив поле_eng і поле_ru) таким чином, і так великі за обсягом таблиці перетворилися просто в непристойно величезні. Тому я почав шукати альтернативу, і не повірите, знайшов її. Чи відчуваєте вже тепліше, та, скоро ми підійдемо до самого гарячого. Я знайшов виходу з цієї ситуації, і зараз має намір пояснити на пальцях його вам, і то зрозумієте ви його чи ні, буде залежати від вас. Спочатку давайте, узгодимо всі деталі.

Для початку нам потрібна, буде таблиця, в якій будуть розміщуватися дані для перекладу. Скажімо у нас є таблиця `articles` в якій будуть розміщені деякі статті, і вони повинні мати, скажімо, два переклади, але один обов'язково. Нас будуть цікавити лише два ключових, в нашому випадку, поля: назва, опис. Ми будемо здійснювати структурування тексту таким чином:

<%eng%>Англійський варіант статті <%ru%>Російський варіант статті

Після рядок у вигляді комбінації з цих двох структур і буде додаватися в поля `title` і` description` таблиці `articles`.

Даний спосіб буде полягати в пошуку першого входження відкриває ключового слова (припустимо<%eng%>), Після ми знайдемо перше входження закриває ключового слова. Але потрібно не забувати що нам потрібно не саме входження, а довжина конструкції. У першому випадку ми до першого входження відкриває конструкції будемо додавати довжину конструкції, другим кроком буде знаходження довжини закриває конструкції. Але ви запитаєте:<Как же мы получим текст?>.

Скориставшись функцією substr (). В якості першого параметра буде сам текст, в якості другого довжина відкриває конструкції, в якості третьої (найцікавіше) різниця між першим входженням закриває конструкції і довгою тексту. Так, розумію це не так легко, але це потрібно зрозуміти. Тому ми зараз це і виконаємо на практиці. Я створив функцію, яка буде виділяти текст між ключовими тегами. Вона буде приймати три параметра: текст для розбору, мова за яким потрібно проводити парсинг, масив конструкцій.

","<%/","%>")) ($ Start_tag \u003d strpos ($ data, $ delimiters. $ Lang. $ Delimiters) + strlen ($ delimiters. $ Lang. $ Delimiters); $ count \u003d (strpos ($ data, $ delimiters. $ Lang. $ delimiters) -strlen ($ data)) $ data \u003d substr ($ data, $ start_tag, $ count); if (trim ($ data) \u003d\u003d "") ($ data \u003d NOT_ENTERED;) return $ data;)?\u003e

Як бачите досить довго і можна заплутатися, але якщо ви і не зрозуміли цього, то це не велика біда, бо функція для перебору вже є, а трохи далі я розгляну інший метод для цієї ж мети. Так, і не забудьте десь оголосити мовну константу NOT_ENTERED, яка буде присвоюватися результату роботи функції в разі, якщо довжина тексту дорівнює нулю.

Так, з перебором з'ясували, але тепер перед нами постає нове завдання, компіляція звичайного тексту в спецформатірованую рядок. Це вже набагато простіше, і якщо ви досить добре знаєте РНР, то ви без праці напишіть таку функцію, а якщо поки плаваєте, то прошу в кабінет.

Алгоритм нескладний і ув'язнений в тому, щоб підставити в усі мовні конструкції в один рядок. Спочатку я в поривах ліні я хотів обмежити скрипт певним числом мов (так його втілити легше), однак після одумався і отримав ось що:

","<%/","%>")) (If (! Is_array ($ data)) (die (PARAM_CHECK_ERROR);) $ data \u003d" "; $ temp \u003d" "; $ count \u003d 0; foreach ($ data as $ k \u003d\u003e $ v) ( if (! is_string ($ k)) (break;) $ count ++; if ($ count\u003e 1 & $ temp \u003d $ k) (die (ERROR_CONSTRUCTION_COUNT);) $ temp \u003d $ k; $ data. \u003d $ delimiters. $ k. $ delimiters. $ v. $ delimiters. $ k. $ delimiters;) return $ data;)?\u003e

Ну, тут я трохи поясню. Як параметр функція приймає масив. Структура масиву повинна бути такою:

"Індіфікатор мови" \u003d\u003e "текст";

Після ми робимо перевірку, що якщо отриманий параметр не масив то<пока Вася!>.

Якщо ж це все-таки масив то звичайно робимо його перебір, і на місце мови в конструкції ставимо ключ даного елемента асоціативного масиву, а на місце тексту безумовно сам текст а тобто значення змінної $ v. Після зливаємо всі дані в один рядок. Але я забув згадати про одну важливу деталь, а іншими словами про досить великому шматку тексту. Спочатку перед циклом ми оголосили три змінні: data, temp, count;

Мінлива count- це кількість ітерацій циклу, і з кожним наступним колом циклу лічильник збільшується. Мінлива data- це майбутня результуючий рядок, в яку будуть зливатися все мовні конструкції. Але більш цікаві змінні count та temp. Для чого вони потрібні? Ну, напевно, більшість вже здогадалися, прочитавши исходник, але тим до кого ще не<дошло> я поясню. Це робиться для перевірки того, що мовна конструкція не була повторена більше разів. Для цього ми і оголосили змінну count. Так як її значення за замовчуванням дорівнює нулю, то ми перевіряємо, що цикл був виконаний хоча б раз, оскільки якщо ми цього не зробимо то, вийде щось подібне 2 \u003d 2 або 0 \u003d 0, адже значення $ k ще не встигло змінитися . Так як в перший раз перевірка буде ігноруватися, ми після перевірки присвоюємо значення змінної $ temp. Це робиться так само не просто так. При першій ітерації все піде нормально, але ж якщо ми все ж присвоїли значення до перевірки, то перевірка робила б перевірку, про яку вже згадувалося (2 \u003d 2, 3 \u003d 3 і т.д.). Ось навіщо ми робимо саме так.

Тепер як логічне завершення ми створимо невеликий сайт, де і буде застосовуватися все вищевикладене:

","<%/","%>")) ($ Data \u003d substr ($ data, (strpos ($ data, $ delimiters. $ Lang. $ Delimiters) + strlen ($ delimiters. $ Lang. $ Delimiters)), (strpos ($ data, $ delimiters. $ lang. $ delimiters) -strlen ($ data))); if (trim ($ data) \u003d\u003d "") ($ data \u003d NOT_ENTERED;) return $ data;) function compilateLanguageString ($ data, $ delimiters \u003d array ( "<%","%>","<%/","%>")) (If (! Is_array ($ data)) (die (PARAM_CHECK_ERROR);) $ data \u003d" "; $ temp \u003d" "; $ count \u003d 0; foreach ($ data as $ k \u003d\u003e $ v) ( if (! is_string ($ k)) (break;) $ count ++; if ($ count\u003e 1 & $ temp \u003d $ k) (die (ERROR_CONSTRUCTION_COUNT);) $ temp \u003d $ k; $ data. \u003d $ delimiters. $ k. $ delimiters. $ v. $ delimiters. $ k. $ delimiters;) return $ data;) // Не забуваємо про<статике> if (! isset ($ _ GET [ "lang"])) (setcookie ( "lang", $ _ GET [ "lang"]); header ( "Location: index.php? module \u003d home");) if (isset ( $ _COOKIE [ "lang"])) (include $ _COOKIE [ "lang"]. "_ map.php";) else (include "ru_map.php":) if (isset ($ _ POST [ "add"])) ( $ description \u003d compilateLanguageString (array ($ _ POST [ "description_en"], $ _ POST [ "description_ru"])); $ title \u003d compilateLanguageString (array ($ _ POST [ "titlte_eng"], $ _ POST [ "title_ru"])); // Процес додавання в базу) echo " "; Echo" "; Echo" "; $ Title \u003d ($ _ SERVER [" REMOTE_ADDR "] \u003d\u003d" 127.0.0.1 ")? ADMIN_WELCOM:" Гостям- Здрастуй! "; Echo $ title; echo""; Echo" "; Echo"": Echo" "; [Email protected]_connect ( "localhost", "root", ""); @mysql_select_db ( "somedatabase"); [Email protected]_query ( "SELECT title, description FROM` articles` LIMIT 0,1 ", $ conn_id); if (@mysql_ num_rows ($ q) \u003d\u003d 0) (ARTCILES_NOT_FOUNDED;) else ( [Email protected]_fetch_array ($ q); $ Title \u003d subTextByLang ($ row [ "title"], $ lang); $ Description \u003d subTextByLang ($ row [ "description"], $ lang); echo "

": Echo" "; Echo" "; Echo" "; Echo"
".ARTICLE_TITLE_TEXT."". $ Title."
". ARTICLE_DESCRIPTION_TEXT."
". $ Description."
";) @Mysql_close ($ conn_id); // Це ще півбіди, тепер потрібно створити форму для додавання статті echo"
"; Echo" "; Echo" "; Echo" "; Echo" "; Echo" "; Echo" "; Echo" "; Echo" "; Echo"
".ARTICLE_TITLE_TEXT." (EN):
".ARTICLE_TITLE_TEXT." (RU):
". ARTICLE_DESCRIPTION_TEXT." (EN):
"; Echo" "; Echo"
". ARTICLE_DESCRIPTION_TEXT." (RU):
"; Echo" "; Echo"
"; Echo"
"; ?>

Що ж ось і все. Однак в скрипті є одне "але", автор не може через форму додати більше двох варіантів перекладу. Не буду, як інші автора, що зробив це для вашої тренування, оскільки якщо чесно то коли я дійшов до цього місця у мене вже голова майже не варила, тому я і залишаю це на ваших плечах. Повірте, варіантів вирішення повно, і я дуже сподіваюся, що ви його знайдете. Щодо функцій, то не можу сказати на всі 100% що вони не викличуть збою але фатальних помилок бути не повинно, хоча всяке буває. Але я впевнений більш ніж на 60% що синтаксис порушений, тому що я не тестував приклади. А ось тут для вас дійсно гарне тренування адже ловля "бліх" дуже корисне заняття!

Що ж, я вважаю, що на цьому статтю можна закінчити. Якщо у вас не буде виходити, чи не зганяти зло на ваш бідний комп'ютер, на клавіатуру, і тим більше на розробників такого чудового мови як РНР, сміливо, всі свої невдачі адресуйте в мою сторону. Я не думаю, що мені від цього стане гірше, а от вам буде на кого зігнати злість.

Для того щоб створити псевдонім (алиас) шляху використовується метод Yii :: setAlias \u200b\u200b():

// псевдонім шляху до папки Yii :: setAlias \u200b\u200b( "@ myalias", "/ path / to / myfolder");
// псевдонім шляху до папки на основі іншого псевдоніма Yii :: setAlias \u200b\u200b( "@ img", "@ myalias / path / to / img");
// псевдонім URL Yii :: setAlias \u200b\u200b( "@ mysite", "http://mysite.com");

Псевдоніми шляхів в yii2 можна задати у файлі конфігурацій програми за допомогою властивості aliases, приклад:

Return [// ... "aliases" \u003d\u003e [ "@myalias" \u003d\u003e "/ path / to / myfolder", "@mysite" \u003d\u003e "http://mysite.com"],];

Як отримати псевдонім (алиас) шляху в Yii 2

Для того щоб отримати псевдонім шляху в yii2 используеться метод Yii :: getAlias \u200b\u200b():

Echo Yii :: getAlias \u200b\u200b( "@ myalias"); // поверне: / path / to / myfolder echo Yii :: getAlias \u200b\u200b( "@ mysite"); // поверне: http://mysite.com echo Yii :: getAlias \u200b\u200b( "@ myalias / other / folder / index.php"); // поверне: /path/to/myfolder/other/folder/index.php

Додатково про псевдонімах шляхів в Yii 2

ім'я псевдоніма

Ім'я псевдоніма може містити /, при цьому метод Yii :: getAlias \u200b\u200b() визначить яка частина є ім'ям псевдоніма, а яка додатковим шляхом, наприклад:

Yii :: setAlias \u200b\u200b( "@ test", "/ path / to / test"); Yii :: setAlias \u200b\u200b( "@ test / val", "/ path / to / val"); Yii :: getAlias \u200b\u200b( "@ test / folder / index.php"); // поверне: /path/to/test/folder/index.php Yii :: getAlias \u200b\u200b( "@ test / val / index.php"); // поверне: /path/to/val/index.php

Якби в рядку 2 небув визначено алиас @ test / val, то рядок 4 повернула б /path/to/test/val/index.php

псевдоніми розширень

При установці розширення за допомогою composer, для нього автоматично задається псевдонім (шлях до кореневої директорії розширення). Наприклад при установці imperavi redactor (vova07 / yii2-imperavi-widget), вам буде доступний псевдонім шляху @ vova07 / imperavi (@ vendor / vova07 / yii2-imperavi-widget / src)

Псевдоніми (аліаси) шляхів в Yii 2 basic додатку

Список основних, заздалегідь заданих псевдонімів (алиасов) шляхів в yii2 basic:

  • @web: Базовий URL додатки
  • @webroot: Webroot додатки

Псевдоніми (аліаси) шляхів в Yii 2 advanced додатку

Список основних, заздалегідь заданих псевдонімів (алиасов) шляхів в yii2 advanced:

  • @app: Кореневий каталог додатки
  • @vendor: Папка vendor, під @app
  • @runtime: Шлях до тимчасових файлів програми runtime / cache
  • @web: Базовий URL додатки
  • @webroot: Каталог з тестами додатки
  • @tests: Каталог з тестами додатки
  • @common: Ім'я користувача (алиас) для common (загальною) директорії під @app
  • @frontend: Ім'я користувача (алиас) для frontend директорії, під @app
  • @backend: Ім'я користувача (алиас) для backend директорії, під @app
  • @console: Ім'я користувача (алиас) для console директорії, під @app

(PHP 5\u003e \u003d 5.3.0)

The ability to refer to an external fully qualified name with an alias, or importing, is an important feature of namespaces. This is similar to the ability of unix-based filesystems to create symbolic links to a file or to a directory.

PHP namespaces support three kinds of aliasing or importing: aliasing a class name, aliasing an interface name, and aliasing a namespace name. Note that importing a function or constant is not supported.

In PHP, aliasing is accomplished with the use operator. Here is an example showing all 3 kinds of importing:

Example # 1 importing / aliasing with the use operator

namespace foo;
use My \\ Full \\ Classname as Another;

// this is the same as use My \\ Full \\ NSname as NSname
use My \\ Full \\ NSname;

// importing a global class
use ArrayObject;

$ Obj \u003d new namespace \\ Another; // instantiates object of class foo \\ Another
$ Obj \u003d new Another; NSname \\ subns \\ func (); $ A \u003d new ArrayObject (array (1)); // instantiates object of class ArrayObject
// without the "use ArrayObject" we would instantiate an object of class foo \\ ArrayObject
?>

Note that for namespaced names (fully qualified namespace names containing namespace separator, such as Foo \\ Bar as opposed to global names that do not, such as FooBar), The leading backslash is unnecessary and not recommended, as import names must be fully qualified, and are not processed relative to the current namespace.

PHP additionally supports a convenience shortcut to place multiple use statements on the same line

Example # 2 importing / aliasing with the use operator, multiple use statements combined

$ Obj \u003d new Another; // instantiates object of class My \\ Full \\ Classname
NSname \\ subns \\ func (); // calls function My \\ Full \\ NSname \\ subns \\ func
?>

Importing is performed at compile-time, and so does not affect dynamic class, function or constant names.

Example # 3 Importing and dynamic names

use My \\ Full \\ Classname as Another, My \\ Full \\ NSname;

$ Obj \u003d new Another; // instantiates object of class My \\ Full \\ Classname
$ A \u003d "Another";
$ Obj \u003d new $ a; ?\u003e

In addition, importing only affects unqualified and qualified names. Fully qualified names are absolute, and unaffected by imports.

Example # 4 Importing and fully qualified names

use My \\ Full \\ Classname as Another, My \\ Full \\ NSname;

$ Obj \u003d new Another; // instantiates object of class My \\ Full \\ Classname
$ Obj \u003d new \\ Another; // instantiates object of class Another
$ Obj \u003d new Another \\ thing; // instantiates object of class My \\ Full \\ Classname \\ thing
$ Obj \u003d new \\ Another \\ thing; // instantiates object of class Another \\ thing
?>

Scoping rules for importing

The use keyword must be declared in the outermost scope of a file (the global scope) or inside namespace declarations. This is because the importing is done at compile time and not runtime, so it can not be block scoped. The following example will show an illegal use of the use keyword:

Example # 5 Illegal importing rule

namespace Languages;

class Greenlandic
{
use Languages \u200b\u200b\\ Danish;

...
}
?>

Importing rules are per file basis, meaning included files will NOT inherit the parent file "s importing rules.

Доброго времени суток друзі! Давай з Вами розглянемо реєстрацію користувачів на PHP. Для початку давайте визначимо умови для нашої реєстрації користувачів:

  • Пароль шифруємо за допомогою алгоритму MD5
  • Пароль будемо "солити"
  • Перевірка на зайнятість Логіна
  • Активація користувача листом.
  • Запис і зберігання даних в СУБД MySQL

Для написання даного скрипта нам потрібно зрозуміти, що таке реєстрація користувача. Реєстрація користувача - це отримання даних реального користувача, обробка та зберігання даних.

Якщо пояснювати простими словами то реєстрація це всього лише запис і зберігання певних даних за якими ми можемо авторизувати користувача в нашому випадку - це Логін і Пароль.

Авторизація - надання певній особі або групі осіб прав на виконання певних дій, а також процес перевірки даних прав при спробі виконання цих дій. Проше кажучи за допомогою авторизації ми можемо розмежувати доступ до того чи іншого контенту на нашому сайті.

Розглянемо структуру каталогів скриптів для реалізації нашої реєстрації з авторизацією. Нам потрібно розбити скрипти на логічні складові. Модулі реєстрації та авторизації ми помістивши в окремий каталог. Так само в окремі каталоги ми помістимо підключення до бази даних MySQL, Файл з одними функціями, файл стилів CSS і наш шаблон HTML. Дана структура дозволяє швидко орієнтуватися в скриптах. Уявіть собі, що у Вас великий сайт з купою модулями і т.д. і якщо не буде порядку, то буде дуже складно щось відшукати в такому бардаку.

Так як ми будемо зберігати всі дані в СУБД MySQL, То давайте створимо не більшу таблицю в якій будемо зберігати дані про реєстрацію.

Для початку потрібно створити таблицю в базі даних. таблицю назвемо bez_reg де bez - це префікс таблиці, а reg назва таблиці.

Структура таблиці: bez_reg

- - Структура таблиці `bez_reg` - CREATE TABLE IF NOT EXISTS` bez_reg` ( `id` int (11) NOT NULL AUTO_INCREMENT,` login` varchar (200) NOT NULL, `pass` varchar (32) NOT NULL , `salt` varchar (32) NOT NULL,` active_hex` varchar (32) NOT NULL, `status` int (1) NOT NULL, PRIMARY KEY (` id`)) ENGINE \u003d MyISAM DEFAULT CHARSET \u003d utf8 AUTO_INCREMENT \u003d 1;

Тепер створимо основні скрипти для подальшої роботи.

файл INDEX.PHP

файл CONFIG.PHP

"); ?>

файл 404.HTML

Помилка 404

Помилка 404

На сторінці сталася помилка 404

повернутися

файл BD.PHP

файл INDEX.HTML

Реєстрація користувачів PHP MySQL з активацією листом

файл FUNCT.PHP

"." \\ N "; if (is_array ($ data)) (foreach ($ data as $ val) $ err. \u003d"

  • ". $ Val."
  • "." \\ N ";) else $ err. \u003d"
  • ". $ Data."
  • "." \\ N "; $ err. \u003d""." \\ N "; return $ err;) / ** Проста обгортка для запитів до MySQL * @param string $ sql * / function mysqlQuery ($ sql) ($ res \u003d mysql_query ($ sql); / * Перевіряємо результат Це показує реальний запит, надісланий до MySQL, а також помилку. Зручно при налагодженні. * / if (! $ res) ($ message \u003d "Невірний запит:". mysql_error (). "\\ n"; $ message. \u003d "запит цілком : ". $ sql; die ($ message);) return $ res;) / ** Простий генератор солі * @param string $ sql * / function salt () ($ salt \u003d substr (md5 (uniqid ()), - 8); return $ salt;)

    Давайте приступимо до написання реєстрації. Для початку нам потрібно буде зробити шаблон форми реєстрації, щоб користувач зміг внести свої дані для обробки. Далі нам потрібно буде написати сам обробник форми, який перевірить на коректність введені дані користувача. Після того як дані успішно перевірені записуємо їх в нашу базу даних і відправляємо лист користувачеві для активації його облікового запису.

    файл REG.PHP

    Ви успішно зареєструвалися! Будь ласка активуйте свій аккаунт !!"; // Виробляємо активацію облікового запису if (isset ($ _ GET [" key "])) (// Перевіряємо ключ $ sql \u003d" SELECT * FROM `". BEZ_DBPREFIX. "Reg` WHERE` active_hex` \u003d "". Escape_str ( $ _GET [ "key"]). "" "; $ res \u003d mysqlQuery ($ sql); if (mysql_num_rows ($ res) \u003d\u003d 0) $ err \u003d" Ключ активації не вірний! "; // Перевіряємо наявність помилок і виводимо користувачеві if (count ($ err)\u003e 0) echo showErrorMessage ($ err); else (// Отримуємо адреса користувача $ row \u003d mysql_fetch_assoc ($ res); $ email \u003d $ row [ "login"]; // Активуємо аккаунт користувача $ sql \u003d "UPDATE` ". BEZ_DBPREFIX." reg` SET `status` \u003d 1 WHERE` login` \u003d "". $ email. "" "; $ res \u003d mysqlQuery ($ sql); // Відправляємо лист для активації $ title \u003d "(! LANG: Ваш аккаунт на http: // сайт успішно активований"; $message = "Поздравляю Вас, Ваш аккаунт на http://сайт успешно активирован"; sendMessageMail($email, BEZ_MAIL_AUTOR, $title, $message); /*Перенаправляем пользователя на нужную нам страницу*/ header("Location:". BEZ_HOST ."less/reg/?mode=reg&active=ok"); exit; } } /*Если нажата кнопка на регистрацию, начинаем проверку*/ if(isset($_POST["submit"])) { //Утюжим пришедшие данные if(empty($_POST["email"])) $err = "Поле Email не может быть пустым!"; else { if(!preg_match("/^!} [Email protected](+ \\.) + (2,6) $ / i ", $ _POST [" email "])) $ err \u003d" Неможливо правильно введений E-mail "." \\ N ";) if (empty ($ _ POST [ "pass"])) $ err \u003d "Поле Пароль не може бути порожнім"; if (empty ($ _ POST [ "pass2"])) $ err \u003d "Поле Підтвердження пароля не може бути порожнім"; // Перевіряємо наявність помилок і виводимо користувачеві if (count ($ err)\u003e 0) echo showErrorMessage ($ err); else (/ * Продовжуємо перевіряти введені дані Перевіряємо на совподеніе паролі * / if ($ _ POST [ "pass"]! \u003d $ _POST [ "pass2" ]) $ err \u003d "Паролі не совподает"; // Перевіряємо наявність помилок і виводимо користувачеві if (count ($ err)\u003e 0) echo showErrorMessage ($ err); else (/ * Перевіряємо чи існує у нас такий користувач в БД * / $ sql \u003d "SELECT` login` FROM `". BEZ_DBPREFIX. "reg` WHERE` login` \u003d "". escape_str ($ _ POST [ "email"]). "" "; $ res \u003d mysqlQuery ($ sql); if (mysql_num_rows ($ res)\u003e 0) $ err \u003d "На жаль Логін: ". $ _POST [" email "]." зайнятий! "; // Перевіряємо наявність помилок і виводимо користувачеві if (count ($ err)\u003e 0) echo showErrorMessage ($ err); else (// Отримуємо хеш солі $ salt \u003d salt (); // Солимо пароль $ pass \u003d md5 (md5 ($ _ POST [ "pass"]). $ salt); / * Якщо все добре, пишемо дані в базу * / $ sql \u003d "INSERT INTO` ". BEZ_DBPREFIX." reg` VALUES ( "", "" . escape_str ($ _ POST [ "email"]). "", "". $ pass. "", "". $ salt. "", "". md5 ($ salt). "", 0) "; $ res \u003d mysqlQuery ($ sql); // Відправляємо лист для активації $ url \u003d BEZ_HOST. "less / reg /? mode \u003d reg & key \u003d". md5 ($ salt); $ title \u003d "(! LANG: Реєстрація на http: / / сайт"; $message = "Для активации Вашего акаунта пройдите по ссылке ". $url .""; sendMessageMail($_POST["email"], BEZ_MAIL_AUTOR, $title, $message); //Сбрасываем параметры header("Location:". BEZ_HOST ."less/reg/?mode=reg&status=ok"); exit; } } } } ?>!}

    файл REG_FORM.HTML

    Реєстрація користувачів PHP MySQL з активацією листом

    E-mail *:
    пароль *:
    підтвердження пароля *:

    Поля зі значком * обов'язкові для заповнення

    Так як реєстрація користувачів у нас готова, саме час написати авторизацію. Створимо форму для авторизації користувачів, далі напишемо обробник форми авторизації і на останок зробимо скрипт show.php який буде показувати нам авторизовані ми в системі чи ні.

    файл AUTH.PHP

    0) echo showErrorMessage ($ err); else (/ * Створюємо запит на вибірку з бази даних для перевірки достовірності користувача * / $ sql \u003d "SELECT * FROM` ". BEZ_DBPREFIX." reg` WHERE `login` \u003d" ". escape_str ($ _ POST [" email "]) . "" AND `status` \u003d 1"; $ res \u003d mysqlQuery ($ sql); // Якщо логін совподает, перевіряємо пароль if (mysql_num_rows ($ res)\u003e 0) (// Отримуємо дані з таблиці $ row \u003d mysql_fetch_assoc ( $ res); if (md5 (md5 ($ _ POST [ "pass"]). $ row [ "salt"]) \u003d\u003d $ row [ "pass"]) ($ _SESSION [ "user"] \u003d true; // скидаємо параметри header ( "Location:". BEZ_HOST. "less / reg /? mode \u003d auth"); exit;) else echo showErrorMessage ( "Неправильний пароль!");) else echo showErrorMessage ( "Логін ". $ _POST [" email "]." не знайден! ");))?\u003e

    Для тих у кого остання версія PHP викладаю даний скрипт з використанням PDO тому розширення MySQL застаріло і було видалено з нової версії PHP. Завантажити реєстрація і авторизація php mysql pdo

    Архів оновлено 24.02.2015г.

    Увага: Якщо ви використовуєте цей скрипт на локальному сервері типу DENWER, XAMPP, То не варто чекати листів на свою поштову скриньку. Листи лежать в заглушці sendmail. В Denwer ви їх можете знайти по шляху Z: \\ tmp \\! Sendmail \\ відкрити ці файли ви зможете в будь-якому поштовому клієнті.

    Типова ситуація: HTTP-клієнт запитує з сервера контент, який або не існує на даному сервері, або розташовується по іншому URL. Причин такому збігу обставин може бути кілька. Ви, наприклад, могли перемістити контент в межах сервера (а то і взагалі за його межі) або ж вам знадобилося реорганізувати логічну структуру адрес вашого проекту. При звичайних умовах запит неіснуючого контенту призведе до того, що сервер повідомить про помилку, однак в Apache є корисний модуль mod_alias, Що надає можливість створювати синоніми URL ( aliasing - алиасинг), А також виконувати перенаправлення клієнтів на інший URL ( redirect - редирект).

    Псевдоніми (аліаси) дозволяють серверу перетворювати один URL в інший, таким чином перенаправляючи клієнтів на потрібний контент, при цьому без фізичної операції перенаправлення: для клієнта подібна операція абсолютно прозора. Це дуже корисна можливість, якщо, наприклад, ви задумали олюднити URL-адреси сторінок вашого проекту з метою SEO-оптимізації або ще чогось.

    За допомогою алиасов ви також можете організувати доступ до файлів, що знаходяться за межами Document Root сервера, таким чином надавши прямий доступ до будь-якої частини ФС сервера, не вдаючись до використання CGI-сценаріїв. Використовуючи редирект, ви отримуєте можливість фізично перенаправляти клієнтів на потрібні URL.

    Директива Alias

    Директива Alias дозволяє непомітно для клієнтів пов'язувати запитувані URL з будь-якою частиною файлової системи сервера. наприклад:

    Директива в прикладі вище призведе до того, що Apache перед тим, як виконувати пошук контенту в файлової системі, в рядку запиту замінить / images / на / ftp / public / images /. Таким чином запит URL http://www.example-domain.com/images/example-image.jpg змусить шукати Apache файл example-image.jpg в фізичному каталозі / ftp / public / images / замість каталогу DOCUMENT_ROOT / images.

    Зверніть увагу на те, що завершальний слеш має значення. Наведений вище приклад не спрацював би, якщо б ми опустили завершальний слеш в першому параметрі Alias. Також, алиасинг не спрацював би в разі, якби клієнт запросив URL, в якому після / images був відсутній завершальний слеш.

    Директива AliasMatch

    Директива AliasMatch працює так само, як і Alias, при цьому дозволяючи використовувати регулярні вирази для визначення вихідних URL:

    AliasMatch /images/(.*)$ / ftp / public / images / $ 1

    Цей приклад демонструє, як ми можете легко зв'язати відносну частину запитуваної URL з частиною фізичної файлової системи. Змінна $ 1 пов'язана з першим відповідністю, виявленим в дужках регулярного виразу, $ 2 - з другим, і так далі. Таким чином, в прикладі вище, запит URL http://www.example-site.com/some_dir/images/img1.jpg призведе до отримання файлу /ftp/public/images/img1.jpg. Використовуючи цю директиву ви можете, наприклад, зберігати всі зображення в одному дереві каталогів, незалежно від відносного положення подстроки / images / в рядку запиту.

    Суттєвою різницею між Alias \u200b\u200bі AliasMatch є їхня поведінка. Різниця полягає в тому, що Alias \u200b\u200bкопіює частину рядка запиту після вирахування з неї першого параметра директиви, в той час як AliasMatch - немає. Тобто:

    Alias \u200b\u200b/ images / / ftp / public / images /

    абсолютно не еквівалентна

    AliasMatch / images / / ftp / public / images /

    оскільки друга транслюватиме всі запити, що містять підрядок / images / до каталогу / ftp / public / images /, не додаючи при перезапису імен файлів. Щоб отримати те, що потрібно, вам знадобиться така інструкція:

    AliasMatch ^ / images /(.*)$ / ftp / public / images / $ 1

    Директива ScriptAlias

    Призначення цієї директиви таке ж, як і Alias, однак при цьому Apache вважає кінцевий каталог таким, який зберігає виконувані CGI-сценарії. Тобто після трансляції запиту і визначення кінцевого шляху запитуваної файлу, Apache спробує виконати останній, як CGI-сценарій.

    ScriptAlias \u200b\u200b/ cgi-bin / / usr / local / apache2 / cgi-bin /

    У наведеному прикладі запит http://www.example-site.com/cgi-bin/some_cgi_script призведе до виконання сценарію, розташованого в файлі / usr / local / apache2 / cgi-bin / some_cgi_script. Альтернативний варіант такої конфігурації можна можна описати таким набором інструкцій:

    Alias \u200b\u200b/ cgi-bin / / usr / local / apache2 / cgi-bin / SetHandler cgi-script Options + ExecCGI

    Директива ScriptAliasMatch

    Дана директива аналогічна попередній, проте вміє працювати з регулярними виразами, як і AliasMatch.

    Директива Redirect

    mod_alias до всього іншого дозволяє явно повідомляти клієнтам про те, що запитаний ними URL є некоректним, повідомляючи інший URL, за яким можна відшукати необхідний контент. Для управління такими перенаправлення використовується директива Redirect.

    Ця директива працює подібно Alias, тільки замість того, щоб виконувати перенаправлення всередині сервера, вона відправляє команду перенаправлення клієнта. Опціональним параметром директиви є тип перенаправлення, який посилає клієнту кодом HTTP-статусу відповіді (про це трохи нижче).

    Redirect permanent / images http://www.another-example-site.com/images

    У наведеному прикладі запит URL http://www.example-site.com/images/img1.gif призведе до перенапрвленію на http://www.another-example-site.com/images/img1.gif.

    Якщо запитуваний URL містить query string, то вона буде залишена без змін, тільки якщо це явно не определнного останнім параметром директиви Redirect.

    Наприклад, правило, розглянуте вище, запит URL http://www.example-site.com/images?img-name\u003d1.gif перенаправить до http://www.another-example-site.com/images?img- name \u003d 1.gif. Однак, якщо ми перепишемо правило в такий спосіб:

    Redirect permanent / images http://www.another-example-site.com/images?q\u003dnew-value

    то той же запит буде перенаправлений на http://www.another-example-site.com/images?q\u003dnew-value.

    Тепер про типи перенаправлення. Для того, щоб повідомити клієнту про необхідність перенаправлення на інший URL, сервер використовує HTTP статус-коди. За допомогою директиви Redirect можна визначити один з чотирьох HTTP-кодів перенаправлення (в дужках вказано символічне ім'я, яке можна використовувати замість номера коду).

    301 (permanent). Ресурс переїхав на нову адресу. Клієнти і проксі-сервери повинні оновити інформацію в своїх кешах (тільки якщо HTTP-заголовки Cache-Control і Expires не перешкоджають цьому) і в майбутньому завжди використовувати нову адресу ресурсу.

    302 (temp). Адреса ресурсу тимчасово змінений. Клієнти і проксі-сервери НЕ повинні оновлювати інформацію в своєму кеші і в майбутньому завжди перевіряти попередній адресу ресурсу, перш ніж виконувати перенаправлення (тільки якщо HTTP-заголовки Cache-Control і Expires не перешкоджають цьому).

    303 (seeother). Ресурс був замінений іншим ресурсом і клієнт повинен виконати перенаправлення, використовуючи метод GET, незалежно від того, який метод використовувався для запиту оригінального ресурсу.

    410 (gone). Ресурс був вилучений і більше недоступний.

    Якщо статус-аргумент буде опущений, то за умовчанням буде використовуватися 302-редирект. Насправді ви можете використовувати будь-який HTTP-статус, а не тільки чотири з наведених вище. Пам'ятайте тільки, що якщо ви використовуєте HTTP-статус, який не потрапляє в діапазон 300-399, останній аргумент директиви повинен бути опущений.

    Директива RedirectMatch

    Ця директива, як вже все здогадалися, працює подібно до попередньої, але дозволяє користуватися регулярними виразами при визначенні умов, надаючи більше гнучкості в налаштування поведінки редиректу. Заради прикладу давайте розглянемо наступне правило:

    RedirectMatch (. *) \\. Gif $ http: //www.example-site.com$1.gif

    Тут все запити адрес, оканчівающіхся.gif, будуть перенаправлені в корінь іншого сервера.

    Так само, як і попередня діректва, RedirectMatch приймає опціональний параметр HTTP статус-коду. В наведеному вище прикладі він не вказаний, і тому буде використовуватися код 302.

    Також, в сімействі Redirect * є ще дві директиви: RedirectPermanent і RedirectTemp, які семантично еквіваленти виразів Redirect permanent і Redirect temp відповідно.

    Порядок обробки директив

    Якщо ви не хочете отримати несподіваного поведінки сервера при роботі з перенаправленням і Алиасинг, ви повинні знати про те, що інструкції редиректу обробляються перед інструкціями аліасинга, Якщо вони були одночасно виявлені в одному і тому ж контексті (наприклад в межах оного і того ж контейнера або ).

    Коли сервер отримує запит, відповідний під умову Redirect або RedirectMatch, то інструкції цих директив будуть оброблені перш, ніж інструкції директив Alias \u200b\u200bі AliasMatch. Це означає те, що в подібних ситуаціях директиви Alias \u200b\u200b* ніколи не будуть спрацьовувати, оскільки буде випоняться редирект.

    Другий момент, про який завжди завжди пам'ятати, це те, що директиви Alias \u200b\u200b* і Redirect * застосовуються в тому порядку, в якому вони з'являються. З цієї причини часто більш розумно визначати більш загальні правила в останню чергу. Наприклад інструкції:

    Alias \u200b\u200b/ sub-dir1 / sub-dir2 / dir3 Alias \u200b\u200b/ sub-dir1 / dir4

    НЕ будуть працювати так само, як і:

    Alias \u200b\u200b/ sub-dir1 / dir4 Alias \u200b\u200b/ sub-dir1 / sub-dir2 / dir3

    оскільки Alias \u200b\u200b/ sub-dir1 / dir4 буде спрацьовувати завжди до того, як дійде черга до Alias \u200b\u200b/ sub-dir1 / sub-dir2 / dir3.

     

     

    Це цікаво: