The basic methodology is to use a sieve to maintain an increasing list of prime numbers, and to work through those numbers until the remainder is 1. In the event that no factors are found up till the square root of the number, it is presumed that any remaining value is prime.

Execution time (Core i5, 4GB RAM, Windows/Apache (not-optimized)) is:

~35ms for n ~10^{9}

~3.5ms for n ~10^{7}

~0.6ms for n ~10^{5}

If looping through many numbers (instead of finding a single solution), maintaining the sieve array will greatly increase efficiency.

```
function pfactor($n){
// max_n = 2^31-1 = 2147483647
$d=2;
$factors = array();
$dmax = floor(sqrt($n));
$sieve = array();
$sieve = array_fill(1, $dmax,1);
do{
$r = false;
while ($n%$d==0){
$factors[$d]++;
$n/=$d;
$r = true;
}
if ($r){
$dmax = floor(sqrt($n));
}
if ($n>1){
for ($i=$d;$i<=$dmax;$i+=$d){
$sieve[$i]=0;
}
do{
$d++;
}while ($sieve[$d]!=1 && $d<$dmax);
if ($d>$dmax){
$factors[$n]++;
}
}
}while($n>1 && $d<=$dmax);
return $factors;
}
```

Usage is quite simple - just pass a number, the return is value is an array, with keys being the prime factors, and values being the exponents:

```
$x=12345;
$factors = pfactor($x);
$fstr = "";
foreach ($factors as $b=>$e){
if($fstr){$fstr .= " x ";}
$fstr .= "$b" . ($e>1?"
```^{$e}":"");
}

]]>