← PHP

Problema com preg_replace em PHP

Lida 10079 vezes

Offline

Liurai 
Membro
Mensagens 16 Gostos 0
Troféus totais: 21
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 4 Level 3 Level 2 Level 1 10 Posts First Post

Olá
O problema passa-se com o preg_replace e com uma função colocada no parâmetro de "replacement". O objectivo é que por cada string que o preg_replace encontrar, ele chamar uma função que faça uma chamada ao MySQL e substituir por outr valor. Uma coisa mais ou menos deste genero:
Código: [Seleccione]
$teste = preg_replace('/thumbnails\.php\?album=([a-z0-9]+)/i',getalbumstring("$1"),"http://www.teste.org/thumbnails.php?album=34");
echo $teste;

function getalbumstring($matches){
$query = "SELECT campo FROM tabela WHERE id='$matches'";
$result = mysql_query($query);
$row = mysql_fetch_array($result);
$campo = $row['campo'];
return $campo;
}
O resultado que está a aparecer no ecrã é «http://www.teste.org/» que claramente não é o pretendido.

Isto não funcionou, apesar de eu ter a certeza que havia valores na tabela para a query executada. Aliás, se substituísse hard-coded o «id='$matches'» directamente por «id='34'», ele funciona na perfeição.

Por isso, comecei a apagar linhas para ver o que se passava.
Código: [Seleccione]
$teste = preg_replace('/thumbnails\.php\?album=([a-z0-9]+)/i',getalbumstring("$1"),"http://www.teste.org/thumbnails.php?album=34");
echo $teste;

function getalbumstring($matches){
return $matches;
}
Depois de fazer esta alteração passou a aparecer no ecrã o seguinte: «http://www.teste.org/34», o que me provou que realmente o valor está a ser bem extraído com o preg_replace. Então fiz mais um teste. Fui ao primeiro troço de código e troquei-o por isto:
Código: [Seleccione]
$teste = preg_replace('/thumbnails\.php\?album=([a-z0-9]+)/i',getalbumstring("$1"),"http://www.teste.org/thumbnails.php?album=34");
echo $teste;

function getalbumstring($matches){
$query = "SELECT campo FROM tabela WHERE id='$matches'";
return $query;
}
O resultado foi como era esperado e apareceu o seguinte: «http://www.teste.org/SELECT campo FROM tabela WHERE id='34'»
Ou seja, a string é bem formada, mas quando voltava a colocá-la na query do mysql, o mysql não funcionava.
Fiz mais um teste:
Código: [Seleccione]
$teste = preg_replace('/thumbnails\.php\?album=([a-z0-9]+)/i',getalbumstring("$1"),"http://www.teste.org/thumbnails.php?album=34");
echo $teste;

function getalbumstring($matches){
$query = "xyz".$matches;
return $query." - ".substr($query,1)." - ".substr($query,2)." - ".substr($query,3)." - ".substr($query,4)." - ".substr($query,3,1)." - ".substr($query,3,2);
}
O resultado é surpreendente e estranho:
Código: [Seleccione]
http://www.teste.org/xyz34 - yz34 - z34 - 34 - 1 - $ - 34
Sinceramente já não sei o que fazer. Já fiz todas as experiências. Já tentei somar um e subtrair um, mas o php não o encara nem como número, nem como caracteres, nem faço ideia como o encara. Como se pode ver pelo exemplo acima, atribuí o seu valor a outra variável, mas pelos vistos a variável, mesmo que tenha lá outras coisas pelo meio, trabalha da mesma forma.

Se alguma alma caridosa e perspicaz me puder ajudar ficarei eternamente agradecido.  :clap:
Offline

skin 
Membro
Mensagens 200 Gostos 0
Troféus totais: 27
Trófeus: (Ver todos)
Avatar Super Combination Combination Topic Starter Poll Voter Level 5 Level 4 Level 3 Level 2 Level 1

Faz antes
$coisa = (int)$_REQUEST['album'];

getalbumstring($coisa); // chama a função que queres.

function getalbumstring($matches){
$query = "SELECT campo FROM tabela WHERE id='$matches' LIMIT 0, 1"; // adicionei o LIMIT 0,1 para o caso de por alguma razão teres mais que um valor na tabela e assim não dar problemas
$result = mysql_query($query);
$row = mysql_fetch_array($result);
$campo = $row[0]; // assim não tens de estar sempre a renomear isto caso mudes os nomes dos campos é menos uma linha para alterar

return $campo;
}
Offline

Liurai 
Membro
Mensagens 16 Gostos 0
Troféus totais: 21
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 4 Level 3 Level 2 Level 1 10 Posts First Post

Obrigado pela resposta rápida, skin

Mas no entanto, fiquei um pouco confuso.
Tendo em atenção que tenho isto no meu código:
Código: [Seleccione]
$teste = preg_replace('/thumbnails\.php\?album=([a-z0-9]+)/i',getalbumstring("$1"),"http://www.teste.org/thumbnails.php?album=34");
echo $teste;

como é que integro a tua solução de forma a que faça aquilo que quero.

Só para não haver dúvidas sobre aquilo que quero: ao longo da aplicação que estou a usar (neste caso o Coppermine), vai sendo formada uma variável de nome $html com todo o conteúdo a "despejar" no browser no final da execução do código.
Imaginando que algures dentro dessa variável existem as seguintes substrings:
 "http://www.teste.org/thumbnails.php?album=34"
 "http://www.teste.org/thumbnails.php?album=18"
 "http://www.teste.org/thumbnails.php?album=22"
O que eu quero com aquele preg_replace é substituir estas substrings por (imaginando que o campo title de cada um daqueles ids tem os nomes dos 3 grandes):
 "http://www.teste.org/Sporting"
 "http://www.teste.org/Benfica"
 "http://www.teste.org/Porto"

Offline

skin 
Membro
Mensagens 200 Gostos 0
Troféus totais: 27
Trófeus: (Ver todos)
Avatar Super Combination Combination Topic Starter Poll Voter Level 5 Level 4 Level 3 Level 2 Level 1

A solução que eu apresentei era para se fosses para esse endereço e não para se fosse inserido pelo código numa página como se fosse texto :P.

Isto funciona:
$xpto = preg_match_all('/thumbnails\.php\?album=(\d+)/i', "http://www.teste.org/thumbnails.php?album=34", $match);
$coiso = $match[1][0];
$teste = preg_replace('/thumbnails\.php\?album=(\d+)/i',getalbumstring($coiso),"http://www.teste.org/thumbnails.php?album=34");
echo $teste;
Offline

Liurai 
Membro
Mensagens 16 Gostos 0
Troféus totais: 21
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 4 Level 3 Level 2 Level 1 10 Posts First Post

A solução que eu apresentei era para se fosses para esse endereço e não para se fosse inserido pelo código numa página como se fosse texto :P.

Isto funciona:
$xpto = preg_match_all('/thumbnails\.php\?album=(\d+)/i', "http://www.teste.org/thumbnails.php?album=34", $match);
$coiso = $match[1][0];
$teste = preg_replace('/thumbnails\.php\?album=(\d+)/i',getalbumstring($coiso),"http://www.teste.org/thumbnails.php?album=34");
echo $teste;

Mais uma vez, agradeço-te a resposta, skin. Apesar de já estar perto daquilo que quero, ainda não resulta na totalidade. Só resulta se houver apenas uma ocorrência. Se existirem mais ocorrências, isto não funciona. Tentei assim:
Código: [Seleccione]
<?php
$teste preg_match_all('/thumbnails\.php\?album=([a-z0-9]+)/i',"http://www.teste.org/thumbnails.php?album=34 http://www.teste.org/thumbnails.php?album=21",$match);
$x $match[1][0];
$teste preg_replace('/thumbnails\.php\?album=([a-z0-9]+)/i',getalbumstring($x),"http://www.teste.org/thumbnails.php?album=34 http://www.teste.org/thumbnails.php?album=21");
echo $teste;

function getalbumstring($matches){
$matches ="xyz".$matches;
return $matches "|";
}
?>

;
E o resultado foi este:
Código: [Seleccione]
http://www.teste.org/xyz34| http://www.teste.org/xyz34|

Tentei outras alternativas ao teu código, mas ainda não consegui :(
Offline

skin 
Membro
Mensagens 200 Gostos 0
Troféus totais: 27
Trófeus: (Ver todos)
Avatar Super Combination Combination Topic Starter Poll Voter Level 5 Level 4 Level 3 Level 2 Level 1

Claro que assim não funciona :P

Para isso terias de primeiramente fazer um ciclo para te contar o número de ocorrências na página, de seguida substituir cada ocorrência.
Offline

Liurai 
Membro
Mensagens 16 Gostos 0
Troféus totais: 21
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 4 Level 3 Level 2 Level 1 10 Posts First Post

Tinha realmente pensado nessa hipótese.
Só tinha esperança que o preg_replace fizesse isso de forma mais automatizada. :( Vou mesmo ter de utilizar um FORzito, certo?
Offline

skin 
Membro
Mensagens 200 Gostos 0
Troféus totais: 27
Trófeus: (Ver todos)
Avatar Super Combination Combination Topic Starter Poll Voter Level 5 Level 4 Level 3 Level 2 Level 1

Verifica assim:

$teste = preg_match_all('/thumbnails\.php\?album=([a-z0-9]+)/i',"http://www.teste.org/thumbnails.php?album=34 http://www.teste.org/thumbnails.php?album=21",$match);
print_r($match);
foreach($match[1] as $xyz) {
   $teste = preg_replace('/thumbnails\.php\?album=(\d+)/i',getalbumstring($xyz),"http://www.teste.org/thumbnails.php?album=1234");
   echo $teste . "<br />";
}


Não ligues aquele 1234, ele só está ali a fazer feitio :P
Offline

anjo2 
Membro
Mensagens 3020 Gostos 0
Troféus totais: 31
Trófeus: (Ver todos)
Super Combination Combination Topic Starter 10 Poll Votes Poll Voter Poll Starter Level 5 Level 4 Level 3 Level 2

Isto não faz muito sentido, para que queres utilizar o preg_replace?
Offline

skin 
Membro
Mensagens 200 Gostos 0
Troféus totais: 27
Trófeus: (Ver todos)
Avatar Super Combination Combination Topic Starter Poll Voter Level 5 Level 4 Level 3 Level 2 Level 1

Pois, na verdade agora nem é necessário..
Offline

anjo2 
Membro
Mensagens 3020 Gostos 0
Troféus totais: 31
Trófeus: (Ver todos)
Super Combination Combination Topic Starter 10 Poll Votes Poll Voter Poll Starter Level 5 Level 4 Level 3 Level 2

<?
        
@preg_match_all('/thumbnails\.php\?album=(\d+)/',"http://www.teste.org/thumbnails.php?album=34 http://www.teste.org/thumbnails.php?album=2m1",$match);
        
$links = array();
        foreach(
$match[1] as $id) {
                
$sql "SELECT campo FROM tabela WHERE id='$id'";               
                
$result mysql_query($sql);
                if(@
mysql_num_rows($result)) {
                        
$query mysql_fetch_array($result);
                        
$links[$query['campo']] = "http://www.teste.org/".$query['campo'];
                }
        }
        
print_r($links);
?>
Offline

Liurai 
Membro
Mensagens 16 Gostos 0
Troféus totais: 21
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 4 Level 3 Level 2 Level 1 10 Posts First Post

Obrigado também à tua resposta, anjo2, mas eu não me devo ter explicado bem.

Utilizei a string de pesquisa "http://www.teste.org/thumbnails.php?album=34 http://www.teste.org/thumbnails.php?album=21" directamente como parâmetro do preg_replace só para simplificar a minha questão, mas pelos vistos compliquei. O que eu preciso é o seguinte:

Código: [Seleccione]
    $html="
<html>
  <body>
     algum texto
     <a href="thumbnails.php?album=34">Portugal</a>
     outro texto e fotos e outros elementos
     <a href="thumbnails.php?album=21">Brasil</a>
     jgfhjh kjdf gkjh dfkjhg dfhg kfhgkjh e mais fotos
     <a href="thumbnails.php?album=87">Mongolia</a>
  </body>
</html>";
/////////////////////////////////
//// Código a ser executado para fazer aquilo que preciso
///////////////////////////////
echo $html;
E quando aparecesse no browser aparecia da seguinte forma:
Código: [Seleccione]
<html>
  <body>
     algum texto
     <a href="miniaturas-Portugal-34.html">Portugal</a>
     outro texto e fotos e outros elementos
     <a href="miniaturas-Brasil-21.html">Brasil</a>
     jgfhjh kjdf gkjh dfkjhg dfhg kfhgkjh e mais fotos
     <a href="miniaturas-Mongolia-87.html">Mongolia</a>
  </body>
</html>
Claro que quando meto na primeira janela de código $html="xyzxyz....." é apenas para este exemplo. Eu quero utilizar isto num script como o Coppermine. Ele já tem um addon que é o SEF_URL que eu estou a utilizar, mas que ainda não faz tudo o que quero. Como é natural, se fosse um troço como o que escrevi em cima e sobre o qual tinha todo o controlo, nem precisava disto. O problema é que o Coppermine antes de formar a página de saída passa por inúmeros ficheiros e não justifica estar a alterar o código desses ficheiros todos. Aliás estas alterações que quero fazer são para ser feitas num ficheiro do próprio addon SEF_URL que já tem a tal variável $html. Eu não tenho qualquer controlo sobre como ela é formada. Só quero alterá-la mesmo antes de o Coppermine fazer echo dela.
Offline

anjo2 
Membro
Mensagens 3020 Gostos 0
Troféus totais: 31
Trófeus: (Ver todos)
Super Combination Combination Topic Starter 10 Poll Votes Poll Voter Poll Starter Level 5 Level 4 Level 3 Level 2

já percebi, mas acho que não faz muito sentido...
<?
        $html
='<html>
        <body>
                algum texto
                <a href="thumbnails.php?album=34">Portugal</a>
                outro texto e fotos e outros elementos
                <a href="thumbnails.php?album=21">Brasil</a>
                jgfhjh kjdf gkjh dfkjhg dfhg kfhgkjh e mais fotos
                <a href="thumbnails.php?album=87">Mongolia</a>
        </body>
</html>'
;
        while(
preg_match_all("/thumbnails\.php\?album=(\d+)/i",$html,$match)) {
                
$texto "";
                
$sql "SELECT campo FROM tabela WHERE id='".$match[1][0]."'";               
                
$result mysql_query($sql);
                if(@
mysql_num_rows($result)) {
                        
$query mysql_fetch_array($result);
                        
$texto $query['campo'];
                }
                if(empty(
$texto)) $texto "Indefinido";
                
$replace 'miniaturas-'.$texto.'-$1';
                
$html preg_replace('/thumbnails\.php\?album=(\d+)/i'$replace$html);
        }
        echo 
$html;
?>


Output:
Citar
<html>
   <body>
      algum texto
      <a href="miniaturas-Portugal-34">Portugal</a>
      outro texto e fotos e outros elementos
      <a href="miniaturas-Brasil-21">Brasil</a>
      jgfhjh kjdf gkjh dfkjhg dfhg kfhgkjh e mais fotos
      <a href="miniaturas-Mongolia-87">Mongolia</a>
   </body>

</html>
Offline

Liurai 
Membro
Mensagens 16 Gostos 0
Troféus totais: 21
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 4 Level 3 Level 2 Level 1 10 Posts First Post

LOL
Desculpa Anjo, mas ou eu continuo a explicar-me mal ou então não consigo fazer passar a minha ideia. #-o

O exemplo que dei no último post foi demasiado especifico e isso induziu-te em erro.

O que eu quero é que se pegue no número que está a seguir a "album" e se vá à tabela de dados buscar o titulo correpondente. Imaginando que o registo com o id=34 (ou neste caso album=34) tem o title="Portugal", então se na tal variável $html estiver por lá a string '<a href="thumbnails.php?album=34">Portugal</a>' deverá aparecer '<a href="miniaturas-Portugal-34">Portugal</a>', mas se estiver outra coisa como texto da âncora, o link deverá ser o mesmo. Portanto:

<a href="thumbnails.php?album=34">Portugal</a> ====><a href="miniaturas-Portugal-34">Portugal</a>
<a href="thumbnails.php?album=34">qualquer coisa</a> ====><a href="miniaturas-Portugal-34">qualquer coisa</a>
<a href="thumbnails.php?album=34">outra ainda</a> ====><a href="miniaturas-Portugal-34">outra ainda</a>
<a href="thumbnails.php?album=21">Brasil</a> ====><a href="miniaturas-Brasil-21">Brasil</a>


Claro que se aquilo que entendeste do post anterior fosse aquilo que eu pretendia, realmente não faria nenhum sentido. Espero que entendas este. :cool:
Offline

Liurai 
Membro
Mensagens 16 Gostos 0
Troféus totais: 21
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 4 Level 3 Level 2 Level 1 10 Posts First Post

Só para complementar, como expliquei anteriormente, eu não sei antecipadamente o conteúdo da variável $html, nem posso prever se a âncora tem texto (nem que texto) ou imagens como conteúdo.