So lets say I have a link like this:
http://mywebsite.com/profile/alexkvazos/
I would like to explode the url and get this:
$uri = array('profile','alexkvazos');
What is the easiest approach to this?
try
// if the url is http://www.example.com/foo/bar/wow
function getUriSegments() {
return explode("/", parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
}
print_r(getUriSegments()); //returns array(0=>'foo', 1=>'bar', 2=>'wow')
Source :- http://www.timwickstrom.com/server-side-code/php/php-get-uri-segments/
Use parse_url()
$path_parts = parse_url('http://mywebsite.com/profile/alexkvazos/');
$uri = explode('/',trim($path_parts['path'],'/'));
print_r($uri);
Working Demo
You could use this piece of code:
<?php
$url = 'http://mywebsite.com/profile/alexkvazos/';
$url = rtrim($url,'/'); // lose the trailing slash
$urlArr = explode("/", $url );
$urlArr = array_reverse( $urlArr );
echo $urlArr[0];
?>
I wouldn't use parse_url, I would just use preg_split like this:
$segments = preg_split('#/#', $_SERVER['REQUEST_URI']);
$final = array();
foreach($segments as $key => $value) {
if($value != '') {
$final[] = $value;
}
}
var_dump($final);
Related
Spotify has two ways to use url's/identifiers. I want to get the last part of the strings below (the ID)
example url's:
a. https://play.spotify.com/artist/6mdiAmATAx73kdxrNrnlao
b. spotify:artist:6mdiAmATAx73kdxrNrnlao
Can't get the code below to work, so I can add more options to it later as well. I tried basename first, but obviously that doesn't work with ':'.
$str = "https://play.spotify.com/artist/6mdiAmATAx73kdxrNrnlao";
or:
$str = "spotify:artist:6mdiAmATAx73kdxrNrnlao";
if (
preg_match('artist/([a-zA-Z0-9]{22})/', $str, $re) ||
preg_match('artist:([a-zA-Z0-9]{22})/', $str, $re)
) {
$spotifyId = $re[1];
}
Any help is appreciated!
Try this for urls having slashes. If the Spotify string uses colons(:) simply switch the / to a : in the explode() function:
// your url
$url = "https://play.spotify.com/artist/6mdiAmATAx73kdxrNrnlao/blah/blah/blah";
// get path only
$path = parse_url($url)['path'];
// seperate by forward slash
$parts = explode('/', $path);
// go through them and find string with 22 characters
$id = '';
foreach ($parts as $key => $value) {
if (strlen($value) === 22 ) {
// found it, now store it
$id = $value;
break;
}
}
A rough sample of a helpful function would be as follows:
function getSpotifyId($spotifyUrl) {
// check for valid url
if (!filter_var($spotifyUrl, FILTER_VALIDATE_URL)) {
// split using colon
$parts = explode(':', parse_url($spotifyUrl)['path']);
} elseif (filter_var($spotifyUrl, FILTER_VALIDATE_URL)) {
// split using forward slash
$parts = explode('/', parse_url($spotifyUrl)['path']);
}
// loop through segments to find id of 22 chars
foreach ($parts as $key => $value) {
// assuming id will always be 22 characters
if (strlen($value) === 22 ) {
// found it, now return it
return $value;
}
}
return false;
}
$id1 = getSpotifyId('http://localhost/xampp/web_development/6mdiAmATAx73kdxrNrnlao/stack.php');
$id2 = getSpotifyId('spotify:artist:6mdiAmATAx73kdxrNrnlao');
$id3 = getSpotifyId('My name is tom');
results:
$id1 = '6mdiAmATAx73kdxrNrnlao'
$id2 = '6mdiAmATAx73kdxrNrnlao'
$id3 = false
I need to identify unique urls from an array.
All of the following variants should count as equal:
http://google.com
https://google.com
http://www.google.com
https://www.google.com
www.google.com
google.com
I have the following solution:
public static function array_unique_url(array $array) : array
{
$uniqueArray = [];
foreach($array as $item) {
if(!self::in_array_url($item, $uniqueArray)){
$uniqueArray[] = $item;
}
}
return $uniqueArray;
}
public static function in_array_url(string $needle, array $haystack): bool {
$haystack = array_map([self::class, 'normalizeUrl'], $haystack);
$needle = self::normalizeUrl($needle);
return in_array($needle, $haystack);
}
public static function normalizeUrl(string $url) {
$url = strtolower($url);
return preg_replace('#^(https?://)?(www.)?#', '', $url);
}
However, this is not very efficient O(n^2). Can anybody point me to a better solution?
in_array is expensive. Instead of doing that create a hash and store values as their counts.
Something like:
$myHash = []; //a global array to hold values.
And while checking, Do this:
if(!empty($myHash[$needle] )){
//already exits
}
I haven't test it, but maybe something like this will work:
function getUniqueUrls(array $urls)
{
$unique_urls = [];
foreach ($urls as $url) {
$normalized_url = preg_replace('#^(https?://)?(www.)?#', '', strtolower($url));
$unique_urls[$normalized_url] = true;
}
return array_keys($unique_urls);
}
$arr = [
'http://google.com',
'https://google.com',
'http://www.google.com',
'https://www.google.com',
'www.google.com',
'google.com'
];
$unique_urls = getUniqueUrls($arr);
Here is a simplified version. It does not use preg_replace as it costs a lot. Also it does not make any unnecessary string operation.
$urls = array(
"http://google.com",
"https://google.com",
"http://www.google.com",
"https://www.google.com",
"www.google.com",
"google.com"
);
$uniqueUrls = array();
foreach($urls as $url) {
$subPos = 0;
if(($pos = stripos($url, "://")) !== false) {
$subPos = $pos + 3;
}
if(($pos = stripos($url, "www.", $subPos)) !== false) {
$subPos = $pos + 4;
}
$subStr = strtolower(substr($url, $subPos));
if(!in_array($subStr, $uniqueUrls)) {
$uniqueUrls[] = $subStr;
}
}
var_dump($uniqueUrls);
Another performance optimization could be implementing binary search on the unique urls because 'in_array' search the whole array as it is not sorted.
<?php
$urls = [
'http://google.com',
'https://google.com',
'http://www.google.com',
'https://www.google.com',
'www.google.com',
'google.com',
'testing.com:9200'
];
$uniqueUrls = [];
foreach ($urls as $url) {
$urlData = parse_url($url);
$urlHostName = array_key_exists('host',$urlData) ? $urlData['host'] : $urlData['path'];
$host = str_replace('www.', '', $urlHostName);
if(!in_array($host, $uniqueUrls) && $host != ''){
array_push($uniqueUrls, $host);
}
}
print_r($uniqueUrls);
?>
why you normlize your result array everytime?
here is a better solution with your code:
public static function array_unique_url(array $array): array
{
$uniqueArray = [];
foreach ($array as $item) {
if (!isset($uniqueArray[$item])) {
$uniqueArray[$item] = self::normalizeUrl($item);
}
}
return $uniqueArray;
}
public static function normalizeUrl(string $url)
{
return preg_replace('#^(https?://)?(www.)?#', '', strtolower($url));
}
When you want your original items you can use array_keys(array_unique_url($array))
for your normalized urls you don't need array_keys
Try this simplest solution. Here we are using two functions preg_replace and parse_url for achieving desired output
Try this code snippet here
<?php
$urls = array(
"http://google.com",
"https://google.com",
"http://www.google.com",
"https://www.google.com",
"www.google.com",
"google.com"
);
$uniqueUrls=array();
foreach($urls as $url)
{
$changedUrl= preg_replace("/^(https?:\/\/)?/", "http://", $url);//adding http to urls which does not contains.
$domain= preg_replace("/^(www\.)?/","",parse_url($changedUrl,PHP_URL_HOST));//getting the desired host and then removing its www.
preg_match("/^[a-zA-Z0-9]+/", $domain,$matches);//filtering on the basis of domains
$uniqueUrls[$matches[0]]=$domain;
}
print_r(array_values($uniqueUrls));
I have a path that is separated by forward slash.
$uri = getenv('REQUEST_URI');
$uri = explode('/', $uri);
$uri = array_filter($uri);
$uri = array_merge($uri, array());
The path would end up something like:
/user/john/account
This will grab the last word in the path, 'account'.
$uri = end($uri);
How can I get the first word found after 'user' into a variable?
In this case it would be 'john', but the name can change on every new URI.
'user' always stays the same word.
$uri = "/user/john/account";
$uri_array = explode("/", $uri);
$key = array_search("user", $uri_array);
$desired_value = array_key_exists($key+1, $uri_array) ? $uri_array[$key+1] : "error";
echo $desired_value;
Here is what you need : Note : "user" is a fixed term in array_search .. you can change it
Before $uri = end($uri) add this:
$uriArray = explode('/',$uri); //$uriArray[0] = 'user' //$uriArray[1] = 'john'
$name = $uriArray[1];
With this you could also get the last element after a slash
EDIT:
You could also use preg_split('pattern',$string) like this:
$name = preg_split('user/',$uri);
$name would be "john/account". Then use explode again, to save it into an array, element 0 is the name
Using preg_match might be more efficient in this case:
Psy Shell v0.8.1 (PHP 7.1.1-1+deb.sury.org~xenial+1 — cli) by Justin Hileman
>>> preg_match('~/user/([^/]+)/?~', '/test/user/username/tuedelue', $matches);
=> 1
>>> $matches;
=> [
"/user/username/",
"username",
]
>>> $matches[1];
=> "username"
>>> |
So these lines
$user = 'unknown';
if (preg_match('~/user/([^/]+)/?~', getenv('REQUEST_URI'), $matches)) {
$user = $matches[1];
}
would solve your problem.
You can use this
$uri='/user/john/account';
$from1 ='/user/';
$to1 ='/';
//$uri = explode('/', $uri);
echo get_string_between($uri,$from1,$to1);
function get_string_between ($str,$from,$to) {
$string = substr($str, strpos($str, $from) + strlen($from));
if (strstr ($string,$to,TRUE) != FALSE) {
$string = strstr ($string,$to,TRUE);
}
return $string;
}
Edit: Use M A SIDDIQUIs answer. It is the better way to solve this problem
You can write a function for this that finds out whitch position of the uri-Array contains the word user and then returns the next position that should contain the name.
function getName($uri)
{
$uri = explode('/', $uri);
for($i = 0; $i < sizeof($uri); $i++){
if($uri[$i] == "user"){
return $uri[$i+1];
}
}
}
Then you just have to print it out with:
echo getName("exmaple/user/username/etc");
Suppose I have the URL look like: http://www.example.com/category/product/htc/desire, I used $_SERVER['REQUEST_URI'] to get /category/product/htc/desire, how can I convert this "/category/product/htc/desire" to array like:
array
(
[0] => category
[1] => product
....
)
Thanks
$array = explode('/', trim($_SERVER['REQUEST_URI'], '/'));
<?php
$url = "/category/product/htc/desire";
$pieces = explode("/", substr($url,1));
print_r($pieces);
?>
obviously $url would be the $_SERVER['REQUEST_URI']
output, see here: http://codepad.org/lIRZNTBI
use explode function
$list = explode('/', trim($_SERVER['REQUEST_URI'], '/'));
Have a look at PHP strtok function
You can do something like that :
$string = "/category/product/htc/desire";
$arr = aray();
$tok = strtok($string, "/");
while ($tok !== false) {
arr[]= $tok:
$tok = strtok(" \n\t");
}
I have a few strings to combine to build a full path. e.g.
$base = "http://foo.com";
$subfolder = "product/data";
$filename = "foo.xml";
// How to do this?
$url = append_url_parts($base, $subfolder, $filename); ???
String concatenation won't do, that would omit the necessary forward slashes.
In Win32 I'd use PathCombine() or PathAppend(), which would handle adding any necessary slashes between strings, without doubling them up. In PHP, what should I use?
Try this:
$base = "http://foo.com";
$subfolder = "product/data";
$filename = "foo.xml";
function stripTrailingSlash(&$component) {
$component = rtrim($component, '/');
}
$array = array($base, $subfolder, $filename);
array_walk_recursive($array, 'stripTrailingSlash');
$url = implode('/', $array);
when it comes down to something like this I like to use a special function with unlimited parameters.
define('BASE_URL','http://mysite.com'); //Without last slash
function build_url()
{
return BASE_URL . '/' . implode(func_get_args(),'/');
}
OR
function build_url()
{
$Path = BASE_URL;
foreach(func_get_args() as $path_part)
{
$Path .= '/' . $path_part;
}
return $Path;
}
So that when I use the function I can do
echo build_url('home'); //http://mysite.com/home
echo build_url('public','css','style.css'); //http://mysite.com/public/css/style.css
echo build_url('index.php'); //http://mysite.com/index.php
hope this helps you, works really well for me especially within an Framework Environment.
to use with params you can append the url like so for simplicity.
echo build_url('home') . '?' . http_build_query(array('hello' => 'world'));
Would produce: http://mysite.com/home?hello=world
not sure why you say string concat won't do, because something like this is basically similar to a string concat. (untested semi-pseudo)
function append_url_parts($base, $subf, $file) {
$url = sprintf("%s%s%s", $base, (($subf)? "/$subf": ""), (($file)? "/$file": ""));
return $url;
}
with string concat, we'd have to write a slightly longer block like so:
function append_url_parts($base, $subf, $file) {
$subf = ($subf)? "/$subf": "";
$file = ($file)? "/$file": "";
$url = "$base$subf$file";
return $url;
}
I usually go simple:
<?
$url = implode('/', array($base, $subfolder, $filename));
Either that or use a framework, and then use whatever route system it has.
There are a few considerations first.
Are you interested in getting the current path of the script or some other path?
How flexible do you need this to be? Is it something that is going to change all the time? Is it something an admin will set once and forget?
You want to be careful not to include the slash bug where your document has a slash added at the end because you were too lazy to figure out how to separate directory vars from the file var. There will only be one file and one base per URL and unknown number of directories in each path, right? :)
If you want to make sure there are no duplicate slashes within the resultant path, I like this little function...simply pass it an array of path part you want combined and it will return a formatted path - no need to worry whether any of the parts contain a slash alerady or not:
function build_url($arr)
{
foreach ( $arr as $path ) $url[] = rtrim ( $path, '/' );
return implode( $url, '/' );
}
This should work on all versions of PHP too.
Not my code, but a handy function which takes an absolute URL and a relative URL and combines the two to make a new absolute path.
The function has been modified to ignore an absolute URL passed as relative ( basically anything that includes a schema ).
$url = "http://www.goat.com/money/dave.html";
$rel = "../images/cheese.jpg";
$com = InternetCombineURL($url,$rel);
public function InternetCombineUrl($absolute, $relative) {
$p = parse_url($relative);
if(isset($p["scheme"]))return $relative;
extract(parse_url($absolute));
$path = dirname($path);
if($relative{0} == '/') {
$cparts = array_filter(explode("/", $relative));
}
else {
$aparts = array_filter(explode("/", $path));
$rparts = array_filter(explode("/", $relative));
$cparts = array_merge($aparts, $rparts);
foreach($cparts as $i => $part) {
if($part == '.') {
$cparts[$i] = null;
}
if($part == '..') {
$cparts[$i - 1] = null;
$cparts[$i] = null;
}
}
$cparts = array_filter($cparts);
}
$path = implode("/", $cparts);
$url = "";
if($scheme) {
$url = "$scheme://";
}
if(isset($user)) {
$url .= "$user";
if($pass) {
$url .= ":$pass";
}
$url .= "#";
}
if($host) {
$url .= "$host/";
}
$url .= $path;
return $url;
}
I wrote this function for all cases to combine url parts with no duplicate slashes.
It accepts many arguments or an array of parts.
Some parts may be empty strings, that does not produce double slashes.
It keeps starting and ending slashes if they are present.
function implodePath($parts)
{
if (!is_array($parts)) {
$parts = func_get_args();
if (count($parts) < 2) {
throw new \RuntimeException('implodePath() should take array as a single argument or more than one argument');
}
} elseif (count($parts) == 0) {
return '';
} elseif (count($parts) == 1) {
return $parts[0];
}
$resParts = [];
$first = array_shift($parts);
if ($first === '/') {
$resParts[] = ''; // It will keep one starting slash
} else {
// It may be empty or have some letters
$first = rtrim($first, '/');
if ($first !== '') {
$resParts[] = $first;
}
}
$last = array_pop($parts);
foreach ($parts as $part) {
$part = trim($part, '/');
if ($part !== '') {
$resParts[] = $part;
}
}
if ($last === '/') {
$resParts[] = ''; // To keep trailing slash
} else {
$last = ltrim($last, '/');
if ($last !== '') {
$resParts[] = $last; // Adding last part if not empty
}
}
return implode('/', $resParts);
}
Here is a check list from unit test. Left array is input and right part is result string.
[['/www/', '/eee/'], '/www/eee/'],
[['/www', 'eee/'], '/www/eee/'],
[['www', 'eee'], 'www/eee'],
[['www', ''], 'www'],
[['www', '/'], 'www/'],
[['/www/', '/aaa/', '/eee/'], '/www/aaa/eee/'],
[['/www', 'aaa/', '/eee/'], '/www/aaa/eee/'],
[['/www/', '/aaa/', 'eee/'], '/www/aaa/eee/'],
[['/www', 'aaa', 'eee/'], '/www/aaa/eee/'],
[['/www/', '/aaa/'], '/www/aaa/'],
[['/www', 'aaa/'], '/www/aaa/'],
[['/www/', 'aaa/'], '/www/aaa/'],
[['/www', '/aaa/'], '/www/aaa/'],
[['/www', '', 'eee/'], '/www/eee/'],
[['www/', '/aaa/', '/eee'], 'www/aaa/eee'],
[['/www/', '/aaa', ''], '/www/aaa'],
[['', 'aaa/', '/eee/'], 'aaa/eee/'],
[['', '', ''], ''],
[['aaa', '', '/'], 'aaa/'],
[['aaa', '/', '/'], 'aaa/'],
[['/', 'www', '/'], '/www/'],
It can be used as implodePath('aaa', 'bbb') or implodePath(['aaa', 'bbb'])