Random Extension Polyfill#
This is a polyfill for the new ext-random
extension that will be released with PHP 8.2.
RFC:
Requirements#
PHP 7.1
GMP extension is strongly recommended on PHP 7 and somewhat recommended on PHP 8
Installation#
composer require 'arokettu/random-polyfill'
Documentation#
Compatibility Notes#
PHP#
The library aims to be compatible with ext-random
as released in PHP 8.2.0 and subsequent patch releases.
The library will not be a full replacement for ext-random
and total compatibility does not seem to be achievable.
Version 1.99.0#
Version 1.99.0 is an empty package for PHP >= 8.2. It ensures that no overhead or extra code will be used for PHP 8.2+ apps.
Known differences#
These differences are considered to be permanent features. However if you know how to fix them, ideas are welcome.
Serialization#
Serialization is only compatible if done in PHP 7.4 and later.
Serializable entities implement
\Serializable
for controlled serialization in PHP 7.1 - 7.3.Entities serialized in PHP 7.1 - 7.3 can be unserialized with the polyfill under any version of PHP but will not be unserializable by the native extension.
Serialization in PHP 7.1 - 7.3 will trigger a warning. Silence it with
@
if you don’t care.Does not throw in GH-9186 case but also does not create a dynamic property (PHP 7.4+) Undefined behavior for PHP <7.4 (returns false with a warning for the given code)
Randomizer#
pickArrayKeys()
messes a lot with the internal structure of the PHP hash tables and therefore may produce different results in the userland. Example from Tim Düsterhus:<?php $r1 = new Random\Randomizer(new Random\Engine\Xoshiro256StarStar(1)); $r2 = new Random\Randomizer(new Random\Engine\Xoshiro256StarStar(1)); $a = [ 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'f' => 6, ]; unset($a['b']); $b = [ 'a' => 1, 'c' => 3, 'd' => 4, 'e' => 5, 'f' => 6, ]; var_dump($a === $b); // bool(true) var_dump( $r1->pickArrayKeys($a, 1), // native: [ 0 => 'e' ], lib: [ 0 => 'd' ] $r2->pickArrayKeys($b, 1), // [ 0 => 'd' ] );
The interpreter operates on the actual hash table that looks different for these arrays. The lib “repacks” arrays and therefore returns
['d']
in both cases.
using
pickArrayKeys()
will trigger a warning if the engine is not CryptoSafeEngine. Silence it with@
if you don’t care.
Mt19937#
Generating integers with
$max - $min >= mt_getrandmax()
withMT_RAND_PHP
is considered undefined behavior. This library is consistent with PHP 8.2 behavior, not the version it runs under.
Warnings#
For obvious reasons, native extension produces E_WARNING
and the library produces E_USER_WARNING
.
Performance Notes#
Well, even with GMP, it’s guaranteed to be slow. Good enough if you need a dozen numbers or so.
Performance test#
https://github.com/arokettu/random-polyfill-perf
Secure engine is mostly unaffected by the choice of backend (except for nextInt() case)
PHP 7:
With GMP installed, all engines is approximately 400 times slower than native
Mersenne Twister is consistently 400 times slower than native, whether you use GMP or not
PCG is 100 times slower than GMP and xoshiro256** is 50 times slower than GMP
PHP 8:
100-150 times slower than native
GMP presence does not affect performance that much, but PCG will run twice as fast
JIT helps almost as much as GMP (use both for max performance)
License#
The library itself is distributed under the 3-Clause BSD License but it also uses some code under other licenses. Here are all the terms on one page.
Random Extension Polyfill for PHP#
The library itself.
Copyright © 2022 Anton Smirnov
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
PHP#
The library includes code taken from the PHP 8.1.0 beta 1 and rewritten from C to PHP.
PHP is distributed under the PHP License.
--------------------------------------------------------------------
The PHP License, version 3.01
Copyright (c) 1999 - 2019 The PHP Group. All rights reserved.
--------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, is permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The name "PHP" must not be used to endorse or promote products
derived from this software without prior written permission. For
written permission, please contact group@php.net.
4. Products derived from this software may not be called "PHP", nor
may "PHP" appear in their name, without prior written permission
from group@php.net. You may indicate that your software works in
conjunction with PHP by saying "Foo for PHP" instead of calling
it "PHP Foo" or "phpfoo"
5. The PHP Group may publish revised and/or new versions of the
license from time to time. Each version will be given a
distinguishing version number.
Once covered code has been published under a particular version
of the license, you may always continue to use it under the terms
of that version. You may also choose to use such covered code
under the terms of any subsequent version of the license
published by the PHP Group. No one other than the PHP Group has
the right to modify the terms applicable to covered code created
under this License.
6. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes PHP software, freely available from
<http://www.php.net/software/>".
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------
This software consists of voluntary contributions made by many
individuals on behalf of the PHP Group.
The PHP Group can be contacted via Email at group@php.net.
For more information on the PHP Group and the PHP project,
please see <http://www.php.net>.
PHP includes the Zend Engine, freely available at
<http://www.zend.com>.
Mersenne Twister#
Mersenne Twister code in PHP is adapted from C++ code distributed under the 3-Clause BSD License.
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
Copyright (C) 2000 - 2003, Richard J. Wagner
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Thanks#
Random extension developers: Go Kudo, Tim Düsterhus, Guilliam Xavier, Christoph M. Becker, Jakub Zelenka, Bob Weinand, Máté Kocsis, and Original RNG implementators
Tim Düsterhus for reviews, issue reports and useful advices
License#
The library is available as open source under the terms of the 3-Clause BSD License. See License for additional licenses.