Your own article spinner in PHP!

Hi man, great share. I'm going to test it asap.

I'm still a noob when it comes to PHP scripting, do you have any advice on how to step up my game?
 
will give this a try mate.. thanks for sharing it with us.
Kevs.
 
So we have to find synonyms and put them on the original text ....
Can you provide a script which will do that job by searching on a synonyms database ???
 
Awesome script even though I haven't tested...

I am watching Lynda.com php video tuts...they are pretty good but I have alot to learn. Thanks for this.
 
Could you please explain how to use this code, See I am new and have no idea how PHP works. Would really appreciate the help thanks.
 
It saved me an hour of coding. Thanks mate.
 
Holy s#it! I have my own spinner and for very large seeds it is extremely slow. Initially it was about 20 times slower but I optimized it, however it still takes a lot to spin a very long seed (20,000 words, 8 levels deep).

I just benchmarked both scripts (yours and mine) and yours is 30+ times faster. Mine takes over 4.2 seconds and yours takes about 0.13 seconds. One significant difference in the algorithm is that mine built an internal tree data structure for the seed (array) which could obviously grow very large.

I will try to understand your algorithm to make sure the randomness is good and there are no strange things in there that would cause bias in the generated spin. Then I rebuild my spinner class on top of yours. Maybe if it is not too much to ask, you care to describe the algorithm for me so I understand it faster.

I'd rep+ you but I can't because I already did on some other thread lately.

Thank you!
 
Thanks man. haha can't believe people actually ask you to put thesaurus, bulk spin and etc into this...when you are already providing something quite valuable that can save money. :)
 
I will try to understand your algorithm to make sure the randomness is good and there are no strange things in there that would cause bias in the generated spin. Then I rebuild my spinner class on top of yours. Maybe if it is not too much to ask, you care to describe the algorithm for me so I understand it faster.

Sorry I just realized you asked a question here. Below is what I'm doing, commented. (PS, I didn't use code tags or PHP tags because I needed to highlight a few things).

function spin($pass){
$mytext = $pass;

while(inStr("}",$mytext)){
// keep spinning until no more } is found

$rbracket = strpos($mytext,"}",0);
// find the position of the very first closing bracket

$tString = substr($mytext,0,$rbracket);
// sets $tString as the entire string of text leading up to the first closing bracket

$tStringToken = explode("{",$tString);
// the short string before the first closing bracket may have 1, 2, 3, etc.
// (in your case sometimes up to 8) beginning brackets ... explode the string
// into an array that consists of all the beginning bracket instances

$tStringCount = count($tStringToken) - 1;
// this counts the array, which basically tells me exactly how many closing brackets
// there are in the initial string. I do this because I want the very last beginning
// bracket available in the initial string. I will only spin after the last beginning
// bracket because that is the one implied by the very first closing bracket

$tString = $tStringToken[$tStringCount];
// this returns the exact text that I want to spin on this while loop pass.
// for instance, in the following snippet ...

/*
I {love to spin|{like|enjoy} spinning}.

You could get 3 different sentences ...

I love to spin.
I like spinning.
I enjoy spinning.

I find the first closing bracket which is here ...
I {love to spin|{like|enjoy} spinning}.

Then I find the last beginning bracket, which is here ...
I {love to spin|{like|enjoy} spinning}.

Then (in this loop only) I have segregated this data and I will only (on this loop) spin the following.
I {love to spin|{like|enjoy} spinning}.
*/

$tStringToken = explode("|",$tString);
// as in the above example I have segregated out like|enjoy. Now I turn into an array exploded with a pipe.

$tStringCount = count($tStringToken) - 1;
// as in above example, this code tells me my array has 2 potential combinations.

$i = rand(0,$tStringCount);
// as in above example, I make a random number which in this case will either be 0 or 1

$replace = $tStringToken[$i];
// as in above example, pulling 0 or 1 out of $tStringToken's array will produce like or enjoy randomly

$tString = "{".$tString."}";
// I rebuild the section I extracted so that I can do a search/replace reconstructing the original spintax variable.
// adding the brackets to it will allow me to fully remove the command to spin the section and replace it with the
// final version word which was selected randomly.

$mytext = str_replaceFirst($tString,$replace,$mytext);
// I replace the original extracted spintax snippet I just manipulated with the $replace var which is either like or enjoy.

}
return $mytext;
}

-----

Assuming on the first loop through and given a random of 0 or 1 ... it picks 0 it
will end up looking like this ...
I {love to spin|like spinning}.

And if it were a 1 it will look like this ...
I {love to spin|enjoy spinning}.

Then on the next pass through the first ending bracket it will find is at the end of spinning. Then it will find the first closing bracket immediately before the first ending bracket (the one in front of love). Then it will spin the love to spin, or enjoy spinning, with 0 or 1 randomly selected.

If you do it this way you could be nested into infinity and its fairly simple and quick to cycle through the spintax.

The main downside of the code is that it will loop into infinity if there are more } than {. I put a time limit of the execution of this script to prevent that from happening.
 
Last edited:
Looks good mate, you can use same thing with preg_replace as well :) then the code will be little bit shorter.
 
Thanks a lot mate. I really appreciate it for taking the time. Let me know if you need a copyscape-like (but somewhat different algorithm) text comparison script (n-gram based). Is not perfect and is kinda slow but works ok (didn't needed it anymore so I abandoned optimizing it). See http://imgur.com/H2d8a

Also I can send you my code for spintax validation so you do a check before spinning to avoid infinite looping.
 
PHP:
	function spin($string) {
		while(true) {
			if(!preg_match_all('/({([^\{]*?)\})/', $string, $matches))
				break;
			foreach($matches[2] as $i => $match) {
				$parts = explode('|', $match);
				$string = str_replace_once($matches[0][$i], $parts[mt_rand(0, count($parts)-1)], $string);
			}
		}
		return $string;
	}

	function str_replace_once($from,$to,$str)
	{
		$str = explode($from,$str,2);
		return $str[0].$to.$str[1];
	}

Little bit cleaner version :) It's on some old thread too, there's a perl version also.
 
Little bit cleaner version :) It's on some old thread too, there's a perl version also.

That's cool. When I made my spinner I had no idea there was another version out there, I looked but couldn't find one.

It'll be interesting to see which of these is actually faster. Sometime soon I'll run a test.

Also I can send you my code for spintax validation so you do a check before spinning to avoid infinite looping.

I have a thesaurus based spinner I've created that returns the same results TBS API returns, and it filters results

http://scrapespinpost.com/spinner/

That's where my spins come from so I don't validate it in the script ... but if I had to validate it I'd probably just explode on { and explode on }, count the vars and if they don't match, cancel the spin.
 
Last edited:
The preg_match_all version has that advantage, as you don't need to validate what you pass to it. If there is broken spintax it just ignores them and leaves them as it is, while still spinning the non-broken parts.
 
Sorry I just realized you asked a question here. Below is what I'm doing, commented. (PS, I didn't use code tags or PHP tags because I needed to highlight a few things).

function spin($pass){
$mytext = $pass;

while(inStr("}",$mytext)){
// keep spinning until no more } is found

$rbracket = strpos($mytext,"}",0);
// find the position of the very first closing bracket

$tString = substr($mytext,0,$rbracket);
// sets $tString as the entire string of text leading up to the first closing bracket

$tStringToken = explode("{",$tString);
// the short string before the first closing bracket may have 1, 2, 3, etc.
// (in your case sometimes up to 8) beginning brackets ... explode the string
// into an array that consists of all the beginning bracket instances

$tStringCount = count($tStringToken) - 1;
// this counts the array, which basically tells me exactly how many closing brackets
// there are in the initial string. I do this because I want the very last beginning
// bracket available in the initial string. I will only spin after the last beginning
// bracket because that is the one implied by the very first closing bracket

$tString = $tStringToken[$tStringCount];
// this returns the exact text that I want to spin on this while loop pass.
// for instance, in the following snippet ...

/*
I {love to spin|{like|enjoy} spinning}.

You could get 3 different sentences ...

I love to spin.
I like spinning.
I enjoy spinning.

I find the first closing bracket which is here ...
I {love to spin|{like|enjoy} spinning}.

Then I find the last beginning bracket, which is here ...
I {love to spin|{like|enjoy} spinning}.

Then (in this loop only) I have segregated this data and I will only (on this loop) spin the following.
I {love to spin|{like|enjoy} spinning}.
*/

$tStringToken = explode("|",$tString);
// as in the above example I have segregated out like|enjoy. Now I turn into an array exploded with a pipe.

$tStringCount = count($tStringToken) - 1;
// as in above example, this code tells me my array has 2 potential combinations.

$i = rand(0,$tStringCount);
// as in above example, I make a random number which in this case will either be 0 or 1

$replace = $tStringToken[$i];
// as in above example, pulling 0 or 1 out of $tStringToken's array will produce like or enjoy randomly

$tString = "{".$tString."}";
// I rebuild the section I extracted so that I can do a search/replace reconstructing the original spintax variable.
// adding the brackets to it will allow me to fully remove the command to spin the section and replace it with the
// final version word which was selected randomly.

$mytext = str_replaceFirst($tString,$replace,$mytext);
// I replace the original extracted spintax snippet I just manipulated with the $replace var which is either like or enjoy.

}
return $mytext;
}

-----

Assuming on the first loop through and given a random of 0 or 1 ... it picks 0 it
will end up looking like this ...
I {love to spin|like spinning}.

And if it were a 1 it will look like this ...
I {love to spin|enjoy spinning}.

Then on the next pass through the first ending bracket it will find is at the end of spinning. Then it will find the first closing bracket immediately before the first ending bracket (the one in front of love). Then it will spin the love to spin, or enjoy spinning, with 0 or 1 randomly selected.

If you do it this way you could be nested into infinity and its fairly simple and quick to cycle through the spintax.

The main downside of the code is that it will loop into infinity if there are more } than {. I put a time limit of the execution of this script to prevent that from happening.

Right after I thought off an instruction about the code, here it is.

But damn, amazing how you come to all this code. I mean, it's not hard to understand what you did, but coming on your own to this code, that is what makes it hard.

Still a lot to learn for a guy like me.

I guess this is just practise..practise...and practise..step-by-step
 
Is there a way to make it spin 3 copies when you hit the submit button? This would be useful for me for UAW submissions.
 
Edit for error commenting... excuseme
 
Last edited:
Back
Top