• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

kingless

[PHP]Full URL Parsing Regex

16 mensagens neste tópico

Boas,

hoje estive no google a procura de uma expressão regular que fizesse o mesmo que a função parse_url(); do php para utilizar em uma classe do meu CMS mas acabei por não encontrar nenhuma expressão que fizesse exactamente aquilo por isso resolvi criar uma expressão regular para fazer aquilo (não foi fácil mas acho que consegui :] ).

<?php
//Full URL Parsing Regex by kingless <blastelf (at) gmail (dot) com> 

$uri = 'http://username:password@www.example.com/path1/path2/file.php?query=1&string=something&this=good#anchor123';

preg_match( '/^(?[a-z]+):\/\/)?(?[\w\-\.]+)?\:*([\w\-\.]+)?\@*)?([\w\.\-]+)*([\/\w]*\/?[\w\.\-]+[^\#\?]+)?(?:\?((?:[^\#].*?)*))?(?:\#?(.*))?$/i', $uri, $match );

print_r( $match );

RESULTADO:

Array
(
    [0] => http://username:password@www.example.com/path1/path2/file.php?query=1&string=something&this=good#anchor123
    [1] => http
    [2] => username
    [3] => password
    [4] => www.example.com
    [5] => /path1/path2/
    [6] => file.php
    [7] => ?query=1&string=something&this=good
    [8] => #anchor123
)

PS: Só não utilizo a função parse_url() porque mostra um E_WARNING quando a URL está mal formada. já agora, se alguém encontrar um bug no regex avise aqui.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu acho que o @ resolvia o problema do E_WARNING, mas não vou afirmar pois não tenho a certeza. No entanto, isso é suposto apenas fazer match aos que estão correctos? É que se eu fizer:

fuck://www.example.com

Funciona, e se calhar não devia... :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Acham que já não tinha pensado nisso ? :)

Parecendo que não o @ executa muitas operações no "background" para terem uma ideia...

Este código:


for( $x = 0; $x < 1000,; $x++ ) {

      error_reporting(0);

      for( $i = 0; $i < 5; $i++ ) { 
              phpversion();
      }

      error_reporting(E_ALL);
}

É muito mais rápido que este:


for( $x = 0; $x < 1000,; $x++ ) {
      for( $i = 0; $i < 5; $i++ ) { 
              @phpversion();
      }
}

(Se tiverem duvida podem testar ai)

Agora imaginem como é que fica a performance do  CMS se a função parse_url(); for chamada umas 20 vezes com o @...

btw,

Corrigi 4 bugs agora o resultado já se assemelha mais ao do parse_url

EDIT:

fuck://www.example.com

Funciona, e se calhar não devia... :P

Aquilo só faz o parsing das URIs não verifica mas se quiser que isso não funcione é só trocar ([a-z]+) por (http\[s\]?)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

@kingless

1) Arranja outro exemplo porque esse do phpverion() provoca um erro fatal e mesmo com @ ou o error_reporting(0), o script termina ai assim que acontecer o primeiro erro. A @ apenas omite o erro, não o vai ignorar...

2) Eu disse "se calhar", porque eu não adivinho o que tu queres fazer, apenas foi uma sugestão. Eu sabia onde tava o erro e resolver isso era básico, foi só mesmo por duas razões, para me meter contigo e porque podia-te ter escapado e ser algo que querias validar, mas pelos vistos não queres.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

@kingless

1) Arranja outro exemplo porque esse do phpverion() provoca um erro fatal e mesmo com @ ou o error_reporting(0), o script termina ai assim que acontecer o primeiro erro. A @ apenas omite o erro, não o vai ignorar...

2) Eu disse "se calhar", porque eu não adivinho o que tu queres fazer, apenas foi uma sugestão. Eu sabia onde tava o erro e resolver isso era básico, foi só mesmo por duas razões, para me meter contigo e porque podia-te ter escapado e ser algo que querias validar, mas pelos vistos não queres.

Como o djthyrax disse não é phpverion() mas sim phpversion() :) E para testar aconselho-te o benchmark profiler do PEAR...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

E para testar aconselho-te o benchmark profiler do PEAR...

Eu normalmente guio-me com o tempo (microtime(true)).
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

E para testar aconselho-te o benchmark profiler do PEAR...

Eu normalmente guio-me com o tempo (microtime(true)).

Eu também utilizava o microtime para fazer os testes mas agora prefiro o benchmark profiler porque é fácil de usar, tem varias opções e mostra os resultados do teste de uma forma organizada.

Exemplo de resultados de teste do laguna cms:

--------------------------------------------------------------------------------------
Section               Total Ex Time         Netto Ex Time         #Calls    Percentage
--------------------------------------------------------------------------------------
include               0.0119528770447       0.0119528770447       1          12.79%
laguna                0.0270891189575       0.0270891189575       1          28.98%
init                  0.0368528366089       0.0368528366089       1          39.43%
getComponent          0.00298810005188      0.00298810005188      1           3.20%
run                   0.00344586372375      0.00344586372375      1           3.69%
display               0.0105741024017       0.0105741024017       1          11.31%
Global                0.0934681892395       -0.0929028987885      2         100.00%

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Desculpa la mas o que tas a dizer não faz sentido nenhum. A arroba, tanto quanto eu sei, é para omitir erros que determinada expressão possa criar, logo, se vais usar a arroba no phpversion(), só por ai, é parvo. o phpversion() existe, logo, não tem lógica nenhuma usar a arroba e/ou o error_reporting, não vão existir erros e não... Se tivesses por exemplo um echo de uma variavel não definida, só provoca um notice e assim, poderia se ver as diferenças de error_reporting() para a arroba, mas o exemplo que deste, não tem sentido nenhum (seja phpverion() ou phpversion()).

Mas pegando no teu exemplo e usando o phpversion(), não notei diferença nenhuma entre os 2... para mim são iguais, não é a diferneça de uns milisegundos que me irá xatear. Acho que tás a dar demasiada importância a pormenores do teu CMS demasiado insignificantes para que alguem esteja minimamente ralado com a forma como o programaste e se poupaste 100ms por teres usado x em vez de y. Acho que devias preocupar mais com o essencial e ter um produto final e estavel em vez de te ralares com esses pormenores. Mas é só o que eu acho.

Quanto a isso do benchmark, podes explicar os resultados? O script é teu, tu é que deves ter uma ideia do que significam, eu olho prai e só vejo numeros, não os sei interpretar.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Desculpa la mas o que tas a dizer não faz sentido nenhum. A arroba, tanto quanto eu sei, é para omitir erros que determinada expressão possa criar, logo, se vais usar a arroba no phpversion(), só por ai, é parvo. o phpversion() existe, logo, não tem lógica nenhuma usar a arroba e/ou o error_reporting, não vão existir erros e não... Se tivesses por exemplo um echo de uma variavel não definida, só provoca um notice e assim, poderia se ver as diferenças de error_reporting() para a arroba, mas o exemplo que deste, não tem sentido nenhum (seja phpverion() ou phpversion()).

O arroba é para omitir erros claro mas mesmo sem omitir qualquer erro em um loop de 1000 o @ diminiu a perfomance do script em mais ou menos 20 milesimos em relação a um loop de 1000 sem o @ mas com o error_reporting digo isto porque eu testei aqui na minha maquina com o benchmark profiler e mesmo assim não precisas de testar só com o phpversion podes tentar criar um e_warning ou algo assim.

Mas pegando no teu exemplo e usando o phpversion(), não notei diferença nenhuma entre os 2... para mim são iguais, não é a diferença de uns milisegundos que me irá xatear. Acho que tás a dar demasiada importância a pormenores do teu CMS demasiado insignificantes para que alguem esteja minimamente ralado com a forma como o programaste e se poupaste 100ms por teres usado x em vez de y. Acho que devias preocupar mais com o essencial e ter um produto final e estável em vez de te ralares com esses pormenores. Mas é só o que eu acho.

Quanto a isso do benchmark, podes explicar os resultados? O script é teu, tu é que deves ter uma ideia do que significam, eu olho prai e só vejo numeros, não os sei interpretar.

Eu não estou preocupado com pormenores como o @ eu não utilizei o parse_url por varias razões uma delas foi o @ mas o @ não é a mais importante ao contrario do que possas pensar a razão mais importante para não utilizar o parse_url foi que eu com o preg_match posso fazer o parsing de outras coisas da url como por exemplo do nome do ficheiro que é uma coisa que o parse_url não faz o parsing e posso fazer o parsing como quiser para satisfazer as minhas necessidades.

Quanto a isso do benchmark, podes explicar os resultados? O script é teu, tu é que deves ter uma ideia do que significam, eu olho prai e só vejo numeros, não os sei interpretar.

Na coluna Section são as secções especificas do código que eu selecciono com o profiler para fazer os testes, na coluna Total Ex Time tens o tempo de execução de cada de secção de código que seleccionei, na coluna Netto... não tenho  a certeza mas acho que é quase a mesma coisa que Total Ex Time... na coluna #Calls tens o número de vezes que uma secção foi chamada no CMS e na coluna Percentage tens a percentagem de tempo de execução de cada secção... Não sei se é isso que querias saber :]

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ta bem, mas no post inicial não deixaste claro e o que me pareceu-me foi que querias fazer algo igual com as mesmas funcionalidades mas evitando o E_WARNING e não que querias fazer algo parecido com funcionalidades extra.

Mas anyway, não sei se esses 20ms é por cada iteração no loop ou no total. Se for no total, I rest my case, é parvo usar error_reporting em vez do @ por apenas 20ms. Se for 20ms por cada iteração, no total a diferença era de 1m40s e assim o caso muda de figura. Mas isto era para 5000 iterações (loop de 0 ate 1000 e loop de 1 a 5) e tu disseste que o teu script executava isso uma 20xs, bem, 20ms 20xs, 400ms, não é muito significativo e penso que ninguém iria ficar importado com 400ms. Ate porque não deves chamar essa instrução 20xs seguidas, logo, o tempo de espera sera espaçado e ninguem iria notar o site lento por uns ms a mais.

Bem, ja divaguei de mais sobre o assunto. Faz o que achares melhor, eu continuo a achar a @ melhor que o error_reporting (para o efeito), mas se a ideia é porque o parse_url não faz tudo que tu queres, tudo bem.

Só acho é que ta uma expressão grande de mais, mas também o URL pode ou não ser um bocado complexo, eu não sei se faria melhor e nem se quer vou tentar, obviamente, por isso, fico-me por aqui.

Manda mase uma beta ou alpha disso ca pa fora, que ja andaste nisto aos anos e ainda não vi quase nada :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ta bem, mas no post inicial não deixaste claro e o que me pareceu-me foi que querias fazer algo igual com as mesmas funcionalidades mas evitando o E_WARNING e não que querias fazer algo parecido com funcionalidades extra.

A minha intenção era só mostrar  um REGEX  para fazer o parsing completo de uma URL  e talvez uma alternativa para o parse_url que também pode ser utilizada em outras linguagens de programação como por exemplo javascript por isso é que não falei mais sobre o queria fazer. :)

Bem, ja divaguei de mais sobre o assunto. Faz o que achares melhor, eu continuo a achar a @ melhor que o error_reporting (para o efeito), mas se a ideia é porque o parse_url não faz tudo que tu queres, tudo bem.

Só acho é que ta uma expressão grande de mais, mas também o URL pode ou não ser um bocado complexo, eu não sei se faria melhor e nem se quer vou tentar, obviamente, por isso, fico-me por aqui.

Vou ver se faço aqui alguns testes para ver se vale a pena mesmo utilizar o preg_match ou não depois disso eu decido qual é a melhor opção para o que pretendo fazer. :]

Manda mase uma beta ou alpha disso ca pa fora, que ja andaste nisto aos anos e ainda não vi quase nada :)

Se continuar com este ritmo de programação acho que em meados de Setembro já tenho a primeira Alpha  pronta  :P Se não me tivesses motivado no outro dia acho que o CMS não estaria onde esta  :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu também utilizava o microtime para fazer os testes mas agora prefiro o benchmark profiler porque é fácil de usar, tem varias opções e mostra os resultados do teste de uma forma organizada.

E como é que se usa isso?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu também utilizava o microtime para fazer os testes mas agora prefiro o benchmark profiler porque é fácil de usar, tem varias opções e mostra os resultados do teste de uma forma organizada.

E como é que se usa isso?

Podes encontrar alguma documentação sobre o benchmark profiler no site da PEAR -> http://pear.php.net/package/Benchmark/docs/1.2.7/Benchmark/Benchmark_Profiler.html

EDIT:

Não te esqueças que primeiro tens que instalar o benchmark profiler não sei como é que se faz no windows mas no linux eu uso este comando na consola

pear install benchmark

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Só para dizer que estou a usar esta função numa biblioteca que vou publicar futuramente aqui no P@P, com o devido cabeçalho "as-in" postaste aqui no forum.

Cumprimentos.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora