Thursday, December 3rd, 2009
Зачем изобретать велосипед? Главное уметь грамотно применить те технологии, которые расшаривают разные люди. Наткнулся на интересный туториал и нужно сказать демо меня впечатлило. Неплохо, не правда ли? А теперь посмотрим как это выглядит изнутри.
Создание Login Page : PHP, MySQL & jQuery
Код пригодится для создание member zone на сайтах (партнерки, дейтенги, или еще какая-нибудь ерунда). Демо можно скачать тут.
Step 1 – MySQL
Естественно для начала нужно обозначить таблицу, в которой будут надежно храниться данные. Для этого ученые мужи придумали SQL.
--
-- Table structure for table `tz_members`
--
CREATE TABLE `tz_members` (
`id` int(11) NOT NULL auto_increment,
`usr` varchar(32) collate utf8_unicode_ci NOT NULL default '',
`pass` varchar(32) collate utf8_unicode_ci NOT NULL default '',
`email` varchar(255) collate utf8_unicode_ci NOT NULL default '',
`regIP` varchar(15) collate utf8_unicode_ci NOT NULL default '',
`dt` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `usr` (`usr`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Мы определили id как auto_increment, это уникальный идентификатор, который будет присвоен каждому пользователю. Так же urs определен как UNIQUE KEY, для того, чтобы гарантировать уникальность юзернейма.
После того как таблица создана, нужно прописать данные в файл connect.php, это несложно. После этого можно будет запустить пример на своем сервере. Допилить напильником, и вставить куда надо.
Step 2 – XHTML
demo.php
Пора включить феб форму логина в нашу страницу.
В нескольких местах кода идет проверка определены ли переменные : $_SESSION['usr'] и $_SESSION['id'], это позволяет определить залогинен ли юзер на сайте или нет. Если они определены то это значит, что юзер уже залонился на сайте и ему нужно показывать совсем другой контент. Позже обсудим этот момент более детально.
После формы login – расположена основная часть страницы. Как это принято у нас, вебмастеров.
A Cool Login System
Easy registration management with PHP & jQuery
This is a ...
Как видите ничего особенного.

Step 3 – PHP
demo.php
Далее собственно логика обработки этой формы. Сделано на PHP, ну хоть на что-то этот язык годен.
В статье дают дельный совет : если вы планируете на века и проект серьезный, будет хорошей идеей разбить в на несколько файлов, и включать их по мере надобности (require). Это важно для больших проектов т.к. позволить использовать код повторно в других местах.
Вот что получается :
define('INCLUDE_CHECK',true);
require 'connect.php';
require 'functions.php';
// Those two files can be included only if INCLUDE_CHECK is defined
session_name('tzLogin');
// Starting the session
session_set_cookie_params(2*7*24*60*60);
// Making the cookie live for 2 weeks
session_start();
if($_SESSION['id'] && !isset($_COOKIE['tzRemember']) && !$_SESSION['rememberMe'])
{
// If you are logged in, but you don't have the tzRemember cookie (browser restart)
// and you have not checked the rememberMe checkbox:
$_SESSION = array();
session_destroy();
// Destroy the session
}
if(isset($_GET['logoff']))
{
$_SESSION = array();
session_destroy();
header("Location: demo.php");
exit;
}
if($_POST['submit']=='Login')
{
// Checking whether the Login form has been submitted
$err = array();
// Will hold our errors
if(!$_POST['username'] || !$_POST['password'])
$err[] = 'All the fields must be filled in!';
if(!count($err))
{
$_POST['username'] = mysql_real_escape_string($_POST['username']);
$_POST['password'] = mysql_real_escape_string($_POST['password']);
$_POST['rememberMe'] = (int)$_POST['rememberMe'];
// Escaping all input data
$row = mysql_fetch_assoc(mysql_query("SELECT id,usr FROM tz_members WHERE usr='{$_POST['username']}' AND pass='".md5($_POST['password'])."'"));
if($row['usr'])
{
// If everything is OK login
$_SESSION['usr']=$row['usr'];
$_SESSION['id'] = $row['id'];
$_SESSION['rememberMe'] = $_POST['rememberMe'];
// Store some data in the session
setcookie('tzRemember',$_POST['rememberMe']);
// We create the tzRemember cookie
}
else $err[]='Wrong username and/or password!';
}
if($err)
$_SESSION['msg']['login-err'] = implode('
',$err);
// Save the error messages in the session
header("Location: demo.php");
exit;
}
Мы ставим cookie tzRemember чтобы всегда знать следует ли логофать пользователя, который не поставил галочку “remember me”. Если кука не стоит (например после рестарта браузера) и посетитель не выбрал “remember me”, ему придеться вбивать логин/пасс заново.
Сама сессия ставится на 2е недели (session_set_cookie_params).
Следующая часть файла demo.php
else if($_POST['submit']=='Register')
{
// If the Register form has been submitted
$err = array();
if(strlen($_POST['username'])<4 || strlen($_POST['username'])>32)
{
$err[]='Your username must be between 3 and 32 characters!';
}
if(preg_match('/[^a-z0-9\-\_\.]+/i',$_POST['username']))
{
$err[]='Your username contains invalid characters!';
}
if(!checkEmail($_POST['email']))
{
$err[]='Your email is not valid!';
}
if(!count($err))
{
// If there are no errors
$pass = substr(md5($_SERVER['REMOTE_ADDR'].microtime().rand(1,100000)),0,6);
// Generate a random password
$_POST['email'] = mysql_real_escape_string($_POST['email']);
$_POST['username'] = mysql_real_escape_string($_POST['username']);
// Escape the input data
mysql_query(" INSERT INTO tz_members(usr,pass,email,regIP,dt)
VALUES(
'".$_POST['username']."',
'".md5($pass)."',
'".$_POST['email']."',
'".$_SERVER['REMOTE_ADDR']."',
NOW()
)");
if(mysql_affected_rows($link)==1)
{
send_mail( 'demo-test@tutorialzine.com',
$_POST['email'],
'Registration System Demo - Your New Password',
'Your password is: '.$pass);
$_SESSION['msg']['reg-success']='We sent you an email with your new password!';
}
else $err[]='This username is already taken!';
}
if(count($err))
{
$_SESSION['msg']['reg-err'] = implode('
',$err);
}
header("Location: demo.php");
exit;
}
$script = '';
if($_SESSION['msg'])
{
// The script below shows the sliding panel on page load
$script = '
';
}
Сохраняем все встречающиеся ошибки в массив $err, который далее присваевается переменной $_SESSION, для того, чтобы сохранить эти данные после редиректа.
Вы могли замететь на некоторых сайтах, что когда заполняете и отправляете форму, а затем обновляете страницу – данные передаются опять. Это может стать проблемой, привести к 2ой регистрации и ненужной нагрузке на сервер, чтобы избежать этого в примере использована функция header, которая просто редиректит браузер на ту же страницу. Страница обновляется, данные не посылаются.
Не забываем о том, что используется $_SESSION для хранения встречающихся ошибок, и важно сделать unset для этой переменной, после того как покажем ошибку юзеру, иначе они будут показываться при каждом просмотре страницы. Обратите внимание, что мы создали дополнительный скрипт (строчки 60-70 2ой части PHP кода), который показывает панель при загрузке страницы.
Теперь CSS

Step 4 – CSS
Выдвигающаясяя панель имеет собственный шаблон CSS.
demo.css
body,h1,h2,h3,p,quote,small,form,input,ul,li,ol,label{
/* The reset rules */
margin:0px;
padding:0px;
}
body{
color:#555555;
font-size:13px;
background: #eeeeee;
font-family:Arial, Helvetica, sans-serif;
width: 100%;
}
h1{
font-size:28px;
font-weight:bold;
font-family:"Trebuchet MS",Arial, Helvetica, sans-serif;
letter-spacing:1px;
}
h2{
font-family:"Arial Narrow",Arial,Helvetica,sans-serif;
font-size:10px;
font-weight:normal;
letter-spacing:1px;
padding-left:2px;
text-transform:uppercase;
white-space:nowrap;
margin-top:4px;
color:#888888;
}
#main p{
padding-bottom:8px;
}
.clear{
clear:both;
}
#main{
width:800px;
/* Centering it in the middle of the page */
margin:60px auto;
}
.container{
margin-top:20px;
background:#FFFFFF;
border:1px solid #E0E0E0;
padding:15px;
/* Rounded corners */
-moz-border-radius:20px;
-khtml-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius:20px;
}
.err{
color:red;
}
.success{
color:#00CC00;
}
a, a:visited {
color:#00BBFF;
text-decoration:none;
outline:none;
}
a:hover{
text-decoration:underline;
}
.tutorial-info{
text-align:center;
padding:10px;
}
Step 5 – jQuery
demo.php
В этом кусочке кода, для начала мы используем библиотеку Google CDN. Затем хак, чтобы долбанный IE отображал все правильно.
В конце страницы вызывается скрипт который показывает нашу панель логина.
Posted in Code | No Comments »
Friday, September 4th, 2009
Да-да, теперь не лезет, в свое время многие постарались на славу, чтобы ушатать этот блогхост кодеками и прочими интересными вещами. Но тем не менее даже на данный момент блогспот можно использовать для привлечения траффика, хотя для этого теперь нужно приложить хоть какие-то усилия. Помимо этого хост можно использовать в качестве индексируемой базы данных (я например какое-то время сохранял результаты google hot trends), собрания каких-либо тематических ссылок. На самом деле вариантов масса, в результате будут получаться различные блоги, и если обновленеи будет поставленно на поток, то эти сайты в конечном итоге послужат фундаментом SEO-империи.
Помимо этого гугл любезно предоставляет API для работы с большей частью своих сервисов, все это дело регулярно апдейтится и документируется, скачать библиотеку для Python можно на официальной странице Google GData Python Client. В данном случае нас интересует работа с blogspot.com. Внутри архива Google GData есть подробная (и короткая) инструкция по установке пакетов (package) для Python.
По поводу использования, на активстэйт как обычно все уже сделали до нас, однако в этом примере мой питон выдает ошибку :
TypeError: CreatePost() takes exactly 6 arguments (5 given)
Это легко исправить, функция CreatePost() помимов всего прочего принимает список тэгов которые нужно добавить к посту. В примере не хватает как раз этого параметра, хз в чем прикол, возможно защита от дурака =) Я пофиксил баг (пример работы с blogspot через API), чтобы все запускалось без проблем, нужно только разобраться в коде и использовать уже готовые функции, единственная не поддающаяся автоматизации через API задача – регистрация аккаунтов, но гмыла можно купить, а регистрировать и оформлять блог или руками, или используя софт эмулирующий работу браузера вроде Human Emulator, хардкорные кодеры, конечно могут реализовать это через curl.
Работать через API конечно удобно, если собирать более-менее красивые блоги в небольшом количестве. В остальных случаях, крайне желательно использовать прокси и как вы понимаете этого (во всяком случае прямо) в API не предусмотрено, нужно или хитрить запуская код через различные проксификаторы или править код самой библиотеки.
Posted in GData, Google, Python | No Comments »
Friday, September 4th, 2009
Бывает вещи кажущиеся авторам очевидными, на самом деле нифига не очевидны. В качестве примера – установка пакетов или дополнений для Python. Когда я только начал знакомиться с сабжем, данный вопрос потребовал некоторого времени и в конце концов был решен методом проб, ошибок и поиска в гугле. В отличии от PHP, где многие модули уже есть “по умолчанию”, питон использует библиотеки которые программист подгружает по мере необходимости. Существует огромная коллекция этих дополнений практически на все случаи жизни, можно посмотреть тут Python Package Index. Установку любого пакета можно выполнить в несколько шагов :
- Скачать архив с пакетом и разархивировать его в какую-нибудь папку.
- Используя либо консоль (как тру-хаккер), либо файл менеджер перейти в папку с исходниками пакета и выполнить комманду : python setup.py install
- Посмотреть как устанавливается пакет, прочитать финальные поздравления и если что-то не так поискать/изучить инструкцию по установке, которая обычно прилагается.
На данный момент официальный репозиторий насчитывает более 7000 наименований, которые даже удобно разделены по категориям.
Posted in Python | No Comments »