I am parsing domains and running into a problem handling subdomains. If the domain is http://www.google.co.uk, I want to obtain the length of google which is 6.
I am using parse_url() to return the host in this case www.google.co.uk like so.
$url = 'http://www.google.co.uk';
$info = parse_url($url);
// remove www. and return google.co.uk
$new = str_replace('www.','',$info['host']);
$pieces = explode(".", $new);
$len = strlen($pieces[0]); // returns character length of google = 6
echo $len;
My code doesn't work if the domain contains a subdomain like http://test.google.co.uk: it returns a length of 4; I expect it to return a length of 6.
Any ideas?
Output is correct. when input is http://test.google.co.uk value of parse_url('http://test.google.co.uk')['host'] is http://test.google.co.uk. When you will exploce this string on dot first element of array will be test and its length is 4.
To get google instead of test you need to replace subdomain with nothing as you did in your first example or take the second element in exploded string. E.g:
$url = 'http://test.google.co.uk';
$info = parse_url($url);
$pieces = explode(".", $info['host']);
$len = strlen($pieces[1]); // returns character length of google = 6
echo $len;
There is not other way than collect and hardcode all known public 2-nd level zones (like co.uk, com.ua, co.tw and so on) and filter them in your code. Be aware to detect test.example.ua as test becouse both example.com.ua and example.ua are valid domains (which is not a case with uk zone).
Your code may look like this:
function mainDomainLength($fullDomain) {
//$fullDomain = 'DOMAIN.co.uk';
$zones = array('uk' => array('co'), 'ua' => array('com', 'org'), ...);
$domainArray = explode('.', $fullDomain);
if (count($domain) > 2 && isset($zones[$domain[count($domain)-1]])) {
if (isset($zones[$domain[count($domain)-1]][$domain[count($domain)-2]])) {
return strlen($domain[count($domain)-3]);
}
} else if (count($domain) > 1) {
return strlen($domain[1]);
} else {
return strlen($domain[0]);
}
}
EDIT: By the way! Look at Get the second level domain of an URL (java). As I can understand there is the answer you need (and url to special domains collection collected be Mozilla).
Related
Hi guys i m using this code to get the id on my url
$string = $url;
$matches = array();
preg_match_all('/.*?\/(\d+)\/?/s', $string, $matches);
$id = $matches[1][0];
this code works for urls like
http://mysite.com/page/1
http://mysite.com/page/somepage/2
http://mysite.com/page/3/?pag=1
i will have id = 1 / id = 2 / id = 3
but for a url like this
http://mysite.com/page/122-page-name/1
this returns id = 122
THe id i m try to get always will be the last part of the url or will have /?p= after
so the urls type i can have
http://mysite.com/page/1
http://mysite.com/page/some-page/2
http://mysite.com/page/12-some-name/3
http://mysite.com/page/some-page/4/?p=1
http://mysite.com/page/13-some-page/5/?p=2
id = 1 / id = 2 / id = 3 / id = 4 / id = 5
If your id will always be located at the end of your url, you could explode the contents of your url and take the last element of the resulting array. If it may include variables (like ?pag=1) you can add a validation after the explode to check for the variable.
$urlArray = explode('/', $url);
$page = end($urlArray);
if(strpos($page, 'pag')!==false){
//get the contents of the variable from the $page variable
//exploding the variable through the ? variable and getting
//the numeric characters at the end
}
I would favor URL parsing over trying to use a regex, especially if you have a wide variety of (valid) URLs to deal with.
end(array_filter(explode('/', parse_url($url, PHP_URL_PATH))));
The array_filter deals with the trailng slash.
Since it's always at the end or has ?p=x after it you can do the following:
$params = explode('/', $_SERVER['REQUEST_URI']);
$c = count($params);
if (is_int($params[$c - 1])
$id = $params[$c - 1];
else
$id = $params[$c - 2];
Not a direct answer, more of a "how to work this out for yourself" answer :]
Place this code at the top of your page, before anything else (but after <?php)
foreach($_SERVER as $k => $v) {
echo $k.' = '.$v.'<br />';
}
exit;
Now load up each of the different URIs in a different tab and look at the results. You should be able to work out what you need to do.
I have a string which can be written in a number of different ways, it will always follow the same pattern but the length of it can differ.
this/is/the/path/to/my/fileA.php
this/could/also/be/the/path/to/my/fileB.php
another/example/of/a/long/address/which/is/a/path/to/my/fileC.php
What I am trying to do is cut the string so that I am left with
path/to/my/file.php
I have some code which I got from this page and modified it to the following
$max = strlen($full_path);
$n = 0;
for($j=0;$j<$max;$j++){
if($full_path[$j]=='/'){
$n++;
if($n>=3){
break 1;
}
}
}
$path = substr($full_path,$j+1,$max);
Which basically cuts it at the 3rd instance of the '/' character, and gives me what is left. This was fine when I was working in one environment, but when I migrated it to a different server, the path would be longer, and so the cut would give me too long an address. I thought that rather than changing the hard coded integer value for each instance, it would work better if I had it cut the string at the 4th from last instance, as I always want to keep the last 4 'slashes' of information
Many thanks
EDIT - final code solution
$exploded_name = explode('/', $full_path);
$exploded_trimmed = array_slice($exploded_name, -4);
$imploded_name = implode('/', $exploded_trimmed);
just use explode with your string and if pattern is always the same then get last element of the array and your work is done
$pizza = "piece1/piece2/piece3/piece4/piece5/piece6";
$pieces = explode("/", $pizza);
echo $pieces[0]; // piece1
echo $pieces[1]; // piece2
Then reverse your array get first four elements of array and combine them using "implode"
to get desired string
This function below can work like a substr start from nth occurrence
function substr_after_nth($str, $needle, $key)
{
$array = explode($needle, $str);
$temp = array();
for ($i = $key; $i < count($array); $i++) {
$temp[] = $array[$i];
}
return implode($needle, $temp);
}
Example
$str = "hello-world-how-are-you-doing";
substr after 4th occurrence of "-" to get "you-doing"
call the function above as
echo substr_after_nth($str, "-", 4);
it will result as
you-doing
I have a large text file with names, location and date of birth of lots of people. I need to find names based on character size. How can I do this with PHP?
In the text file, data is organised like this:
Name-Location ID DOB
Bob-LA 110 12/01/1987
Lia-CA 111 11/09/1984
Neil-LA 112 17/10/1982
Emon-CA 113 07/12/1991
Elita-CA 113 13/06/1983
Ron-CA 114 16/02/1979
and so on
Now I wish to search for people with certain character name and with same location (say I wish to find all the people whose name has 4 letter and are from CA [Emon-CA]). How can I do that?
I can normally search through a file using PHP, where I know the string I am looking for. But here I actually don't know how to set the condition to show up my desired results. Can someone please help me?
Thanks in advance.
You can try
$filename = "log.txt";
foreach ( new TextFileFilterIterator($filename) as $line ) {
list($name, $location, $id, $dob) = $line;
if (strlen($name) == 4 && $location == "CA") {
echo implode(",", $line), PHP_EOL;
}
}
Output
Emon,CA,113,07/12/1991
Class Used
class TextFileFilterIterator extends ArrayIterator {
private $filter;
function __construct($filename) {
parent::__construct(array_filter(array_map("trim", file($filename))));
}
public function current() {
$c = array_filter(explode(" ", parent::current()));
list($n, $l) = explode("-", array_shift($c));
array_unshift($c, $n, $l);
return array_map("trim", $c);
}
}
I'd suggest using regular expressions, something like this:
// assume $text contains the contents of your text file
$namelength = 4; // change this as needed
$location = 'CA'; // again, change as needed
If you just want to count the results
$count = preg_match_all('|^\s*([\w]{'.$namelength.'})-'.$location.'\s*(\d+)\s*(\d{2}/\d{2}/\d{4})$|',$text,$matches);
Otherwise, If you want to do something with each match:
if(preg_match_all('|^\s*([\w]{'.$namelength.'})-'.$location.'\s*(\d+)\s*(\d{2}/\d{2}/\d{4})$|',$text,$matches)){
foreach($matches as $match){
$name = $match[1];
$id = $match[3];
$dob = $match[4];
// Do something with each name.
}
}
Is there a way in php to do a preg_match on a url like below
dynamic/dynamic/dev/new_mobile/lib
and it would only pull out dev/new_mobile, and the link also has the ability to be like this too
dynamic/dynamic/dynamic/tst/new_mobile/lib
In the above example it would only pull out tst/new_mobile. The key is it would grab the last two directories before lib. Any idea how this could be done?
Here's a regex that will get the part you want:
$url = 'dynamic/tst/new_mobile/lib/foo/bar';
if (preg_match('#^(?:.*?/)?([^/]+/[^/]+)/lib(?:/.+)?$#', $url, $matches)) {
$part = $matches[1];
var_dump($part); // "tst/new_mobile"
}
This will get the 2 directories before the lib directory allowing for any directories before and after. It will also match a couple of edge cases that you don't mention whether you need:
tst/new_mobile/lib/foo/bar
/tst/new_mobile/lib/foo/bar
just explode then reverse array, simple and easy to use.
$array_url = explode('/',$url);
$tmp_array_url = array_reverse($array_url);
then you can rebuild as you will, no need to wonder with how many dynamic parts come before.
echo $tmp_array_url[0]; // "lib";
echo $tmp_array_url[1]; // "new_mobile";
echo $tmp_array_url[2]; // "dev";
EDIT: since you got lib constant, just do something like this :
$the_two_before = "";
for($i = 0; $i < count($tmp_array_url); $i++){
if($tmp_array_url[$i] == "lib"){
$the_two_before = $tmp_array_url[$i+2]."/".$tmp_array_url[$i+1];
}
}
The main string contains parts which are separated by #
I need to check if the incoming string contains any of the banned keys.
In real example the keys are made by md5($var), each key 32 character length. Number of keys are variable in both $banned_keys and $incoming_keys1
$banned_keys = 'abc1#abc2#abc3#abc4';
$incoming_keys1='asd1#asd2#asd3#asd4'; //should pass no banned key found
$incoming_keys2='asd1#asd2#asd3#abc3'; //Should fail, contains banned key 'abc3'
$banned_array = explode('#', $banned_keys);
$incoming_array = explode('#', $incoming_keys);
// compute intersection of two sets
if( array_intersect($banned_array, $incoming_array) )
...
Try converting the strings to arrays using explode('#',$string) for both the incoming and the banned keys, then use in_array() to check.
For example
$banned = explode('#','abc1#abc2#abc3#abc4');
$incoming = explode('#','asd1#asd2#asd3#asd4');
if(in_array($banned,$incoming)){
//fail
}
There may be a better way, but this should work :)
You could 'explode' the strings to transform them into arrays and then match the array entries (if the intersection contains any entries, at least one banned key is provided):
$banned_keys_ary = explode('#', $banned_keys);
$incoming_keys_ary = explode('#', $incoming_keys);
if (count(array_intersect($incoming_keys_ary, $banned_keys_ary)) > 0)
{
// fail, at least one banned key found
}
else
{
// pass, no banned keys found
}
Try following:
$banned_keys_array = explode("#", $banned_keys);
$incoming_keys_arr = explode("$", $incoming_keys);
$is_valid_key = true;
foreach($incoming_keys_arr as $key) {
if (in_array($key, $banned_keys_array) {
// Invalid key found;
$is_valid_key = false;
break;
}
}
// check $is_valid_key here
Try looking here:
http://www.webcheatsheet.com/php/regular_expressions.php#match
and for the Regular Expression..
http://www.w3schools.com/jsref/jsref_obj_regexp.asp
I'm still new at using Regular Expression..
I guess for your problem, the pattern would be...
/abc1|abc2|abc3|abc4/g
then the could should be..
<?php
$subject = "asd1#asd2#asd3#asd4";
$pattern = '/abc1|abc2|abc3|abc4/g';
if (preg_match($pattern, $subject, $matches)) {
echo "Match was found <br />";
echo $matches[0];
}
?>
The preg_match() function returns 1 if a match is found and 0 otherwise.