tags:

views:

41

answers:

2

The Function:

function doSomething($url){
    $url = "<a href=\"{$url}\" target=\"blank\" title=\"{$url}\">{$url}</a>";
    return $url;
}

The replacement

$content = preg_replace("#(http:\/\/+[^\s]+)#ie","doSomething('$1')", $content);

The Problem:

Fatal error: Cannot redeclare doSomething() (previously declared in http://example.com/test.php:69) in http://example.com/test.php on line 69

Note: The current function does not represent my real function, I know that for this situation I don't need any functions but in my real code I need. But this is a better example also.

A: 

Well... error message says the problem. You have a declaration for doSomething() function several times.

Check out line 69 of test.php and try to comment declaration.

Otar
@Otar I don't use more than once `doSomething()`. I think the problem comes for the `e` modifier which enables `preg_replace` to use the function multiple times, but I don't know how to fix it.
CIRK
the problem is obviously not that `doSomething()` is declared more than once, since the error message says that it's declared twice on the same line, i.e. the line with `preg_replace()`
Frxstrem
@Frxstrem: how do you know the error is on the same line as the preg_replace()?
hopeseekr
@hopeseekr: okay, I do not exactly know, but since the first declaration and the second declaration are on the same line, I assumed it was not because of a double declaration, which from my point of view seems like a pretty good assumption too. double declarations happen **very rarely** on the same line
Frxstrem
@Frxstrem nice idea :)
CIRK
@Frxstrem - Double declarations happen very rarely on the same line, unless a file with a function declaration is included twice in another file.
Peter Ajtai
+3  A: 

Well, it's because the function was already defined in a prior function call (That's the danger in declaring a function inside of another function). There are a few options.

Conditionally declaring the function

if (!function_exists('doSomething')) {
    function doSomething($url)...
}

Declaring an anonymous function:

PHP 5.3+ :

$callback = function($url) {
    //...
}

PHP 5.2+ :

$callback = create_function('$url', '//...');

Using a class:

class foo {
    public function doReplace($string) {
        $callback = array($this, 'doSomething');
        // Do your matching here
    }
    public function doSomething($url) {
        //...
    }
}

Also, I'd suggest not using the e modifier for the regex (it's just not necessary, and it's basically just eval, which is typically seen as evil). You should instead just use preg_replace_callback:

Assuming $callback is a valid callback:

$callback = function($match) {
    $url = $match[1];
    //... Do stuff here
}
$string = preg_replace_callback($regex, $callback, $string);
ircmaxell
@ircmaxell Hi! Thanks very much for your answer! I think this will help me a lot.
CIRK
I have PHP 5.3 but I get this error `Catchable fatal error: Object of class Closure could not be converted to string in example.com/test.php on line 83` Also I have `Dreamweaver CS5` what highlights the anonymous function as invalid. I've read this http://www.php.net/manual/en/functions.anonymous.php and I made it as it writes but I don't know what is the problem :S
CIRK
Like I said, don't use the `e` modifier, and pass the callback as a varaible to `preg_replace_callback`: `$string = preg_replace_callback($regex, $callback, $string);` where `$callback` is the anonymous function directly. There's no need to cast anything to objects... And I would suggest getting a decent IDE for writing PHP (Dreamweaver is not a development environment)...
ircmaxell
The replacement: `$content = preg_replace_callback("#(http:\/\/+[^\s]+)#i", $do('$1'), $content);` The function: `$do = function($url){ $url = "<a href=\"{$url}\" target=\"blank\" title=\"{$url}\">{$url}</a>"; return $url; };` the error: `Warning: preg_replace_callback() [function.preg-replace-callback]: Requires argument 2, '<a href="$1" target="blank" title="$1">$1</a>', to be a valid callback in C:\wamp\www\includes\all_news.php on line 83`
CIRK
You don't need to add the `('$1')` to the `$do` variable... You should just do: `$do = function($match){ $url = $match[1]; $url = "<a href=\"{$url}\" target=\"blank\" title=\"{$url}\">{$url}</a>"; return $url; };` And then call it with `$content = preg_replace_callbac($regex, $do, $content);`...
ircmaxell
Jesus!! You are a fucking genius!!! :D AAAAAAAAA, I'm so happy!! It works :D but I don't understand how :O the `$do` will contain the regex's `$1` `$2` etc.. because of the `preg_replace_callback` or what?
CIRK
`$do` is just a [callback](http://us3.php.net/manual/en/language.pseudo-types.php#language.types.callback). The function it "points" to gets called for each match with the match array as the first parameter (A native PHP array, with `0` matching the entire match, `1` being the first sub-pattern, etc)... Take a read through the `preg_replace_callback` docs that I linked to in my answer for more info on what's going on...
ircmaxell
Thanks very much for your help!! Blessing to you! :D
CIRK