Good Day,
Below I have provided 2 codes, which I did not write but grabbed from a forum. I really need to learn the solution to this new mystery. Both make use of the urlencode(). They are nearly the same code.
I notice that, only the 1st code's output is normal and not encoded while the 2nd one's output is encoded. Why ?
Since both are making use of the urlencode() then shouldn't both their outputs be in encoded format ? This has been greatly puzzling me for days now. I give-up. What's the mystery behind this ?
1st Code:
$url = 'http://nogdog.com/cat/subcat?var 1=value 1&var2=2&this other=thing&number is=12';
echo prepare_url($url) . "\n";
function prepare_url($url) {
$url_parts = parse_url($url);
if($url_parts === false or empty($url_parts['host'])) {
return false;
}
$url_out = preg_match('/^https?/i', $url_parts['scheme']) ? strtolower($url_parts['scheme']) : 'https';
$url_out .= "://{$url_parts['host']}{$url_parts['path']}";
if(!empty($url_parts['query'])) {
parse_str($url_parts['query'], $query_parts);
foreach($query_parts as $q_key => $q_value) {
$query_string_parts[] = urlencode($q_key).'='.urlencode($q_value);
}
$url_out .= '?'.implode('&', $query_string_parts);
}
return $url_out;
}
2nd Code:
function prepare_url2($url) {
$url_parts = parse_url($url);
if($url_parts === false or empty($url_parts['host'])) {
return false;
}
// re-assemble the start of url string
$url_start = preg_match('/^https?/i', $url_parts['scheme']) ? strtolower($url_parts['scheme']) : 'https';
$url_start .= "://{$url_parts['host']}{$url_parts['path']}";
// rawurlencode the start of url string
$url_out = rawurlencode($url_start);
if(!empty($url_parts['query'])) {
parse_str($url_parts['query'], $query_parts);
foreach($query_parts as $q_key => $q_value) {
// assemble and check if value is numeric
$query_string_parts[] = urlencode($q_key).'='.(is_numeric($q_value) ? intval($q_value) :urlencode($q_value));
}
$url_out .= '?'.implode('&', $query_string_parts);
}
return $url_out;
}
$url = 'http://zorg.com/cat/subcat?var 1=value 1&var2=2&this other=thing&number is=13';
echo prepare_url2($url);
NOTE
The difference between the two codes are that, the 1st one defines the $url and calls the prepare_url() function at the top. (Before the prepare_url() function's code).
$url = 'http://nogdog.com/cat/subcat?var 1=value 1&var2=2&this other=thing&number is=12';
echo prepare_url($url) . "\n";
While, the 2nd one defines the $url and calls the prepare_url() function at the bottom. (After the prepare_url() function's code).
$url = 'http://zorg.com/cat/subcat?var 1=value 1&var2=2&this other=thing&number is=13';
echo prepare_url($url);
Apart from that, both codes are the same.
So, if both the codes are the same (so to speak), then why does the 1st code output like this:
http://nogdog.com/cat/subcat?var_1=value+1&var2=2&this_other=thing&number_is=12
And, why does the 2nd code output like this:
http%3A%2F%2Fzorg.com%2Fcat%2Fsubcat?var_1=value+1&var2=2&this_other=thing&number_is=13
Related
I want to make action if the current url only equals to this: https://www.example.co.il/index.php?id=1000&2222
$url = 'https://www.example.co.il/index.php?id=1000';
if(strpos($url,'&2222'))
{
// Do something
echo "2222";
}
else
{
// Do Nothing
}
To exactly do what you are asked, try this
//actual link (http or https)
$actualUrl = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$url = 'https://www.example.co.il/index.php?id=1000';
if($actualUrl === $url) {
//do something
}
But if you just want to retrieve the id :
$id = $_GET('id');
//return 1000 in your case
You're able to read the parameters in the URL using the $_GET object. It lists the keys and values in the querystring, i.e. in your example,
https://www.example.co.il/index.php?id=1000
if you use:
print $_GET['id'];
you'll see 100.
so you could simply check for the existence of the key 2222:
if (isset($_GET['2222'])) { /** do something **/ }
bear in mind, this is only the case if you're actually reading a URL the script is running on.
your method of searching for a string within the URL is appropriate if you simply want to match a value in a string, whether its a URL or not.
USE THIS
// Assign your parameters here for restricted access
$valid_url = new stdClass();
$valid_url->scheme = 'https';
$valid_url->host = 'www.example.co.il';
$valid_url->ids = array(1000,2222);
$url = 'https://www.example.co.il/index.php?id=1000&2222';
$urlinfo = parse_url($url); // pass url here
$ids = [];
parse_str(str_replace('&', '&id1=', $urlinfo['query']), $ids);
if($urlinfo['scheme'] == $valid_url->scheme && $urlinfo['host'] == $valid_url->host && count(array_intersect($valid_url->ids, $ids)) == count($valid_url->ids)){
echo 'valid';
// Do something
}else{
echo 'in valid';
// error page
}
I know this question is similar to other questions that have been posted. I have followed exactly what was suggested in answers to those questions but still can't figure out why the output is shown at the the top of the page.
function foo_shortcode($atts, $content = null) {
$datashortcode = '<div>'.(function_exists('rtb_kk') ? rtb_kk() : '').'</div>';
return $datashortcode;
}
add_shortcode('showfoo', 'foo_shortcode');
Any idea?
Without knowing how the rtb_kk() function works, I can only assume it uses echo to display content rather than using return. This is what causes the output of that function to appear at the top of the page.
To work around this issue, you can capture the output of the function with ob_start() and ob_get_clean():
function foo_shortcode($atts, $content = null) {
if (function_exists('rtb_kk')) {
// Start output buffering
ob_start();
// Run the function
rtb_kk();
// Capture buffer as a string
$output = ob_get_clean();
} else {
// Function doesn't exist so we return an empty string
$output = '';
}
return '<div>' . $output . '</div>';
}
add_shortcode('showfoo', 'foo_shortcode');
Alternative method
If you're able to use the bcn_display() instead of the rtb_kk() method you're using, then there is no need to rely on ob_get_clean().
function foo_shortcode($atts, $content = null) {
if (function_exists('bcn_display')) {
// Return the output as a string so we can control when it's displayed
$output = bcn_display( true );
} else {
// Function doesn't exist so we return an empty string
$output = '';
}
return '<div>' . $output . '</div>';
}
add_shortcode('showfoo', 'foo_shortcode');
This will solve your problem, just try
<script type="text/javascript">
function foo_shortcode($atts, $content = null) {
if(function_exists('rtb_kk')){
$rtb_kk = rtb_kk();
}else{
$rtb_kk = '';
}
$datashortcode = "<div>$rtb_kk</div>";
return $datashortcode;
}
add_shortcode('showfoo', 'foo_shortcode');
</script>
I'm not so sure whether it is smart to post both problems in one question, but lets try:
So, I was checking my server's error log and it still has two notices, both about "Array to string conversion in [...]".
The first line should be this:
$replace = $route['keywords'][$key]['prepend'].$params[$key].$route['keywords'][$key]['append'];
Context:
// Build an url which match a route
if ($this->use_routes || $force_routes) {
$url = $route['rule'];
$add_param = array();
foreach ($params as $key => $value) {
if (!isset($route['keywords'][$key])) {
if (!isset($this->default_routes[$route_id]['keywords'][$key])) {
$add_param[$key] = $value;
}
} else {
if ($params[$key]) {
$replace = $route['keywords'][$key]['prepend'].$params[$key].$route['keywords'][$key]['append'];
} else {
$replace = '';
}
$url = preg_replace('#\{([^{}]*:)?'.$key.'(:[^{}]*)?\}#', $replace, $url);
}
}
$url = preg_replace('#\{([^{}]*:)?[a-z0-9_]+?(:[^{}]*)?\}#', '', $url);
if (count($add_param)) {
$url .= '?'.http_build_query($add_param, '', '&');
}
}
The second one is this line:
$uri_path = __PS_BASE_URI__.$id_image.($type ? '-'.$type : '').$theme.'/'.$name.'.jpg';
as part of this:
// legacy mode or default image
$theme = ((Shop::isFeatureActive() && file_exists(_PS_PROD_IMG_DIR_.$ids.($type ? '-'.$type : '').'-'.(int)Context::getContext()->shop->id_theme.'.jpg')) ? '-'.Context::getContext()->shop->id_theme : '');
if ((Configuration::get('PS_LEGACY_IMAGES')
&& (file_exists(_PS_PROD_IMG_DIR_.$ids.($type ? '-'.$type : '').$theme.'.jpg')))
|| ($not_default = strpos($ids, 'default') !== false)) {
if ($this->allow == 1 && !$not_default) {
$uri_path = __PS_BASE_URI__.$ids.($type ? '-'.$type : '').$theme.'/'.$name.'.jpg';
} else {
$uri_path = _THEME_PROD_DIR_.$ids.($type ? '-'.$type : '').$theme.'.jpg';
}
} else {
// if ids if of the form id_product-id_image, we want to extract the id_image part
$split_ids = explode('-', $ids);
$id_image = (isset($split_ids[1]) ? $split_ids[1] : $split_ids[0]);
$theme = ((Shop::isFeatureActive() && file_exists(_PS_PROD_IMG_DIR_.Image::getImgFolderStatic($id_image).$id_image.($type ? '-'.$type : '').'-'.(int)Context::getContext()->shop->id_theme.'.jpg')) ? '-'.Context::getContext()->shop->id_theme : '');
if ($this->allow == 1) {
$uri_path = __PS_BASE_URI__.$id_image.($type ? '-'.$type : '').$theme.'/'.$name.'.jpg';
} else {
$uri_path = _THEME_PROD_DIR_.Image::getImgFolderStatic($id_image).$id_image.($type ? '-'.$type : '').$theme.'.jpg';
}
}
return $this->protocol_content.Tools::getMediaServer($uri_path).$uri_path;
}
public function getMediaLink($filepath)
{
return $this->protocol_content.Tools::getMediaServer($filepath).$filepath;
}
PHP is not my strength, so I have no idea what to do :/
Also I found some other questions about Array to string notices, but it seemed to me like you can't solve them the same way...
Thanks in advance for any help!
This error is appearing because some of the variables in these two lines are supposed to be String but they are actually array.
You need to print all the variables used in these 2 lines using the var_dump() function of PHP, this will tell you which of the variables are actually an Array, but they are supposed to be a String as per your code.
On the basis of the output, you need to modify your code to fix the issue.
I need create a function that checks a parsed value to see if it matches a few other values and then return that match. For example I am trying to match video urls correctly. So if it's youtube do this or if it's vimeo do this or if it's nothing do this. I know how to create a function but I'm not sure what to use for the parse, would it be parse_url?
For my test cases I need to send in the right parameter and then see that the returned values are matching what I want them to be.
Here's what I've tried so far:
function get_video_embed_string($videostring) {
$video_url_parse = parse_url( $videostring, PHP_URL_HOST ); //get the input string ready to parse
$returnstring = ""; //default return string to empty string
if ($video_url_parse === 'vimeo.com') {
$returnstring = str_replace( 'vimeo.com', 'player.vimeo.com', $video_url_parse );
} else if ($video_url_parse === 'youtube.com') {
$returnstring = str_replace( 'youtube.com', 'youtube.com/embed/', $video_url_parse );
} else {
//do nothing
}
return $returnstring;
}
parse_str($returnstring);
//now setup your test cases and see what echos out of the above method
if ($returnstring === 'player.vimeo.com') {
echo "vimeo: <" . get_video_embed_string ("https://vimeo.com/abcdefg123") . ">";
} else if ($returnstring === 'youtube.com/embed/'){
echo "youtube: <" . get_video_embed_string ("https://youtube.com/abcdefg123") . ">";
} else if($returnstring === '' ){
echo "nothing: <" . get_video_embed_string ("https://abc123.com/abcdefg123") . ">";
} else {
echo "empty:< " . get_video_embed_string ("") . ">";
}
I think you're on the right track using parse_url, but I have a couple suggestions for improvement:
instead of the run-on if/elseif chain, use a switch
the str_replace isn't working well as is because you're replacing the parsed host, so why spend the overhead searching again for the string to replace when you've already found it.
in the user comments for parse_url, there's an excellent example to reconstruct the parsed url. this will avoid string replacements where the host name is also part of the url (www.youtube.com/youtubevideo123)
simplify your test cases by just calling your function for each case instead of another if/else chain check.
function get_video_embed_string($videostring) {
$video_url_parse = parse_url($videostring); //get the input string ready to parse
switch ($video_url_parse['host']) {
case 'vimeo.com':
$video_url_parse['host'] = 'player.vimeo.com';
return unparse_url($video_url_parse);
case 'youtube.com':
$video_url_parse['host'] = 'youtube.com/embed';
return unparse_url($video_url_parse);
default:
return unparse_url($video_url_parse);
}
}
function unparse_url($parsed_url) {
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
$user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
$pass = ($user || $pass) ? "$pass#" : '';
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
$query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
return "$scheme$user$pass$host$port$path$query$fragment";
}
//now setup your test cases and see what echos out of the above method
echo "vimeo: <" . get_video_embed_string ("https://vimeo.com/abcdefg123") . ">\n";
echo "youtube: <" . get_video_embed_string ("https://youtube.com/abcdefg123") . ">\n";
echo "nothing: <" . get_video_embed_string ("https://abc123.com/abcdefg123") . ">\n";
echo "empty:< " . get_video_embed_string ("") . ">\n";
This will result in the following output in source:
vimeo: <https://player.vimeo.com/abcdefg123>
youtube: <https://youtube.com/embed/abcdefg123>
nothing: <https://abc123.com/abcdefg123>
empty:< >
parse_url() is very good for parsing URLs and - in your case - extract the host name from it.
Your example is a little messed up. $returnstring is not defined outside of your function. You should turn error reporting on, so you will see NOTICE messages on this kind of errors.
I assume, your function should return the video embed url, not only the host name. So you should do your replace on $videostring, not $video_url_parse:
function get_video_embed_string($videostring) {
$video_url_parse = parse_url( $videostring, PHP_URL_HOST ); //get the input string ready to parse
$returnstring = ""; //default return string to empty string
if ($video_url_parse === 'vimeo.com') {
$returnstring = str_replace( 'vimeo.com', 'player.vimeo.com', $videostring );
} else if ($video_url_parse === 'youtube.com') {
$returnstring = str_replace( 'youtube.com', 'youtube.com/embed', $videostring );
} else {
//do nothing
}
return $returnstring;
}
This will give you this output:
echo get_video_embed_string("https://vimeo.com/abcdefg123"); // https://player.vimeo.com/abcdefg123
echo get_video_embed_string("https://youtube.com/abcdefg123"); // https://youtube.com/embed/abcdefg123
echo get_video_embed_string("https://abc123.com/abcdefg123"); // <empty string>
[For a more robust approach, I would probably try to extract the video ID from all known valid URL schemes using regexp and just insert this ID in the embed url.]
I am writing what I thought would be a simple script but I am stuck.
The scenario is that I want to create 2 strings from the GET request.
eg: domain.com/script.php?Client=A12345
In script.php it needs to grab the "Client" and create 2 variables. One is $brand and needs to grab the A or B from the URL. The Other is $id which needs to grab the 12345 from the URL.
Now, after it has these 2 variables $brand and $id it needs to have an if statement to redirect based on the brand like below
if ($brand=="A") {
header('Location: http://a.com');
}
if ($brand=="B") {
header('Location: http://b.com');
At the end of each URL I want to apend the $id though and I am unsure on how to do this.
So for example I would access the script at domain.com/script?Client=A1234 and it needs to redirect me to a.com/12345
Thanks in advance!
$fullCode = $_REQUEST['Client'];
if(strpos($fullCode, 'A') !== false) {
$exp = explode('A',$fullcode);
header('Location: http://a.com/' . $exp[1]);
}
else if(strpos($fullCode, 'B') !== false) {
$exp = explode('B',$fullcode);
header('Location: http://b.com/' . $exp[1]);
}
else {
die('No letter occurence');
}
You can easily do,
$value = $_GET['Client'];
$brand = substr($value, 0, 1);
$rest = substr($value, 1, strlen($brand)-1);
now you have the first character in $brand string and you can do the if statement and redirect the way you want...
You mean like this?
Notice: this will only work if brand is just 1 character long. If that's not the case, please give better examples.
<?php
$client = $_GET['Client'];
$brand = strtolower(substr($client, 0, 1));
$id = substr($client, 1);
if ($brand == 'a')
{
header("Location: http://a.com/$id");
}
elseif ($brand == 'b')
{
header("Location: http://b.com/$id");
}
?>
Try using:
preg_match("/([A-Z])(\d*)/",$_GET['Client'],$matches);
$matches[1] will contain the letter and $matches[2] will contain your id.
Then you can use:
if ($matches[1]=="A")
{
header('Location: http://a.com/{$matches[2]}');
}
if ($matches[1]=="B")
{
header('Location: http://b.com/{$matches[2]}');
}
suggest you could also try
$requested = $_GET["Client"];
$domain = trim(preg_replace('/[^a-zA-Z]/',' ', $requested)); // replace non-alphabets with space
$brand = trim(preg_replace('/[a-zA-Z]/',' ', $requested)); // replace non-numerics with space
$redirect_url = 'http://' . $domain . '/' . $brand;
header('Location:' . $redirect_url);
but it'd be better if you could get the domain name and brand as two individual parameters and sanitize them individually before redirecting them to prevent the overhead of extracting them from a single parameter.
Note: this expression might be useless when the domain name itself has numerics and because the Client is obtained through get a good deal of validation and sanitation would be required in reality.
$brand = strtolower($_GET['Client'][0]);
$id = substr($_GET['Client'], 1);
header("Location: http://{$brand}.com/{$id}");
If for some purpose you want to use explode, then you need to have a separator.
Let's take '_' as the separator, so your example would be something like this: domain.com/script.php?Client=A_12345
$yourstring = explode("_",$_GET["Client"]);
echo $yourstring[0];
//will output A
echo $yourstring[1];
//will output 12345
//your simple controller could be something like this
switch($yourstring[0]){
case: 'A':
header('Location: http://a.com?id='.$yourstring[1]);
exit();
break;
case: 'B':
header('Location: http://b.com?id='.$yourstring[1]);
exit();
break;
default:
//etc
}