In $var there is some code. I'm trying to operate a nl2br() on text inside each <p></p>.
echo preg_replace('/<p>(.*?)</p>/i', nl2br('${1}'), $var);
This code doesn't work.
How do I fix this?
You probably need to escape <\/p>
It looks like preg_replace_callback might be what you're looking for: http://us3.php.net/manual/en/function.preg-replace-callback.php
ETA: In your specific example, you could either use an anonymous function (only if you're doing this once or twice, otherwise it eats up memory) or define a helper function
function nl2br_wrapper($matches)
{
return "<p>".nl2br($matches[1])."</p>";
}
preg_replace_callback('/<p>(.*?)<\/p>/si', "nl2br_wrapper", $var);
Like kernal mentions you could use an anonymous function(PHP 5)
function replaceText($data, $html)
{
$callback = function ($matches) use ($data){
return ( isset($data[$matches[1]]) )
? nl2br($data[$matches[1]])
: $matches[0];
};
return preg_replace_callback(
'/\<p>(.*?)\</p>',
$callback,
$html);
}
echo replaceText($replace_with, $html);
Related
I'm working on implementation of a CMS and want to include functionality similar to how word press uses short codes, but I am having trouble replacing the "shortcode" with the function callback.
I'm using the below regex to find all "shortcodes" in the code and it works, I just can't figure out how to go about replacing it with function callbacks.
Regex: /[([^]]*)]/
What I have so far(not working)
function runShortcodes($input){
return preg_replace_callback(
'/\[([^\]]*)\]/', function ($matches)
{
$function = $matches[1];
ob_start();
$function();
$return = ob_get_contents();
ob_end_clean();
return $return;
}, $input
);
}
function event(){
return 'it worked';
}
echo runShortcodes('test [event]');
Right now i'm just trying to replace the [event] with the return data of the event function.
As you are using output buffering to capture the value from the short code function, you will need to actually output something from the event() function...
function event(){
return 'it worked';
}
just passes the value back, try...
function event(){
echo 'it worked';
}
Or remove the output buffering and just return the value from the short code...
function runShortcodes($input){
return preg_replace_callback(
'/\[([^\]]*)\]/', function ($matches)
{
$function = $matches[1];
return $function();
}, $input
);
}
function event(){
return 'it worked';
}
echo runShortcodes('test [event]');
I have created function
function do_stuff($text) {
$new_text = nl2br($text);
return $new_text;
}
$result = do_stuff("Hello \n World!");
//returns "Hello <br /> World!"
I want to be able to supply another simple built in PHP function e.g. strtoupper() inside my function somehow, its not just strtoupper() that i need, i need ability to supply different functions into my do_stuff() function.
Say i want to do something like this.
$result = do_stuff("Hello \n World!", "strtolower()");
//returns "Hello <br /> World!"
How would i make this work without creating another function.
function do_stuff($text, $sub_function='') {
$new_text = nl2br($text);
$sub_function($new_text);
return $new_text;
}
$result = do_stuff("Hello \n World!");
//returns "Hello <br /> World!"
P.S. Just remembered variable variables, and googled, there's actually is Variable functions too, might answer this one myself.
http://php.net/manual/en/functions.variable-functions.php
You have it in your second example. Just make sure to check that it exists and then assign the return to the string. There is an assumption here about what the function accepts/requires as args and what it returns:
function do_stuff($text, $function='') {
$new_text = nl2br($text);
if(function_exists($function)) {
$new_text = $function($new_text);
}
return $new_text;
}
$result = do_stuff("Hello \n World!", "strtoupper");
Callables can be strings, arrays with a specific format, instances of the Closure class created using the function () {};-syntax and classes implementing __invoke directly. You can pass any of these to your function and call them using $myFunction($params) or call_user_func($myFunction, $params).
Additionally to the string examples already given in other answers you may also define a (new) function (closure). This might be especially beneficial if you only need the contained logic in one place and a core function is not suitable. You can also wrap paramters and pass additional values from the defining context that way:
Please be aware that the callable typehint requires php 5.4+
function yourFunction($text, callable $myFunction) { return $myFunction($text); }
$offset = 5;
echo yourFunction('Hello World', function($text) use($offset) {
return substr($text, $offset);
});
Output: http://3v4l.org/CFMrI
Documentation hints to read on:
http://php.net/manual/en/functions.anonymous.php
http://php.net/manual/en/language.types.callable.php
You can call a function like this:
$fcn = "strtoupper";
$fcn();
in the same way (as you found out yourself), you can have variable variables:
$a = "b";
$b = 4;
$$a; // 4
Looks like you're almost there, just need to leave off the parentheses in the second parameter:
$result = do_stuff("Hello \n World!", "strtolower");
Then this should work after a little cleanup:
function do_stuff($text, $sub_function='') {
$new_text = nl2br($text);
if ($sub_function) {
$new_text = $sub_function($new_text);
}
return $new_text;
}
How can I call a function within preg_replace()?
$template = '<div> [BILD="123"][BILD="246"] </div>';
$pat = '/\[BILD="(.*?)"\]\[BILD ="(.*?)"\]/';
$ret = getImageArea($id, $config, '$1', '$2');
return preg_replace($pat, $rep, $template);
It fails opening the function and doesn't sends 123 or 246.
It just sends $1 and $2.
As I (and many others) told in comments, you have to use preg_replace_callback in this case. One possible approach:
$template = '<div> [BILD="123"][BILD="246"] </div>';
$pat = '/\[BILD="(.*?)"\]\[BILD="(.*?)"\]/';
return preg_replace_callback($pat, function($matches) use($id, $config) {
return getImageArea($id, $config, $matches[1], $matches[2]);
}, $template);
Demo. As you see, it's quite straight-forward; the only catch is making $id and $config variables available inside the callback (which is done with use op).
This does not work
$check["pattern"] = "/correct/";
$callback = "function ($m) { return ucfirst($m[0]);}";
echo preg_replace_callback($check["pattern"],$callback,"correct" );
output: correct
This works
$check["pattern"] = "/correct/";
echo preg_replace_callback($check["pattern"],function ($m) { return ucfirst($m[0]);},"correct" );
output: Correct
Why, and how to make it work with the function stored inside a var? :)
Why would you want to do that? I see no reason to store the function inside a variable, to be honest. Nevertheless, if you really want to do this, take a look at create_function:
<?php
$check["pattern"] = "/correct/";
$callback = create_function('$m', 'return ucfirst($m[0]);');
echo preg_replace_callback( $check['pattern'], $callback, "correct" );
// Output: "Correct"
If you do a var_dump on $callback = "function ($m) { return ucfirst($m[0]);}"; the result is a string. In the working situation you pass a Closure (anonymous function) as callback.
The manual is clear: a Closure is allowed, if you pass a string, it must be the name of a function.
Is this anywhere near something acceptable? I need a function for each HTML tag, and they need to be defined for later use in a Heredoc string. This is my code so far.
<?php
$tags = array (h1, h2, h3, b, i);
foreach ($tags as $key => $value)
{
eval ('function '.$value.' ($str) { return "<'.$value.'>$str</'.$value.'>"; }');
}
This basically takes care of the Heredoc problem concerning functions within heredoc. A quick example:
<<<example
<h1>This is ordinary HTML</h1>
{$h1('This is HTML via. PHP')}
example;
I did all the code over by heart, so please don't be suprised if they contain any errors. I haven't executed the eval-function yet, but it looks alright. Anyway, my question would be: Is this okay, or is it better to go do it the hard-way:
function h1 ($str) { return ...; }
function h2 ($str) { return ...; }
function h3 ($str) { return ...; }
function b ($str) { return ...; }
function i ($str) { return ...; }
And so on ..?
You could use the create_function provided by PHP but...Since the code is simple why not just use one function to rule them all?
function createTag($tag, $text) {
return "<{$tag}>{$text}</{$tag}>";
}
Should do what you are after.
As an after thought, you might want to check out the PHP DOM as that would probably be the route to go, but will take some time to learn and get used to using it.
If you could live with a more elaborate:
<h1>This is ordinary HTML</h1>
{$h->h1("This is HTML via PHP.")}
Then it would suffice to define a single:
class html {
function __call($name, $args) {
return "<$name>$args[0]</$name>";
}
}
$h = new html();
Would be faster than multiple eval roundtrips to define functions.
If you're going to use an ugly hack anyway, I'd much rather do:
function create_html($tag, $val) {
return "<{$tag}>{$val}</{$tag}>";
}
$html = 'create_html';
<<<example
<h1>Test</h1>
{$html('h2','Another test')}
example;
If you're on PHP 5.3, you could use closures. Far superior to create_function. Avoid eval().