Ir para conteúdo
Fórum Script Brasil
  • 0

Desafio Php


Leo Todeschini

Pergunta

Tentem desvendar o mistério do código abaixo!

<?   
   // Analise o script abaixo:   

   $a = 10;
   $b = false;
   $c = "a12";
   $d = "10b";
      
   $r = ((($a==$d)+(($a==$d)&&(!$b))+(12==$c))*2);
   
   echo $r;

   // Pergunta: porque $r no final tem o valor 4?
?>

Link para o comentário
Compartilhar em outros sites

11 respostass a esta questão

Posts Recomendados

  • 0

É exatamente essa a questão...

O porque do seguinte:

12 ser diferente de a12

e

10 ser igual a 10b

Mas sua resposta não deixa de estar parcialmente correta

Link para o comentário
Compartilhar em outros sites

  • 0

Por você estar utilizando o comparador igual (eq, ==), o core do PHP não verifica se eles são idênticos (===). Ao utilizar "10b", o PHP PODE interpretar como números, e assim confirmar a igualdade com (int)"10", uma apelação para comparação de strings.

Eu ainda não fiz o teste, pois estou no trabalho. E para provar que POSSO estar certo, faz o seguinte $a==(string)$d .

Isso deve dar false, pois não vai forçar o PHP a interpretar $d como sendo int.

Já o "a12" força o core a interpretá-lo como string, por começar com um alpha...

Foi mal qualquer tipo de burrice...

Flws

Link para o comentário
Compartilhar em outros sites

  • 0

Por começar com um alpha, o php o trata como string.

Sempre que o PHP compara utilizando o ==, ele faz as tranformações necessárias. Uma das tranformações é converter string em int (ou vice-versa):

print ('1' == 1)
// Retorna True

O a12 começa com uma string, fazendo que o php aceite-a como tal, diferente do 10b, que começa com numérico.

Link para o comentário
Compartilhar em outros sites

  • 0

Deixarei minha resposta ao enigma...

Bom vamos lá:

Antes falarei sobre um tema que discuti com Daniel Kushner o diretor educacional da Zend (Empresa responsável pelo PHP que trabalhamos hj) em um email sobre uma dúvida que tive na função intval, cuja sintaxe é:

int intval ( mixed var [, int base])

Bom, essa função é chamada automaticamente quando tentamos realizar uma operação lógica ou aritmética entre inteiros e strings, em especial nas strings, tentando transformar essas em um possível inteiro. O PHP só realiza esse casting (conversão de tipos) por não haver uma definição prévia das variáveis envolvidas num script.

Então, se analisando uma situação do tipo:

$a = (10=="10");

PHP trataria assim:

$a = (10==intval("10"));

O resultado disso é mais previsível... seria:

$a = (10==10);

$a = 1;

Até ai tudo bem... mas nossos problemas e dúvidas ainda não se esgotaram..

Como seria o resultado de:

$a = (10=="10a");

Ai sim dissecamos o modo de trabalho de intval, pois pensamos em qual seria a lógica no tratamento dessa string? Será que a conversão NÃO seria feita por se tratar dessa string possuir um caracter alpha? Ou trataria somente a parte numérica separadamente? Bem, a resposta é simples.

intval lê a matriz unidimensional "10a" e verifica se esta começa com um número.. se sim então procura por números adjacentes até o fim ou até encontrar um alpha. Se encontrar um alpha depois de um número qualquer na posição 0 desconsidera o restante e fica com o início numérico convertido em inteiros. Se a função encontrar um alpha na posição 0 então já encara a string como 0. Interessante isso, porque inval é chamada sem ser mostrada, é chamada automaticamente no sistema interno do PHP.

Agora fica fácil de resolver o problema:

$a = (10=="10a");

Internamente seria:

$a = (10==intval("10a"));

Agora sabemos que intval considera o início inteiro e quando encontra o caractere alpha "a" o ignora, assim como ignoriaria tudo que viesse depois, mesmo sendo um número.

O resultado então seria:

$a = (10==10); ou seja $a=1; outra vez.

Outros exemplos de caso:

$a = (15=="aeiou15");

intval trataria a string "aeiou15" como "false" ou 0, porque a mesma inicia-se com um alpha.. logo tudo que vem depois foi ignorado... inclusive os caracteres numéricos.

Traduzindo seria:

$a = (15==0); ou seja $a=0;

Outro exemplo:

$a = (12=="12b13c14f");

Na solução, a função intval verifica que a posição 0 da string é numérica ai então analisa o que há de números após a posição 0, enquanto houver números esses serão considerados, em nosso caso a posição 0 e 1.. porém o que vem depois é totalmente desconsiderado pelo fato de existir um b na posição 2 da string... mesmo tendo números após a posição 2, todo o resto é desconsiderado.

Tento em mãos essas informações.. é simples como 2+2 resolver o enigma, veja:

$r = ((($a==$d)+(($a==$d)&&(!$b))+(12==$c))*2);

Traduzindo:

$r = (((10==intval("10b"))+((10==intval("10b"))&&(!false)+(12==intval("a12")))*2);

$r = (((10==10) + ((10==10)&&(true)) + (12==0))*2);

$r = (((1)+(1&&1)+(0))*2);

$r = (((1)+(1)+(0))*2);

$r = ((2)*2);

$r = 4;

Espero que depois de entender intval, possa fazer sentido a explicação que dei.

O problema aqui Não era saber o resultado, e sim entender melhor o funcionamento interno do PHP, para que possamos entender certas armadilhas.

Obrigado pela atenção de todos, e espero ter adicionado algum conhecimento a vocês..

Abraços,

Leonardo Todeschini

Link para o comentário
Compartilhar em outros sites

  • 0

Com essa explicação até minha avó saberia!!! Hehehe

Valeu Leo, agora ficou claro, muito boa a sua explicação, parabéns.

Mas fiquei com uma dúvida, além da função intval(), que você falou que é automática, existe alguma outra que também é automática?

Link para o comentário
Compartilhar em outros sites

  • 0

Existe outras sim fsphp...

Podemos citar funções de casting (conversão de tipo) da mesma linha de intval como:

Função: strval

Sintaxe: string strval ( mixed var)

Objetivo: converte qualquer tipo NÃO string em um string...

Ex.:

$inteiro = 10;

$str = "O resultado é ".$inteiro;

Repare que será executado

$str = "O resultado é ".strval(10);

ou seja

$str = "O resultado é "."10";

Outra

Função: floatval

Sintaxe: float floatval ( mixed var)

Objetivo: converte uma variável em float... a mesma filosofia de intval

Ex.:

$variavel = '122.34343STRING';

$valor_float = floatval ($variavel);

print $valor_float; // mostra 122.34343

(Obs.: Código retirado da documentação do PHP)

Bom, uma coisa que muitas pessoas não sabem é que pode-se declarar variáveis em PHP, talvez nós não às declaramos por conveniência ou por preguiça (hehehe) ou quem sabe porque o PHP já faz isso pra nós...

Vejamos como declarar variáveis em PHP:

Sem declarações:

$a = 10; // automaticamente essa variável se torna um inteiro, pela atribuição recebida..

$b = 20.48; // a mesma coisa acontece aqui.. pela atribuição a variável se torna um float...

$c = $a + $b; // Na soma por questões de precedência... tudo é transformado em float e o resultado obtido em $c é 30.48

Com declarações:

settype($a,"integer");

settype($b,"float");

settype($c,"float");

$a = 10;

$b = 20.48;

$c = $a + $b;

Obs.: a vantagem aqui é que sabemos quais são os tipos das variáveis, porém vale lembrar que se $c tivesse sido declarado como um inteiro, tb teríamos um $c float no final.. por respeito a essa precedência de tipos.

Nota: Os tipos suportados pelo PHP são:

- boolean

- integer

- float

- string

- array

- object

- null //disponível só a partir da versão 4.2.0 do PHP

Bom fsphp, acho que está ilustrado mais algumas funções que agem por debaixo dos panos em PHP, espero ter respondido a dúvida e obrigado por se interessar pelo tópico...

Abraços

Leonardo Todeschini, ou simplesmente Leo smile.gif

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      651,8k
×
×
  • Criar Novo...