Make the URL path count backwards - php

I learned how to parse an URL and return me a specific part of it.
For now, I'm currently working in a localhost server, which contains a long basename:
localhost/mydocs/project/wordpress/mexico/cancun
If I want to get the word mexico I would have to count 4 until there.
$url = localhost/mydocs/project/wordpress/mexico/cancun
$parse = parse_url($url);
$path = explode('/', $parse[path]);
echo = $path[4]
Even though it works fine for localhost, when uploading in the server, the basename get shorter and the number 4 can not reach mexico, because the URL becomes:
example.com/mexico/cancun
I'd like to know if there is a global solution for it. I thought about counting backwards, like using -2, so it would start counting from the word "cancun", but I don't know whether is possible or not!
Thank you!

use $path[count($path)-2] -2 being the configurable part.
Note this will only work for numeric indices, like for your case.

Related

php __FILE__ inside includes?

I have (maybe) an unusual issue with using __FILE__ in a file within a file.
I created a snippet of code (in the php 5 my server mandates) to take elements of the current filename and put it into a variable to use later. After some headache, I got it working totally fine. However, I realized I didn't want to have to write it every time and realized "oh no, if I include this it's only going to work on the literal filename of the include". If I wanted to grab the filename of the page the user is looking at, as opposed to the literal name of the included file, what's the best approach? Grab the URL from the address bar? Use a different magic variable?
EDIT1: Example
I probably should have provided an example in the first draft, pfft. Say I have numbered files, and the header where the include takes place in is 01header.php, but the file it's displayed in is Article0018.html. I used:
$bn = (int) filter_var(__FILE__, FILTER_SANITIZE_NUMBER_INT);
…to get the article number, but realized it would get the 1 in the header instead.
EDIT2: Temporary Solution
I've """solved""" the issue by creating a function to get the URL / URI and putting it into the variable $infile, and replaced all former appearances of __FILE__ with $infile, like so:
function getAddress() {
$protocol = $_SERVER['HTTPS'] == 'on' ? 'https' : 'http';
return $protocol.'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];}
$infile = urlencode(getAddress());
$bn = (int) filter_var($infile, FILTER_SANITIZE_NUMBER_INT);
echo "$bn";
So if the file the user is looking at is called "005-extremelynormalfile.html", I can display the number 5 inside the page, e.g., to say it's article number five.
While it's not as bad as I initially thought based on your description your code is still very fragile, and really only works by accident. If you have any other digits or hyphens it's going to go wrong, as below.
$infile = 'https://example-123.com/foo/42/bar/005-extremelynormalfile.html?x=8&y=9';
var_dump(
filter_var($infile, FILTER_SANITIZE_NUMBER_INT),
(int)filter_var($infile, FILTER_SANITIZE_NUMBER_INT)
);
Output:
string(12) "-12342005-89"
int(-12342005)
Sanitize functions are a blunt instrument for destroying data, and should only ever be used as a last resort when all other good sense has failed.
You need to use a proper parsing function to parse the url into its component parts, and then a simple regular expression to get what you want out of the filename.
function getIdFromURL($url) {
$url_parts = parse_url($url);
$path = $url_parts['path'];
$path_parts = explode('/', $path);
$filename = end($path_parts);
if( preg_match('/^(\d+)/', $filename, $matches) ) {
return (int)$matches[1];
}
return null;
}
var_dump(
getIdFromURL($infile)
);
Lastly, a lot of people are tempted to cram as much logic as possible into a regular expression. If I wanted to the above could be a single regex, but it would also be rigid, unreadable, and unmaintainable. Use regular expressions sparingly, as there's nearly always a parser/library that already does what you want, or the majority of it.
Quickly threw together a function that gets the url from the page as a variable, and replaced all occurrences of __FILE__ with that variable, and it worked correctly. Assuming the user cannot edit the URL / URI in any way, this should work well enough.

PHP str_replace not replacing a windows path string correctly

$search = 'C:\xampp1.7.7\htdocs\myproject\uploads/files/temp-ds-original';
$subject = 'C:\xampp1.7.7\htdocs\myproject\uploads\files\temp-ds-original\32bd76470cff973ec873d43a4e84dd2f.jpg';
echo str_replace($search, '', $subject);
It just prints $subject without doing any replacements. I thought it could be due to some php version issue as it was on a php 5.3 but then I moved to php 7.2 but still the same result. Not sure what's going wrong here?
Is it something to do with the slashes?
I have hardcoded string values above but in the actual script, I am using $f->getRealPath() to get subject and search. $f is an object of RecursiveIteratorIterator
EDIT
As soon as I posted this question, I could spot the issue as code highlighting made it quite clearer to see that slashes don't match - which means str_replace considers it a non-match. What I am trying to achieve is get relative path which in above example is \32bd76470cff973ec873d43a4e84dd2f.jpg ... the code is here at line 48 https://gist.github.com/bubba-h57/5117694
The above output is on a Windows machine but I will be using this script later on a Linux server. So I need to think about how to get the paths consistent so that str_replace can do the replacement correctly. $search is something I provide manually where $subject is being retrieved automatically using $f->getRealPath().
Update and Answer of my question
I don't believe this question is duplicate to the linked question. People are quick here to show off their skills without paying due attention to details. :)
It turned out to be a simple solution. All I need to do is use realpath() i.e. $search = realpath($search); which gives me the correct result.
Just so that it helps anyone -
$search = 'C:\xampp1.7.7\htdocs\myproject\uploads/files/temp-ds-original';
$subject = 'C:\xampp1.7.7\htdocs\myproject\uploads\files\temp-ds-original\32bd76470cff973ec873d43a4e84dd2f.jpg';
echo str_replace($search, '', $subject);
Output was:
C:\xampp1.7.7\htdocs\myproject\uploads\files\temp-ds-original\32bd76470cff973ec873d43a4e84dd2f.jpg
However I was expecting to be:
\32bd76470cff973ec873d43a4e84dd2f.jpg
I failed to notice the slashes mismatch and therefore str_replace was not at fault at. Importantly, I wasn't trying to get the filename only which I could get from basename() or other methods so I needed to get the slashes right.
All I needed to was to use PHP's realpath() i.e.
$search = realpath($search);
That's it. However, you need to be careful that it only worked for me because I was parsing an actual path i.e. the folder in the $search existed on the disk. So, if you tried to parse a path string which is dummy or not a real directory, realpath() would return empty or false.
you have to do this
you have to use doble backslash if you use only one dont work !
result:
You could just use the same search always
(eg: $search = 'C:\xampp1.7.7\htdocs\myproject\uploads\files\temp-ds-original';)
then change the subject's slashes by using str_replace('/','\',$subject);
Or you could detect the OS and then use the matching $search
You can do this by checking the PHP Constant PHP_OS (Documentation in the link)
I hope that solves it.

How do I get the depth of a URL using PHP?

I'd like to echo the depth (or number of directories from my home) of my current page's URL using PHP. How would I do that?
For example, if I'm on mysite.com, the output displays "0", if I'm on mysite.com/recipes, the output displays "1", and if I'm on mysite.com/recipes/pies, the output displays "2", and so on.
How do I do that?
I tried simplifying it and doing this, but it's exporting as 0:
$folder_depth = substr_count($_SERVER["PHP_SELF"] , "/");
echo $folder_depth;
Just for fun, here is my cheap and cheezy solution using PHP's parse_url() and its PHP_URL_PATH return value along with a couple of other functions:
$url = 'http://universeofscifi.com/content/tagged/model/battlestar_galactica.html';
echo var_dump(parse_url($url, PHP_URL_PATH));
echo count(explode('/', (parse_url($url, PHP_URL_PATH)))) - 2;
This returns:
string(47) "/content/tagged/model/battlestar_galactica.html"
3
I subtract 2 from the count to discard the domain at the front and the file at the end, leaving only the directory depth count.
If you won't have a query string, you can explode on /. If you will have a query string, you need to remove that first, such as...
$url = preg_replace('/?.*$/','',$url);
If you have http:// or https:// at the front of your URL, that can mess it up also. So remove it...
$url = preg_replace('~^https*://~','',$url);
Now, you only have the url as example.com/some/path/to/something. You can explode on / and get a count:
$a = explode('/',$url);
The size of $a will be 1 more than what you want. So, you need to subtract one:
$depth = sizeof($a)-1;
New problem... I just counted the file itself, such as example.com/links.html will come up as 1, not just 0. So, before the explode I need to get rid of the file name. But... how do I know if it is a file or a directory? That isn't built into the URL specification. For example, example.com/test could be a file or it could be a directory (and then it automatically goes to example.com/test/index.html). You need to assume what file extensions you will have and remove those files before you explode, such as:
$url = preg_replace('~/[^/]+.(html|php|gig|png|mp3)$~','',$url);
#kainaw, I like your answer! Thanks!
I took a spin on that. First, I noticed I was using the wrong PHP function to get the part of the URL I needed. Second, I needed to use #kaniaw's example and get the parts of the URL which I'm supposed to count, and ignore the others.
I also had to account for urls without content between the "/", so something like /word//// would still count as 1. Therefore, I only counted array elements after explode() which were not empty.
Here's my code:
$url = $_SERVER['REQUEST_URI'];
//echo "*".$_SERVER['REQUEST_URI']."*";
//$url = preg_replace('/?.*$/','',$url);
//$url = preg_replace('~^https*://~','',$url);
//$url = preg_replace('~/[^/]+.(html|php|gig|png|mp3)$~','',$url);
$a = explode('/',$url);
$depth =count(array_filter($a));
echo $depth;
I commented out some of those lines because I didn't seen them, but they were mentioned above.
Thanks!

Extract domain name from affiliate URL using PHP

Here is the format of affiliate URL I have http://tracking.vcommission.com/aff_c?offer_id=2119&&url=http%3A%2F%2Fwww.netmeds.com%2F%3Fsource_attribution%3DVC-CPS-Emails%26utm_source%3DVC-CPS-Emails%26utm_medium%3DCPS-Emails%26utm_campaign%3DEmails
If you see it has 2 URLs:
first URL: is for vcommission.com and
Second URL: netmeds.com
I have CSV file with lot of rows. Each rows may have different second URL. I wanted to get second URL for each rows. First URL is also not static as for different CSV, this would also different.
How can I get second URL?
Some basic string parsing like this should give you an idea.
$url='http://tracking.vcommission.com/aff_c?offer_id=2119&&url=http%3A%2F%2Fwww.netmeds.com%2F%3Fsource_attribution%3DVC-CPS-Emails%26utm_source%3DVC-CPS-Emails%26utm_medium%3DCPS-Emails%26utm_campaign%3DEmails';
list($u,$q)=explode('url=',urldecode($url));
$o=(object)parse_url($q);
echo $o->host;
A good way to find the domain for a URL is with parse_url
Unfortunately due to the way your data is stored this is not really an option however you may be able to use some sort of regex to find contained web addresses in the query string
<?php
$url = "http://tracking.vcommission.com/aff_c?offer_id=2119&&url=http%3A%2F%2Fwww.netmeds.com%2F%3Fsource_attribution%3DVC-CPS-Emails%26utm_source%3DVC-CPS-Emails%26utm_medium%3DCPS-Emails%26utm_campaign%3DEmails";
$p = parse_url($url);
$pattern = "/www[^%]*/";
preg_match($pattern, $p['query'], $result);
var_dump($result);
You may need to adjust the regex pattern based on how the other data presents itself.

Remove certain part of string in PHP [duplicate]

This question already has answers here:
Get domain name (not subdomain) in php
(18 answers)
Closed 10 years ago.
I've already seen a bunch of questions on this exact subject, but none seem to solve my problem. I want to create a function that will remove everything from a website address, except for the domain name.
For example if the user inputs: http://www.stackoverflow.com/blahblahblah I want to get stackoverflow, and the same way if the user inputs facebook.com/user/bacon I want to get facebook.
Do anyone know of a function or a way where I can remove certain parts of strings? Maybe it'll search for http, and when found it'll remove everything until after the // Then it'll search for www, if found it'll remove everything until the . Then it keeps everything until the next dot, where it removes everything behind it? Looking at it now, this might cause problems with sites as http://www.en.wikipedia.org because I'll be left with only en.
Any ideas (preferably in PHP, but JavaScript is also welcome)?
EDIT 1:
Thanks to great feedback I think I've been able to work out a function that does what I want:
function getdomain($url) {
$parts = parse_url($url);
if($parts['scheme'] != 'http') {
$url = 'http://'.$url;
}
$parts2 = parse_url($url);
$host = $parts2['host'];
$remove = explode('.', $host);
$result = $remove[0];
if($result == 'www') {
$result = $remove[1];
}
return $result;
}
It's not perfect, at least considering subdomains, but I think it's possible to do something about it. Maybe add a second if statement at the end to check the length of the array. If it's bigger than two, then choose item nr1 instead of item nr0. This obviously gives me trouble related to any domain using .co.uk (because that'll be tree items long, but I don't want to return co). I'll try to work around on it a little bit, and see what I come up with. I'd be glad if some of you PHP gurus out there could take a look as well. I'm not as skilled or as experienced as any of you... :P
Use parse_url to split the URL into the different parts. What you need is the hostname. Then you will want to split it by the dot and get the first part:
$url = 'http://facebook.com/blahblah';
$parts = parse_url($url);
$host = $parts['host']; // facebook.com
$foo = explode('.', $host);
$result = $foo[0]; // facebook
You can use the parse_url function from PHP which returns exactly what you want - see
Use the parse_url method in php to get domain.com and then use replace .com with empty string.
I am a little rusty on my regular expressions but this should work.
$url='http://www.en.wikipedia.org';
$domain = parse_url($url, PHP_URL_HOST); //Will return en.wikipedia.org
$domain = preg_replace('\.com|\.org', '', $domain);
http://php.net/manual/en/function.parse-url.php
PHP REGEX: Get domain from URL
http://rubular.com/r/MvyPO9ijnQ //Check regular expressions
You're looking for info on Regular Expression. It's a bit complicated, so be prepared to read up. In your case, you'll best utilize preg_match and preg_replace. It searches for a match based on your pattern and replaces the matches with your replacement.
preg_match
preg_replace
I'd start with a pattern like this: find .com, .net or .org and delete it and everything after it. Then find the last . and delete it and everything in front of it. Finally, if // exists, delete it and everything in front of it.
if (preg_match("/^http:\/\//i",$url))
preg_replace("/^http:\/\//i","",$url);
if (preg_match("/www./i",$url))
preg_replace("/www./i","",$url);
if (preg_match("/.com/i",$url))
preg_replace("/.com/i","",$url);
if (preg_match("/\/*$/",$url))
preg_replace("/\/*$/","",$url);
^ = at the start of the string
i = case insensitive
\ = escape char
$ = the end of the string
This will have to be played around with and tweaked, but it should get your pointed in the right direction.
Javascript:
document.domain.replace(".com","")
PHP:
$url = 'http://google.com/something/something';
$parse = parse_url($url);
echo str_replace(".com","", $parse['host']); //returns google
This is quite a quick method but should do what you want in PHP:
function getDomain( $URL ) {
return explode('.',$URL)[1];
}
I will update it when I get chance but basically it splits the URL into pieces by the full stop and then returns the second item which should be the domain. A bit more logic would be required for longer domains such as www.abc.xyz.com but for normal urls it would suffice.

Categories