From:             theultramage at gmail dot com
Operating system: Windows/FreeBSD
PHP version:      5.2.9
PHP Bug Type:     Arrays related
Bug description:  array_rand broken sorting semantics

Description:
------------
The code of PHP_FUNCTION(array_rand) contains a conditional call to
array_data_shuffle ('shuffle()' function). It was added in
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.79&r2=1.80&;
to resolve bug http://bugs.php.net/bug.php?id=7492 . There are several
mistakes here:

1. The developer used the comparison (num_req_val == num_avail). However,
these are not constants and change a lot during the execution of the
algorithm. While it is true that the check holds true in the case where the
user requests all elements in the array, it also holds true in the general
case where both of these variables reach the value '0' at the end of the
loop, which is 10+% of the time and occurs randomly. This causes array_rand
to produce sequences that are "in ascending order, but sometimes completely
random". See http://php.net/manual/en/function.array-rand.php#74406.

2. The developer should have never made this change in the first place.
The user's complaint was "If I ask array_rand() to pick 6 elements out of
6, the result isn't randomized". But here the user failed to realize that
it's not array_rand's job to produce the results randomly ordered. It's to
"pick K random entries out of N". Therefore the change 1.80 was out of
scope of what array_rand was intended for. The developer should have
instead instructed the user to use shuffle() on the result if he required a
shuffled result.

My proposal: Remove the two lines that do the shuffling in array_rand's
code, since they're broken and don't make sense even if they were fixed.
It's not the function's task to randomize the output's order - that should
be done by the user if he needs to do so.

PS: A more detailed analysis can be found at
http://netvor.sk/~umage/wtf/www/php/array_rand.html .

Reproduce code:
---------------
<?php
        // also see http://php.net/manual/en/function.array-rand.php#74406

        // test case for '3 out of 10'... try this and then try '8 out of 10'
        $n = 20;
        $a = array(0,1,2,3,4,5,6,7,8,9);

        for( $i = 0; $i < $n; $i++ )
        {
          $keys = array_rand($a,3);
          printf("%d %d %d\n", $keys[0], $keys[1], $keys[2]);
        }
?>

Expected result:
----------------
Individual sequences should appear in ascending order, since that's how
the original code generated them.

Actual result:
--------------
The sequences are mostly sorted, sometimes shuffled. This occurs randomly
on each run. The percentage of shuffled sequences increases as the
requested number nears the number of entries in the array.

-- 
Edit bug report at http://bugs.php.net/?id=48224&edit=1
-- 
Try a CVS snapshot (PHP 5.2):        
http://bugs.php.net/fix.php?id=48224&r=trysnapshot52
Try a CVS snapshot (PHP 5.3):        
http://bugs.php.net/fix.php?id=48224&r=trysnapshot53
Try a CVS snapshot (PHP 6.0):        
http://bugs.php.net/fix.php?id=48224&r=trysnapshot60
Fixed in CVS:                        
http://bugs.php.net/fix.php?id=48224&r=fixedcvs
Fixed in CVS and need be documented: 
http://bugs.php.net/fix.php?id=48224&r=needdocs
Fixed in release:                    
http://bugs.php.net/fix.php?id=48224&r=alreadyfixed
Need backtrace:                      
http://bugs.php.net/fix.php?id=48224&r=needtrace
Need Reproduce Script:               
http://bugs.php.net/fix.php?id=48224&r=needscript
Try newer version:                   
http://bugs.php.net/fix.php?id=48224&r=oldversion
Not developer issue:                 
http://bugs.php.net/fix.php?id=48224&r=support
Expected behavior:                   
http://bugs.php.net/fix.php?id=48224&r=notwrong
Not enough info:                     
http://bugs.php.net/fix.php?id=48224&r=notenoughinfo
Submitted twice:                     
http://bugs.php.net/fix.php?id=48224&r=submittedtwice
register_globals:                    
http://bugs.php.net/fix.php?id=48224&r=globals
PHP 4 support discontinued:          http://bugs.php.net/fix.php?id=48224&r=php4
Daylight Savings:                    http://bugs.php.net/fix.php?id=48224&r=dst
IIS Stability:                       
http://bugs.php.net/fix.php?id=48224&r=isapi
Install GNU Sed:                     
http://bugs.php.net/fix.php?id=48224&r=gnused
Floating point limitations:          
http://bugs.php.net/fix.php?id=48224&r=float
No Zend Extensions:                  
http://bugs.php.net/fix.php?id=48224&r=nozend
MySQL Configuration Error:           
http://bugs.php.net/fix.php?id=48224&r=mysqlcfg

Reply via email to