Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

HTML без проблем! Советы профессионалов! (выпуск 15)


Информационный Канал Subscribe.Ru

Создать профессиональный web-сайт - легко!
Создать профессиональный web-сайт - легко!
или
все о PHP шаг за шагом.

     Сегодня в выпуске (N 15):
4 мая 2005 года 
     ВНИМАНИЕ !!!
тираж выпуска: 5000 
- От автора (рекомендуется прочитать)
- Новое на форуме
        ∙ задать вопрос
- Автору


Сайт рассылки

- Новости сайта
- Поиск по сайтам web-програмирования и дизайна

- Учебник по HTML
- Учебник по CSS
- Учебник по PHP
- Учебник по JavaScript

- Скачать
- Гостевая книга
- Форум
- Регистрация
- О рассылке

Архив рассылки

     Академия народного хозяйства при Правительстве РФ совместно с компанией NetPromoter проводят практическую конференцию «Кибермаркетинг. Стратегия и тактика продвижения ресурса». Конференция состоится 19-20 мая 2005 в Центре Международной Торговли (Москва). Вниманию слушателей будут предложены доклады и мастер-классы, раскрывающие практические аспекты поискового продвижения. Подробнее >>>
     От автора (рекомендуется прочитать):
Добрый день, уважаемые подписчики.

     Рассылка снова долго не выходила. Но на это были опять же свои причины.Вызвано это было тем, что сайт переехал на платный хостинг. Теперь адрес сайта:

http://web-mir.com/


     В лучшую строну то, что сайт претерпел ряд изменений. Сейчас это уже не сайт про PHP, а настоящий портал для веб-дизайнера, в котором есть разделы по HTML, CSS, JavaScript, Photoshp, раскрутка сайта и многое другое. Разделы построены на уроках и представляют собой учебник, который любому поможет разобраться. В скором времени планируется создать еще один раздел под названием "Шаблоны", в котором можно скачать 300 готовых профессионально-выполненых шаблонов для своего сайта. Улучшился форум, в котором появилось много новых разделов. Кстати теперь сайт принадлежит 2 человекам: мне и Jesk'у.

     Если у Вас есть сайт тематики web-программирования или дизайна, Вы можете добавить его в Базу Данных поиска, что, вероятно, поможет в его раскрутке, а у пользователей поисковика будет больше результатов поиска.
     Статья выпуска "Сессии в PHP":
Введение
Сессии - это на самом деле очень просто.
Надо только понимать, для чего они нужны и как устроены.
Ответим сначала на первый вопрос.
Веб-сервер не поддерживает постоянного соединения с клиентом, и каждый запрос обрабатывается, как новый, безо всякой связи с предыдущими.
То есть, нельзя ни отследить запросы от одного и того же посетителя, ни сохранить для него переменные между просмотрами отдельных страниц. Вот для решения этих двух задач и были изобретены сессии.
Собственно, сессии, если в двух словах - это механизм, позволяющий однозначно идентифицировать браузер и создающий для этого браузера файл на сервере, в котором хранятся переменные сеанса.

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

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

Как устроены, и как работают сессии?
Для начала надо как-то идентифицировать браузер. Для этого надо выдать ему уникальный идентификатор и попросить передавать его с каждым запросом. Стыдно признаться, но когда я впервые узнал о сессиях, я думал, что это какой-то особый механизм, некий новый способ общения браузера с сервером - "сессии". Что идентификатор сессии передается каким-то особым образом. Разочарование было жестоким.
Сессии используют стандартные, хорошо известные способы передачи данных. Собственно, других-то просто и нет.
Идентификатор - это обычная переменная. По умолчанию ее имя - PHPSESSID.
Задача PHP отправить ее браузеру, чтобы тот вернул ее со следующим запросом. Из уже упоминавшегося раздела FAQ ясно, что переменную можно передать только двумя способами: в куках или POST/GET запросом.
PHP использует оба варианта.
За это отвечают две настройки в php.ini:
session.use_cookies - если равно 1, то PHP передает идентификатор в куках, если 0 - то нет.
session.use_trans_sid если равно 1, то PHP передает его, добавляя к URL и формам, если 0 - то нет.

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

Если включена только вторая, то кука не выставляется. А происходит то, ради чего, в основном, собственно, и стоит использовать встроенный механизм сессий. После того, как скрипт выполняет свою работу, и страница полностью сформирована, PHP просматривает ее всю и дописывает к каждой ссылке и к каждой форме передачу идентификатора сессии. Это выглядит примерно так:
<a href="/index.php">Index</a> превращается в
<a href="/index.php?PHPSESSID=9ebca8bd62c830d3e79272b4f585ff8f">Index</a>
а к формам добавляется скрытое поле
<input type="hidden" name="PHPSESSID" value="00196c1c1a02e4c37ac04f921f4a5eec" />
И браузер при клике на любую ссылку, или при нажатии на кнопку в форме, пошлет в запросе нужную нам переменную - идентификатор сессии!

Теоретически, в наших с вами самодельных сессиях на куках и базе, можно самому, руками приписать ко всем ссылками передачу ид - и тогда наши собственные сессии будут работать независимо от кук. Но, согласитесь - приятнее, когда эту работу делает кто-то другой? ;-)

По умолчанию в последних версиях PHP включены обе опции. Как PHP поступает в этом случае? Кука выставляется всегда. А ссылки автодополняются только если РНР не обнаружил куку с идентификатором сессии. Когда пользователь в првый раз за этот сеанс заходит на сайт, ему ставится кука, и дополняются ссылки. При следующем запросе, если куки поддерживаются, PHP видит куку и перестает дополнять ссылки. Если куки не работают, то PHP продолжает исправно добавлять ид к ссылкам, и сессия не теряется.
Пользователи, у которых работают куки, увидят длинную ссылку с ид только один раз.

Фух. С передачей идентификатора закончили.
Теперь осталось привязать к нему файл с данными на стороне сервера.
PHP это сделает за нас. Достаточно просто написать
session_start();
$_SESSION['test']='Hello world!';

И PHP запишет в файл, связанный с этой сессией, переменную test.
Здесь очень важное замечание.
Массив $_SESSION - особенный.
В нем, собственно, и находятся переменные, которые мы ходим сделать доступными в различных скриптах.
Чтобы поместить переменную в сессию, достаточно присвоить ее элементу массива $_SESSION.
Чтобы получить ее значение - достаточно обратиться к тому же элементу. Пример будет чуть ниже.

Cборкой мусора - удалением устаревших файлов PHP тоже занимается сам. Как и кодированием данных и кучей всяких других нужных вещей. В результате этой заботы работа с сессиями оказывается очень простой.
Вот мы, собственно, и подошли к примеру работы сессий.
Пример очень маленький:
<?
session_start
();
if (!isset(
$_SESSION['counter'])) $_SESSION['counter']=0;
echo
"Вы обновили эту страницу ".$_SESSION['counter']++." раз. ";
echo
"<br><a href=".$_SERVER['PHP_SELF'].">обновить";
?>

Мы проверяем, есть ли у нас в сессии переменная counter, если нет, то создаем ее со значением 0, а дальше выводим ее значение и увеличиваем на единицу. Увеличенное значение запишется в сессию, и при следующем вызове скрипта переменная будет иметь значение 1, и так далее.
Все очень просто.

Для того, чтобы иметь доступ к переменным сессии на любых страницах сайта, надо написать ТОЛЬКО ОДНУ(!) строчку в самом начале КАЖДОГО файла, в котором нам нужны сессии:
session_start();
И далее обращаться к элементам массива $_SESSION. Например, проверка авторизации будет выглядеть примерно так:
session_start();
if (
$_SESSION['authorized']<>1) {
header("Location: /auth.php");
exit;
}


Удаление переменных из сессии.
Если у вас register_globals=off, то достаточно написать
unset($_SESSION['var']);
Если же нет, то тогда рядом с ней надо написать
session_unregister('var');

Область применения.
Очень важно понимать, для чего сессии стоит использовать, а для чего - нет.

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

Во-вторых. Важно четко себе представлять тот факт, что сессия - это сеанс работы с сайтом, так как его понимает человек. Пришел, поработал, закрыл браузер - сессия завершилась. Как сеанс в кино. Хочешь посмотреть еще один – покупай новый билет. Стартуй новый сеанс. Этому есть и техническое объяснение. Гарантированно механизм сессий работает только именно до закрытия браузера. Ведь у клиента могут не работать куки, а в этом случае, естественно, все дополненные идентификатором ссылки пропадут с его закрытием.
Правда, сессия моджет пропасть и без закрытия браузера. В силу ограничений, рассмотренных в самом главном разделе этого FAQ, механизм сессий не может определить тот момент, когда пользователь закрыл браузер. Для этого используется таймаут – заранее определенное время, по истечении которого мы считаем, что пользователь ушел с сайта. По умолчанию этот параметр равен 24 минутам.
Если вы хотите сохранять пользовательскую информацию на более длительный срок, то используйте куки и, если надо - базу данных на сервере. В частности, именно так работают все популярные системы авторизации:
- по факту идентификации пользователя стартует сессия и признак авторизованности передается в ней.
- Если надо "запомнить" пользователя, то ему ставится кука, его идентифицирующая.
- При входе пользователя на сайт, для того, чтобы авторизоваться, он должен либо ввести пароль, либо система сама его опознает, стартуя сессию. Новую сессию, а не продолжая старую.

В-третьих, и самое, пожалуй, важное. Надо помнить, что механизм устроен так, что страницы, сгенерированные с его использованием, не рассчитаны на кэширование и индексирование. Поэтому, если вы, конечно, не хотите обидеть поисковик, сессии ни в коем случае не надо стартовать любому входящему. Никогда не используйте сессии по пустякам – к примеру, в счетчиках. Пользы никакой, а вред огромный.
Если сессии используются для ограничения доступа к какому-то разделу сайта – то тут все просто. Поисковик просто и не должен индексировать закрытые страницы. Если же приходится показывать одну и ту же страницу как авторизованным, так и не авторизованным пользователям, то тут поможет такой трюк – стртовать сессию только тем, кто ввел пароль, или тем, у кого уже стартовала сессия.
Для этого в начало каждой страницы вместо просто session_start() пишем
if (isset($_REQUEST[session_name()])) session_start();
таким образом, Мы стартуем сессию только тем, кто прислал идентификатор.
Соответственно, надо еще в первый раз отправить его пользователю – в момент авторизации.
Если имя и проль верные – пишем session_start()!

Ошибки.

Самыми распространенными ошибками, которые выдает РНР при попытке работать с сессиями, являются такие:
Две из них,
Warning: Cannot send session cookie - headers already sent
Warning: Cannot send session cache limiter - headers already sent

вызваны одной и той же причиной, решение описано в этом факе здесь
Третья,
Warning: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/tmp)
если перевести ее с английского, подробно объясняет проблему: недоступен указанный в php.ini путь к каталогу, в который пишутся файлы сессий. Эту ошибку исправить проще всего. Просто прописать каталог, который существует, и доступен на запись, например,
session.save_path = c:\windows\temp
И не забыть перезагрузить апач после этого.

Как выясняется, сообразительность людская не имеет пределов, и поэтому я вынужден пояснить:
сообщение о третьей ошибке (невозможно найти каталог) НЕИЗБЕЖНО приведет к появлению первых двух, поскольку сообщение об ошибке - это вывод в браузер и после него заголовками пользоваться нельзя. Поэтому не спешите искать преждевременный вывод, а сначала пропишите правильный путь!


Если не работает, но и никаких сообщений не выводится, то добавьте в самое начало скрипта две строчки, отвечающие за вывод ВСЕХ ошибок на экран - вполне возможно, что ошибки есть, но вы их просто не видите.
ini_set('display_errors',1);
error_reporting(E_ALL);

или смотрите ошибки в error_log. Вообще, тема отображения сообщений об ошибках выходит за рамки данной статьи, поэтому просто убедитесь хотя бы, что вы можете их видеть. Чуть продробнее о поиске ошибок можно прочитать в этом разделе.

Если вы уверены, что ошибок нет, но приведенный пример не работает все равно, то, возможно, в PHP не включена передача ид через урл, а куки по каким-то причинам не работают.
Смотрите, что у вас с куками.
Вообще, если у вас "не работают" сессии, то сначала попробуйте передать идентификатор сессии руками, то есть, сделать ссылку и приписать к ней идентификатор:
<?
session_start
();
if (!isset(
$_SESSION['counter'])) $_SESSION['counter']=0;
echo
"Вы обновили эту страницу ".$_SESSION['counter']++." раз.<br>
<a href="
.$_SERVER['PHP_SELF'].'?'.session_name().'='.session_id().">обновить";
?>

И, если не работает, то проблема либо в банальных опечатках (половина "проблем" с сессиями происходит от неправильно написанного имени переменной), либо в слишком старой версии PHP: поддержка сессий появилась в версии 4.0, а массив $_SESSION - в 4.1 (До этого использовался $HTTP_SESSION_VARS).
Если же заработает - то проблема в куках. Отслеживайте - что за куку ставит сервер браузеру, возвращает ли браузер ее. Искать очень полезно, просматривая просматривая обмен HTTP-заголовками между браузером и сервером.

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

Еще одна проблема может возникнуть, если вы используете перенаправление через header.
Дело в том, что РНР сам автодополняет ссылки на странице, но не делает этого для header-ов
Поэтому надо добавлять СИД руками, например, так:
header("Location: /script.php?".SID);

Дополнительная информация:

  • Кроме кук, механизм сессий посылает еще и заголовки, запрещающие кэширование страниц (тот самый cache limiter). Для html это правильно и необходимо. Но вот когда вы пытаетесь скриптом, проверяющим авторизацию, отдать файл, то интернет эксплорер отказывается его скачивать. Именно из-за этого заголовка. Вызов
    session_cache_limiter("private");
    перед стартом сессии должен решить проблему.
  • Как это ни кажется странным, но в массиве $_SESSION нельзя использовать числовые индексы - $_SESSION[1], $_SESSION['10'] - cессии работать не будут.
  • Где-то между версиями 4.2 и 5.0 невозможно было установить session.use_trans_sid с помощью ini_set(). Начиная с 5.0уже можно снова
  • До версии 4.3.3 куку PHP отправлял куку только если при старте сессии в запросе отсутстввал идентификатор. Теперь же кука посылается при каждом вызове session_start()
Статья была взята с webscript.ru.
     Новое на форуме:
Вопрос № 1. От: robot:
Воть какая ппроблема. Я пишу локатор для одной из онлайн игр. Тут на сайте я нащёл что-то типо грабера. вот что у меня получилось.
http://mrak.dragonclan.biz/lockator.php?name=robot- 1
имя пока передаётся как гет переменная....Но вот один глюк...Какой бы я размер не ставил... Всё равно выводит только до определённого символа...
Вот код:
<!doctype html public "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<title>Eieaoi?</title>
</hea d>
<body>
<?php
$name=$_GET["name"];
// ia?aei
$file = fopen("http://neverlands.ru/playerinfo.php?playername=$name",\ "r");
$rf = fread($file,120000);

//$rf = trim (chop ($rf));
//$s = strpos($rf, "</script>"); $rf = substr($rf, $s);

// 2
//$s = strpos($rf, "Место"); $rf = substr($rf, 0, $s);




echo "$rf";

fclose($file);

?>

</body>
</html>

Почему он не выводит мне весь файл...
Помочь | Задать свой вопрос

Вопрос № 2. От: serj:
Подскажите пожалуйста как можно реализовать с помощью php сессий такую задачу:

нужно чтобы все посетители заходили на сайт через главную страницу. Если посетитель зашел не через главную, нужно чтобы его перебросило на главную, а если он прошел через главную, то он может свободно ходить по сайту.

Отвечает: Serega:

Очень просто.

Надо на главной странице вставить код:

<?
session_start();
$from = "index";
session_register("from");
?>

А на остальных:

<?
session_start();
if(isset($from)) if($from != "index") Header("Location: index.php");
?>



Отвечает: serj:

Большое спасибо!!!
Очень благодарен.

Помочь | Задать свой вопрос

Вопрос № 3. От: Almaz:
Доброго времени суток!
На моем сайте все новости размещаются из БД. Есть ли возможность из той же базы данных выкладывать новости в WAP?
Помочь | Задать свой вопрос

Вопрос № 4. От: Serega:
Первое тестовое сообщение.

Отвечает: Klaid:

Сайт, конечно, очень интересный.
Нашёл для себя много нового.
Но есть одно БОЛЬШОЕ "НО", которое создаёт дискомфорт и оставляет неприятный осадок.
А именно - наличие на сайта множества грамматических ошибок!
Статьи читать очень неудобно.
Уважая язык, на котром мы излагаем свои мысли, мы уважаем и своего собеседника.
Если это просто опечатки, тогда не всё ещё потеряно.
Грамматика текста в программе Word проверяется элементарно.


Отвечает: Klaid:

ну вот! Сам поторопился и 2 слова написал с опечатками! Извините.


Отвечает: DarkLioN:

Есть замечательная штука на эту тему - проект Orphus.
Оформление - маааленький кусочек кода на страничке и кнопка.
Суть - увидевший ошибку на страничке выделяет слово мышкой и нажимает CTRL-D. Все! Сообщение об ошибке уходит автору сайта с указанием страницы и слова с ошибкой. Посмотреть как работает можно на моем сайте - www.deirkirov.best-host.ru
Код взять вроде бы на www.orphus.ru (или с моего сайта на кнопку нажать - перекинет куда надо)


Отвечает: rotate:

Вроде форум тут обновлялся, 3 раза, прям, трудно сказать, что лучше


Отвечает: Serega:

Проверка отправки сообщения, на емаил отправителя.

Помочь | Задать свой вопрос



...наверх...
     Автору:
      Если Вы - опытный веб-дизайнер или вам есть, что сказать читателям, то присылайте Ваши статьи по адресу serega@web-mir.com. Тема author. Ваши статьи будут опубликованы в близжайших выпусках рассылки (если, конечно, они будут содержать полезную информацию о веб-дизайне). В письме должны быть статья, ее название и контактная информация о авторе (имя и e-mail (например, с которого отправлено письмо) обязательно). Также Вы можете стать ведущими рассылки. Для этого отправьте письмо на этот же e-mail с той же темой, указав контактную информацию и тематику ваших статей.

     Возможно, подписываясь на эту рассылку, Вы уже имели опыт работы с PHP и создали какие-нибудь скрипты. Поэтому, если у Вас есть полезный скрипт для сайта, написанный на PHP, присылайте его мне на e-mail serega@web-mir.com с темой script. Он обязательно появится в этой рассылке и разделе "Скачать" с контактной информацией автора.


     На сегодня это все. Увидимся в следующем выпуске.
Рассылку подготовил, Ястребов Сергей.
Сайт рассылки http://www.web-mir.com/.
...наверх...

http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: inet.webbuild.abouthtml
Отписаться

В избранное