Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Black::CGI, обсуждение модуля 
:(
    Опции темы
BlackLFL
Дата 10.2.2006, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



 Добрый день, уважаемые посетители!

Представляю на всеобщее обозрение свой первый модуль ( что он первый это не совсем верно, но это тут ни причем ).
Я с первого дня програмирования на Perl не пользовался модулем CGI.pm, многие меня укоряли за это, кто-то хвалил, но данный поступок был сугубо личным... хотелось бы попросить не обсуждать тут, что-то вроде "пользуйса CGI.pm и не мешай нам жить".

Перед написанием модуля, были просмотрены CGI.pm, cgi-lib, другие реализации, но основным источником конечно являются специйикации RFC ( если кому интересно, можете почитать RFC 2388 и дальше по тексту ).


Что делает модуль?
  • Разбирает данные переданые методами POST, GET
  • Разбирает теневые посылки, более известные как куки
Код модуля
Вы можете скачать с моего сайта Black::CGI.pm, тут не выкладываю, чтобы всегда была последняя версия модуля.

Как использовать модуль?
Примеры
Последняя версия документации Black::CGI.pod
Код

#!/usr/bin/perl
use strict;
use warnings;
use Black::CGI;

## Разбираем данные
my $cgi = Black::CGI->new
    ( 
        # Максимально разрешенный объем POST запроса, в байтах.
        # Поумолчанию 2097152 = 2 МБ
        post_max_length => 2097152,
        # Максимально разрешенный объем GET запроса, в байтах.
        # Поумолчанию 1024
        get_max_length => 1024,
        # Директоря, в которой будут храниться временный файлы, полученые через multipart/form-data
        # Должены быть права на запись
        # По умолчанию, текущая директория ./
        temp_folder => "/tmp",
        # Очищать временную папку, если она переполнена
        # 0 - отключен, 1 - включен
        # Поумолчанию отключено
        clear_temp_folder => 0,
        # Префикс перед именем временного файла
        temp_file_prefix => "black-cgi-",
        # Режим отладки
        # Если режим отладки включен, будет выводиться ошибка полученная через STDERR
        # 0 - отключен, 1 - включен
        # По умолчанию выключен
        debug => 0,
        # Максимально разрешенный размер временой папки (при суммирование размера всех временных файлов)
        # Размер должен быть минимум больше разрешенного объема POST запроса (post_max_length) на 1 кб
        temp_size => 2098176
    );
# Все опции необязательны, и имеют значения "по умолчанию"

## Создаем хэш метода POST
my $_POST = $cgi->post;
## Получаем значение поля title 
$_POST->{title}

## Создаем хэш метода GET
my $_GET = $cgi->get;
## Получаем значение поля title 
$_GET->{title}

## В некоторых случаях следует объеденить два метода в один, например,
# когда передается ключ сессии, который может передоваться
# как через POST так и через GET.
# Приоритет останвлен за методом POST, т.е. если данные были переданы через 
# POST и GET, одновременно, будет возращено значение переданное через POST
## Получаем значение поля session_key 
my $session_key = $cgi->param('session_key');

## Создаем хэш информации о файлах
my $_FILE = $cgi->file;
## Получаем информацию о файле из поля image
## имя файла
$_FILE->{image}->{name}
## путь, где хранится временный фаил
$_FILE->{image}->{temp_name}
## Расширение файла
$_FILE->{image}->{expansion}
## Тип файла
$_FILE->{image}->{content_type}

## Получаем содержание файла
my $file_body = $cgi->receive_file( $_FILE->{image} ) or die $cgi->error;

## Создаем хэш теневых посылок
my $_COOKIE = $cgi->cookie;
# Получаем значение password 
$_COOKIE->{password}

# Удаление временных файлов, 
# загруженных посредством метода POST multipart/form-data
# вызывается авматичеси по завершению работы скрипта

Хотелось бы услышать Ваши отзывы, рекомендации, пожелания по работе модуля.
Если кому интересно, можете присоединиться!

Заранее благодарен за любые комментарии! 

Это сообщение отредактировал(а) BlackLFL - 18.3.2008, 13:48
PM WWW   Вверх
sharq
Дата 11.2.2006, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Perl Liker
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 13.12.2004
Где: Ростов-на-Дону

Репутация: 2
Всего: 28



Это очень бегло и только по коду,
не тестировал, не сравнивал...

1. Если это готовый модуль, то из модуля необходимо убрать строки:
Код

use strict;
use warnings;

2. Ключи хеша бери в кавычки, т.к. возможно у тебя будет функция с одноименным названием и произойдет ее вызов.
3.
Код

    bless $self;
    # Возращаем экземпляр
    return $self;

можно написать короче
Код

    # Возращаем экземпляр
    return bless $self;;

или
Код

bless $self;

4.
Код

my($buffer);

избавляйся от лишних скобок
5.
Код

Argument "\r\n\r\n" isn't numeric in numeric ne (!=) at CGI.pm line 147.

6.
Код

            # Декодируем названия поля, значение
            $name =~ tr/+/ /;
            $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack( "C", hex($1) )/ge;
            $content =~ tr/+/ /;
            $content =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack( "C", hex($1) )/ge;

Эта часть кода повторяется несколько раз.
7. Это должно вызываться автоматически, т.е. деструктором
Код

# В конце работы, не забывайте вызывать метод удаления временных файлов, 
# загруженных посредством метода POST multipart/form-data
$cgi->remove or print $cgi->error;

8.
Код

use lib ("./");

Это лишняя строка, т.к. по умолчанию модули ищутся в текущей директории.

В принципе, хорошо написано, не останавливайся на этом, продолжай совершенствоваться, удачи.

smile


--------------------
[color=gray]There's More Than One Way To Do It[/color]
PM MAIL WWW ICQ Skype   Вверх
BlackLFL
Дата 11.2.2006, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



Цитата

1. Если это готовый модуль, то из модуля необходимо убрать строки:
Код

use strict;
use warnings;


модуль не закончен, когда выйдет первый релиз, уберу.

Цитата

2. Ключи хеша бери в кавычки, т.к. возможно у тебя будет функция с одноименным названием и произойдет ее вызов.

Спасибо, приму к сведенью!

Цитата

3.
Код

    bless $self;
    # Возращаем экземпляр
    return $self;

можно написать короче
Код

    # Возращаем экземпляр
    return bless $self;;

или
Код

bless $self;


об этом я конечно знаю, написал пошагово, чтобы начинающим програмистам было более понятно.

Цитата

4.
Код

my($buffer);

избавляйся от лишних скобок

забыл убрать smile , спасибо

Цитата

6.
Код

            # Декодируем названия поля, значение
            $name =~ tr/+/ /;
            $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack( "C", hex($1) )/ge;
            $content =~ tr/+/ /;
            $content =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack( "C", hex($1) )/ge;

Эта часть кода повторяется несколько раз.

вывел в отделную функцию.
Код

### Функция декодирования переданых данных
sub decode {
    my $self = shift;
    $self =~ tr/+/ /;
    $self =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack( "C", hex($1) )/ge;
    
    return $self;
}
...
$name = decode ( $name );
$content = decode ( $content );


Цитата

7. Это должно вызываться автоматически, т.е. деструктором
Код

# В конце работы, не забывайте вызывать метод удаления временных файлов, 
# загруженных посредством метода POST multipart/form-data
$cgi->remove or print $cgi->error;


Вы правы, многие могут забыть ... сделал деструктор.
Код

sub DESTROY {
    my $self = shift;
    eval { $self->remove; }
}


Цитата

8.
Код

use lib ("./");

Это лишняя строка, т.к. по умолчанию модули ищутся в текущей директории.

Спасибо, не знал!

Цитата

В принципе, хорошо написано, не останавливайся на этом, продолжай совершенствоваться, удачи.

Спасибо за коментарии!!
PM WWW   Вверх
BlackLFL
Дата 13.2.2006, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



добавлен метод получения содержания файла

Код

## Получаем содержание файла
my $file_body = $cgi->receive_file( $_FILE->{image} ) or die $cgi->error;


CGI.pm
Код

### Функция возврата содержания файла
sub receive_file {
    my($self, $file) = @_;
    my $body;
    
    if( defined $file->{'temp_name'} ) {
        local *FILE;
        
        open( FILE, $self->{'temp_folder'} . $file->{'temp_name'} ) or $self->{'error'} = ( $self->{'debug'} ) ? $! : "Невозможно открыть временный фаил" and return 0;
        eval { flock( FILE, 2 ); };
        binmode( FILE );
        read( FILE, $body, -s $self->{'temp_folder'} . $file->{'temp_name'} );
        close( FILE );
    }
    else {
        $self->{'error'} = "Невозможно открыть временный фаил";
        return 0;
    }
    
    return $body;
}


Это сообщение отредактировал(а) BlackLFL - 14.2.2006, 11:56
PM WWW   Вверх
BlackLFL
Дата 13.2.2006, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



как Вы считаете, лучше ли использовать read для чтения бинарных файлов?
в функции receive_file вместо
Код

$body .= $_ while( <file_data> );
# =>
read( file_data, $body, -s $self->{'temp_folder'} . $file->{'temp_name'} );



Это сообщение отредактировал(а) BlackLFL - 13.2.2006, 12:32
PM WWW   Вверх
korob2001
Дата 13.2.2006, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 13
Всего: 61



Привет!
Я весь модуль не смотрел пока, но по последним постам есть несколько пожеланий:
Почему для именования дескриптора файла не используешь прописные символы? Это конечно не обязательно, но всё же это общее соглашение, хотя и не писанное.

А так же совсетую объявлять typeglob в теле подпрограммы, как локальный, перед использованием дескриптора:
Код

local *DESCRIPTOR;
open(DESCRIPTOR, "file.test") or die $!;

Или позволь Perl'у именовать дескриптор самостоятельно.
Код

open my $out, '>', "file.test" or die $!;

Хотя я всё же предпочитаю делать это первым способом, наверно просто привык. ;)))))


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
BlackLFL
Дата 14.2.2006, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



Цитата

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

Привычка была писать маленькими буквами, исправил smile

Цитата

А так же совсетую объявлять typeglob в теле подпрограммы, как локальный, перед использованием дескриптора:

Объявил, хотя думаю это было необязательно делать, всеравно сразу закрывал дескриптор, а навание было коректным smile

Спасибо за коментарии!
PM WWW   Вверх
BlackLFL
Дата 11.3.2006, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



добавлена проверка на переполнение временной папки

Код

## Проверям, есть ли свободное место в временной папке
local *DIR;

my $temp_folder_size;
opendir( DIR, $self->{'temp_folder'} );
my @temp_files = grep {!(/^\.(\.)?$/) && -f "$self->{'temp_folder'}$_"} readdir( DIR );
closedir( DIR );
                
$temp_folder_size += -s "$self->{'temp_folder'}$_" foreach ( @temp_files );
                
if ( $temp_folder_size > $self->{'temp_size'} ) {
    $self->{'error'} = "Временая папка переполнена.";
    return 0;
}
##

PM WWW   Вверх
Kiber_rat
Дата 16.3.2006, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MACMANIAC
**


Профиль
Группа: Участник
Сообщений: 276
Регистрация: 18.4.2002
Где: Ashdod, Israel

Репутация: 1
Всего: 9



Возможно кто-то посчитает это не важным, но тем не менее smile
Желательно код форматировать так, что бы он вписывался в 80 символов на строку. Во первых, большинство perl программистов работают в *nix, и как следствие в vi, да и на удаленной машине используется vi, а там 80 символов - наиболее комфортно.
Ну и все таки это негласное соглашение по форматированию ввода, такое же
как отступ в 4 пробела (а не в символ табуляции) и т.п.
Второе. Кодировка комментов win1251, опять таки, модуль будут использовать чаще всего на *nix серверах, и прочитать там комменты без перекодировки невозможно...
Надеюсь что мои "придирки" не лишние smile


--------------------
Best regards!                                                             
@..@_____Ku6ep
=*=______\______KPbIC
Код
print join "",map{chr}(split/(\w{2})/,hex(int(2175.57302796298**2)))
PM WWW ICQ Skype Jabber YIM   Вверх
sharq
Дата 16.3.2006, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Perl Liker
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 13.12.2004
Где: Ростов-на-Дону

Репутация: 2
Всего: 28



Kiber_rat, согласен, кроме
Цитата(Kiber_rat @ 16.3.2006, 15:21 Найти цитируемый пост)
Ну и все таки это негласное соглашение по форматированию ввода, такое же
как отступ в 4 пробела (а не в символ табуляции) и т.п.

Очень внимательно прочти perldoc perlstyle!

smile



--------------------
[color=gray]There's More Than One Way To Do It[/color]
PM MAIL WWW ICQ Skype   Вверх
Phoinix
Дата 16.3.2006, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 16.11.2004
Где: Moskau

Репутация: 1
Всего: 2



BlackLFL,

Пробегусь беглым взглядом...

1. Если уж я включаю модуль CGI в скрипт, то значит переданные данные я буду использовать в любом случае, поэтому метод parse - лишний, точнее его следовало бы запускать во время создания объекта в процедуре ew модуля;

2.
Код

( ( defined $hash{'key'} ) ? $hash{'key'} : 2097152 )

Поменять на
Код

($hash{'key'} || 2097152 )

Этого будет достаточно

3.
Код

# Получаем разделитель полей 
($divider) = $ENV{'CONTENT_TYPE'} =~ /boundary="([^"]+)"/;
($divider) = $ENV{'CONTENT_TYPE'} =~ /boundary=(\S+)/ unless defined $divider;

Ну очень некрасиво... и дальше тоже, я смотрю, такая же песня...

4. В продолжение п.3... ой... а что вообще за паровоз с разделителем? Не проще ли?
Код

(my $divider, my $end, $buffer) = $buffer =~m /^([^\r\n]+)([\n\r]+)(.*?)\2\1\-\-\2*$/s;


5.
Код

$temp_file_name = "$self->{'temp_file_prefix'}$temp_file_name";

Сразу "двойка" за код... это даже не смешно...

6.
Код

# Проверяем максимально разрешеный объем данных
if ( length $ENV{'QUERY_STRING'} > $self->{'get_max_length'} ) {
    $self->{'error'} = "Слишком большой объем данных (метод GET)";
    return 0;
}

Поверь... методом GET особо много не передашь и без твоих проверок... не помню какой RFC

7.
Код

    my @temp = delete( $self->{'get'}->{$name} );
    push( @{ $self->{'get'}->{$name} }, @temp, $content );

Что-то я не понял смысл этого кода...
Код

$self->{'get'}->{$name} = [$self->{'get'}->{$name}, $content];


8. Метод remove используется только в DESTROY... собственно, а зачем он отдельно?
PM WWW ICQ   Вверх
BlackLFL
Дата 17.3.2006, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



Цитата(Kiber_rat @ 16.3.2006, 15:21 Найти цитируемый пост)
Возможно кто-то посчитает это не важным, но тем не менее
Желательно код форматировать так, что бы он вписывался в 80 символов на строку. Во первых, большинство perl программистов работают в *nix, и как следствие в vi, да и на удаленной машине используется vi, а там 80 символов - наиболее комфортно.

учту

Цитата(Kiber_rat @ 16.3.2006, 15:21 Найти цитируемый пост)
Второе. Кодировка комментов win1251, опять таки, модуль будут использовать чаще всего на *nix серверах, и прочитать там комменты без перекодировки невозможно...

учту
спасибо!!

Цитата(Phoinix @ 16.3.2006, 20:01 Найти цитируемый пост)
1. Если уж я включаю модуль CGI в скрипт, то значит переданные данные я буду использовать в любом случае, поэтому метод parse - лишний, точнее его следовало бы запускать во время создания объекта в процедуре ew модуля;

я хотел сделать полное управление процессом, но замечание хорошее... может дать дополнительную возможность при создание объекта, если передан аргумент parse, производить разбор? например:
Код

my $cgi = Black::CGI->new( parse => 1 );



Цитата(Phoinix @ 16.3.2006, 20:01 Найти цитируемый пост)

Код

( ( defined $hash{'key'} ) ? $hash{'key'} : 2097152 )

Поменять на
Код

($hash{'key'} || 2097152 )

Этого будет достаточно

Спасибо, очень дельное замечание!

Цитата(Phoinix @ 16.3.2006, 20:01 Найти цитируемый пост)

Код

# Получаем разделитель полей 
($divider) = $ENV{'CONTENT_TYPE'} =~ /boundary="([^"]+)"/;
($divider) = $ENV{'CONTENT_TYPE'} =~ /boundary=(\S+)/ unless defined $divider;

Ну очень некрасиво... и дальше тоже, я смотрю, такая же песня...

Я постарался упростить код, чтобы новичкам было лекго в нем разобраться, меня такая конструкция устраивает smile

Цитата(Phoinix @ 16.3.2006, 20:01 Найти цитируемый пост)

В продолжение п.3... ой... а что вообще за паровоз с разделителем? Не проще ли?
Код

(my $divider, my $end, $buffer) = $buffer =~m /^([^\r\n]+)([\n\r]+)(.*?)\2\1\-\-\2*$/s;

Сейчас Вы допустили очень серъезную ошибку, операционные системы поразному отображают перенос строки, надо указывать код символа \x0D\x0A
Паровоз построил, чтобы было понятно, как разбирать тело запроса по шагам, но замечание опять хорошее (про поровоз), думаю в будущем я от него избавлюсь, и напишу просто комментарии smile

Цитата(Phoinix @ 16.3.2006, 20:01 Найти цитируемый пост)

Код

$temp_file_name = "$self->{'temp_file_prefix'}$temp_file_name";

Сразу "двойка" за код... это даже не смешно...

Только вчера заметил, хотел убрать, опередили smile

Цитата(Phoinix @ 16.3.2006, 20:01 Найти цитируемый пост)
Поверь... методом GET особо много не передашь и без твоих проверок... не помню какой RFC

Я об этом знаю, но лучше перестрахуюсь ...

Цитата(Phoinix @ 16.3.2006, 20:01 Найти цитируемый пост)
 
Код

my @temp = delete( $self->{'get'}->{$name} );
    push( @{ $self->{'get'}->{$name} }, @temp, $content );
Что-то я не понял смысл этого кода...

Если передано два поля с одним именем, чтобы не затереть первое значение, мы создаем хэш массива
Потом обращаемся к нему через индекс
Код

$_GET->{'var1'}[0] - $_GET->{'var1'}[1]


Цитата(Phoinix @ 16.3.2006, 20:01 Найти цитируемый пост)

Код

$self->{'get'}->{$name} = [$self->{'get'}->{$name}, $content];
8. Метод remove используется только в DESTROY... собственно, а зачем он отдельно?

Не только, я забыл задокументировать, что если его вызвать с аргументом
Код

$cgi->remove( files => "all" ) or print $cgi->error;

то будут удалены все файлы из временой директории, например те, которые были созданы сторонними програмами ...

Спасибо за комментарии!!!!!

Это сообщение отредактировал(а) BlackLFL - 17.3.2006, 12:46
PM WWW   Вверх
Phoinix
Дата 17.3.2006, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 16.11.2004
Где: Moskau

Репутация: 1
Всего: 2



Цитата(BlackLFL @ 17.3.2006, 10:43 Найти цитируемый пост)
я хотел сделать полное управление процессом, но замечание хорошее... может дать дополнительную возможность при создание объекта, если передан аргумент parse, производить разбор? например:

Тебе что нужно? полное управление процессом или все-таки данные разобрать?


Цитата(BlackLFL @ 17.3.2006, 10:43 Найти цитируемый пост)
Сейчас Вы допустили очень серъезную ошибку, операционные системы поразному отображают перенос строки, надо указывать код символа \x0D\x0A
Паровоз построил, чтобы было понятно, как разбирать тело запроса по шагам, но замечание опять хорошее (про поровоз), думаю в будущем я от него избавлюсь, и напишу просто комментарии


Насчет кодов символов - не буду спорить, хотя я не согласен, коды здесь не при чем, перенос строки может быть либо \n, либо \r либо \r\n, хотя изменить рег - не сложно, и если ты заметил, мой рег выбирает и код переноса строки ($end), что бы его можно было в дальнейшем использовать в split.
Насчет новичков - а ты не спрашивал их знают ли они в каком виде получаются данные? Если я этого не знаю, то твой код ничего мне не объяснит... А мой рег, не настолько сложен для разбора...
Вообще, сложилось мнение, что ты просто не знаешь как его упростить, извиняюсь если не прав, но рег должен быть такой:
Код

~ /boundary=(?:\"|)([^\"\s]+)(?:\"|)/;
# Можно и так:
~ /boundary=[\"]*([^\"\s]+)[\"]*/;

Остальные - в том же ракурсе...

Цитата(BlackLFL @ 17.3.2006, 10:43 Найти цитируемый пост)
Я об этом знаю, но лучше перестрахуюсь ...


Это перестраховка? Хм... кстати, только сейчас заметил насчет твоих перестраховок - почитай, чем отличается || от or и сделай выводы... особенно когда файлы открываешь...

Цитата(BlackLFL @ 17.3.2006, 10:43 Найти цитируемый пост)
то будут удалены все файлы из временой директории, например те, которые были созданы сторонними програмами ...

И зачем? У тебя модуль данные разбирает или чистит файлы? тем более можно случайно удалить лишнее... у тебя есть в объекте список полученных файлов, вот их и удаляй...
PM WWW ICQ   Вверх
BlackLFL
Дата 17.3.2006, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



Цитата(Phoinix @ 17.3.2006, 13:03 Найти цитируемый пост)
Тебе что нужно? полное управление процессом или все-таки данные разобрать?

разве не может быть случая, когда ненадо разбирать данные, а просто нужно получить даныне объекта?
думаешь лучше все-таки разбирать сразу?

Цитата(Phoinix @ 17.3.2006, 13:03 Найти цитируемый пост)
Насчет кодов символов - не буду спорить, хотя я не согласен, коды здесь не при чем, перенос строки может быть либо \n, либо \r либо \r\n

если мне не изменяет память, обсуждалось это на Xpoint... пришли к выводу, что лучше код символа указывать ...

Цитата(Phoinix @ 17.3.2006, 13:03 Найти цитируемый пост)
Вообще, сложилось мнение, что ты просто не знаешь как его упростить, извиняюсь если не прав, но рег должен быть такой:

Я знаю как упростить, хотел в таком стиле написать ... на работоспособность это не влияет, но за замечание спасибо, изменю.
Цитата

извиняюсь если не прав

Все в порядке, я сам просил дать комментарии, любой вправе предположить smile

Цитата(Phoinix @ 17.3.2006, 13:03 Найти цитируемый пост)
Это перестраховка? Хм... кстати, только сейчас заметил насчет твоих перестраховок - почитай, чем отличается || от or и сделай выводы... особенно когда файлы открываешь...

В приоритете ... Вы правы, я слишком намудрил ...
сделал так
Код

unless ( open( FILE, $self->{'temp_folder'} . $file->{'temp_name'} ) ) {
    $self->{'error'} = ( $self->{'debug'} ) ? $! : "Невозможно открыть временный фаил";
    return 0;
}


Цитата(Phoinix @ 17.3.2006, 13:03 Найти цитируемый пост)
И зачем? У тебя модуль данные разбирает или чистит файлы? тем более можно случайно удалить лишнее... у тебя есть в объекте список полученных файлов, вот их и удаляй...

Например, если временная папка переполнена сторонними файлами, а указать другую нет возможности.
Я в коментариях написал
Цитата

# Удаление всех временных файлов
# Использовать, только, если Вы понимаете зачем это надо
# При использование данной функции, можно лишиться ВАЖНЫХ файлов, в том числе СИСТЕМНЫХ!


Спасибо за комментарии!!

Это сообщение отредактировал(а) BlackLFL - 17.3.2006, 12:45
PM WWW   Вверх
Phoinix
Дата 18.3.2006, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 16.11.2004
Где: Moskau

Репутация: 1
Всего: 2



Цитата(BlackLFL @ 17.3.2006, 12:41 Найти цитируемый пост)
разве не может быть случая, когда ненадо разбирать данные, а просто нужно получить даныне объекта?
думаешь лучше все-таки разбирать сразу?

Вот честно, думаю, думаю, а зачем мне данные объекта? Никак не приложу ума нафиг они мне нужны...

Еще: Я что-то не пойму а методом POST передаются только типы данных: application/x-www-form-urlencoded и multipart/form-data???
Честно говоря, не буду проверять, но я часто POST'ом передаю и обычный text/plain (например: в TEXTAREA большой текст)...

Цитата(BlackLFL @ 17.3.2006, 12:41 Найти цитируемый пост)
если мне не изменяет память, обсуждалось это на Xpoint... пришли к выводу, что лучше код символа указывать ...

IMHO метасимвол на то и метасимвол, а жеский код указывать - только увеличивает вероятность несоответсвия... но это совершенно другая тема...

Цитата(BlackLFL @ 17.3.2006, 12:41 Найти цитируемый пост)
Например, если временная папка переполнена сторонними файлами, а указать другую нет возможности.
Я в коментариях написал

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

И еще: В своих скриптах я часто использую некоторые переменные которые постоянно передаются между пользователем и сервером, например, уникальный ключ сессии, так вот этот параметр проверяется сразу при запуске скрипта, а передаваться он может как POST'ом так и GET'ом... А ты взял и разделил данные... Если честно, то это сделано по типу PHP и мне такая реализация ну совсем не нравится, при использовании PHP мне приходится делать двойные проверки... А смысл? Я лично не могу себе представить, что буду одновременно передавать разные(!) данные под одним и тем же именем, но разными методами...
PM WWW ICQ   Вверх
korob2001
Дата 18.3.2006, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 13
Всего: 61



Цитата(Phoinix @ 18.3.2006, 08:24 Найти цитируемый пост)

И еще: В своих скриптах я часто использую некоторые переменные которые постоянно передаются между пользователем и сервером, например, уникальный ключ сессии, так вот этот параметр проверяется сразу при запуске скрипта, а передаваться он может как POST'ом так и GET'ом... А ты взял и разделил данные... Если честно, то это сделано по типу PHP и мне такая реализация ну совсем не нравится, при использовании PHP мне приходится делать двойные проверки... А смысл? Я лично не могу себе представить, что буду одновременно передавать разные(!) данные под одним и тем же именем, но разными методами...

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

Это сообщение отредактировал(а) korob2001 - 18.3.2006, 11:47


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
BlackLFL
Дата 18.3.2006, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



Цитата(Phoinix @ 18.3.2006, 12:24 Найти цитируемый пост)
Вот честно, думаю, думаю, а зачем мне данные объекта? Никак не приложу ума нафиг они мне нужны...

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

Цитата(Phoinix @ 18.3.2006, 12:24 Найти цитируемый пост)
Ну так надо сделать алгоритм, который проверяет, переполнена папка или нет, и в случае чего чичтить их, если указан, скажем, какой-либо ключ при инициализации объекта...

хорошая идея, добавил параметр clear_temp_folder, метод сделал приватным.
Поумолчанию функция очистки отключена ...

Код

my $cgi = Black::CGI->new( clear_temp_folder => 1 );


Цитата(Phoinix @ 18.3.2006, 12:24 Найти цитируемый пост)
И еще: В своих скриптах я часто использую некоторые переменные которые постоянно передаются между пользователем и сервером, например, уникальный ключ сессии, так вот этот параметр проверяется сразу при запуске скрипта, а передаваться он может как POST'ом так и GET'ом... А ты взял и разделил данные... Если честно, то это сделано по типу PHP и мне такая реализация ну совсем не нравится, при использовании PHP мне приходится делать двойные проверки... А смысл? Я лично не могу себе представить, что буду одновременно передавать разные(!) данные под одним и тем же именем, но разными методами...

согласен с korob2001, методы должны быть разделены ...

Цитата(korob2001 @ 18.3.2006, 12:46 Найти цитируемый пост)
Просто нужно добавить возможность и их совместного использования, для передачи тех же ключей сессии, так как сессия должна сохраниться не в зависимости от метода передачи данных.

я сейчас подумаю как это реализовать ... есть идеи?
PM WWW   Вверх
korob2001
Дата 19.3.2006, 02:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 13
Всего: 61



Можно добавить метод который смешивает оба хеша и возвращает ссылку на новый анонимный хеш. Я назвал бы его param:
Код

sub param {
        my $self = shift;
        return {%{$self->{get}},%{$self->{post}}};
}

C другой стороны это пожалуй далеко не лучший вариант. Можно получать в методе param имя параметра, проверять оба метода и возвращать value.
Код

sub param {
        my $self = shift;
        return $self->{post}{$_[0]} || $self->{get}{$_[0]};
}

Хотя мне кажется парвильнее делать вот такую проверку:
Код

sub param {
        my $self = shift;
        return exists ${$self->{post}}{$_[0]} ? $self->{post}{$_[0]} :
               exists ${$self->{get}}{$_[0]}  ? $self->{get}{$_[0]}  : undef;
}


Это сообщение отредактировал(а) korob2001 - 19.3.2006, 03:06


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
BlackLFL
Дата 19.3.2006, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



ты читаешь мои мысли, ночью тоже самое приснилось smile

Цитата

Код

sub param {
    my $self = shift;
    return exists ${$self->{post}}{$_[0]} ? $self->{post}{$_[0]} :
        exists ${$self->{get}}{$_[0]}  ? $self->{get}{$_[0]}  : undef;
}


следовательно
Код

# POST = "";
# GET = "73427842742"

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

исходя из твоего предложения, мы неполучим ничего ...
может лучше все-таки воспользоваться вторым вариантом?
Код

sub param {
    my($self, $name) = @_;

    return $self->{'post'}->{$name} || $self->{'get'}->{$name};
}

в этом случае мы получим значение GET 73427842742
как ты думаешь?

p.s. приоритет наверно за POST оставим?
PM WWW   Вверх
korob2001
Дата 19.3.2006, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 13
Всего: 61



Цитата(BlackLFL @ 19.3.2006, 08:24 Найти цитируемый пост)
исходя из твоего предложения, мы неполучим ничего ...

Почему?

Цитата(BlackLFL @ 19.3.2006, 08:24 Найти цитируемый пост)
может лучше все-таки воспользоваться вторым вариантом?
Код

sub param {
    my($self, $name) = @_;

    return $self->{'post'}->{$name} || $self->{'get'}->{$name};
}

в этом случае мы получим значение GET 73427842742
как ты думаешь?

А как же быть с параметром prm=0 ?


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
BlackLFL
Дата 19.3.2006, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



Цитата(korob2001 @ 19.3.2006, 13:28 Найти цитируемый пост)
А как же быть с параметром prm=0 ?

об этом я и не подумал ...

тогда делаем окончательный вариант
Код

### Функция возврата объединяющая POST, GET
sub param {
    my($self, $name) = @_;
    return exists $self->{'post'}->{$name} ? $self->{'post'}->{$name} : 
           exists $self->{'get'}->{$name} ? $self->{'get'}->{$name} : undef;
}

поддерживаешь?

ты так и не ответил про приоритет ...

PM WWW   Вверх
korob2001
Дата 19.3.2006, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 13
Всего: 61



Цитата(BlackLFL @ 19.3.2006, 09:56 Найти цитируемый пост)
поддерживаешь?

Ну пока лучшего варианта в голову не приходит, так что можно добавить, если будет лучший вариант то никогда не поздно подправить.
Цитата(BlackLFL @ 19.3.2006, 09:56 Найти цитируемый пост)
ты так и не ответил про приоритет ...

Оставляй приоритет за post, хотя думаю это не столь важно, так как нельзя заранее предугадать какой из методов будет использоваться чаще.
Вот ещё как вариант:
Код

sub param {
        my $self = shift;
        return keys %{$self->{post}} ? $self->{post}{$_[0]} : $self->{get}{$_[0]};
}


Это сообщение отредактировал(а) korob2001 - 19.3.2006, 15:21


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
BlackLFL
Дата 17.4.2006, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



модуль обновился до версии 0.2

Еще раз выражаю огромное спасибо всем, кто принимает участие в тестирование модуля, высказывают свои пожелания и замечания!

В новой версии модуля оптимизированы отдельные фрагменты кода, исправлены мелкие недочеты. 
Добавлены примеры работы с модулем.  

Это сообщение отредактировал(а) BlackLFL - 17.4.2006, 11:06
PM WWW   Вверх
BlackLFL
Дата 21.2.2007, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



модуль обновился до версии 0.3

Еще раз выражаю огромное спасибо всем, кто принимает участие в тестирование модуля, высказывают свои пожелания и замечания!

В новой версии модуля оптимизированы отдельные фрагменты кода.

Это сообщение отредактировал(а) BlackLFL - 21.2.2007, 20:57
PM WWW   Вверх
ochnev
Дата 1.3.2007, 03:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 253
Регистрация: 27.3.2006

Репутация: нет
Всего: нет



А почему из готового модуля нужно убирать "use strict"?

PM MAIL   Вверх
Nab
Дата 1.3.2007, 06:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 25.3.2006
Где: Kiev

Репутация: 8
Всего: 37



Цитата(ochnev @  1.3.2007,  03:05 Найти цитируемый пост)
А почему из готового модуля нужно убирать "use strict"?

Убирать не обязательно, просто в готовом отлаженном модуле она не нужна... какуюто, хоть и не большую но явно лишнюю нагрузуку он создает. А если весь код отлажен, то почему бы не убрать?....



BlackLFL, я давно приглядуюсь к Вашему модулю, но честно сказать не особенно вижу каое будущее Вы ему готовите smile

Ведь его получается можно использовать только в новых разработках, заменить им, более легким, CGI.pm в старых проектах не представляеется возможным,  слишком трудоемкий процесс получиться smile они не совместимы никак smile Также заменить Ваш модуль, если он перестанет удовлетворять функционалу приложения, тоже затруднительно. Тоесть его можно заюзать только в мелких законченных решениях...

Просто я сейчас разрабатываю достаточно оьбъемный проект, и там как базовая возможность по работе с cgi - окружением используется именно CGI.pm. Так было задумано не мной, но я вполне поддержую эту стратегию, потому как этот модуль есть практически везде... 
И что более важно, к нему есть расширения, и альтернативы. Расширение типа CGI::Compress::Gzip, позволяют очень просто добавить к своему приложению gzip сжатие, что сейчас и востребовано и необходимо и все чаще используется...
А альтернативы, это в первую очередь CGI::Simple, сравнение по скорости можно глянуть вот здесь http://search.cpan.org/src/JFREEMAN/Cgi-Si..._vs_cgi-pm.html . Также есть еще CGI::Minimal, для работы с параметрами очень даж не плох, но необходимой мне совместимости не имеет smile... хотя там уже присутствует функционал, для которого я подключаю внешние модули... 
Есть еще некоторые альтернативы, но они менее совместимы...

Я это все к тому, что, если бы Ваш модуль, предоставлял интерфейс более совместимый с CGI.pm, пускай и не в полном объеме, то количество пользователей и и широта использования думаю выросли бы ...




--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
Vaneska
Дата 29.8.2007, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 141
Регистрация: 15.3.2005
Где: Москва

Репутация: 1
Всего: 4



Потестил, нашел баг.
В $ENV{'CONTENT_TYPE'} не всегда передается только строчка application\/x-www-form-urlencoded,
поэтому при таком условии:
Код

if ( uc( $ENV{'REQUEST_METHOD'} ) eq "POST" && $ENV{'CONTENT_TYPE'} eq 'application\/x-www-form-urlencoded' )

запрос не обрабатывается. Надо бы поставить регексп, как в условии для multipart/form-data
--------------------
http://isokolov.blogspot.com/
PM MAIL ICQ   Вверх
BlackLFL
Дата 30.8.2007, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



Цитата(Vaneska @ 29.8.2007,  21:49)
Потестил, нашел баг.
В $ENV{'CONTENT_TYPE'} не всегда передается только строчка application\/x-www-form-urlencoded,
поэтому при таком условии:
Код

if ( uc( $ENV{'REQUEST_METHOD'} ) eq "POST" && $ENV{'CONTENT_TYPE'} eq 'application\/x-www-form-urlencoded' )

запрос не обрабатывается. Надо бы поставить регексп, как в условии для multipart/form-data

Спасибо подправил.

Добавлено @ 11:18
2Nab, прошу прощения за долгий ответ, не было возможности ответить сразу, а потом забыл :(
Полностью с Вами согласен, функционал отличается кардинально, сам столкнулся с интеграцией в большой проект ...

Цитата

Также заменить Ваш модуль, если он перестанет удовлетворять функционалу приложения, тоже затруднительно.

На самом деле, модуль содержит минимальный набор методов для работы с CGI, а если нужны дополнительные возможности, можно будет подключить внешние модули ...

Цитата

Расширение типа CGI::Compress::Gzip, позволяют очень просто добавить к своему приложению gzip сжатие, что сейчас и востребовано и необходимо и все чаще используется...

Бесспорно, минус, но не для всех проектов, например, для внутренний разработок, он не нужен ИМХО.

Цитата

Я это все к тому, что, если бы Ваш модуль, предоставлял интерфейс более совместимый с CGI.pm, пускай и не в полном объеме, то количество пользователей и и широта использования думаю выросли бы ...

Интерфейс делал похожий на PHP, т.к. на мой взгляд там он более наглядный ...

Спасибо за конструктивную критику!

Это сообщение отредактировал(а) BlackLFL - 30.8.2007, 11:19
PM WWW   Вверх
Vaneska
Дата 8.4.2008, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 141
Регистрация: 15.3.2005
Где: Москва

Репутация: 1
Всего: 4



Нашел хитрый баг!
Если на серваке ограничено количество оперативной памяти для cgi-скрипта, то при загрузке данных от 4 мб. случается хватка памяти.

Приношу свои извинения!
Это у меня в скрипте какая-то утечка..

Это сообщение отредактировал(а) Vaneska - 8.4.2008, 11:52
--------------------
http://isokolov.blogspot.com/
PM MAIL ICQ   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl: CGI программирование"
korob2001
sharq
  • В этом разделе обсуждаются вопросы относящиеся только к CGI программированию
  • Если ваш вопрос не относится к системному или CGI программированию, задавайте его в общем разделе
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", качать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: разработка для Web | Следующая тема »


 




[ Время генерации скрипта: 0.1897 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.