Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: разработка для Web > Подтверждение на Perl


Автор: Digo 12.4.2005, 09:08
Доброго времени суток!
Я в Perl только начинаюший и много не понимаю... Вообщем возникла необходимось создать приметивный скрипт подтверждения. Идея такова: человек заполняет анкету, после заполнения PHP скрипт отсылает на маил указанный в ней письмо, где есть сформированная сылочка типа http://mysite.ru/cgi-bin/script.pl?name=hisname Вообщем передаем параметры скрипту, который отсылает на мой маил этот параметр и текст что регистрация подтверждена. Еще где-то прочитал, что если параметр 1 его можно передавать так http://mysite.ru/cgi-bin/script.pl/hisname , или я что-то путаю?
Заранее благодарен.

Автор: Phoinix 12.4.2005, 15:21
Digo

Цитата(Digo @ 12.4.2005, 09:08)
если параметр 1 его можно передавать так http://mysite.ru/cgi-bin/script.pl/hisname


http://mysite.ru/cgi-bin/script.pl?hisname

Вообще-то не hisname, а уникальный ключ, по которому ты определяешь какого пользователя активизировать...

Автор: Secandr 12.4.2005, 15:34
Digo ты можешь параметры передать и так:

http://mysite.ru/reg/hisname

для этоого есть примочка к апачу mod_rewrite, которая сделает перенаправление с http://mysite.ru/reg/hisname на http://mysite.ru/cgi-bin/script.pl?name=hisname

Автор: Digo 12.4.2005, 20:37
Спасибо!
Да я там немного напутал... smile
Теперь столкнулся с проблемой как реализовать сам скрипт. Я походу че-то не так делаю или передаю, постоянно серверная ошибка 500. Идея такая кликая по ссылке передаю параметр, который присылается мне в письме... Может кто поможет?

Автор: Secandr 13.4.2005, 15:03
скорей всего у тебя ошибка в первой строке, неверные права на файл или символы с кодом 10 завершают строку.

Автор: Digo 14.4.2005, 13:23
Решил начать с простого:
вот код
Код

#!/usr/bin/perl
my $LastName = param{'lastname'} ;
print "Подтверждение: ", param('lastname'),"<BR>";


передаю по ссылке http://mysite.ru/cgi-bin/script.pl?lastname=hisname
Вообщем для начала хочу просто ввыводить параметр переданный ссылкой на экран.
Опять та же фигня... Права 644, путь тот, символы с кодом 10 не знаю что это smile вроде набирал в блокноте...

Автор: Secandr 14.4.2005, 15:42
Digo вот вот, ты набирал в блокноте у тебя ентер - это два символа 10 и 13, а в юниксе только 13. И шел считает что путь у тебя к #!/usr/bin/perl◙

Автор: korob2001 14.4.2005, 16:07
Где заголовок???
Где подключение модуля CGI.pm???
param() это функция, потому передавать ей значение не нужно в фигурных скобках .
Привыкай всегда использовать use strict, не самая плохая привычка ;)))).
После того как получил параметр и сохранил его в переменную, не используй больше param(), пользуйся только той переменной в которую был сохранён параметр, можешь легко запутаться.
Код

#!/usr/bin/perl
use strict;
use CGI qw( :standard );
print header( -charset => 'Windows-1251');
my $LastName = param('lastname') ;
print "Подтверждение: ", $LastName, "<BR>";

Удачи.

Автор: Secandr 14.4.2005, 16:28
korob2001 это следующий этап.

Автор: korob2001 14.4.2005, 16:34
Цитата

korob2001 это следующий этап.

Secandr - ну может ты и прав, но только вот 500-ю ошибку он будет получать до тех пор, пока не выведет заголовок и не подключит модуль CGI.pm, он ведь пытается юзать param() именно из CGI.pm smile

Автор: Secandr 14.4.2005, 16:45
Вообщем чинить и чинить...

Автор: Digo 15.4.2005, 09:01
Очень признателен вам Secandr и korob2001 за консультацию! smile
Вот только где тогда набирать скрипт если даже блокнот не подходит?

Автор: Kiber_rat 15.4.2005, 12:44
Поставь VI под Windows или используй любой редактор с подсветкой синтаксиса из этой ветки форума: http://forum.vingrad.ru/index.php?showtopic=43960

Автор: korob2001 15.4.2005, 14:27
Заюзай DZSoft Perl Editor 5.4

Автор: Digo 15.4.2005, 19:39
Скачал DZSoft Perl Editor 5.6 рулит!!! спасибо, korob2001... правда trial до 120 строк кода smile
Все работает!!!
Теперь буду думать как переданный параметр на свой почтовый ящик отправлять...

Автор: Digo 16.4.2005, 09:05
Вот опять столкнулся с проблемами:
Вроде скрипт работает, выводит параметры, но почту не отсылает, в чем может быть дело?

Код

#!/usr/bin/perl
#$mail_prog = '/usr/sbin/sendmail' ;
#$recipient = '[email protected]';
use strict;
use CGI qw( :standard ); print header( -charset => 'Windows-1251');
my $LastName = param('lastname') ;
print "Подтверждение: ", $LastName, "<BR>";

open (MAIL,"|/usr/sbin/sendmail");
print MAIL "To: xxx\@mail.ru\n";
print MAIL "Content-Type: text/plain; charset=windows-1251\n";
print MAIL "From: digo\@list.ru\n";
print MAIL "Subject: Subject\n\n";
print MAIL "Подтверждение от ".$LastName." \n" ;
close MAIL;


Автор: Secandr 17.4.2005, 08:30
а точно путь /usr/sbin/sendmail

где ты его взял?

Автор: Digo 17.4.2005, 10:14
Да, я в супорте своего хоста спросил, они сказали /usr/sbin/sendmail К тому же у меня работает другой скрипт отправки почты, у него тот же путь...

Автор: korob2001 17.4.2005, 17:39
Код

open (MAIL,"|/usr/sbin/sendmail");

Добавь ключи:
Код

open (MAIL,"|/usr/sbin/sendmail -t -oi -odq");

-t - Поля заголовка берутся из входных данных, а не из командной строки
-oi - Символ точки не считать признаком конца сообщения
-odq - Ставит сообщения в очередь, а не пытается отправить его немедленно, этот ключ можно убрать, но без него sendmail становится уязвим при атаке "Отказ от обслуживания".

Автор: Digo 18.4.2005, 18:41
Спасибо smile smile , теперь работает, правда письма с задержкой доходят...
Последний шаг это редирект после выполнения скрипта... Я как понял он осуществляется
print "Location: http://www.mysite.ru/\n\n";

когда выполняю скрипт, все просто выводится на экран, и никуда не переходит...

Автор: korob2001 18.4.2005, 19:00
Для того, что бы работал редирект, им нужно заменить заголовок:
print "Content-type: text/html\n\n";
Т.е. строку заголовка нужно заменить следующей:
Код

print "Location: http://yandex.ru\n\n";

Если используешь CGI.pm, то заголовок:
Код

print $cgi->header();

Нужно заменить на такой
Код

my $cgi = new CGI;
print $cgi->redirect( -uri => 'http://yandex.ru' );


Если нужно просто перенаправить пользователя через определённое кол-во секунд, то вставляешь в код страницы, с которой будет осуществляться перенаправление, такую строку в раздел <HEAD></HEAD>:
Код

<meta HTTP-EQUIV="Refresh" CONTENT="5;URL='http://yandex.ru'">

Другими словами, в HTML коде это будет выглядеть примерно так:
Код

<html>
 <head>
   <meta HTTP-EQUIV="Refresh" CONTENT="5;URL='http://yandex.ru'">
    <title>Перенаправление</title>
 </head>
 <body>
   <!--// Здесь тело документа //-->
 </body>
</html>

В последнем примере, перенаправление произойдёт через 5 секунд.
Удачи.

Автор: Digo 18.4.2005, 21:01
В принципе все понятно... только вот что менять?, нужно же оставить print header( -charset => 'Windows-1251');(чтоб русские буквы отображал)??? А если дописывать пишет Status: 302 Moved Location:http://yandex.ru
Кстати редирект будет осуществлятся после отправки письма?

Код

use strict;
use CGI qw( :standard );
print header( -charset => 'Windows-1251');
my $cgi = new CGI;
print $cgi->redirect( -uri => 'http://yandex.ru' );

....



Автор: korob2001 18.4.2005, 23:33
redirect() - это и есть хеадер, только с перенаправлением.
charset - указывай на той странице, куда перенаправляешь пользователя, можешь ещё указать прямо в redirect'e.
Код

print $cgi->redirect( -uri => 'http://yandex.ru',
                      -charset => 'Windows-1251' );

Если используешь redirect, то header не нужен.
Код

use strict;
use CGI;
my $cgi = new CGI;
print $cgi->redirect( -uri => 'http://yandex.ru',
                       -charset => 'Windows-1251' );

Удачи.

ЗЫ: если используешь CGI.pm объектно ориентированно, то не нужно указывать qw( :standard ). Просто пиши так use CGI; , создавай объект и орудуй всеми методами и свойствами этого, чудного, модуля.

Автор: Digo 19.4.2005, 18:07
Большое спасибо smile , а то я никак не знал как редирект осуществлять, только теперь письма не отправляет, похоже просто не выполняется все что ниже, как же тогда делать если нужно осуществлять редирект после отправки письма?

Автор: korob2001 19.4.2005, 21:04
Разбей программу на подпрограммы, там геде нужен redirect, юзай redirect, там где нужен header, юзай header.

Структура примерно такая:
Код

#!/usr/bin/perl -w
use strict;
use CGI;
my $cgi = new CGI;

sub show_form {
       
       print $cgi->header( -charset => 'Windows-1251' );
       # Здесь тело подпрограммы выводящей форму в браузер

}


sub send_mail {

      # Здесь тело подпрограммы которая отправляет E-mail
      # ни header, ни redirect здесь не нужны

      # Здесь отправляем письмо

      # А здесь перенаправляем пользователя
      enjoy();
      
}


sub user_controll {

      # Здесь тело подпрограммы, которая проверяет полученные параметры
      # Ни header, ни redirect здесь не нужны

}


sub enjoy {
      
      # Здесь перенаправляем юзера
      print $cgi->redirect( -charset => 'indows-1251',
                            -uri => 'http://yandex.ru' );
     
}

# Здесь делаем условия по которым будем запускать ту, или иную подпрограмму
if ( defined $cgi->param('send') ) {
     # Если программа получила параметр send, запускаем подпрограмму проверки данных
     # если она вернёт истенное значение значит данные обрботаны и в порядке. Тогда
     # передадим управление подпрограмме send_mail();
     send_mail if user_controll();
} else {
     # Если параметры не полученны, выводим форму в браузер
     show_form();
}

Получается такая последовательность, когда запускается программа, она пропускает все подпрограммы. Когда доходит до условного выражения if ...else она проверяет был ли передан программе параметр send - это может быть имя кнопки SUBMIT.

Если параметр определён, то значит пользователь нажал кнопку SUBMIT и нам нужно сделать проверку данных если подпрограмма user_controll вернула истенное значение, то значит данные проверены и готовы к отправке. Запускаем подпрограмму send_mail.

Далее подпрограмма send_mail отправляет данные и из неё запускается подпрограмма enjoy, которая и перенаправляет пользователя на нужную тебе страницу.

Вообще-то я упростил код и условия для наглядности, для удобства можно было бы передавать параметры из одной подпрограммы, в другую. Не мешало бы ещё создать подпрограмму, которая выводила бы ошибки, если подпрограмма user_controll их опеределит. Но это уже лирика, цель была объяснить принцип и удобство работы программы, которая разбита на несколько подпрограмм.

Вроде понятно изложил.

Удачи.

Автор: Digo 23.4.2005, 11:19
Спасибо за программу, я вчера в ней разбирался весь вечер с книгой (вернее в использовании процедур smile ) Вот только вопрос нельзя ли как-то упростить программку, мне например не нужно проверять данные и передавать параметр или выводить что-то в браузере(это я делал для проверки) Мне только нужно отправить в письме переданный по ссылке параметр и после осуществить редирект на html страницу.
Пытаюсь вызвать процедуру с конца, но че-то не пашет...

Код

#!/usr/bin/perl -w
use strict;
use CGI;
my $cgi = new CGI;

sub enjoy {

      # Здесь перенаправляем юзера
      print $cgi->redirect( -charset => 'Windows-1251',
                            -uri => 'http://yandex.ru' );

}



open (MAIL,"|/usr/sbin/sendmail -t -oi -odq");
print MAIL "To: orders\@helpos.org\n";
print MAIL "Content-Type: text/plain; charset=windows-1251\n";
print MAIL "From: xxx\@mail.ru\n";
print MAIL "Subject: Subject\n\n";
print MAIL "Переданный  параметр ".$LastName." \n" ;
close MAIL;

enjoy();


Автор: korob2001 23.4.2005, 12:35
Ну, а где переменная $LastName получает параметр??? Вобщем замени строку:
Код

print MAIL "Переданный  параметр ".$LastName." \n" ;

На такую:
Код

print MAIL "Переданный  параметр ". $cgi->param('lastName') ." \n" ;

Естественно измени lastName на сой параметр.

ЗЫ: Только этот код очень опасен, я надеюсь ты понимаешь почему.

Удачи.

Автор: Digo 23.4.2005, 17:31
Да, я просто не все скопировал...
Все равно ошибки не возникает, редирект проходит, а письмо не отсылается:
Код

#!/usr/bin/perl -w
use strict;
use CGI;
my $cgi = new CGI;

sub enjoy {

      # Здесь перенаправляем юзера
      print $cgi->redirect( -charset => 'Windows-1251',
                            -uri => 'http://yandex.ru' );

}


print "Переданный  параметр ". $cgi->param('lastName') ." \n" ;
open (MAIL,"|/usr/sbin/sendmail -t -oi -odq");
print MAIL "To: orders\@helpos.org\n";
print MAIL "Content-Type: text/plain; charset=windows-1251\n";
print MAIL "From: xxx\@mail.ru\n";
print MAIL "Subject: Subject\n\n";
print MAIL "Переданный  параметр ". $cgi->param('lastName') ." \n" ;
close MAIL;

enjoy();

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

Автор: korob2001 23.4.2005, 17:42
Только что проверил, всё работает только строку:
Код

print "Переданный  параметр ". $cgi->param('lastName') ." \n" ;

нужно убрать.

Автор: Digo 23.4.2005, 19:25
Да, верно просто у меня сервер тормозит только сейчас письмо дошло smile , только в письме не пришел сам параметр
Пришло: Переданный параметр и все...

Автор: korob2001 24.4.2005, 01:11
Цитата

Да, верно просто у меня сервер тормозит только сейчас письмо дошло

-odq - Ставит сообщения в очередь, а не пытается отправить его немедленно, этот ключ можно убрать, но без него sendmail становится уязвим при атаке "Отказ от обслуживания".
Думаю ты понял, что это не сервер тормозит, а ты сам его поставил в очередь.
Цитата

только в письме не пришел сам параметр

Если у ты принимаешь параметр так:

Код

my $LastName = $cgi->param('LastName');

то вызывать скрипт нужно с параметром script.pl?LastName=Vasya

ЗЫ: Особое внимаение обрати на регистр букв.

Удачи.


Автор: Digo 25.4.2005, 20:29
Спасибо большое korob2001 smile ты мне очень помог не только написать программу, но и разобратся с некоторыми нюансами языка.
З.Ы. Ошибка была в регистре... smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)