Link to home
Start Free TrialLog in
Avatar of Aidam-Unlimited
Aidam-UnlimitedFlag for United Kingdom of Great Britain and Northern Ireland

asked on

PHP Article Spinner - echo each variation just once

Hi guys,

below PHP code spins the article with variations and echo them.

Originally posted on
http://www.paul-norman.co.uk/2009/06/spin-text-for-seo/

How it works
It just turns for example this
{Hello|Hi}, how are you?

into two sentences

Hello, how are you?
Hi, how are you?

Problem
Often it echoes two or more same variations.
Hello, how are you?
Hello, how are you?

Solution?
Does anybody have an idea how to make the script produce each variation just once?

Thanks in advance!
Adam
<!-- spin.php -->
<?
function spin($string, $seedPageName = true, $calculate = false, $openingConstruct = '{', $closingConstruct = '}')
{
    # Choose whether to return the string or the number of permutations
    $return = 'string';
    if($calculate)
    {
        $permutations   = 1;
        $return         = 'permutations';
    }

    # If we have nothing to spin just exit (don't use a regexp)
    if(strpos($string, $openingConstruct) === false)
    {
        return $$return;
    }
    
    if(preg_match_all('!'.$openingConstruct.'(.*?)'.$closingConstruct.'!s', $string, $matches))
    {
        # Optional, always show a particular combination on the page
        if($seedPageName)
        {
            mt_srand(crc32($_SERVER['REQUEST_URI']));
        }

        $find       = array();
        $replace    = array();

        foreach($matches[0] as $key => $match)
        {
            $choices = explode('|', $matches[1][$key]);

            if($calculate)
            {
                $permutations *= count($choices);
            }
            else
            {
                $find[]     = $match;
                $replace[]  = $choices[mt_rand(0, count($choices) - 1)];
            }
        }

        if(!$calculate)
        {
            # Ensure multiple instances of the same spinning combinations will spin differently
            $string = str_replace_first($find, $replace, $string);
        }
    }

    return $$return;
}

# Similar to str_replace, but only replaces the first instance of the needle
function str_replace_first($find, $replace, $string)
{
    # Ensure we are dealing with arrays
    if(!is_array($find))
    {
        $find = array($find);
    }

    if(!is_array($replace))
    {
        $replace = array($replace);
    }

    foreach($find as $key => $value)
    {
        if(($pos = strpos($string, $value)) !== false)
        {
            # If we have no replacement make it empty
            if(!isset($replace[$key]))
            {
                $replace[$key] = '';
            }

            $string = mb_substr($string, 0, $pos).$replace[$key].mb_substr($string, $pos + mb_strlen($value));
        }
    }

    return $string;
}
?>

<!-- example.php -->

<?
require('spin.php');
?>
<form action="example.php">
<textarea name="text" rows="18" cols="100"><? echo $_GET['text']; ?></textarea>
<input type="submit">
</form>
<?
$string = $_GET['text'];

echo '<p><b>'.spin($string, false, true).'</b> permutations...</p><p>';

$times = spin($string, false, true);

echo "<p>";
for($i = 1; $i <= $times; $i++)
{
echo spin($string, false).'<br />';
}

echo '</p>';
?>

Open in new window

Avatar of 50cal
50cal
Flag of United Kingdom of Great Britain and Northern Ireland image

Avatar of Aidam-Unlimited

ASKER

Thanks, that look interesting but is there any way how to do it without session?
If you're just choosing to randomly select a set of strings, wouldn't this function be better?

You use it like this:
$haystack = "This is my haystack, I said it's my haystack!";
$spin = array("is" => "are", "haystack" => "bunches");
spin($haystack, $spin);

Make a multidim array of stuff you want to change like
"is" => "are"

That changes 'is' to 'are.'

Let me know if you have any questions.
function spin($haystack, $spin) {

  if (is_string($haystack) && is_array($spin)) {

    foreach ($spin as $key => $value) {

      $haystack = preg_replace("/$key/", $value, $haystack);

    }

    echo $haystack;

  }

}

$haystack = "This is my haystack, I said it's my haystack!";
$spin = array("is" => "are", "haystack" => "bunches");
spin($haystack, $spin);

Open in new window

EMB01 thanks for your post but I'm afraid I don't understand how it solves my problem? Could you please explain in relation to the original code posted on the top.

Many thanks
Sorry if I misunderstood your original post, but I thought you wanted a script that you would replace:
Hello, how are you?
With:
Hi, how are you?

To do this, you would use my function as follows:
$haystack = "Hello, how are you?";
$spin = array("Hello" => "Hello, Hi");
spin($haystack, $spin);

I updated the function to support multiple spins.  See below for code and please let me know if you have any more questions.
function spin($haystack, $spin) {

  if (is_string($haystack) && is_array($spin)) {

    foreach ($spin as $key => $value) {

      $array = explode(",",$value);

      $rand = rand(0, sizeof($array)-1);

      $replacement = $array[$rand];

      var_dump($array);

      $haystack = preg_replace("/$key/", $replacement, $haystack);

    }

    echo $haystack;

  }

}

$haystack = "Hello, how are you?";
$spin = array("Hello" => "Hello, Hi");
spin($haystack, $spin);

Open in new window

Note:  The code will not just replace "hello" with "hi", it will (at random) replace Hello with hello, hi, etc.  You could do this, for example:
$haystack = "Hello, how are you?";
$spin = array("Hello" => "Hello, Hi, how are you, nice to meet you");
spin($haystack, $spin);

And, the code would produce results like (one per each run):
Hello, how are you?";
how are you, how are you?";
Hi, how are you?";
nice to meet you, how are you?";
etc.
EMB01, sorry let me clarify my case.

To get exact idea how script works please click:
http://test.adamhusar.com/example.php?text={Hello|Hi},+how+are+you%3F+{Im|Were}+fine,+thanks.

and you'll see sometimes it gets duplicate combinations and sometimes not.

I'd like to find a way how to prevent script to echo duplicate variations.
URL once again.
http://test.adamhusar.com/example.php?text={Hello|Hi},+how+are+you%3F+{Im|Were}+fine,+thanks.

Open in new window

I'm saying you should just use my code.  I modified my code fit your custom syntax.  I haven't tested it.  Let me know how it works.
<!-- spin.php -->
<?
function spin($haystack, $spin) {

  if (is_string($haystack) && is_array($spin)) {

    foreach ($spin as $key => $value) {

      $array = explode(",",$value);

      $rand = rand(0, sizeof($array)-1);

      $replacement = $array[$rand];

      var_dump($array);

      $haystack = preg_replace("/$key/", $replacement, $haystack);

    }

    echo $haystack;

  }

}

?>

<!-- example.php -->

<?
require('spin.php');
?>
<form action="example.php">
<textarea name="text" rows="18" cols="100"><? echo $_GET['text']; ?></textarea>
<input type="submit">
</form>
<?
$string = $_GET['text'];

echo '<p><b>'.spin($string, false, true).'</b> permutations...</p><p>';

preg_match_all("/\{.*\}/", $string, $matches);

// testing
echo "preg_match:<br />";
var_dump($matches);

foreach ($matches as $match) {

  $match = preg_replace("/|/", ",", $match);

  $replacements[] = $match;

}

// testing
echo "<br />replacements:<br />";
var_dump($replacements);

// however many times you want...
$times = 4;

echo "<p>";
for($i = 1; $i <= $times; $i++)
{
spin($string, $replacements).'<br />';
}

echo '</p>';
?>

Open in new window

I don't understand, it gives following output:
permutations...

preg_match:
array(1) { [0]=> array(1) { [0]=> string(10) "{hello|hi}" } } 
replacements:
array(1) { [0]=> array(1) { [0]=> string(21) ",{,h,e,l,l,o,|,h,i,}," } }

NULL {hello|hi} dsfdsNULL {hello|hi} dsfdsNULL {hello|hi} dsfdsNULL {hello|hi} dsfds

Open in new window

Thanks for output.  Seldom does my code work on first run!  Try escaping the regex, just use this code:
<!-- spin.php -->
<?
function spin($haystack, $spin) {

  if (is_string($haystack) && is_array($spin)) {

    foreach ($spin as $key => $value) {

      $array = explode(",",$value);

      $rand = rand(0, sizeof($array)-1);

      $replacement = $array[$rand];

      var_dump($array);

      $haystack = preg_replace("/$key/", $replacement, $haystack);

    }

    echo $haystack;

  }

}

?>

<!-- example.php -->

<?
require('spin.php');
?>
<form action="example.php">
<textarea name="text" rows="18" cols="100"><? echo $_GET['text']; ?></textarea>
<input type="submit">
</form>
<?
$string = $_GET['text'];

echo '<p><b>'.spin($string, false, true).'</b> permutations...</p><p>';

preg_match_all("/\{.*\}/", $string, $matches);

// testing
echo "preg_match:<br />";
var_dump($matches);

foreach ($matches as $match) {

  $match = preg_replace("/\|/", ",", $match);

  $replacements[] = $match;

}

// testing
echo "<br />replacements:<br />";
var_dump($replacements);

// however many times you want...
$times = 4;

echo "<p>";
for($i = 1; $i <= $times; $i++)
{
spin($string, $replacements).'<br />';
}

echo '</p>';
?>

Open in new window

It gives the following.

Any idea how to turn it in format like
1. Variation1
2. Variation2
etc...

Thanks
Sorry
preg_match:
array(1) { [0]=> array(1) { [0]=> string(10) "{hello|hi}" } } 
replacements:
array(1) { [0]=> array(1) { [0]=> string(10) "{hello,hi}" } }

NULL {hello|hi}, how are you?NULL {hello|hi}, how are you?

Open in new window

Are you using PHP 4 or 5?  If you're using 4, please try this code.  Otherwise, if your on PHP 5, I'll give you a different code.
<!-- spin.php -->
<?
function spin($haystack, $spin) {

  if (is_string($haystack) && is_array($spin)) {

    foreach ($spin as $key => $value) {

      $array = explode(",",$value);

      $rand = rand(0, sizeof($array)-1);

      $replacement = $array[$rand];

      var_dump($array);

      $haystack = preg_replace("/$key/", $replacement, $haystack);

    }

    echo $haystack;

  }

}

?>

<!-- example.php -->

<?
require('spin.php');
?>
<form action="example.php">
<textarea name="text" rows="18" cols="100"><? echo $_GET['text']; ?></textarea>
<input type="submit">
</form>
<?
$string = $_GET['text'];

echo '<p><b>'.spin($string, false, true).'</b> permutations...</p><p>';

preg_match_all("/\{.*\}/", $string, $matches);

// testing
echo "preg_match:<br />";
var_dump($matches);

function array_combine($arr1,$arr2) { 
   $out = array(); 
   foreach($arr1 as $key1 => $value1)    { 
    $out[$value1] = $arr2[$key1]; 
   } 
   return $out ;
} 
function strstrb($h,$n){
    return strrev(array_pop(explode($n,strrev($h))));
}

foreach ($matches as $match) {

  $match = preg_replace("/\|/", ",", $match);

  $replacements[] = $match;

}

var_dump($replacements);

foreach ($replacements as $replacement) {

  $keys[] = strstrb($replacement, ',', ',');

}

$spin = array_combine($keys, $replacements);

var_dump($spin);

// testing
echo "<br />replacements:<br />";
var_dump($replacements);

// however many times you want...
$times = 4;

echo "<p>";
for($i = 1; $i <= $times; $i++)
{
spin($string, $replacements).'<br />';
}

echo '</p>';
?>

Open in new window

Small change, use this one:
<!-- spin.php -->
<?
function spin($haystack, $spin) {

  if (is_string($haystack) && is_array($spin)) {

    foreach ($spin as $key => $value) {

      $array = explode(",",$value);

      $rand = rand(0, sizeof($array)-1);

      $replacement = $array[$rand];

      var_dump($array);

      $haystack = preg_replace("/$key/", $replacement, $haystack);

    }

    echo $haystack;

  }

}

?>

<!-- example.php -->

<?
require('spin.php');
?>
<form action="example.php">
<textarea name="text" rows="18" cols="100"><? echo $_GET['text']; ?></textarea>
<input type="submit">
</form>
<?
$string = $_GET['text'];

echo '<p><b>'.spin($string, false, true).'</b> permutations...</p><p>';

preg_match_all("/\{.*\}/", $string, $matches);

// testing
echo "preg_match:<br />";
var_dump($matches);

function array_combine($arr1,$arr2) { 
   $out = array(); 
   foreach($arr1 as $key1 => $value1)    { 
    $out[$value1] = $arr2[$key1]; 
   } 
   return $out ;
} 
function strstrb($h,$n){
    return strrev(array_pop(explode($n,strrev($h))));
}

foreach ($matches as $match) {

  $match = preg_replace("/\|/", ",", $match);

  $replacements[] = $match;

}

var_dump($replacements);

foreach ($replacements as $replacement) {

  $keys[] = strstrb($replacement, ',', ',');

}

$spin = array_combine($keys, $replacements);

var_dump($spin);

// testing
echo "<br />replacements:<br />";
var_dump($replacements);

// however many times you want...
$times = 4;

echo "<p>";
for($i = 1; $i <= $times; $i++)
{
spin($string, $spin).'<br />';
}

echo '</p>';
?>

Open in new window

Another error
Notice: Undefined index: text in /Users/macmini/Sites/example.php on line 9
permutations...

preg_match:
array(1) { [0]=> array(0) { } } array(1) { [0]=> array(0) { } } 
Warning: strrev() expects parameter 1 to be string, array given in /Users/macmini/Sites/example.php on line 27
array(1) { [""]=> array(0) { } } 
replacements:
array(1) { [0]=> array(0) { } }

Open in new window

And
preg_match:
array(1) { [0]=> array(1) { [0]=> string(9) "{hi|helo}" } } array(1) { [0]=> array(1) { [0]=> string(9) "{hi,helo}" } } 
Warning: strrev() expects parameter 1 to be string, array given in /Users/macmini/Sites/example.php on line 27
array(1) { [""]=> array(1) { [0]=> string(9) "{hi,helo}" } } 
replacements:
array(1) { [0]=> array(1) { [0]=> string(9) "{hi,helo}" } }


Warning: explode() expects parameter 2 to be string, array given in /Users/macmini/Sites/spin.php on line 8
NULL {hi|helo} effdf
Warning: explode() expects parameter 2 to be string, array given in /Users/macmini/Sites/spin.php on line 8
NULL {hi|helo} effdf
Warning: explode() expects parameter 2 to be string, array given in /Users/macmini/Sites/spin.php on line 8
NULL {hi|helo} effdf
Warning: explode() expects parameter 2 to be string, array given in /Users/macmini/Sites/spin.php on line 8
NULL {hi|helo} effdf

Open in new window

Okay, so I tested this and it works in my environment.  We need to find out what version of PHP you have.  To do this, please put the following code in a page and tell me what version it says:
<?
phpinfo();
?>
It's Version 5.3.2
K, so try this code, instead.
<!-- spin.php -->
<?
function spin($haystack, $spin) {

  if (is_string($haystack) && is_array($spin)) {

    foreach ($spin as $key => $value) {

      $array = explode(",",$value);

      $rand = rand(0, sizeof($array)-1);

      $replacement = $array[$rand];

      var_dump($array);

      $haystack = preg_replace("/$key/", $replacement, $haystack);

    }

    echo $haystack;

  }

}

?>

<!-- example.php -->

<?
require('spin.php');
?>
<form action="example.php">
<textarea name="text" rows="18" cols="100"><? echo $_GET['text']; ?></textarea>
<input type="submit">
</form>
<?
$string = $_GET['text'];

echo '<p><b>'.spin($string, false, true).'</b> permutations...</p><p>';

preg_match_all("/\{.*\}/", $string, $matches);

// testing
echo "preg_match:<br />";
var_dump($matches);

foreach ($matches as $match) {

  $match = preg_replace("/\|/", ",", $match);

  $replacements[] = $match;

}

var_dump($replacements);

foreach ($replacements as $replacement) {

  $keys[] = strstr($replacement, ',', true);

}

$spin = array_combine($keys, $replacements);

var_dump($spin);

// testing
echo "<br />replacements:<br />";
var_dump($replacements);

// however many times you want...
$times = 4;

echo "<p>";
for($i = 1; $i <= $times; $i++)
{
spin($string, $spin).'<br />';
}

echo '</p>';
?>

Open in new window

Maybe if you'd test it we'd save a bit of time...?

Cheers!
preg_match:
array(1) { [0]=> array(1) { [0]=> string(9) "{hi|helo}" } } array(1) { [0]=> array(1) { [0]=> string(9) "{hi,helo}" } } 
Warning: strstr() expects parameter 1 to be string, array given in /Users/macmini/Sites/example.php on line 31
array(1) { [""]=> array(1) { [0]=> string(9) "{hi,helo}" } } 
replacements:
array(1) { [0]=> array(1) { [0]=> string(9) "{hi,helo}" } }


Warning: explode() expects parameter 2 to be string, array given in /Users/macmini/Sites/spin.php on line 8
NULL {hi|helo} effdf
Warning: explode() expects parameter 2 to be string, array given in /Users/macmini/Sites/spin.php on line 8
NULL {hi|helo} effdf
Warning: explode() expects parameter 2 to be string, array given in /Users/macmini/Sites/spin.php on line 8
NULL {hi|helo} effdf
Warning: explode() expects parameter 2 to be string, array given in /Users/macmini/Sites/spin.php on line 8
NULL {hi|helo} effdf

Open in new window

I did test it and it works on my end.  I'll have to leave this up to the other experts until I get back.  I have to leave now.  Sorry we could get it to work in time.
No worries, thanks anyway for your time, EMB01!
Avatar of Marco Gasi
Hi. Your question made me mad, but it is almost solved. I rewrote completely your code and I confess I don't like my code: I'm sure there is a more elegant way to accomplish your goal, but... waiting for it, my code works. I post a snippet: simply copy and paste in an empty file to test it. I omitted the seedPage condition (not in decalration but in the code) because it's not so clear what is its function, but I think you can easily reintroduce it if needed.

Hope this helps

Best
<?php
function generateCodes($arr) {
    global $returnArray, $tempArray, $pos;
    if(count($arr)) {
        for($i=0; $i<count($arr[0]); $i++) {
            $tmp = $arr;
            $tempArray[$pos] = $arr[0][$i];
            $tarr = array_shift($tmp);
            $pos++;
            generateCodes($tmp);
        }
    } else {
        $returnArray[] = join("", $tempArray);
    }
    $pos--;
}
function getVariables($string, $seedPageName = true, $calculate = false, $openingConstruct = '{', $closingConstruct = '}'){
    preg_match_all("/(?<=$openingConstruct)[^$closingConstruct]+(?=$closingConstruct)/", $string, $matches);
    foreach($matches[0] as $match){
        $result[] = explode('|', $match);
    }
    if($calculate){
        foreach ($result as $r){
            for($i=0;$i<count($r);$i++){
                $cnt[] = $r[$i];
            }
        }
        $permutations = count($cnt);
        return $permutations;
   }else return $result;
}
function getFixed($string, $seedPageName = true, $calculate = false, $openingConstruct = '{', $closingConstruct = '}'){
    preg_match_all("/(?<=$closingConstruct)[^$openingConstruct]*/", $string, $matches2);
    foreach($matches2[0] as $match2){
        $res2[] = explode('|', $match2);
    }
    foreach ($res2 as $r2){
        for($i=0;$i<count($r2);$i++){
            $result2[] = $r2[$i];
        }
    }
    return $result2;
}

?>

<form action="example.php">
<textarea name="text" rows="18" cols="100"><?php echo $_GET['text']; ?></textarea>
<input type="submit">
</form>
<?php

$string = $_GET['text'];
$variables = getVariables($string);
$fixed = getFixed($string);
$fixed1 = array($fixed[0]);
$fixed2 = array($fixed[1]);
$final1 = array($variables[0], $fixed1);

$returnArray = array();
$tempArray = array();
$pos = 0;
generateCodes($final1);
$finalArray = array($returnArray[0], $returnArray[1]);
$final2 = array($variables[1], $fixed2);
$returnArray = array();
$tempArray = array();
$pos = 0;
generateCodes($final2);
$finalArray[] = $returnArray[0];
$finalArray[] = $returnArray[1];
echo '<p><b>'.getVariables($string, false, true).'</b> permutations...</p><p>';
foreach($finalArray as $fa){
    echo $fa."<br />";
}
?>

Open in new window

marqusG, many thanks, we're nearly there. If I could make you even more mad :), what about multiple variations in one sentence?

Like {hello|hi} how are {you|there}? - this is one sentence.

Your code's output is:
hi gggg
hello gggg
how you?
there you?

But it should be like:
hi how are you
hi how are there
hello how are you
hello how are there

Any idea?

Again many thanks.
SOLUTION
Avatar of Marco Gasi
Marco Gasi
Flag of Spain image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I'm going to try to write something up, it should only take a moment.
Okay, I think I got it!  The attached code takes this syntax:
{hello,hi} my name is Dom. {before,after} my data. {I,we} finally fixed it!

And turns it in to a number of possibilites such as:
hi my name is Dom. before my data. we finally fixed it!
hi my name is Dom. after my data. I finally fixed it!
hello my name is Dom. after my data. I finally fixed it!

You can delete all that other stuff and just use spin($text) as your function!  Let me know how you like it.
function spin($text) {

  preg_match_all("/{(.*?)}/", $text, $matches);

  foreach ($matches[0] as $match) {

      $i = 0;
      $array = explode(",", $match);
      $rand = rand(0, sizeof($array)-1);
      $replacement = $array[$rand];
      $replacement = str_replace("{", "", $replacement);
      $replacement = str_replace("}", "", $replacement);
      $text = preg_replace("/".$match."/", $replacement, $text);
      $i++;

  }

  echo $text;

}

$text = "{hello,hi} my name is Dom. {before,after} my data. {I,we} finally fixed it!";
spin($text);

Open in new window

By the way, my function also allows for unlimited comma separated variables within parenthesis.  So, this will also work:
{hello,hi,hows it going,howdy,whats up,hello there} my name is Dom. {before,after, etc.} my data. {I,we, all of us!} finally fixed it!"
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi, adam. There is some pattern in text strings you have to process. I'm working on some code for you, but i need to know where do replacements. If i have "{Hello|Hi},+how+are+you?+{Im|Were}+fine,+thanks." how can know that "Hello/Hi" go only before "how are you?" and not before "fine, thanks"? And how to know that "Im/Were" go only before "fine, thanks" and not before "how are you?"
EMB01, you've made it! Thanks.

Now I just need to find out how to count number of variations in total and display it above.

Thanks!
Thanks guys
"Now I just need to find out how to count number of variations in total and display it above."

You want to count variations?  Then let's put the iterator back in!  Check this out, bud...
function spin($text, $variations) {

  preg_match_all("/{(.*?)}/", $text, $matches);

  foreach ($matches[0] as $match) {

    while ($i = 0; $i <= $variations; $i++) {

      $array = explode(",", $match);
      $rand = rand(0, sizeof($array)-1);
      $replacement = $array[$rand];
      $replacement = str_replace("{", "", $replacement);
      $replacement = str_replace("}", "", $replacement);
      $text[] = preg_replace("/".$match."/", $replacement, $text);

    }

  }

  return $text;

}

$text = "{hello,hi} my name is Dom. {before,after} my data. {I,we} finally fixed it!";
spin($text, 4);

Open in new window

"Now I just need to find out how to count number of variations in total and display it above."

I'm very close to a solution.  I can't work on it anymore until I get back; but you should probably have a solution by days end time permitting.
function spin($text, $variations) {

  preg_match_all("/{(.*?)}/", $text, $matches);

  foreach ($matches[0] as $match) {

    while ($i = 0; $i <= $variations; $i++) {

      $array = explode(",", $match);
      $rand = rand(0, sizeof($array)-1);
      $replacement = $array[$rand];
      $replacement = str_replace("{", "", $replacement);
      $replacement = str_replace("}", "", $replacement);
      $text[] = preg_replace("/".$match."/", $replacement, $text);

    }

  }

  return $text;

}

$text = "{hello,hi} my name is Dom. {before,after} my data. {I,we} finally fixed it!";
spin($text, 4);

Open in new window

Note:  Didn't mean to post that code, please disregard.
@EMB01 Sorry, as you know I followed this thread, and I've tested your code but I get a strange result:

array(3) {
  [0]=>
  string(67) "hi my name is Dom. {before,after} my data. {I,we} finally fixed it!"
  [1]=>
  string(58) "hi my name is Dom. after my data. {I,we} finally fixed it!"
  [2]=>
  string(53) "hi my name is Dom. after my data. I finally fixed it!"
}

That code has been accepted as solution, and this means it works... Missed I something?
Which code are you talking about?  The attached code works.  The previously attached code was a mistake, I didn't mean to upload it.
// this code works

function spin($text) {

  preg_match_all("/{(.*?)}/", $text, $matches);

  foreach ($matches[0] as $match) {

      $array = explode(",", $match);
      $rand = rand(0, sizeof($array)-1);
      $replacement = $array[$rand];
      $replacement = str_replace("{", "", $replacement);
      $replacement = str_replace("}", "", $replacement);
      $text = preg_replace("/".$match."/", $replacement, $text);

  }

  echo $text;

}

$text = "{hello,hi} my name is Dom. {before,after} my data. {I,we} finally fixed it!";
spin($text);

Open in new window

Okay, got it, again!  Does this mean I get more points?  The following code will allow you to enter your text variable, then enter your number of permutations.  A call like this:
perms($text, 4);

Will output text like this:
hello my name is Dom. before my data. I finally fixed it!
hi my name is Dom. before my data. we finally fixed it!
hello my name is Dom. after my data. we finally fixed it!
hi my name is Dom. after my data. we finally fixed it!
Permutations: 4
function spin($text) {
  
  preg_match_all("/{(.*?)}/", $text, $matches);

    foreach ($matches[0] as $match) {

      $array = explode(",", $match);
      $rand = rand(0, sizeof($array)-1);
      $replacement = $array[$rand];
      $replacement = str_replace("{", "", $replacement);
      $replacement = str_replace("}", "", $replacement);
      $text = preg_replace("/".$match."/", $replacement, $text);

    }

  echo $text;

}
function perms($text, $perms) {

  if (is_int($perms) && is_string($text)) {

    for ($i = 0; $i < $perms; $i++) {

      spin($text);
      echo "<br />";

    }

    echo "Permutations: " . $perms;

  }

}

$text = "{hello,hi} my name is Dom. {before,after} my data. {I,we} finally fixed it!";
perms($text, 4);

Open in new window

I'm sorry, but it was not my intention to offend you, I only wont to understand... Beautiful code!
@marqusG:  No!  You didn't offend me at all.  Thanks for the compliment and I'm glad you like the code.

@Aidam-Unlimited:  I'm interested to know if this helps your SEO.  Please let me know.  That's how you can repay me for my extra work!
EMB01, many thanks for your work!

Regarding to SEO, I'm about to launch it, but I'm sure it will help a bit definitely.
This spinning technique is nothing new, lots of SEO geeks use it.
The magic is if you know how to take as much as possible from this technique, only then you win.

Cheers
"The magic is if you know how to take as much as possible from this technique, only then you win."

I get the feeling there's something you're not telling me.  Do you recommend any articles to learn the "magic?"

Also, I consolidated the function into a single function for ease of programming.  Use of the optional "true" parameter will simply output the number of permutations.  See code for usage examples.
function spin($input, $perms, $boolean = false) {

  if ($boolean == false) {

    for ($i = 0; $i < $perms; $i++) {

      $text = $input;
  
      preg_match_all("/{(.*?)}/", $text, $matches);

      foreach ($matches[0] as $match) {

        $array = explode(",", $match);
        $rand = rand(0, sizeof($array)-1);
        $replacement = $array[$rand];
        $replacement = str_replace("{", "", $replacement);
        $replacement = str_replace("}", "", $replacement);
        $text = preg_replace("/".$match."/", $replacement, $text);

      }

      $output[] = $text;

    }

    foreach ($output as $var) {

      echo $var . "<br />";

    }

  } else {

    echo $perms;

  }

}

$text = "{hello,hi} my name is Dom. {before,after} my data. {I,we} finally fixed it!";
spin($text, 4, true);
// previous line outputs "4"
spin($text, 4, true);
// previous line outputs 4 permutations

Open in new window

EMB01, you're right :)

I mean you need to test a few ways of spreading the articles, find a places where to pu them (blog, social networks and so on).
I'm sure you know SEO is a long-term journey and details are something like know-how of each SEO guy.
Obviously I can't tell you details because I haven't tested nothing yet.

Anyway thanks for you work!
Okay, well good luck.  By the way, the last two lines should be:

spin($text, 4);
// previous line outputs 4 permutations

or
spin($text, 4, false);
// previous line outputs 4 permutations