Форум: "Прочее";
Текущий архив: 2008.06.01;
Скачать: [xml.tar.bz2];
ВнизКоллеги, поможите чем можете :) Найти похожие ветки
← →
Ega23 © (2008-04-15 16:57) [0]смысл такой: требуется парсер параметров, что передаются веб-серверу через Get или Post методы. Желательно на паскале, хотя можно и на С или PHP. Ну или ссылку, где эти правила детально описаны (сам "с ходу" не нашёл :( ).
В принципе, там после нескольких экспериментов более-менее понятно, как строки передаются, и самому написать не сильно сложно, но поскольку в веб-программировании я новичок, то тупо могу каких-то нюансов не учесть.
← →
antonn © (2008-04-15 17:01) [1]в каком смысле парсер?
print_r($_POST); выведет все элементы, перебор их:
foreach ($_POST as $key => $content){
//$key - ключ
echo($_POST[$key]);// выведет $content
}
← →
БарЛог © (2008-04-15 17:02) [2]для
http://delphimaster.net/view/15-1208264263/
принимаешь
$id=
$n=
Вроде как-то так, если память не изменяет. Точно не уверен - не проверял.
← →
antonn © (2008-04-15 17:03) [3]get запросы хранятся в массиве $_GET, post в $_POST.
не пойму вопроса :)
← →
DVM © (2008-04-15 17:03) [4]
> смысл такой: требуется парсер параметров, что передаются
> веб-серверу через Get или Post методы.
только текстовых параметров? Там и файлы ведь могут быть.
← →
antonn © (2008-04-15 17:04) [5]
> принимаешь
> $id=
> $n=
неправильно, нафиг regystry_globals :)
для http://delphimaster.net/view/15-1208264263/
$_GET["id"] будет равен 1208264263
$_GET["n"] будет равен 3
проверка на существование - isset($_GET["n"]), присутсвует регистрозависимость :)
← →
wicked © (2008-04-15 17:04) [6]на PHP это делается очень просто (без проверки на ошибки)
$params1 = explode("&", $param_string);
$params2 = array();
foreach($params1 as $line){
list($key, $value) = explode("=", $line);
params2[urldecode($key)] = urldecode($value);
}
(не учитывая, что за тебя это уже сделал веб-сервер)
но вряд ли тебе это поможет - в делфи нету explode
а ежели с проверкой на ошибки - то лучше юзать автоматы (КА) и перебирать по символу
← →
antonn © (2008-04-15 17:10) [7]
> на PHP это делается очень просто (без проверки на ошибки)
ужась :) на php есть уже готовые пропарсенные массивы :)
← →
wicked © (2008-04-15 17:12) [8]
>
> ужась :) на php есть уже готовые пропарсенные массивы :)
ужась у вас, поскольку вы не читаете, чего хочет автор...
а автор хочет парсер гетов-постов на паскале.... я и привел принцип разбора, но на пхп
зато теперь я знаю, по какому принципу набирают в супорт хостерам }:->
← →
tesseract © (2008-04-15 17:13) [9]
> где эти правила детально описаны (сам "с ходу" не нашёл
> :( ).
Google+regexp + Delphi. Или сам конечноый автомат катай, но я думаю будет лень.
← →
БарЛог © (2008-04-15 17:14) [10]antonn © (15.04.08 17:04) [5]
> неправильно, нафиг regystry_globals :)
Я уже догадался :)
← →
antonn © (2008-04-15 17:17) [11]
> wicked © (15.04.08 17:12) [8]
я просто не понял, зачем показывать аналог парсера на языке, где уже все сделано %)
← →
Оригинал (2008-04-15 17:20) [12]
const
CR = CHR(13)+CHR(10);
BufSize = 4096;
function GetMethod: String;
var
buf: PChar;
begin
GetMem(buf,BufSize);
GetEnvironmentVariable(PChar("REQUEST_METHOD"),Buf,BufSize);
Result := String(buf);
FreeMem(buf);
end;
...
if GetMethod = "POST"
then Str := GetPostEnv
else Str := GetGetEnv;
function ParamByName(inParams: String;Name: String): String;
var
ss,st: String;
k: Integer;
begin
Result := "";
ss := InParams;
while Length(ss)>0 do
begin
k := Pos("&",ss);
if k>0 then
begin
st := Copy(ss,1,k-1);
ss := Copy(ss,k+1,10000);
end
else
begin
st := ss;
ss := "";
end;
k := Pos("=",st);
if K>0 then
begin
if Name=Copy(st,1,k-1) then
begin
Result := Decode(Copy(st,k+1,6000));
end;
end;
end;
end;
function Decode(Value: String):String;
var
i,L: Integer;
begin
Result := "";
L := 0;
for i := 1 to Length(Value) do
begin
if (Value[i]<>"%") and (Value[i]<>"+") and (L<1) then
begin
Result := Result + Value[i];
end
else
begin
if Value[i]="+" then Result := Result+" "
else if Value[i]="%" then
begin
L := 2;
if (i<Length(Value)-1) then
begin
Result := Result + Chr(StrToInt("$"+Copy(Value,i+1,2))); //Chr(HexToInt(Value[i+1])*16+HexToInt(Value[i+2]));
end;
end
else Dec(L);
end;
end;
end;
function GetGetEnv: String;
var
buf: PChar;
begin
GetMem(buf,BufSize);
GetEnvironmentVariable(PChar("QUERY_STRING"),Buf,BufSize);
Result := String(buf);
FreeMem(buf);
end;
function GetPostEnv: String;
var
StdIn,Size,Actual: Cardinal;
begin
Result := "";
StdIn := GetStdHandle(STD_INPUT_HANDLE);
Size := SetFilePointer(StdIn,0,nil,FILE_END);
SetFilePointer(StdIn,0,nil,FILE_BEGIN);
SetLength(Result,Size);
if Size>0 then
begin
ReadFile(StdIn,Result[1],Size,Actual,nil);
end;
end;
← →
DVM © (2008-04-15 17:20) [13]
> я просто не понял, зачем показывать аналог парсера на языке,
> где уже все сделано
Чтобы понять как сделать на делфи или как вообще это делается очевидно. Хотя [6] на делфи все одно не портируешь в лоб.
← →
Оригинал (2008-04-15 17:23) [14]Вдогонку пример получения значения параметра:
for i := Low(tCommand) to High(tCommand) do
begin
if ParamByName(Str,"typedocau")= tCommand[i] then isTrue := True;
end;
← →
Ega23 © (2008-04-15 17:28) [15]Сорри, тут разговор был.
поясняю: парсер нужен для FastCGI-программы. всё, что приходит через GET - имеем в QUERY_STRING. Всё, что приходит через POST - в fastcgi-аналоге stdin.
Понятно, что всё суть "parameter1=value1¶meter2=value2" и т.д.
Просто там ещё всякие спец-символы и т.п.
Вот технологию передачи спец-символов я так до конца и не понял.
Если есть где описание - ткните носом, сам парсер напишу. Просто в OpenSource-коды лезть крайне не хочется... :)
← →
Kolan © (2008-04-15 17:31) [16]>
> Google+regexp + Delphi. Или сам конечноый автомат катай,
> но я думаю будет лень.
Я тоже хотел сначала написать, но, имхо, Ega и так про это знает. Он само выражения написать незнает как правильно.
← →
DVM © (2008-04-15 17:32) [17]
> Если есть где описание - ткните носом, сам парсер напишу
RFC 1945 сам просил :)
← →
Ega23 © (2008-04-15 17:34) [18]Опытным путём вижу следующее:
есть строка Input Buffer:auth=1&login=%25%25%25&pwd=%25%3D%25%3D
Сначала пройти по строке разбить на пары по "&". Потом каждую пару разбить на сочетания параметр-значение по "="
Потом найти все сочетания "%__", заменить их на символ Chr(__) с учётом того, что они в Hex.
← →
tesseract © (2008-04-15 17:39) [19]
> Опытным путём вижу следующее:
Ну в общем так и есть. Изредка возможно коррективы.
← →
Оригинал (2008-04-15 17:43) [20]
> Ega23 © (15.04.08 17:28) [15]
> Сорри, тут разговор был.
> поясняю: парсер нужен для FastCGI-программы. всё, что приходит
> через GET - имеем в QUERY_STRING. Всё, что приходит через
> POST - в fastcgi-аналоге stdin.
> Понятно, что всё суть "parameter1=value1¶meter2=value2"
> и т.д.
> Просто там ещё всякие спец-символы и т.п.
> Вот технологию передачи спец-символов я так до конца и не
> понял.
> Если есть где описание - ткните носом, сам парсер напишу.
> Просто в OpenSource-коды лезть крайне не хочется... :)
А какая разница - CGI или FASTCGI при передаче параметров клиентом?
Получение типа запроса:function GetMethod: String;
Получение строки с запросом в зависимости от типа запроса(GET,POST):function GetGetEnv: String;
function GetPostGetEnv: String;
Получение значения параметра из строки с запросом:function ParamByName(inParams: String;Name: String): String;
Декодирование значения параметра в запросе:function Decode(Value: String):String;
← →
Ega23 © (2008-04-15 17:45) [21]
> Оригинал (15.04.08 17:43) [20]
Я как раз сейчас твой код смотрю, правильно ли я всё понял.
← →
Ega23 © (2008-04-15 17:46) [22]
> Ну в общем так и есть. Изредка возможно коррективы.
Вот не хотелось бы, чтобы "коррективы" всплыли в самый ненужный момент.. :)
← →
Kolan © (2008-04-15 17:48) [23]
>
> Вот не хотелось бы, чтобы «коррективы» всплыли в самый ненужный
> момент… :)
Надо прочитать стандарт на эту строку и полностью его реализовать.
← →
palva © (2008-04-15 17:50) [24]
>
> Вот не хотелось бы, чтобы "коррективы" всплыли в самый ненужный
> момент.. :)
>
Плюсик заменяется на пробел.
Может быть, это не относится к FastCGI, не в курсе, что это такое.
← →
Ega23 © (2008-04-15 17:51) [25]
> Надо прочитать стандарт на эту строку и полностью его реализовать.
5 баллов. А то я не понимаю... :)
Покажи стандарт, я ещё в [0] просил. Желательно оригинал, а не перевод.
← →
Ega23 © (2008-04-15 17:53) [26]
> Оригинал (15.04.08 17:43) [20]
Спасибо, код посмотрел, всё более-менее ясно.
Половину я уже и так написал, сейчас остальное добью.
← →
Kolan © (2008-04-15 18:01) [27]> Покажи стандарт
Я не уверен, но может:
http://ru.wikipedia.org/wiki/URI
← →
Ega23 © (2008-04-15 18:06) [28]
> Я не уверен, но может:
> http://ru.wikipedia.org/wiki/URI
Спасибо, юникод я как раз и не учёл... :)
← →
palva © (2008-04-15 18:08) [29]Если кодировка страницы UTF8, то русские символы в значениях будут состоять из двух байтов (два знака %)
← →
Kolan © (2008-04-15 18:08) [30]> Спасибо, юникод я как раз и не учёл… :)
Прикалываешься? Или нет?
Вроде вот регулярка:^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
← →
Kolan © (2008-04-15 18:10) [31]Мое имхо, что стандарт надо искать где-то на http://www.w3.org/
← →
Мазут Береговой © (2008-04-15 18:12) [32]http://www.scalabium.com/faq/dct0126.htm
http://www.delphidabbler.com/codesnip.php?action=named&routines=URLDecode&showsrc=1
← →
palva © (2008-04-15 18:16) [33]посмотреть
C:\Program Files\Borland\Delphi7\Source\Indy\IdURI.pas
там есть
class function URLDecode(ASrc: string): string;
class function URLEncode(const ASrc: string): string;
class function ParamsEncode(const ASrc: string): string;
class function PathEncode(const ASrc: string): string;
← →
Ega23 © (2008-04-15 18:17) [34]Всё, всем спасибо, дальше я сам. :)
← →
Fantasist.. (2008-04-15 19:47) [35]Я когда-то в писал множество разнообразных парсеров. По мне так лучше сразу распарсить строку в ассоциативный массив параметров.Так можно и все параметры посмотреть и все имена и по имени параметр взять - удобнее в общем.
Заодно разбор может сразу указать, если строка содержит ошибки.
interface
TTokenType = (ttSpace,ttSymbol,ttWord,ttEOL,ttEOF);
TLexer = class
private
fToken:string;
fCur:PChar;
function checkEOL:boolean;
public
constructor Create(s:string);
destructor Destroy; override;
function next: TTokenType;
property token:string read fToken;
end;
TURLParams = class
private
fParams:THashMap;
parser:TLexer;
tokenType:TTokenType;
procedure parse;
public
constructor Create(s:string);
params:THashMap read fParams;
end;
implementation
function isSpace(c:char):boolean;
begin
result := (c=" ") or (c=9);
end;
function isLetterOrDigit(c:char):boolean;
begin
result:= (c in ["0".."9"]) or (c in ["A".."Z"]) or (c in ["a".."z"])
end;
function isDigit(c:char):boolean;
begin
result:=(c in ["0".."9"]);
end;
consturctor TLexer.Create(s:string)
begin
fCur:=pointer(s);
end;
function TLexer.checkEOL:boolean;
begin
result:=false;
if fCur = 13 then
begin
inc(fCur);
if fCur = 10 then
inc(fCur);
resut:=true;
end
else if fCur = 10 then
begin
inc(fCur);
result:=true;
end;
end;
function TLexer.next:TTokenType;
var
ps:PChar;
begin
if fCur = 0 then
begin
result:=ttEOF;
exit;
end;
ps := fCur;
if ckechEOL then
result:=ttEOL
else
if isSpace(fCur) then
begin
while isSpace(fCur) then inc(fCur);
result:=ttSpace;
end
else if isLetterOrDigit(fCur) then
begin
while isLetterOrDigit(fCur) then inc(fCur);
result:=ttWord;
end
else
begin
inc(fCur);
result:=ttSymbol;
end
SetLength(fToken,Integer(fCur)-Integer(ps));
move(ps^,pointer(fToken)^,Integer(fCur)-Integer(ps));
end;
constructor TURLParams.Create(s:string);
begin
parser:=TLexer.Create(s);
fParams:=THashMap.Create;
parse;
parser.Free;
end;
function TURLParams.getDecoded:char;
begin
result:="";
tokenType:=parser.next;
if (tokenType=ttWord) and (length(parser.token)=2) then
result:=chr(StrToInt("$"+parser.token));
end;
function TURLParams.getParamName:string;
begin
tokenType:=parser.next;
if (tokenType <> ttWord) then ; //Error!!! (throw exception)
result := parser.token;
end
function TURLParams.getParamValue:string;
begin
result:="";
tokenType:=parser.next;
repeat
case tokenType of
ttWord: result:=result+parser.token;
ttSymbol:
case parser.token[1] of
"+": result:=result+" ";
"%": result:=result+getDecoded;
"&":exit;
else
; //Error or Ignore???
end;
ttSpace: ;//Error or Ignore???
end;
until (tokenType=ttEOF) or (tokenType = ttEOL);
end;
procedure TURLParams.parse
var
paramName,paramValue:string;
begin
repeat
paramName := getParamName;
parser.next;
if (parser.token[i]<>"=") then ; //Error!!! (throw exception)
paramValue:= getParamValue;
fParams[paramName] = paramValue;
until (tokenType=ttEOF) or (tokenType = ttEOL);
end;
Тут парочку вещей можно оптимизировать (например, getDecoded можно читать по символам и переводить в ручную, а не вызывать IntToStr; можно сделать лексеру способность чтения символа, когда токен состоит из одного символа, вместо того, чтобы копировать его в строку; строки можно не складывать плюсом, а дойти до конца выражения чтобы узнать длинну [тут заодно можно и getDecoded, оптимизировать как описанно выше] и скопировать строку целиком), немножко отладить, добавить нормальную обработку исключений и будет то что надо. :)
Да и омтимизация эта в данном случае скорее чисто для своего удовольствия - вряд ли реально на этом можно существенно сократить время выполнения.
Вместо hash map можно тоже что-нибудь другое использовать. Map просто удобнее.
← →
Fantasist.. (2008-04-15 19:50) [36]Мда... Наверное это уже никому не нужно, но самому мне было приятно. Давно на Делфи ничего не писал, но как оказывается все само в памяти всплывает. :)
← →
Ega23 © (2008-04-15 20:03) [37]
> Fantasist.. (15.04.08 19:47) [35]
ну я как раз приблизительно так и сделал.
Всё, вопрос снят, тему можно закрыть.
Всем спасибо!
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2008.06.01;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.05 c