How would I replace all question marks after the first - php

So, a lot of my form systems redirect back to the previous page, although, they display a message in the process. The way I display a message is by simply using ?message=messageCode in the URL.
However, if they use the form from a page that already has a query string, it adds a second query string, messing everything up.
Example:
if I were to login from the navigation bar, on the URL "mywebsite.com/something?message=1", it would log in, but redirect to "mywebsite.com/something?message=1?message=2"
This results in no message being displayed.
What I am asking here is, how could I change all of the question marks AFTER the first question mark, to and signs?
Example:
From: mywebsite.com/page?blah=1?something=2?hi=3
To: mywebsite.com/page?blah=1&something=2&hi=3
I have searched around, as well as tried some methods of my own, but nothing seems to work properly.

What you should be doing is build a proper URL, appending ? or & when appropriate.
$url = 'mywebsite.com/something?message=1';
$new_url = sprintf('%s%s%s',
$url,
strpos($url, '?') === false ? '?' : '&',
http_build_query(['message' => 2])
);
Or, first parse the previous URL and merge the query string.

Use it like below:-
<?php
$str = 'mywebsite.com/something?message=1?message=2';
$pos = strpos($str,'?'); //check the last occurrence of ?
if ($pos !== false) {
$str = substr($str,0,$pos+1) . str_replace('?','&',substr($str,$pos+1));// replacement of ? to &
}
echo $str;
?>
Output:- https://eval.in/388308

Related

How can I str_replace partially in PHP in a dynamic string with unknown key content

Working in WordPress (PHP). I want to set strings to the database like below. The string is translatable, so it could be in any language keeping the template codes. For the possible variations, I presented 4 strings here:
<?php
$string = '%%AUTHOR%% changed status to %%STATUS_new%%';
$string = '%%AUTHOR%% changed status to %%STATUS_oldie%%';
$string = '%%AUTHOR%% changed priority to %%PRIORITY_high%%';
$string = '%%AUTHOR%% changed priority to %%PRIORITY_low%%';
To make the string human-readable, for the %%AUTHOR%% part I can change the string like below:
<?php
$username = 'Illigil Liosous'; // could be any unicode string
$content = str_replace('%%AUTHOR%%', $username, $string);
But for status and priority, I have different substrings of different lengths.
Question is:
How can I make those dynamic substring be replaced on-the-fly so that they could be human-readable like:
Illigil Liosous changed status to Newendotobulous;
Illigil Liosous changed status to Oldisticabulous;
Illigil Liosous changed priority to Highlistacolisticosso;
Illigil Liosous changed priority to Lowisdulousiannosso;
Those unsoundable words are to let you understand the nature of a translatable string, that could be anything other than known words.
I think I can proceed with something like below:
<?php
if( strpos($_content, '%%STATUS_') !== false ) {
// proceed to push the translatable status string
}
if( strpos($_content, '%%PRIORITY_') !== false ) {
// proceed to push the translatable priority string
}
But how can I fill inside those conditionals efficiently?
Edit
I might not fully am clear with my question, hence updating the query. The issue is not related to array str_replace.
The issue is, the $string that I need to detect is not predefined. It would come like below:
if($status_changed) :
$string = "%%AUTHOR%% changed status to %%STATUS_{$status}%%";
else if($priority_changed) :
$string = "%%AUTHOR%% changed priority to %%PRIORITY_{$priority}%%";
endif;
Where they will be filled dynamically with values in the $status and $priority.
So when it comes to str_replace() I will actually use functions to get their appropriate labels:
<?php
function human_readable($codified_string, $user_id) {
if( strpos($_content, '%%STATUS_') !== false ) {
// need a way to get the $status extracted from the $codified_string
// $_got_status = ???? // I don't know how.
get_status_label($_got_status);
// the status label replacement would take place here, I don't know how.
}
if( strpos($_content, '%%PRIORITY_') !== false ) {
// need a way to get the $priority extracted from the $codified_string
// $_got_priority = ???? // I don't know how.
get_priority_label($_got_priority);
// the priority label replacement would take place here, I don't know how.
}
// Author name replacement takes place now
$username = get_the_username($user_id);
$human_readable_string = str_replace('%%AUTHOR%%', $username, $codified_string);
return $human_readable_string;
}
The function has some missing points where I currently am stuck. :(
Can you guide me a way out?
It sounds like you need to use RegEx for this solution.
You can use the following code snippet to get the effect you want to achieve:
preg_match('/%%PRIORITY_(.*?)%%/', $_content, $matches);
if (count($matches) > 0) {
$human_readable_string = str_replace("%%PRIORITY_{$matches[0]}%%", $replace, $codified_string);
}
Of course, the above code needs to be changed for STATUS and any other replacements that you require.
Explaining the RegEx code in short it:
/
The starting of any regular expression.
%%PRIORITY_
Is a literal match of those characters.
(
The opening of the match. This is going to be stored in the third parameter of the preg_match.
.
This matches any character that isn't a new line.
*?
This matches between 0 and infinite of the preceding character - in this case anything. The ? is a lazy match since the %% character will be matched by the ..
Check out the RegEx in action: https://regex101.com/r/qztLue/1

Parsing closed brackets in URL and http_build_query with it inserts number in closed bracket

may not have explained this properly but here we go.
I have a URL that looks like http://www.test.co.uk/?page=2&area[]=thing&area[]=thing2
Multiple "area"s can be added or removed from the URL via links on the site. on each addition of n "area" I wanted to remove the "page" part of the URL. so it can be reset to page1. I used parse_url to take that bit out.
Then I built an http query so it could generate the URL properly without "page"
this resulted in "area%5B0%5D=" "area%5B1%5D=" instead of "area[]="
When I use urldecode, now it shows "area[0]=" and "area[1]="
I need it to be "[]" because when using a link to remove an area, it checks for the "[]=" - when it's [0] it doesn't recognise it. How do I keep it as "[]="?
See code below.
$currentURL = currentURL();
$parts = parse_url($currentURL);
parse_str($parts['query'], $query);
unset($query['page']);
$currenturlfinal = http_build_query($query);
urldecode($currenturlfinal);
$currentURL = "?" . urldecode($currenturlfinal);
This is what I've done so far - it fixes the visual part in the URL - however I don't think I've solved anything as I've realised that what represents 'area' and 'thing' is not recognised as $key or $val as a result of what I think is parsing or reencoding the url in accordance with the code below. So I still can't remove 'areas' using the links
$currentURL_with_QS2 = currentURL();
$parts = parse_url($currentURL_with_QS2);
parse_str($parts['query'], $query);
unset($query['page']);
$currenturlfinal = http_build_query($query);
$currenturlfinal = preg_replace('/%5B[0-9]+%5D/simU', '[]', $currenturlfinal);
urldecode($currenturlfinal);
$currentURL_with_QS = "?" . $currenturlfinal;
$numQueries = count(explode('&', $_SERVER['QUERY_STRING']));
$get = $_GET;
if (activeCat($val)) { // if this category is already set
$searchString = $key . '[]= ' . $val; // we build the query string to remove
I'm using Wordpress as well may I add - maybe there's a way to reset the pagination through Wordpress. of course even then - when I go to page 2 on any page it still changes the "[]" to "5b0%5d" etc....
EDIT: this is all part of a function that refers to $key (the area/category) and $val (name of area or category) which is echoed in the link itself
EDIT2: It works now!
I don't know why but I had to use the original code and make the adjustments I did before again and now it works exactly how I want it to! Yet I couldn't see any visible differences in both codes afterwards. Strange...
As far as I know, there is no built-in way to do this.
You could try with:
$currenturlfinal = http_build_query($query);
Where $query is querystring part w/o area parameters and then:
foreach ($areas as $area) {
$currenturlfinal .= '&area[]='.$area;
}
UPD:
you could try with:
$query = preg_replace('/%5B[0-9]+%5D/simU', '%5B%5D', $query);
just place it right after http_build_query call.

if else on variable link input

I have a method of pulling Youtube video data from API links. I use Wordpress and ran into a snag.
In order to pull the thumbnail, views, uploader and video title I need the user to input the 11 character code at the end of watch?v=_______. This is documented with specific instructions for the user, but what if they ignore it and paste the whole url?
// the url 'code' the user should input.
_gXp4hdd2pk
// the wrong way, when the user pastes the whole url.
https://www.youtube.com/watch?v=_gXp4hdd2pk
If the user accidentally pastes the entire URL and not the 11 character code then is there a way I can use PHP to grab either the code or whats at the end of this url (11 characters after 'watch?v='?
Here is my PHP code to pull the data:
// $url is the code at the end of 'watch?v=' that the user inputs
$url = get_post_meta ($post->ID, 'youtube_url', $single = true);
// $code is a variable for placing the $url in a youtube link so I can output it to an API link
$code = 'http://www.youtube.com/watch?v=' . $url;
// $code is called at the end of this oembed code, allowing me to decode json data and pull elements from json to echo in my html
// echoed output returns json file. example: http://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=_gXp4hdd2pk
$json = file_get_contents('http://www.youtube.com/oembed?url='.urlencode($code));
Im looking for something like...
"if user inputs code, use this block of code, else if user inputs whole url use a different block of code, else throw error."
Or... if they use the whole URL can PHP only use a specific section of that url...?
EDIT: Thank you for all the answers! I am new to PHP, so thank you all for your patience. It is difficult for graphic designers to learn PHP, even reading the PHP manual can give us headaches. All of your answers were great and the ones ive tested have worked. Thank you so much :)
Try this,
$code = 'https://www.youtube.com/watch?v=_gXp4hdd2pk';
if (filter_var($code, FILTER_VALIDATE_URL) == TRUE) {
// if `$code` is valid url
$code_arr = explode('?v=', $code);
$query_str = explode('&', $code_arr[1]);
$new_code = $query_str[0];
} else {
// if `$code` is not a valid url like '_gXp4hdd2pk'
$new_code = $code;
}
echo $new_code;
Here's a simple option for you to do, unless you want to use regex like Nisse Engström's Answer.
Using the function parse_url() you could do something like this:
$url = 'https://www.youtube.com/watch?v=_gXp4hdd2pk&list=RD_gXp4hdd2pk#t=184';
$split = parse_url('https://www.youtube.com/watch?v=_gXp4hdd2pk&list=RD_gXp4hdd2pk#t=184');
$params = explode('&', $split['query']);
$video_id = str_replace('v=', '', $params[0]);
now $video_id would return:
_gXp4hdd2pk
from the $url supplied in the above code.
I suggest you read the parse_url() documentation to ensure you understand and grasp it all :-)
Update
for your comment.
You'd use something like this to make sure the parsed value is a valid URL:
// this will check if valid url
if (filter_var($code, FILTER_VALIDATE_URL)) {
// its valid as it returned true
// so run the code
$url = 'https://www.youtube.com/watch?v=_gXp4hdd2pk&list=RD_gXp4hdd2pk#t=184';
$split = parse_url('https://www.youtube.com/watch?v=_gXp4hdd2pk&list=RD_gXp4hdd2pk#t=184');
$params = explode('&', $split['query']);
$video_id = str_replace('v=', '', $params[0]);
} else {
// they must have posted the video code as the if check returned false.
$video_id = $url;
}
Just try as follows ..
$url =" https://www.youtube.com/watch?v=_gXp4hdd2pk";
$url= explode('?v=', $url);
$endofurl = end($url);
echo $endofurl;
Replace $url variable with input .
I instruct my users to copy and paste the whole youtube url.
Then, I do this:
$video_url = 'https://www.youtube.com/watch?v=_gXp4hdd2pk'; // this is from user input
$parsed_url = parse_url($video_url);
parse_str($parsed_url['query'], $query);
$vidID = isset($query['v']) ? $query['v'] : NULL;
$url = "http://gdata.youtube.com/feeds/api/videos/". $vidID; // this is used for the Api
$m = array();
if (preg_match ('#^(https?://www.youtube.com/watch\\?v=)?(.+)$#', $url, $m)) {
$code = $m[2];
} else {
/* No match */
}
The code uses a Regular Expression to match the user input (the subject) against a pattern. The pattern is enclosed in a pair of delimiters (#) of your choice. The rest of the pattern works like this:
^ matches the beginning of the string.
(...) creates a subpattern.
? matches 0 or 1 of the preceeding character or subpattern.
https? matches "http" or "https".
\? matches "?".
(.+) matches 1 or more arbitrary charactes. The . matches any character (except newline). + matches 1 or more of the preceeding character or subpattern.
$ matches the end of the string.
In other words, optionally match an http or https base URL, followed by the video code.
The matches are then written to $m. $m[0] contains the entire string, $m[1] contains the first subpattern (base URL) and $m[2] contains the second subpattern (code).

Create URL with only A-Z characters that includes variable and extension

I am trying to create file links based a variable which has a "prefix" and an extension at the end.
Here's what I have:
$url = "http://www.example.com/mods/" . ereg("^[A-Za-z_\-]+$", $title) . ".php";
Example output of what I wish to have outputted (assuming $title = testing;):
http://www.example.com/mods/testing.php
What it currently outputs:
http://www.example.com/mods/.php
Thanks in advance!
Perhaps this is what you need:
$title = "testing";
if(preg_match("/^[A-Za-z_\-]+$/", $title, $match)){
$url = "http://www.example.com/mods/".$match[0].".php";
}
else{
// Think of something to do here...
}
Now $url is http://www.example.com/mods/testing.php.
Do you want to keep letters and remove all other chars in the URL?
In this case the following should work:
$title = ...
$fixedtitle=preg_replace("/[^A-Za-z_-]/", "", $title);
$url = "http://www.example.com/mods/".$fixedtitle.".php";
the inverted character class will remove everything you do not want.
OK first it's important for you to realize that ereg() is deprecated and will eventually not be available as a command for php, so to prevent an error down the road you should use preg_match instead.
Secondly, both ereg() and preg_match output the status of the match, not the match itself. So
ereg("^[A-Za-z_\-]+$", $title)
will output an integer equal to the length of the string in $title, 0 if there's no match and 1 if there's a match but you didn't pass it another variable to store the matches in.
I'm not sure why it's displaying
http://www.example.com/mods/.php
It should actually be outputting
http://www.example.com/mods/1.php
if everything was working correctly. So there is something going on there, and it's definitely not doing what you want it to. You need to pass another variable to the function that will store all the matches found. If the match is successful (which you can check using the return value of the function) then that variable will be an array of all matches.
Note that with preg_match by default only the first match will be returned. but it will still generate an array (which can be used to get isolated portions of the match) whereas preg_match_all will match multiple things.
See http://www.php.net/manual/en/function.preg-match.php for more details.
Your regex looks more or less correct
So the proper code should look something like:
$title = 'testing'; //making sure that $title is what we think it is
if (preg_match('/^[A-Za-z_\-]+$/',$title,$matches)) {
$url = "http://www.example.com/mods/" . $matches[0] . ".php";
} else {
//match failed, put error code in here
}

Add/Replace URL GET parameter depending on current URL

I’ve tried for some time now to solve what probably is a small issue but I just can’t seem get my head around it. I’ve tried some different approaches, some found at SO but none has worked yet.
The problem consists of this:
I’ve a show-room page where I show some cloth. On each single item of cloth there is four “views”
Male
Female
Front
Back
Now, the users can filter this by either viewing the male or female model but they can also filter by viewing front or back of both gender.
I’ve created my script so it detects the URL query and display the correct data but my problem is to “build” the URL correctly.
When firstly enter the page, the four links is like this:
example.com?gender=male
example.com?gender=female
example.com?site=front
example.com?site=back
This work because it’s the “default” view (the default view is set to gender=male && site=front) in the model.
But if I choose to view ?gender=female the users should be able to filter it once more by adding &site=back so the complete URL would be: example.com?gender=female&site=back
And if I then press the link to see gender=male it should still keep the URL parameter &site=back.
What I’ve achived so far is to append the parameters to the existing URL but this result in URL strings like: example.com?gender=male&site=front&gender=female and so on…
I’ve tried but to use the parse_url function, the http_build_query($parms) method and to make my “own” function that checks for existing parameters but it does not work.
My latest try was this:
_setURL(‘http://example.com?gender=male’, ‘site’, ‘back’);
function _setURL($url, $key, $value) {
$separator = (parse_url($url, PHP_URL_QUERY) == NULL) ? '?' : '&';
$query = $key."=".$value;
$url .= $separator . $query;
var_dump($url); exit;
}
This function works unless the $_GET parameter already exists and thus should be replaced and not added.
I’m not sure if there is some “best practice” to solve this and as I said I’ve looked at a lot of answers on SO but none which was spot on my issue.
I hope I’ve explained myself otherwise please let me know and I’ll elaborate.
Any help or advice would be appreciated
You can generate the links dynamically using the following method:
$frontLink = (isset($_GET['gender'])) ? 'mydomain.com?gender='.$_GET['gender'].'&site=front':'mydomain.com?site=front';
$backLink = (isset($_GET['gender'])) ? 'mydomain.com?gender='.$_GET['gender'].'&site=back':'mydomain.com?site=back';
This is a 1 line if statement which will set the value of the variables $frontLink and $backlink respectively. The syntax for a 1 line if statement is $var = (if_statement) ? true_result:false_result; this will set the value of $var to the true_result or false_result depending on the return value of the if statement.
You can then do the same for the genders:
$maleLink = (isset($_GET['site'])) ? 'mydomain.com?gender=male&site='.$_GET['site']:'mydomain.com?gender=male';
$femaleLink = (isset($_GET['site'])) ? 'mydomain.com?gender=female&site='.$_GET['site']:'mydomain.com?gender=female';
Found this by searching for a better solution then mine and found this ugly one (That we see a lot on the web), so here is my solution :
function add_get_parameter($arg, $value)
{
$_GET[$arg] = $value;
return "?" . http_build_query($_GET);
}
<?php
function requestUriAddGetParams(array $params)
{
$parseRes=parse_url($_REQUEST['REQUEST_URI']);
$params=array_merge($_GET, $params);
return $parseRes['path'].'?'.http_build_query($params);
}
?>
if(isset($_GET['diagid']) && $_GET['diagid']!='') {
$repParam = "&diagid=".$_GET['diagid'];
$params = str_replace($repParam, "", $_SERVER['REQUEST_URI']);
$url = "http://".$_SERVER['HTTP_HOST'].$params."&diagid=".$ID;
}
else $url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']."&diagid=".$ID;

Categories