php – Failed to detect URL from / while loop

Question:

In my database it is allowed to enter images locally -> imagen.png or from a URL -> https://dominio/ruta/imagen.png , the main idea is to be able to detect if that data starts with: http , https , ftp .

Using the following code I get this response without any problem:

$image = "http://www.example.com";

$UrlImage = $image;
if(preg_match('/^(http|ftp|https)\:\/\/+[a-z0-9\.\_-]+$/i',$UrlImage)) {
    //echo '<img src="'.$image.'">';
    echo 'URL';
} else {
    //echo '<img src="assets/img/website/catalog/'.$image.'">';
    echo 'No URL';
}

It should be noted that the variable $image can store two values local image 1.png or image URL http://dominio/ruta/1.png

The error

When executing said example inside a while loop it shows me as a result that everything is No URL even the one that if they are URL shows me that it is No URL , this is my code:

$stmt->bind_result(
                    $id_product,
                    $image,
                    $product
);

while ($stmt->fetch()) {

    $UrlImage = $image;
    
    if(preg_match('/^(http|ftp|https)\:\/\/+[a-z0-9\.\_-]+$/i',$UrlImage)) {
        //echo '<img src="'.$image.'">';
        echo 'URL';
    } else {
        //echo '<img src="assets/img/website/catalog/'.$image.'">';
        echo 'No URL';
    }
}

Can you explain to me how to solve the problem, what I am doing wrong.

Answer:

The error is in the regex you used

/^(http|ftp|https)\:\/\/+[a-z0-9\.\_-]+$/i

that will clearly match a URL that only has the domain, as in the case "http://www.example.com" , but it will not match a longer path as in "http://dominio/ruta/1.png"

Why? Because a-z0-9._- are the allowed characters, and it does not contain the / within them.

On the other hand, if we add it to that character class, the following expression will match:

/^(https?|ftp):[-a-z0-9._\/]+$/i

Another way to validate URLs, without worrying about the regex syntax is using filter_var () :

if (filter_var($UrlImage, FILTER_VALIDATE_URL) !== false) {
    echo 'URL válida';
}

and in case it helps you, you can also pass options as 3rd parameter to filter_var() :

FILTER_FLAG_SCHEME_REQUIRED   Sólo si respeta el RFC
FILTER_FLAG_HOST_REQUIRED     Debe contener el dominio (www.ejemplo.com)
FILTER_FLAG_PATH_REQUIRED     Debe contener una ruta (/ruta/archivo.html)
FILTER_FLAG_QUERY_REQUIRED    Debe contener parámetros de consulta (?a=busqueda)
Scroll to Top