После создания базы данных назрел вопрос о том, каким образом данные будут туда попадать. В связи с этим мы рассмотрим формы HTML. Через них любой пользователь твиттера сможет добавить свой аккаунт в мой рейтинг. Перед сохранением данных, введённых будущим участников рейтинга, их нужно проверить. Для этого требуется ряд функций, которые мы рассмотрим в этом посту. Но перед тем, как мы продолжим, небольшое отступление. Я сразу кинулся докладывать про свои опыты с PHP и забыл написать о том, какое программное обеспечения я использую. Как локальный сервер я использую сборку XAMPP. XAMPP состоит из Apache, MySQL, PHP, Perl, OpenSSL, phpMyAdmin, FileZilla FTP Server и большое количество дополнительных библиотек, позволяющих запустить полноценный веб-сервер. Джентельменский набор веб-разработчика, сокращённо Denwer, мене не понравился. С ходу с ним разобраться не получилось, а в XAMPP всё "с первого взгляда" и "с первого клика". Для написания кода я использую бесплатную интегрированную среду разработки Code::Blocks, с которой я знаком с проектов на C/C++. Правда, PHP там не поддерживается, то есть, нет некоторых фич, типа, подсветки кода. Потихоньку я готов для знакомства с каким-нибудь фреймворком для PHP. Хоть я работаю с этим языком программирования только с неделю, но мене уже сейчас надоело писать каждую функцию самостоятельно. Нашёл список фреймворков, может кто поделится советом, какой из них лучший? А теперь продолжим с PHP. Формы HTML Начнём с форм HTML. Они исплользуются для ввода данных пользователем, их передачи серверу с целью их манипуляций. Я у себя в блоге не буду рассматривать все подробности форм, с ними можно ознакомиться на других ресурсах. Здесь я только рассмотрю формуляр для моего рейтинга для твиттера. Всего нужно заполнить 3 поля: ник на твиттер, электронную почту и обратную ссылку. Все три поля - это простой текст (type="text"). maxlen ограничивает количество символов для ввода, size - это размер поля, value - начальное значение, а name - название поля. Эта информация передаётся методом post скрипту post.php, который её обрабатывает. Code <form action="post.php" method="post"/> Ник на Twitter: <input type="text" name="username" maxlen="50" size="50"/> Почта: <input type="text" name="email" maxlen="50" size="50"/> Обратная ссылка: <input type="text" name="backlink" maxlen="50" size="50"/> <input type="reset" value="Очистить"/> <input type="submit" name="go" value="Отослать"/> </form> Обработка данных на сервере Теперь к скрипту post. Первым делом в его состав включается файл func.php, в который я запихал все функции. Потом присваиваем переменным $username, $email и $backlink отправленные пользователем данные и проверяем эти данные. Если есть пустые поля, если нет такого пользователя на твиттер, если были введены неправильные значения в поля электронная почта и обратная ссылка, то выводим соответственное сообщение. Если всё было заполнено правильно, то подключаемся к базе данных, данные для доступа к БД прописаны в db.php. Проверяем, есть ли такой участник в рейтинге. Если нет, то добавляем нового участника. Code include ("func.php");
$username = ($_POST['username']); $email = ($_POST['email']); $backlink = ($_POST['backlink']);
if( ($username == NULL) || ($email == NULL) || ($backlink == NULL) || (checklink($username, 1, 0) == 0) ) { if($username == NULL) { echo "Введите ваш ник на Twitter!<br/>"; } if($email == NULL) { echo "Введите вашу электронную почту!<br/>"; } if($backlink == NULL) { echo "Введите адрес обратной ссылки!<br/>"; } if(checklink($username, 1, 0) == 0) { echo "Не найден такой пользователь на Twitter!<br/>"; } } else { if( (check_email($email) == 1) || (check_url($backlink) == 1) ) { if(check_url($backlink) == 1) { echo "Введите действительную обратную ссылку!"; } if(check_email($email) == 1) { echo "Введите правильный адрес электронной почты!"; } } else { include ("db.php"); $result = mysql_query("SELECT count(*) FROM `user` WHERE username = '$username';", $db); $row = mysql_fetch_array($result, MYSQL_NUM); if($row[0] != 0) { echo "В рейтинге уже есть участник с ником $username.<br/>"; } else { // добавляем в базу данных добавляется аккаунт $str_sql_query = "INSERT INTO `user` (`regdate` ,`username` ,`email` ,`backlink` ,`activated`) VALUES (NOW(), '$username', '$email', '$backlink', '0');";
if(!$result = mysql_query($str_sql_query, $db)) { echo "Ошибка при добавлении участника в базу данных!<br/>"; exit(); } else echo "Новый участник был добавлен в базу данных!<br/>После проверки модератором он появится в рейтинге."; } mysql_close($db); } } Проверка поля для электронной почты Проверяем синтаксис введённого электронного ящика с помощью регулярных выражений. В принципе, функция eregi проверяет символ не обращая внимания на регистр букв.Но код этой проверки я откуда-то скопипастил, а менять ничего не охота. Как гласит одна программерская мудрость, работает - не трогай. Потом мы разбиваем адрес ящика на юмя пользователя и сервер. Функция getmxrr производит получение MX записи для интернет-хоста, а с помощью функции fsockopen мы соединяемся с сервером. Смысл этих действий, выяснить, существует ли такой сервер вообще. Если да, то возвращаем нолик, если нет, то единицу. Code function check_email($email) { if (!eregi("^[\._a-zA-Z0-9-]+@[\.a-zA-Z0-9-]+\.[a-z]{2,6}$", $email)) return 1; list($username, $domain) = split("@",$email); if (@getmxrr($domain, $MXHost)) return 0; else { $f = @fsockopen($domain, 25, $errno, $errstr, 30); if($f) { fclose($f); return 0; } else return 1; } } Проверка поля с урлом Эта функция делает почти тоже самое, что и check_email. Она проверяет синтаксис заданной пользователем обратной ссылки и наличие такого сервера. Если проверка синтаксиса вам кажется странной, то не забывайте, что ссылка на сообщение в твиттере выглядит так: http://twitter.com/RealyMoney/status/7693084442. Функция head проверяет HTTP статус страницы, "нормальная" страница без ошибок имеет статус 200, о ней речь пойдёт ниже. Если всё нормально, возвращаем нолик, если что-то неладно, то единицу. Code function check_url($url) { if(preg_match("!^(http|https)+(://)+(www\.|[a-z0-9\.-]{3,})?([a-z0-9\.-]{3,})+[a-z]{2,4}+(/)?([a-z0-9\-]{0,})?(/)?([a-z0-9\-]{0,})?(/)?([a-z0-9\-]{0,})?$!i",$url) && head($url, 0) == 200) { return 0; } return 1; } Проверка существования URL Теперь мы приближаемся к самой хитрой функции на сегодны, функции head, которая проверяет, существует ли веб-адрес. Она обрабатывает два варианта веб-адресов - страница пользователя твиттера и путь к XML-файлу пользователя твиттера. Я её редко использую напрямую, как в функции check_url, она обычно вызывается из функции checklink. checklink требует три параметра, имя юзера на твиттер, и две цифры, которые могут имет значение 0 или 1. Первая цифра указывает, проверяем мы страницу пользователя или урл к XML. Вторая цифра указывает, печатать полученные подробности или нет. Code function checklink($user, $kind, $print) { if($kind == 0) { $url = get_user_url($user); } if($kind == 1) { $url = get_user_xml($user); } if(head($url, $print) == 200) { return 1; } // линк существует else return 0; // линк не существует } Чтобы получить нужные урлы, используются две простенькие функции. При этом ник пользователя твиттера вставляется в адрес к странице пользователя или к XML. Code function get_user_xml($user) // получаем ссылку на xml пользователя { return "http://twitter.com/users/show/$user.xml"; }
function get_user_url($user) // получаем ссылку на блог пользователя { return "http://twitter.com/$user"; } Вот и добрались до самой хитрожопой функции. Сперва с помощью функции trim заменяем http в адресе на пустую строку, то есть просто-напросто убираем. Потом ищем с помощью функции strpos слэш. Если слэша нет, то в переменной $url осталось только название хоста, а $path присваивается корневая папка. Если путь указан, то до первого слэша находится хост, а всё, что потом идёт, это путь. Соединяемся с сервером, делаем запрос и читаем ответ сервера. Честно говоря, я сам не до конца понимаю, что там написано, так как жта часть кода была самым наглым образом присвоена. Единственное, что я понимаю, что мы запрашиваем статус страницы, сервер нам отвечает и мы этот статус вычитываем из ответа. Если статус 200, то страница есть и всё в порядке. Если страница временно или навсегда перемещена (статусы 301 и 302), то вся функция выполняется с новым адресом. Во всех остальных случаях возвращается нолик. Code function head($url, $print_head) { $replace = "/^http:\/\//i"; $by = ""; $url = trim(preg_replace($replace, $by, $url)); $c = strpos($url,"/"); if(!$c) { $host=$url; $path="/"; } else { $host = substr($url, 0, $c); $path = substr($url, $c); } if($print_head) echo "Location: $location<br>host: $host<br> path: $path<br>";
$fp = fsockopen($host, 80, &$errno, &$errstr, 10); if($fp) { fputs($fp,"HEAD $path HTTP/1.0\r\n"); fputs($fp,"Host: $host\r\n"); fputs($fp,"User-Agent: PHP/StatusCheck V0.2\r\n"); fputs($fp,"\r\n");
while(!feof($fp)) { $c=fgets($fp,133); if(strlen($c)==2) break; if($print_head) echo htmlentities($c)."<br>"; if(preg_match("/^HTTP.*? ([0-9]{3})/i", $c, $match)) $status = 0 + $match[1]; if(preg_match("/^Location: (.*)$/i", $c, $match)) $newLocation=$match[1]; } if($print_head) echo " =>Status: $status<br><br>"; if(($status==302 || $status==301) && $newLocation) return(head($newLocation, $print_head)); else return ($status); fclose($fp); } else { if($print_head) { echo "Не могу подсоединиться!"; echo "Errno:$errno Errstr:$errstr<br><br>"; } return 0; } } Ещё совсем немного и мой твиттер-рейтинг будет готов! А пока вы можете добавлять свои чирикалки в базу данных. Всё уже десять раз поменялось, структура базы данных поменялась, по этому скрипт отседова убираю. Так же с "совсем немного и будет готов" я поспешил.
|