strpos() not behaving as it should

Asked

Viewed 143 times

0

strpos() is not behaving as it should, it always returns FALSE even with the two strings containing the value of the $czech variable.

<?php
$checa = "https://www.site.com.br/";

$url_ref = $_GET['url_ref']; // Recebe: https://www.site.com.br/login/usuarios/

if( strpos( $url_ref, $checa ) !== false ) {
    echo "Confere" . "<br>\n";
} else {
    echo "Não confere" . "<br>\n";
}
?>

It is always returning FALSE ( Does not check ).

If I change the variable, it also gives FALSE

<?php
$checa = "Qualquer coisa";

$url_ref = $_GET['url_ref']; // Recebe: https://www.site.com.br/login/usuarios/

if( strpos( $url_ref, $checa ) !== false ) {
    echo "Confere" . "<br>\n";
} else {
    echo "Não confere" . "<br>\n";
}
?>
  • Just for the sake of conscience: your code is also missing one ; in the first line?

  • @fernandosavio no, ajustei!

  • Strange, I can’t think of anything. Except to print out the two variables and check in the eye what’s going on.

  • As I left commented in the $_GET string, it is the site address with friendly URL, and nothing else, if it contains https://www.site.com.br/ in https://www.site.com.br/login/usuarios/ should return TRUE and not FALSE, and change $czech to anything, always returns FALSE.

  • Thank you all

1 answer

6


First we validate Urls so the chance of failing is very high, following problem points:

  • strpos only case-sensitive czech
  • strpos "can" (depends on how you use) fail depending on the case
  • strpos will not differentiate https from http
  • strpos will not ignore spaces at the beginning and end

Other problems:

  • Foul isset or empty
  • strpos( $url_ref, $checa ) !== false only check whether it contains or not, the "correct" (theoretically) would be used with "ZERO" strpos( $url_ref, $checa ) === 0) { echo 'confere'

A suggestion, you want to validate URL by domain, then use parse_url (and the trim) to remove spaces, a revised code:

<?php
$checa = "www.site.com.br"; //Sem http, sem https

if (empty($_GET['url_ref'])) {
    echo "Vazio ou não definido<br>\n"; //Customize a mensagem de erro
} else {
    $url = trim($_GET['url_ref']);

    if ($url == '') {
         echo "Vazio<br>\n"; //Customize a mensagem de erro
    } else {
         $scheme = parse_url($url, PHP_URL_SCHEME);

         if (!in_array($scheme, array('http', 'https'))) {
              echo "Não é HTTP(S)<br>\n"; //Customize a mensagem de erro
         } else {
              $host = parse_url($url, PHP_URL_HOST);

              if ($host === $checa) {
                  echo "Confere<br>\n";
              } else {
                  echo "Não confere<br>\n";
              }
         }
    }
}

With regex (preg_match)

Of course you could use regex as well, which would even reduce the code a little bit, so:

<?php
//NÃO passe o http, sem https
//preg_quote escapa caracteres que podem after a regex, no exemplo converte pontos em `\.`
$checa = preg_quote("www.site.com.br");

if (empty($_GET['url_ref'])) {
    echo "Vazio ou não definido<br>\n"; //Customize a mensagem de erro
} elseif (preg_match("#^https?://{$checa}(/|$)#", trim($_GET['url_ref']))) {
    echo "Confere<br>\n";
} else {
    echo "Não confere<br>\n";
}

Explaining the regex:

^https?://www\.site\.com\.br(/|$)
 ^         ^                 ^
 |         |                 |
 |         |                 |
 |         |                 +--- Checa se tem barra `/`, se não tiver deve ser o final das string, caso contrário é uma dominio invalido
 |         |
 |         +--- Url passada na variavel, ela esta com \. no lugar de pontos, porque `.` é um caractere usado para expressões regulares, então o preg_quote o escapou
 |
 +--- Verifica se começa com HTTP ou HTTPS, o `?` após o `s` faz ele ser "opcional"
  • Thank you, perfect!

  • 1

    @Eliseub. if you are using the preg_match switch https?://{$checa}(/|$) for ^https?://{$checa}(/|$), was my fault, was missing the ^

Browser other questions tagged

You are not signed in. Login or sign up in order to post.