PHP _SELF в атрибуті форми action.

  • Переклад
  • Tutorial

Це третя стаття в серії, де я описую свій досвід написання веб-програми на Python з використанням мікрофреймворку Flask.

Мета даного керівництва - розробити досить функціональний додаток-мікроблог, який я за повною відсутністю оригінальності вирішив назвати microblog.

Коротке повторення У попередній частині ми визначили простий шаблон для домашньої сторінки та використовували уявні об'єкти як прототипи речей, яких у нас ще немає. Наприклад, користувачі або записи.

У цій статті ми збираємося заповнити один із прогалин, які є в нашому додатку. Ми розглянемо роботу із формами.

Форми є одними з основних блоків в будь-якому веб-додатку. Використання форм дозволить користувачам залишати записи в блозі, а також логінуватись у додаток.

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

Конфігурація Для обробки форм ми будемо використовувати розширення Flask-WTF, яке є обгорткою WTForms і чудово інтегрується з Flask додатками.

Багато розширень Flask вимагають деякої настройки, тому ми створимо файл конфігурації всередині нашої кореневої папки microblog, тому він буде легко доступний для зміни, якщо знадобиться. Ось із чого ми почнемо (файл config.py):
CSRF_ENABLED = True SECRET_KEY = "you-will-never-guess"

Все просто, це дві настройки, які потрібні нашому розширенню Flask-WTF. CSRF_ENABLED активує запобігання підробленим міжсайтовим запитам. У більшості випадків ви захочете включити цю опцію, що зробить вашу програму більш захищеною.

SECRET_KEY потрібен лише тоді, коли включено CSRF . Він використовується для створення криптографічного токена, який використовується для валідації форми. Коли ви пишете свою програму, переконайтеся, що ваш секретний ключ складно підібрати.

Тепер у нас є конфіг, і ми повинні сказати Flask"у прочитати і використовувати його. Ми зможемо зробити це відразу після того, як об'єкт програми Flask створений. (файл app/__init__.py):
from flask import Flask app = Flask(__name__) app.config.from_object("config") from app import views

Форма входу У Flask-WTF форми представлені як об'єктів підкласу від класу Form . Підклас форм просто визначає поля форм як змінні у класі.

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

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

Напишемо нашу першу форму (файл app/forms.py):
від flask.ext.wtf import Form від wtforms import TextField, BooleanField від wtforms.validators import Required class LoginForm(Form): openid = TextField("openid", validators = ) remember_me = BooleanField("rem

Впевнений, що клас каже сам за себе. Ми імпортували клас Form і два класи полів, які нам знадобляться, TextField та BooleanField .

Імпортований Required - це валідатор, функція, яка може бути прикріплена до поля для виконання валідації даних відправлених користувачем. Валідатор Required просто перевіряє, що поле не було відправлене порожнім. У Flask-WTF є багато валідаторів, ми будемо використовувати кілька нових у майбутньому.

Шаблони форм Ще нам потрібний HTML шаблон, який містить форму. Хорошою новиною буде те, що клас LoginForm, який ми тільки-но створили, знає як віддавати поля форми в HTML, тому нам просто потрібно сконцентруватися на макеті. Ось наш шаблон логіна: (файл app/templates/login.html):
Sign In ((form.hidden_tag()))

Please enter your OpenID:
((form.openid(size=80)))

(% endblock %)

Зверніть увагу на те, що ми знову використовуємо шаблон base.html через оператор успадкування, розширюючи його. Ми будемо робити це з усіма нашими шаблонами, забезпечуючи узгодження макета на всіх сторінках.

Є кілька цікавих відмінностей між звичайною HTML формою та нашим шаблоном. Шаблон очікує екземпляр класу форми, який ми щойно призначили в аргумент шаблону form . Ми подбаємо про надсилання цього аргументу шаблону в майбутньому, коли напишемо функцію подання, яка віддає цей шаблон.

Параметр шаблону form.hidden_tag() буде замінений прихованим полем для запобігання CSRF, увімкненим у нашому файлі налаштувань. Це поле має бути у всіх ваших формах, якщо CSRF увімкнено.

Поля нашої форми віддані об'єктом форми, ви повинні звертатися до аргументу ((form.field_name)) у тому місці шаблону, де має бути вставлено поле. Деякі поля можуть приймати аргументи. У нашому випадку, ми просимо форму створити наше поле openid з шириною 80 символів.

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

Уявлення форм Останнім кроком перед тим, як ми зможемо побачити нашу форму, буде написання функції представлення, яка дає шаблон.

Насправді це дуже просто, тому що ми повинні лише передати об'єкт форми в шаблон. ось наша нова функція представлення (файл app/views.py):
from flask import render_template, flash, redirect from app import app from forms import LoginForm # функція представлення index опущена для стислості @app.route("/login", methods = ["GET", "POST"]) def login(): form = LoginForm() return render_template("login.html", title = "Sign In", form = form) !}

Ми імпортували наш клас LoginForm, створили його екземпляр і відправили до шаблону. Це все, що потрібно для того, щоб відмалювати поля форми.

Не звертатимемо уваги на імпорт flash і redirect. Ми використовуємо їх трохи пізніше.

Ще одне нововведення – це аргументи методу в декораторі route. Тут ми говоримо Flask, що функція подання приймає GET та POST запит. Без цього подання прийматиме лише GET запити. Ми хочемо отримувати запити POST, які будуть віддавати форму з наведеними користувачем даними.

На цій стадії ви можете запустити програму і подивитися на вашу форму в браузері. Після запуску відкрийте адресу, яку ми пов'язали з функцією представлення login: http://localhost:5000/login

Ми ще не запрограмували ту частину, яка приймає дані, тому натискання на кнопку submit не дасть жодного ефекту.

Набуття даних форми
Ще одна область, де Flask-WTF полегшує нашу роботу – обробка відправлених даних. Це нова версія нашої функції представлення login , яка валідує та зберігає дані форми (файл app/views.py):
@app.route("/login", methods = ["GET", "POST"]) def login(): form = LoginForm() if form.validate_on_submit(): flash("Login requested for OpenID="" + form.openid.data + "", remember_me=" + str(form.remember_me.data)) return redirect("/index") return render_template("login.html", title = "Sign In", form = form) !}

Метод validate_on_submit робить процес обробки. Якщо ви викликали метод, коли форма буде представлена ​​користувачеві (тобто перед тим, як користувач матиме можливість ввести туди дані), то він поверне False , в такому випадку ви знаєте, що повинні відмалювати шаблон.

Якщо validate_on_submit викликається разом як частина запиту відправки форми, він збере всі дані, запустить будь-які валідатори, прикріплені до полів, і якщо все гаразд поверне True , що свідчить про валідність даних. Це означає, що дані безпечні для включення до програми.

Якщо щонайменше одне поле не проходить валідацію, тоді функція поверне False і це знову викличе малювання форми перед користувачем, тим самим давши можливість виправити помилки. Пізніше ми навчимося показувати повідомлення про помилку, коли проходить валідація.

Коли validate_on_submit повертає True , наша функція представлення викликає дві нові функції, імпортовані з Flask. Функція Flash - це швидкий спосіб відображення повідомлення на наступній сторінці, представленій користувачеві. У даному випадку ми будемо використовувати це для налагодження доти, доки у нас немає інфраструктури, необхідної для логування, натомість ми просто виводитимемо повідомлення, яке буде показувати надіслані дані. Також flash надзвичайно корисний на продакшн-сервері для забезпечення зворотного зв'язку з користувачем.

Flash повідомлення не будуть автоматично з'являтися на нашій сторінці, наші шаблони повинні відображати повідомлення у тому вигляді, який підходить для макету нашого сайту. Ми додамо повідомлення до базового шаблону, так що всі наші шаблони успадковують цю функціональність. Це оновлений шаблон base (файл app/templates/base.html):
(% if title %) ((title)) - microblog (% else %) microblog (% endif %) Microblog: Home (% with messages = get_flashed_messages() %) (% if messages %)

    (% for message in messages %)
  • ((message))
  • (% endfor %)
(% endif %) (% endwith %) (% block content %)(% endblock %)

Сподіваюся, що спосіб відображення повідомлень не вимагає пояснень.

Інша нова функція, яку ми використовували у нашому поданні login-redirect. Ця функція перенаправляє клієнтський веб-браузер на іншу сторінку замість запитуваної. У нашій функції представлення ми використовували редирект на головну сторінку, розроблену у попередніх частинах. Майте на увазі, що flash повідомлення будуть відображені навіть якщо функція закінчується перенаправленням.

Прекрасний час для того, щоб запустити програму та перевірити як працюють форми. Спробуйте надіслати форму з порожнім полем openid, щоб побачити, як валідатор Required зупиняє процес передачі.

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

Що ми пропустили, то це повідомлення користувача про те, що саме не так з формою. На щастя, Flask-WTF також полегшує це завдання.

Коли поле не проходить валідацію Flask-WTF додає наочне повідомлення про помилку об'єкт форми. Ці повідомлення доступні в шаблоні, тому нам просто потрібно додати трохи логіки для їх відображення.

Це наш шаблон login із повідомленнями валідації полів (файл app/templates/login.html):
(% extends "base.html" %) (% block content %) Sign In ((form.hidden_tag()))

Please enter your OpenID:
((form.openid(size=80)))
(% for error in form.errors.openid %) [((error))] (% endfor %)

((form.remember_me)) Remember Me

(% endblock %)

Єдина зміна, яку ми зробили - додали цикл, який малює будь-які додані валідатором повідомлення про помилки праворуч від поля openid. Як правило, будь-які поля, що мають прикріплені валідатори, будуть мати помилки, додані як form.errors.ім'я_поля. У нашому випадку ми використовуємо form.errors.openid. Ми відображаємо ці повідомлення у червоному кольорі, щоб звернути на них увагу користувача.

Взаємодія з OpenID Насправді ми стикатимемося з тим, що багато людей навіть не знають, що у них вже є парочка OpenID. Не дуже відомо, що низка великих постачальників послуг в Інтернеті підтримує OpenID автентифікацію для їх користувачів. Наприклад, якщо у вас є обліковий запис у Google, то з ним у вас є і OpenID. Так само як і в Yahoo, AOL, Flickr та безлічі інших сервісів.

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

Почнемо із визначення списку OpenID провайдерів, яких ми хочемо уявити. Ми можемо зробити це в нашому конфігураційному файлі (файл config.py):
OPENID_PROVIDERS = [ ( "name": "Google", "url": "https://www.google.com/accounts/o8/id" ), ( "name": "Yahoo", "url": "https ://me.yahoo.com" ), ( "name": "AOL", "url": "http://openid.aol.com/" ), ( "name": "Flickr", "url" : "http://www.flickr.com/" ), ( "name": "MyOpenID", "url": "https://www.myopenid.com" )]

Тепер подивимося як ми використовуємо цей список у нашій функції представлення login:
@app.route("/login", methods = ["GET", "POST"]) def login(): form = LoginForm() if form.validate_on_submit(): flash("Login requested for OpenID="" + form.openid.data + "", remember_me=" + str(form.remember_me.data)) return redirect("/index") return render_template("login.html", title = "Sign In", form = form, providers = app.config["OPENID_PROVIDERS"]) !}

Тут ми отримуємо налаштування шляхом їх пошуку за ключом у app.config. Далі список додається у виклик render_template як аргумент шаблону.

Як ви здогадалися, нам потрібно зробити ще один крок, щоб покінчити з цим. Зараз нам потрібно вказати, як ми хотіли б відображати посилання на цих провайдерів у нашому шаблоні login (файл app/templates/login.html):
(% extends "base.html" %) (% block content %) function set_openid(openid, pr) ( u = openid.search("") if (u != -1) ( // openid requires username user = prompt ("Enter your " + pr + " username:") openid = openid.substr(0, u) + user ) form = document.forms["login"]; form.elements["openid"].value = openid ) Sign In ((form.hidden_tag()))

Подивіться на ваш OpenID, або виберіть один з дизайнерів нижче:
((form.openid(size=80))) (% for error in form.errors.openid %) [((error))] (% endfor %)
|(% for pr in providers %) ((pr.name))| (% endfor %)

((form.remember_me)) Remember Me

(% endblock %)

Шаблон вийшов дещо довгим у зв'язку з усіма цими змінами. Деякі OpenID включають імена користувачів, для них у нас має бути трохи javascript магії, яка просить ім'я користувача, а потім створює OpenID. Коли користувач натискає на посилання OpenID провайдера та (опційно) вводить ім'я користувача, OpenID для цього провайдера вставляється у текстове поле.

скріншот нашої сторінки входу після натискання на посилання Google OpenID

Заключні слова Хоча ми досягли великого прогресу з нашими формами логіну, насправді ми не зробили нічого для входу користувачів до нашої системи. Все що ми зробили стосувалося GUI процесу входу. Це тому, що, перш ніж ми зможемо зробити реальні логіни, нам потрібно мати базу даних, де ми можемо записувати наших користувачів.

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

Додаток microblog у його поточному стані доступний для завантаження тут.

У статті докладно йдеться про використання змінної PHP _SELF.

Що за змінна PHP _SELF?

Змінна PHP _SELF повертає ім'я та шлях до поточного файлу (щодо кореня документа). Ви можете використовувати цю змінну в атрибуті форми action. Існують також деякі нюанси, які ви маєте знати. Ми, звичайно, ніяк не можемо обминути ці нюанси.

Давайте розглянемо кілька прикладів.

Echo $_SERVER["PHP_SELF"];

1) Припустимо, що ваш php файл розташований за наступною адресою:

http://www.yourserver.com/form-action.php

У цьому випадку змінна PHP _SELF міститиме:

"/form-action.php"

2) Припустимо, ваш php файл розташований за такою адресою:

http://www.yourserver.com/dir1/form-action.php

PHP _SELF буде:

"/dir1/form-action.php"

PHP _SELF в атрибуті форми action. Навіщо вона там знадобилася?

Зазвичай змінну PHP _SELF використовують у атрибуті action тега form . В атрибуті action вказується адреса, за якою буде надіслано зміст форми після підтвердження (клік користувачем по кнопці з type="submit"). Як правило це та сама сторінка, з якої пішла форма.

Однак, якщо ви перейменуєте файл, на який посилається форма, вам знадобиться перейменувати назву файлу в атрибуті action, інакше форма не працюватиме.

Змінна PHP _SELF позбавить вас зайвих виправлень, оскільки адреса сторінки буде генеруватися автоматично, виходячи з назви файлу.

Допустимо, у вас є файл з формою form-action.php, і ви хочете, щоб після підтвердження форма відправлялася на той самий файл. Зазвичай пишуть так:

Але ви можете використовувати змінну PHP _SELF замість form-action.php. У цьому випадку код виглядатиме:



Останні матеріали розділу:

Значення чижів федор васильович у короткій біографічній енциклопедії У центрі ділової росії
Значення чижів федор васильович у короткій біографічній енциклопедії У центрі ділової росії

Сьогодні, коли з такою жорстокістю точаться суперечки про Росію та росіян, неминуче звернення до життя та ідей костромича Ф.В.Чижова, фізика та...

Ссср: чим пишалися радянські люди і про що їм не розповідали
Ссср: чим пишалися радянські люди і про що їм не розповідали

30 грудня 1922 року на Першому Всесоюзному з'їзді Рад главами делегацій було підписано Договір про утворення СРСР. Спочатку до складу СРСР входили...

Платон та його академія Що таке академія платона
Платон та його академія Що таке академія платона

Поблизу Афін, у гаю, присвяченому герою Кадму. Згодом ці філософи розійшлися в поглядах і напрямі, і тим дали привід пізнішим...