How to use and parse custom user input variables %var% with PHP? - php

I want to enter some news into my website and enter a variable like %custom_heading% and get PHP to replace this with the custom heading I have set, this allows me to enter it in wherever I want, how would I go about doing this?
Update: Thanks this helped a lot :) Already in my code now.

Very simple use str_replace on the string...
$vars = array(
'name' => 'Joe',
'age' => 10
);
$str = 'Hello %name% you are %age% years old!';
foreach ($vars as $key => $value) {
$str = str_replace('%' . $key . '%', $value, $str);
}
echo $str; // Hello Joe you are 10 years old!

Related

PHP - How to change specific word in string using array [duplicate]

This question already has an answer here:
Replace templates in strings by array values
(1 answer)
Closed 6 years ago.
$str = "Hello {{name}} welcome to {{company_name}}";
$array = ['name' => 'max', 'company_name' => 'Stack Exchange'];
how to replace {{name}} and {{company_name}} using array value. any php function that return output like
Hello max welcome to Stack Exchange
First create a new array with your search fields, wrapped in curly braces:
$searchArray = array_map(function($value) {
return "{{" . $value . "}}";
}, array_keys($array));
Now you have an array with the tokens you are searching for, and you already have an array of values you want to replace the tokens with.
So just do a simple str_replace:
echo str_replace($searchArray, $array, $str);
Working example: https://3v4l.org/8tPZt
Here's a tidy little function put together:
function fillTemplate($templateString, array $searchReplaceArray) {
return str_replace(
array_map(function($value) { return "{{" . $value . "}}"; }, array_keys($searchReplaceArray)),
$searchReplaceArray,
$templateString
);
}
Now you can call it like this:
echo fillTemplate(
"Hello {{name}} welcome to {{company_name}}",
['name' => 'max', 'company_name' => 'Stack Exchange']
);
// Hello max welcome to Stack Exchange
Example: https://3v4l.org/rh0KX
Checkout this nice function of PHP: http://php.net/manual/de/function.strtr.php
You can find there examples and explanation of it.
$str = "Hello {{name}} welcome to {{company_name}}";
$array = ['{{name}}' => 'max', '{{company_name}}' => 'Stack Exchange'];
print strtr ($str, $array);

Error parsing regex pattern in php

I want to split a string such as the following (by a divider like '~##' (and only that)):
to=enquiry#test.com~##subject=test~##text=this is body/text~##date=date
into an array containing e.g.:
to => enquiry#test.com
subject => test
text => this is body/text
date => date
I'm using php5 and I've got the following regex, which almost works, but there are a couple of errors and there must be a way to do it in one go:
//Split the string in the url of $text at every ~##
$regexp = "/(?:|(?<=~##))(.*?=.*?)(?:~##|$|\/(?!.*~##))/";
preg_match_all($regexp, $text, $a);
//$a[1] is an array containing var1=content1 var2=content2 etc;
//Now create an array in the form [var1] = content, [var2] = content2
foreach($a[1] as $key => $value) {
//Get the two groups either side of the equals sign
$regexp = "/([^\/~##,= ]+)=([^~##,= ]+)/";
preg_match_all($regexp, $value, $r);
//Assign to array key = value
$val[$r[1][0]] = $r[2][0]; //e.g. $val['subject'] = 'hi'
}
print_r($val);
My queries are that:
It doesn't seem to capture more than 3 different sets of parameters
It is breaking on the # symbol and so not capturing email addresses e.g. returning:
to => enquiry
subject => test
text => this is body/text
I am doing multiple different regex searches where I suspect I would be able to do one.
Any help would be really appreciated.
Thanks
Why are you using regex when there is much simple method to do this by explode like this
$str = 'to=enquiry#test.com~##subject=test~##text=this is body/text~##date=date';
$array = explode('~##',$str);
$finalArr = array();
foreach($array as $val)
{
$tmp = explode('=',$val);
$finalArr[$tmp['0']] = $tmp['1'];
}
echo '<pre>';
print_r($finalArr);

One regex, multiple replacements [duplicate]

This question already has answers here:
Parse through a string php and replace substrings
(2 answers)
Closed 9 years ago.
OK, that's what I need :
Get all entries formatted like %%something%%, as given by the regex /%%([A-Za-z0-9\-]+)%%/i
Replace all instances with values from a table, given the index something.
E.g.
Replace %%something%% with $mytable['something'], etc.
If it was a regular replacement, I would definitely go for preg_replace, or even create an array of possible replacements... But what if I want to make it a bit more flexible...
Ideally, I'd want something like preg_replace($regex, $mytable["$1"], $str);, but obviously it doesn't look ok...
How should I go about this?
Code:
<?php
$myTable = array(
'one' => '1!',
'two' => '2!',
);
$str = '%%one%% %%two%% %%three%%';
$str = preg_replace_callback(
'#%%(.*?)%%#',
function ($matches) use ($myTable) {
if (isset($myTable[$matches[1]]))
return $myTable[$matches[1]];
else
return $matches[0];
},
$str
);
echo $str;
Result:
1! 2! %%three%%
if you don't want to tell upper from lower,
<?php
$myTable = array(
'onE' => '1!',
'Two' => '2!',
);
$str = '%%oNe%% %%twO%% %%three%%';
$str = preg_replace_callback(
'#%%(.*?)%%#',
function ($matches) use ($myTable) {
$flipped = array_flip($myTable);
foreach ($flipped as $v => $k) {
if (!strcasecmp($k, $matches[1]))
return $v;
}
return $matches[1];
},
$str
);
echo $str;

Replacing Placeholder Variables in a String

Just finished making this function. Basically it is suppose to look through a string and try to find any placeholder variables, which would be place between two curly brackets {}. It grabs the value between the curly brackets and uses it to look through an array where it should match the key. Then it replaces the curly bracket variable in the string with the value in the array of the matching key.
It has a few problems though. First is when I var_dump($matches) it puts puts the results in an array, inside an array. So I have to use two foreach() just the reach the correct data.
I also feel like its heavy and I've been looking over it trying to make it better but I'm somewhat stumped. Any optimizations I missed?
function dynStr($str,$vars) {
preg_match_all("/\{[A-Z0-9_]+\}+/", $str, $matches);
foreach($matches as $match_group) {
foreach($match_group as $match) {
$match = str_replace("}", "", $match);
$match = str_replace("{", "", $match);
$match = strtolower($match);
$allowed = array_keys($vars);
$match_up = strtoupper($match);
$str = (in_array($match, $allowed)) ? str_replace("{".$match_up."}", $vars[$match], $str) : str_replace("{".$match_up."}", '', $str);
}
}
return $str;
}
$variables = array("first_name"=>"John","last_name"=>"Smith","status"=>"won");
$string = 'Dear {FIRST_NAME} {LAST_NAME}, we wanted to tell you that you {STATUS} the competition.';
echo dynStr($string,$variables);
//Would output: 'Dear John Smith, we wanted to tell you that you won the competition.'
I think for such a simple task you don't need to use RegEx:
$variables = array("first_name"=>"John","last_name"=>"Smith","status"=>"won");
$string = 'Dear {FIRST_NAME} {LAST_NAME}, we wanted to tell you that you {STATUS} the competition.';
foreach($variables as $key => $value){
$string = str_replace('{'.strtoupper($key).'}', $value, $string);
}
echo $string; // Dear John Smith, we wanted to tell you that you won the competition.
I hope I'm not too late to join the party — here is how I would do it:
function template_substitution($template, $data)
{
$placeholders = array_map(function ($placeholder) {
return strtoupper("{{$placeholder}}");
}, array_keys($data));
return strtr($template, array_combine($placeholders, $data));
}
$variables = array(
'first_name' => 'John',
'last_name' => 'Smith',
'status' => 'won',
);
$string = 'Dear {FIRST_NAME} {LAST_NAME}, we wanted to tell you that you have {STATUS} the competition.';
echo template_substitution($string, $variables);
And, if by any chance you could make your $variables keys to match your placeholders exactly, the solution becomes ridiculously simple:
$variables = array(
'{FIRST_NAME}' => 'John',
'{LAST_NAME}' => 'Smith',
'{STATUS}' => 'won',
);
$string = 'Dear {FIRST_NAME} {LAST_NAME}, we wanted to tell you that you have {STATUS} the competition.';
echo strtr($string, $variables);
(See strtr() in PHP manual.)
Taking in account the nature of the PHP language, I believe that this approach should yield the best performance from all listed in this thread.
EDIT: After revisiting this answer 7 years later, I noticed a potentially dangerous oversight on my side, which was also pointed out by another user. Be sure to give them a pat on the back in the form of an upvote!
If you are interested in what this answer looked like before this edit, check out the revision history
I think you can greatly simplify your code, with this (unless I'm misinterpreting some of the requirements):
$allowed = array("first_name"=>"John","last_name"=>"Smith","status"=>"won");
$resultString = preg_replace_callback(
// the pattern, no need to escape curly brackets
// uses a group (the parentheses) that will be captured in $matches[ 1 ]
'/{([A-Z0-9_]+)}/',
// the callback, uses $allowed array of possible variables
function( $matches ) use ( $allowed )
{
$key = strtolower( $matches[ 1 ] );
// return the complete match (captures in $matches[ 0 ]) if no allowed value is found
return array_key_exists( $key, $allowed ) ? $allowed[ $key ] : $matches[ 0 ];
},
// the input string
$yourString
);
PS.: if you want to remove placeholders that are not allowed from the input string, replace
return array_key_exists( $key, $allowed ) ? $allowed[ $key ] : $matches[ 0 ];
with
return array_key_exists( $key, $allowed ) ? $allowed[ $key ] : '';
Just a heads up for future people who land on this page: All the answers (including the accepted answer) using foreach loops and/or the str_replace method are susceptible to replacing good ol' Johnny {STATUS}'s name with Johnny won.
Decent Dabbler's preg_replace_callback approach and U-D13's second option (but not the first) are the only ones currently posted I see that aren't vulnerable to this, but since I don't have enough reputation to add a comment I'll just write up a whole different answer I guess.
If your replacement values contain user-input, a safer solution is to use the strtr function instead of str_replace to avoid re-replacing any placeholders that may show up in your values.
$string = 'Dear {FIRST_NAME} {LAST_NAME}, we wanted to tell you that you {STATUS} the competition.';
$variables = array(
"first_name"=>"John",
// Note the value here
"last_name"=>"{STATUS}",
"status"=>"won"
);
// bonus one-liner for transforming the placeholders
// but it's ugly enough I broke it up into multiple lines anyway :)
$replacement = array_combine(
array_map(function($k) { return '{'.strtoupper($k).'}'; }, array_keys($variables)),
array_values($variables)
);
echo strtr($string, $replacement);
Outputs: Dear John {STATUS}, we wanted to tell you that you won the competition.
Whereas str_replace outputs: Dear John won, we wanted to tell you that you won the competition.
This is the function that I use:
function searchAndReplace($search, $replace){
preg_match_all("/\{(.+?)\}/", $search, $matches);
if (isset($matches[1]) && count($matches[1]) > 0){
foreach ($matches[1] as $key => $value) {
if (array_key_exists($value, $replace)){
$search = preg_replace("/\{$value\}/", $replace[$value], $search);
}
}
}
return $search;
}
$array = array(
'FIRST_NAME' => 'John',
'LAST_NAME' => 'Smith',
'STATUS' => 'won'
);
$paragraph = 'Dear {FIRST_NAME} {LAST_NAME}, we wanted to tell you that you {STATUS} the competition.';
// outputs: Dear John Smith, we wanted to tell you that you won the competition.
Just pass it some text to search for, and an array with the replacements in.
/**
replace placeholders with object
**/
$user = new stdClass();
$user->first_name = 'Nick';
$user->last_name = 'Trom';
$message = 'This is a {{first_name}} of a user. The user\'s {{first_name}} is replaced as well as the user\'s {{last_name}}.';
preg_match_all('/{{([0-9A-Za-z_]+)}}/', $message, $matches);
foreach($matches[1] as $match)
{
if(isset($user->$match))
$rep = $user->$match;
else
$rep = '';
$message = str_replace('{{'.$match.'}}', $rep, $message);
}
echo $message;

Regex preg_replace for emoticons [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Replace a list of emoticons with their images
i'm developing a website where i want to give users possibility to put smiles on posts.
My (just functional) idea is to use array in this way:
$emoticons = array(
array("17.gif",":)"),
array("6.jpg",":P"),
.....
array("9.jpg",":'("),
array("5.gif","X)")
);
with image on [0] and emoticon on [1].
And on each $post:
foreach($emoticons as $emoticon){
$quoted_emoticon = preg_quote($emoticon[1],"#");
$match = '#(?!<\w)(' . $quoted_emoticon .')(?!\w)#';
$post = preg_replace($match,'<img src="images/emoticons/'.$emoticon[0].'">',$post);
}
This is working good, but my problem is '#(?!<\w)(' and ')(?!\w)#' because I want emoticons to apply only when preceding characters are "begin" (^) or "blank" and succeeding characters are "end" ($) or "blank". What is the right regex to do this?
I think you want the positive look behind and positive look ahead.
Example:
(?<=\s|^)(\:\))(?=\s|$)
Your example updated:
foreach($emoticons as $emoticon){
$quoted_emoticon = preg_quote($emoticon[1],"#");
$match = '(?<=\s|^)(' . $quoted_emoticon .')(?=\s|$)';
$post = preg_replace($match,'<img src="images/emoticons/'.$emoticon[0].'">',$post);
}
I would go with:
$e = array( ':)' => '1.gif',
':(' => '2.gif',
);
foreach ($e as $sign => $file) {
$sign = preg_replace('/(.)/', "\\$1", $sign);
$pattern = "/(?<=\s|^)$sign(?=\s|$)/";
$post = preg_replace($pattern, " <img src=\"images/emoticons/$file\">", $post);
}

Categories