I want to make sure the link is from the chosen social type.
help!!
$socialType = 'youtube';
$link = 'https://www.youtube.co.uk/watch?v=DBK-Cy9ge4M';
if (!preg_match("/^(http|https):\\/\\/[a-z0-9_]+$socialType*\\.[_a-z]{2,5}"."((:[0-9]{1,5})?\\/.*)?$/i",$link))
{
return Response::json('inValid');
}
{
return Response::json('Valid');
}
There will be two options as-
1. with preg_match -
$subject = "https://www.youtube.co.uk/watch?v=DBK-Cy9ge4M";
$pattern = '/^youtube/';
preg_match($pattern, substr($subject,7), $matches);
print_r($matches);
2. with strops as (Ruslan Osmanov)-
$socialType = 'youtube';
$link = 'https://www.youtube.co.uk/watch?v=DBK-Cy9ge4M';
if (strpos($link, $socialType) !== false) {
return Response::json('Valid');
}
You can simply check, if the link contains your substring using strpos:
$link = 'https://www.youtube.co.uk/watch?v=DBK-Cy9ge4M';
$type = 'youtube';
if (strpos($link, $type) !== false) {
// passed
}
Or use a simple regular expression, if you want stricter check:
$reg_type = preg_quote($type, '/');
if (preg_match("/^https?:\/\/(www\.)?$reg_type/", $link)) {
// passed
}
Note, you should escape values passed into the regular expression using preg_quote.
The pattern should be just enough. Don't overcomplicate. It's generally impossible to write a perfect regular expression. For example, it is very unlikely to find HTTP(S) protocol prefix + optional "www." + "youtube." in an URL not belonging to Youtube.
Also, I wouldn't expect to get the answer with a universal regular expression for all kinds of social networks. Each has its own pattern.
Related
Good evening.
I'm making an IRC bot that responds when you mention him. What I want to know is how to make him reply when someone actually says his name. This is what I have so far ($match[3] is the message that someone said on a channel and yes, stripos is because I want it case-insensitive ):
if (stripos($match[3], "ircBot") !== false) {
$isMentioned = true;
}else { $isMentioned = false; }
while this does in fact detect if someone said his name, it only works if he's mentioned at the very beginning of the message so for example:
"ircBot is at the beginning of this sentance" would make $isMentioned true
"There's ircBot in between this sentance" would make $isMentioned false
"At the end of this sentance is ircBot" would make $isMentioned false
I want it to return true if "ircBot" is anywhere inside $match[3] and not just the beginning
You have to look for word boundaries to avoid someone called MircBot
// using in_array
$isMentioned = in_array('ircbot', preg_split('/\s+/', mb_strtolower($match[3])));
// using regex word boundaries
$isMentioned = preg_match('/\b(ircBot)\b/i', $match[3]);
http://3v4l.org/lh3JT
Use stristr instead
if (stristr($match[3], "ircBot") !== false) {
$isMentioned = true;
}else { $isMentioned = false; }
I think your error is somewhere else, e.g. the construction of $match[3]. This works fine:
$isMentioned = stripos('This is in the middle of ircBot the string','ircbot') !== false;
echo( $isMentioned ? 'Is Mentioned' : 'Sad ignored bot');
I want to echo/print only a certain piece of input. For example i have this youtube url http://www.youtube.com/watch?v=p963CeTtJVM how would i be able to only echo the last piece of :"p963CeTtJVM" from the input. As far as i know their always 11 symbols.
Code:
if (empty($_POST["website"]))
{$website = "";}
else
{
$website = test_input($_POST["website"]);
// check if URL address syntax is valid (this regular expression also allows dashes in the URL)
if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&##\/%?=~_|!:,.;]*[-a-z0-9+&##\/%=~_|]/i",$website))
{
$websiteErr = "Invalid URL";
}
}
list ($void, $query_string) = split('?', $url); // or list(,$qs)
parse_str($query_string, $data);
var_dump($data);
For this specific string substr($str, -11) will take the last 11 chars, but that doesn't include other tags. Check out parse_str, it will probably save you a headache in the long run.
I hope it can help you.
<?php
$url = 'http://www.youtube.com/watch?v=p963CeTtJVM';
$urlParts = explode('v=', $url);
if (count($urlParts) == 2 && isset($urlParts[1])) {
echo "youtube code : {$urlParts[1]}";
} else {
echo "Invalid Youtube url.";
}
You can use substr method to return part of a string.
You can use the explode function to seperate the video ID and the rest of the link like this:
$array = explode("=", $website);
echo $array[1];
This parses the URL into its component parts, then parses the query string into an associative array.
$url = parse_url($url);
parse_str($url['query'], $params);
$v = $params['v'];
I need to detect if a provided URL matches the one currently navigated to. Mind you the following are all valid, yet semantically equivalent URLs:
https://www.example.com/path/to/page/index.php?parameter=value
https://www.example.com/path/to/page/index.php
https://www.example.com/path/to/page/
https://www.example.com/path/to/page
http://www.example.com/path/to/page
//www.example.com/path/to/page
//www/path/to/page
../../../path/to/page
../../to/page
../page
./
The final function must return true if the given URL points back to the current page, or false if it does not. I do not have a list of expected URLs; this will be used for a client who just wants links to be disabled when they link to the current page. Note that I wish to ignore parameters, as these do not indicate the current page on this site. I got as far as using the following regex:
/^((https?:)?\/\/www(\.example\.com)\/path\/to\/page\/?(index.php)?(\?.+=.*(\&.+=.*)*)?)|(\.\/)$/i
where https?, www, \.example\.com, \/path\/to\/page, and index.php are dynamically detected with $_SERVER["PHP_SELF"] and made into regex form, but that doesn't match the relative URLs like ../../to/page.
EDIT: I got a bit farther with the regex: refiddle.com/gv8
now I'd just need PHP to dynamically create the regex for any given page.
First off, there is no way to predict the total list of valid URLs that will result in display of the current page, since you can't predict (or control) external links that might link back to the page. What if someone uses TinyURL or bit.ly? A regex will not cut the mustard.
If what you need is to insure that a link does not result in the same page, then you need to TEST it. Here's a basic concept:
Every page has a unique ID. Call it a serial number. It should be persistent. The serial number should be embedded somewhere predictable (though perhaps invisibly) within the page.
As the page is created, your PHP will need to walk through all the links for each page, visit each one, and determine whether the link resolves to a page with a serial number that matches the calling page's serial number.
If the serial number does not match, display the link as a link. Otherwise, display something else.
Obviously, this will be an arduous, resource-intensive process for page production. You really don't want to solve your problem this way.
With your "ultimate goal" comment in mind, I suspect your best approach is to be approximate. Here are some strategies...
First option is also the simplest. If you're building a content management system that USUALLY creates links in one format, just support that format. Wikipedia's approach works because a [[link]] is something THEY generate, so THEY know how it's formatted.
Second is more the direction you've gone with your question. The elements of a URL are "protocol", "host", "path" and "query string". You can break them out into a regex, and possibly get it right. You've already stated that you intend to ignore the query string. So ... start with '((https?:)?//(www\.)?example\.com)?' . $_SERVER['SCRIPT_NAME'] and add endings to suit. Other answers are already helping you with this.
Third option is quite a bit more complex, but gives you more fine-grained control over your test. As with the last option, you have the various URL elements. You can test for the validity of each without using a regex. For example:
$a = array(); // init array for valid URLs
// Step through each variation of our path...
foreach([$_SERVER['SCRIPT_NAME'], $_SERVER['REQUEST_URI']] as $path) {
// Step through each variation of our host...
foreach ([$_SERVER['HTTP_HOST'], explode(".", $_SERVER['HTTP_HOST'])[0]] as $server) {
// Step through each variation of our protocol...
foreach (['https://','http://','//'] as $protocol) {
// Set the URL as a key.
$a[ $protocol . $server . $path ] = 1;
}
}
// Also for each path, step through directories and parents...
$apath=explode('/', $path); // turn the path into an array
unset($apath[0]); // strip the leading slash
for( $i = 1; $i <= count($apath); $i++ ) {
if (strlen($apath[$i])) {
$a[ str_repeat("../", 1+count($apath)-$i) . implode("/", $apath) ] = 1;
// add relative paths
}
unset($apath[$i]);
}
$a[ "./" . implode("/", $apath) ] = 1; // add current directory
}
Then simply test whether the link (minus its query string) is an index within the array. Or adjust to suit; I'm sure you get the idea.
I like this third solution the best.
A regex isn't actually necessary to strip off all the query parameters. You could use strok():
$url = strtok($url, '?');
And, to check the output for your URL array:
$url_list = <<<URL
https://www.example.com/path/to/page/index.php?parameter=value
https://www.example.com/path/to/page/index.php
...
./?parameter=value
./
URL;
$urls = explode("\n", $url_list);
foreach ($urls as $url) {
$url = strtok($url, '?'); // remove everything after ?
echo $url."\n";
}
As a function (could be improved):
function checkURLMatch($url, $url_array) {
$url = strtok($url, '?'); // remove everything after ?
if( in_array($url, $url_array)) {
// url exists array
return True;
} else {
// url not in array
return False;
}
}
See it live!
You can use this approach:
function checkURL($me, $s) {
$dir = dirname($me) . '/';
// you may need to refine this
$s = preg_filter(array('~^//~', '~/$~', '~\?.*$~', '~\.\./~'),
array('', '', '', $dir), $s);
// parse resulting URL
$url = parse_url($s);
var_dump($url);
// match parsed URL's path with self
return ($url['path'] === $me);
}
// your page's URL with stripped out .php
$me = str_replace('.php', '', $_SERVER['PHP_SELF']);
// assume this is the URL you are matching against
$s = '../page/';
// compare $me with $s
$ret = checkURL($me, $s);
var_dump($ret);
Live Demo: http://ideone.com/OZZM53
As I have been paid to work on this for the last couple days, I wasn't just sitting around waiting for an answer. I've come up with one that works in my test platform; what does everyone else think? It feels a little bloated, but also feels bulletproof.
Debug echoes left in in case you wanna echo out some stuffs.
global $debug;$debug = false; // toggle debug echoes and var_dumps
/**
* Returns a boolean indicating whether the given URL is the current one.
*
* #param $otherURL the other URL, as a string. Can be any URL, relative or canonical. Invalid URLs will not match.
*
* #return true iff the given URL points to the same place as the current one
*/
function isCurrentURL($otherURL)
{global $debug;
if($debug)echo"<!--\r\nisCurrentURL($otherURL)\r\n{\r\n";
if ($thisURL == $otherURL) // unlikely, but possible. Might as well check.
return true;
// BEGIN Parse other URL
$otherProtocol = parse_url($otherURL);
$otherHost = $otherProtocol["host"] or null; // if $otherProtocol["host"] is set and is not null, use it. Else, use null.
$otherDomain = explode(".", $otherHost) or $otherDomain;
$otherSubdomain = array_shift($otherDomain); // subdom only
$otherDomain = implode(".", $otherDomain); // domain only
$otherFilepath = $otherProtocol["path"] or null;
$otherProtocol = $otherProtocol["scheme"] or null;
// END Parse other URL
// BEGIN Get current URL
#if($debug){echo '$_SERVER == '; var_dump($_SERVER);}
$thisProtocol = $_SERVER["HTTP_X_FORWARDED_PROTO"]; // http or https
$thisHost = $_SERVER["HTTP_HOST"]; // subdom or subdom.domain.tld
$thisDomain = explode(".", $thisHost);
$thisSubdomain = array_shift($thisDomain); // subdom only
$thisDomain = implode(".", $thisDomain); // domain only
if ($thisDomain == "")
$thisDomain = $otherDomain;
$thisFilepath = $_SERVER["PHP_SELF"]; // /path/to/file.php
$thisURL = "$thisProtocol://$thisHost$thisFilepath";
// END Get current URL
if($debug)echo"Current URL is $thisURL ($thisProtocol, $thisSubdomain, $thisDomain, $thisFilepath).\r\n";
if($debug)echo"Other URL is $otherURL ($otherProtocol, $otherHost, $otherFilepath).\r\n";
$thisDomainRegexed = isset($thisDomain) && $thisDomain != null && $thisDomain != "" ? "(\." . str_replace(".","\.",$thisDomain) . ")?" : ""; // prepare domain for insertion into regex
// v this makes the last slash before index.php optional
$regex = "/^(($thisProtocol:)?\/\/$thisSubdomain$thisDomainRegexed)?" . preg_replace('/index\\\..+$/i','?(index\..+)?', str_replace(array(".", "/"), array("\.", "\/"), $thisFilepath)) . '$/i';
if($debug)echo "\r\nregex is $regex\r\nComparing regex against $otherURL";
if (preg_match($regex, $otherURL))
{
if($debug)echo"\r\n\tIt's a match! Returning true...\r\n}\r\n-->";
return true;
}
else
{
if($debug)echo"\r\n\tOther URL is NOT a fully-qualified URL in this subdomain. Checking if it is relative...";
if($otherURL == $thisFilepath) // somewhat likely
{
if($debug)echo"\r\n\t\tOhter URL and this filepath are an exact match! Returning true...\r\n}\r\n-->";
return true;
}
else
{
if($debug)echo"\r\n\t\tFilepath is not an exact match. Testing against regex...";
$regex = regexFilepath($thisFilepath);
if($debug)echo"\r\n\t\tNew Regex is $regex";
if($debug)echo"\r\n\t\tComparing regex against $otherFilepath...";
if (preg_match($regex, $otherFilepath))
{
if($debug)echo"\r\n\t\t\tIt's a match! Returning true...\r\n}\r\n-->";
return true;
}
}
}
if($debug)echo"\r\nI tried my hardest, but couldn't match $otherURL to $thisURL. Returning false...\r\n}\r\n-->";
return false;
}
/**
* Uses the given filepath to create a regex that will match it in any of its relative representations.
*
* #param $path the filepath to be converted
*
* #return a regex that matches a all relative forms of the given filepath
*/
function regexFilepath($path)
{global $debug;
if($debug)echo"\r\nregexFilepath($path)\r\n{\r\n";
$filepathArray = explode("/", $path);
if (count($filepathArray) == 0)
throw new Exception("given parameter not a filepath: $path");
if ($filepathArray[0] == "") // this can happen if the path starts with a "/"
array_shift($filepathArray); // strip the first element off the array
$isIndex = preg_match("/^index\..+$/i", end($filepathArray));
$filename = array_pop($filepathArray);
if($debug){var_dump($filepathArray);}
$ret = '';
foreach($filepathArray as $i)
$ret = "(\.\.\/$ret$i\/)?"; // make a pseudo-recursive relative filepath
if($debug)echo "\r\n$ret";
$ret = preg_replace('/\)\?$/', '?)', $ret); // remove the last '?' and add one before the last '\/'
if($debug)echo "\r\n$ret";
$ret = '/^' . ($ret == '' ? '\.\/' : "((\.\/)|$ret)") . ($isIndex ? '(index\..+)?' : str_replace('.', '\.', $filename)) . '$/i'; // if this filepath leads to an index.php (etc.), then that filename is implied and irrelevant.
if($debug)echo'\r\n}\r\n';
}
This seems to match everything I need it to match, and not what I don't need it to.
The following code works with all YouTube domains except for youtu.be. An example would be: http://www.youtube.com/watch?v=ZedLgAF9aEg would turn into: ZedLgAF9aEg
My question is how would I be able to make it work with http://youtu.be/ZedLgAF9aEg.
I'm not so great with regex so your help is much appreciated. My code is:
$text = preg_replace("#[&\?].+$#", "", preg_replace("#http://(?:www\.)?youtu\.?be(?:\.com)?/(embed/|watch\?v=|\?v=|v/|e/|.+/|watch.*v=|)#i", "", $text)); }
$text = (htmlentities($text, ENT_QUOTES, 'UTF-8'));
Thanks again!
//$url = 'http://www.youtube.com/watch?v=ZedLgAF9aEg';
$url = 'http://youtu.be/ZedLgAF9aEg';
if (FALSE === strpos($url, 'youtu.be/')) {
parse_str(parse_url($url, PHP_URL_QUERY), $id);
$id = $id['v'];
} else {
$id = basename($url);
}
echo $id; // ZedLgAF9aEg
Will work for both versions of URLs. Do not use regex for this as PHP has built in functions for parsing URLs as I have demonstrated which are faster and more robust against breaking.
Your regex appears to solve the problem as it stands now? I didn't try it in php, but it appears to work fine in my editor.
The first part of the regex http://(?:www\.)?youtu\.?be(?:\.com)?/matches http://youtu.be/ and the second part (embed/|watch\?v=|\?v=|v/|e/|.+/|watch.*v=|) ends with |) which means it matches nothing (making it optional). In other words it would trim away http://youtu.be/ leaving only the id.
A more intuitive way of writing it would be to make the whole if grouping optional I suppose, but as far as I can tell your regex is already solving your problem:
#http://(?:www\.)?youtu\.?be(?:\.com)?/(embed/|watch\?v=|\?v=|v/|e/|.+/|watch.*v=)?#i
Note: Your regex would work with the www.youtu.be.com domain as well. It would be stripped away, but something to watch out for if you use this for validating input.
Update:
If you want to only match urls inside [youtube][/youtube] tags you could use look arounds.
Something along the lines of:
(?<=\[youtube\])(?:http://(?:www\.)?youtu\.?be(?:\.com)?/(?:embed/|watch\?v=|\?v=|v/|e/|[^\[]+/|watch.*v=)?)(?=.+\[/youtube\])
You could further refine it by making the .+ in the look ahead only match valid URL characters etc.
Try this, hope it'll help you
function YouTubeUrl($url)
{
if($url!='')
{
$newUrl='';
$videoLink1=$url;
$findKeyWord='youtu.be';
$toBeReplaced='www.youtube.com';
if(IsContain('watch?v=',$videoLink1))
{
$newUrl=tMakeUrl($videoLink1);
}
else if(IsContain($videoLink1, $findKeyWord))
{
$videoLinkArray=explode('/',$videoLink1);
$Protocol='';
if(IsContain('://',$videoLink1))
{
$protocolArray=explode('://',$videoLink1);
$Protocol=$protocolArray[0];
}
$file=$videoLinkArray[count($videoLinkArray)-1];
$newUrl='www.youtube.com/watch?v='.$file;
if($Protocol!='')
$newUrl.=$Protocol.$newUrl;
else
$newUrl=tMakeUrl($newUrl);
}
else
$newUrl=tMakeUrl($videoLink1);
return $newUrl;
}
return '';
}
function IsContain($string,$findKeyWord)
{
if(strpos($string,$findKeyWord)!==false)
return true;
else
return false;
}
function tMakeUrl($url)
{
$tSeven=substr($url,0,7);
$tEight=substr($url,0,8);
if($tSeven!="http://" && $tEight!="https://")
{
$url="http://".$url;
}
return $url;
}
You can use bellow function for any of youtube URL
I hope this will help you
function checkYoutubeId($id)
{
$youtube = "http://www.youtube.com/oembed?url=". $id ."&format=json";
$curl = curl_init($youtube);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$return = curl_exec($curl);
curl_close($curl);
return json_decode($return, true);
}
This function return Youtube video detail if Id match to youtube video ID
A little improvement to #rvalvik answer would be to include the case of the mobile links (I've noticed it while working with a customer who used an iPad to navigate, copy and paste links). In this case, we have a m (mobile) letter instead of www. Regex then becomes:
#(https?://)?(?:www\.)?(?:m\.)?(?:youtu\.be/|youtube\.com(?:/embed/|/v/|/watch?.*?v=))([\w\-]{10,12}).*#x
Hope it helps.
A slight improvement of another answer:
if (strpos($url, 'feature=youtu.be') === TRUE || strpos($url, 'youtu.be') === FALSE )
{
parse_str(parse_url($url, PHP_URL_QUERY), $id);
$id = $id['v'];
}
else
{
$id = basename($url);
}
This takes into account youtu.be still being in the URL, but not the URL itself (it does happen!) as it could be the referring feature link.
Other answers miss out on the point that some youtube links are part of a playlist and have a list paramater also which is required for embed code. So to extract the embed code from link one could try this JS code:
let urlEmbed = "https://www.youtube.com/watch?v=iGGolqb6gDE&list=PL2q4fbVm1Ik6DCzm9XZJbNwyHtHGclcEh&index=32"
let embedId = urlEmbed.split('v=')[1];
let parameterStringList = embedId.split('&');
if (parameterStringList.length > 1) {
embedId = parameterStringList[0];
let listString = parameterStringList.filter((parameterString) =>
parameterString.includes('list')
);
if (listString.length > 0) {
listString = listString[0].split('=')[1];
embedId = `${parameterStringList[0]}?${listString}`;
}
}
console.log(embedId)
Try it out here: https://jsfiddle.net/AMITKESARI2000/o62dwj7q/
try this :
$string = explode("=","http://www.youtube.com/watch?v=ZedLgAF9aEg");
echo $string[1];
would turn into: ZedLgAF9aEg
I'm making a link and text service, but I have a problem, which is: there is only 1 input text form, and the user could paste something like this:
http:// asdf .com - which would register as a link, or 'asdf http:// test .com' because of the http://, it would register as a url, or
asdf - which would register as a string, because it doesn't contain http://
BUT my problem arises when the user writes something like:
asdf http://asdf.com, which in my current program outputs a "url" value. I've been experimenting for about an hour now, and I've got 3 bits of code (they were all in the same document being commented, so forgive me if they give errors!)
<?
$str = $_POST['paste'];
if(stristr($str, "http://")) {
$type = "url";
}
if(stristr($str, "https://")) {
$type = "url";
}
if($type!="url") {
$type = "string";
}
?>
Next:
<?
$type = "url";
if($type=="url"){
$t = substr($str, 8);
if(stristr($t, "https://")==$t){
$type = "url";}
if(stristr($t, "https://")==$t){
$type = "url";}
if(stristr($t, "http://")!=$t){
$type = "string";}
if(stristr($t, "https://")!=$t){
$type = "string";}
}
echo $type;
?>
Next:
<?
$url = "hasttp://cake.com";
if(stristr($url, "http://")=="") {
$type = "string"; } else {
$type = "url";
$sus = 1;}
if(stristr($url, "http://")==$url) {
$type = "url"; }
if($sus==1) {
$r = substr($url, 7);
if(stristr($r,"http://")!="http://") {
$type = "url"; }
if($r=="") {
$type = "string";
}
}
echo $type;
?>
I have no clue how I could go about classifying a string like 'asdf http://asdf.com' as a string, whilst classifying 'asdf' as a string, and classifying 'http://asdf.com' as a url.. Another idea I haven't tried yet is strpos, but that's what I'm working on now.
Any ideas?
Thanks alot! :)
Some parts of this question are getting cut off for some reason, apologies!
$type = '';
if (preg_match('%^https?://[^\s]+$%', $url)) {
$type = 'url';
} else {
$type = 'string';
}
This will match any value which starts with http:// or https://, and does not contain any space in it as type url. If the value does not start with http:// or https://, or it contains a space in it, it will be type string.
PHP parse_url is your function:
On seriously malformed URLs, parse_url() may return FALSE.
If the component parameter is omitted, an associative array is returned. At least one element will be present within the array. Potential keys within this array are:
scheme - e.g. http
host
port
user
pass
path
query - after the question mark ?
fragment - after the hashmark #
If the component parameter is specified, parse_url() returns a string (or an integer, in the case of PHP_URL_PORT) instead of an array. If the requested component doesn't exist within the given URL, NULL will be returned.
If I'm understanding the problem correctly you want to detect when the user inputs both a string and a url and parse each of them correspondingly.
Try using explode(" ", $userInput);, this will return an array containing all strings separated by a space. Than you can check that for each element in the array and set the type.
$type = strpos($str, 'http') === 0 ? 'url' : 'string':
The strpos function returns the position of a match within a string or FALSE if no match. The tripple equals checks that the result does not only translates to 0 (as FALSE would have done), but that it is in fact integer as well (i.e., the string begins with http).
You could also use something like
switch (true) {
case strpos(trim($str), 'http://') === 0:
case strpos(trim($str), 'https://') === 0:
$type = 'url';
break;
default:
$type = 'string';
break; // I know this is not needed, but it is pretty :-)
}
You should use a regular expression to check if the string starts with http
if(preg_match('/^http/',$string_to_check)){
//this is a url
}