In my database it is allowed to enter images locally -> imagen.png
or from one URL
-> https://dominio/ruta/imagen.png
, the main idea is to be able to detect if said data starts with: http
, https
, ftp
.
Using the following code I get that 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 urlhttp://dominio/ruta/1.png
The error
When executing said example inside a loop, while
it shows me as a result that everything is No URL
even the one that if they are , URL
it 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 tell me how to solve the problem, what am I doing wrong?
The error is in the regular expression you used
which will clearly match a domain-only URL, as in
"http://www.example.com"
, but will not match a longer path as in"http://dominio/ruta/1.png"
Why? Because
a-z0-9._-
they are the allowed characters, and it does not contain the/
within them.Instead, if we add it to that character class, the following expression will match:
Another way to validate URLs, without worrying about regex syntax, is to use filter_var() :
and in case it helps you can also pass options as 3rd parameter to
filter_var()
:Sorry to differ from the second part of @Pollo's answer regarding the use of
filter_var()
, as this function would consider a URL like this to be valid:ttp://www.example.com
. Also, the intention is not to actually validate a URL, but to check if it starts withhttp
,https
orftp
.If you want to avoid using regular expressions, this could easily be done using
parse_url()
. By passing the flagPHP_URL_SCHEME
you would get only the first part of the URL and you could check the data against an array containing the values of your whitelist usingin_array()
.The code would look like this:
To simplify and/or create portable code , you can create a function that returns a boolean and call it from within the loop, something like this:
If whitelists vary by context you can take it out
$whiteList
of the function and put it as a parameter, then you would declare$whiteList
in the context.To use the function in the loop:
OBSERVE that in
while
I am passing$image
to the function, since it is redundant to do this:$UrlImage = $image;
, because you already have the data in$image
.