Can a php application instantiate multiple RNGs - php

Update - this question applies to PHP < 8.2 - for 8.2+, You have access to Randomizer
PHP supports `mt_rand()` and `mt_srand()`, but these are global and static.
I notice in the PHP C source that mt_rand uses a engine_mt19937 instance; is there a way in PHP to instantiate our own instance of this RNG so we can control its seed?

On PHP 8.2+, yes. See #AlexHowansky's answer for that. On earlier PHP versions, no.
Your link to the source code points to the master branch, which already has the PHP 8.2 logic in it since it was officially released last month. That is why the master branch includes the reference to an MT19937 engine.
On older versions (e.g. the latest 8.1 branch) you can see that mt_rand() did not use a configurable engine but just checked if it was already seeded. PHP 8.1 and earlier used a single global generator for mt_rand() so it is not possible to have multiple RNGs with different seeds if you want to use the native functions.
Having said that, you could probably roll your own implementation of an MT19937 RNG for PHP 8.1. Others have.

is there a way in PHP to instantiate our own instance of this RNG so we can control its seed?
With PHP 8.2+, yes. See the \Random classes. You can do something like:
$rand1 = new \Random\Engine\Mt19937($seed1);
$value1 = $rand1->generate();
$rand2 = new \Random\Engine\Mt19937($seed2);
$value2 = $rand2->generate();

Related

check the php version compatibility of a php script

I have a php script. I want to check the php version compatibility that each function of this script has.
For example the script has the hash() function. If we look at php.net site it says that this function was added (PHP 5 >= 5.1.2, PECL hash >= 1.1).
So assuming that this script has only this function we say that it is compatible with php 5.1.2 and onwards. Is there any software tool that can scan the script and tell you the changelog of every function and possibly gives you the lowest possible score e.g. (php version 4.3 and on)? It is a bit tedious to check manually every function in the script.
Thank you in advance
As PHP supports dynamic function/method names, just searching through the source code would not give reliable results.
Example:
$function = 'strpos';
$result = $function(...);
You might use xdebug function traces together with a 100% test coverage. This could give you all function names which had been called during a test suite run with 100% coverage - meaning all code has run. But even this isn't reliable as you would have to make sure, that your test suite covered all possible dynamic function names what is impossible. (assuming the max length of a function name is unlimited)
My final answer is: this isn't reliably possible.

PHP ignoring returned reference from function considered harmful?

Derick Rethans has an old article that says:
Please do note that it is harmful not to accept a reference from a
function that returns a reference. In some cases, PHP will get
confused and cause memory corruptions which are very hard to find and
debug. It is also not a good idea to return a static value as
reference, as the PHP engine has problems with that too. In PHP 4.3,
both cases can lead to very hard to reproduce bugs and crashes of PHP
and the web server. In PHP 5, this works all a little bit better. Here
you can expect a warning and it will behave “properly”.
Does it mean that in PHP 5 we are allowed to ignore the returned reference from a function?
By that, I mean this:
function &GetRef(&$array){
$item =& $array[0];
return $item;
}
$array = array(0, 1, 2);
$item =& GetRef($array); /* Normal usage of the function using assign by reference
also known as "accepting" the reference. */
$item = GetRef($array); /* Notice that here we didn't assign by reference.
Are we allowed to ignore the returned reference
and simply do normal assignment? */
The PHP Manual states:
Unlike parameter passing, here [return by reference] you have to use &
in both places - to indicate that you want to return by reference, not
a copy, and to indicate that reference binding, rather than usual
assignment, should be done for $myValue.
It doesn't explicitly say that we must accept the returned reference.
Does it mean that we are free to ignore returned references?
As discussed in the comments, you should generally ignore at least that section in the linked article, if not the entire thing.
The article talks about references in the context of PHP 4.3, released in December, 2002 and EOL'd at the end of 2007. PHP 4 should never be used today. As a general rule, when it comes to learning about working with PHP, you should not trust any article that targets PHP versions older than 5.2 (as of mid-2013).
PHP 5.0 features Zend Engine 2, a new virtual machine on which PHP runs. This is where references are implemented. 5.1 introduces some backwards-incompatible changes with regard to manipulation of return values. 5.3 introduces real garbage collection and deprecates both call-time pass-by-reference and assigning new by reference. These important changes are not addressed by that prehistoric article.
Does it mean that in PHP 5 we are allowed to ignore the returned reference from a function?
Yes. Modern PHP versions have no problem with discarding the return value of any function, reference or not. If you encounter behavior that seems to contradict this expectation, create a reduced test case and file a bug with the PHP maintainers.
Also, think twice before using references in your code. Passing around references will not save time, will not save memory and will not increase performance except in rare cases. Use them sparingly to keep complexity under control.

PHP/JS Text Diff

First off, this is an exact duplicate of these four questions:
Highlight the difference between two strings in PHP
JavaScript based diff utility
How to do text DIFF using PHP?
Calculate text diffs in PHP
It seems as though times have changed since these questions were first asked and I am wondering what is a good tool now-a-days for this sort of comparison? I have looked at (additionally to those questions):
https://github.com/nuxodin/diff_match_patch-php
http://pear.php.net/package/Text_Diff
https://github.com/paulgb/simplediff/blob/5bfe1d2a8f967c7901ace50f04ac2d9308ed3169/simplediff.php
http://www.raymondhill.net/finediff/viewdiff-ex.php
But all of the ones I get are either unmantained now or seem a little dodgy in that they are not used that much (and some even hint that they are not very performant) and the PEAR one worries me. I hate to install PEAR for one little module not only that but it seems like throwing a brick through my own window to install it for such a small module in comparison to PEAR in general not only that but the module has been superseded and placed on a different channel (dunno why?). I would use the PEAR version if it is my only choice but I want to use the upto date package.
Does anyone know of a well used and currently maintained or built in function (even if it is a PHP extension) text diff for PHP and/or JavaScript (JQuery as well)?
Ok so it has been a while.
I actually decided to look around at what other people use and stumbled upon what Yii ( http://www.yiiframework.com ) uses.
They actually use the PEAR module for their text_diff and they use it in its new form on the horde channel. It seems that text_diff is now a horde project but you can just as easily integrate a version of it into your application and that is what Yii does by default (it comes pre-bundled with a version of it).
So I searched around a bit to find out how they used it and how to get into it and I came across:
public function actionDiff()
{
Yii::import('gii.components.TextDiff');
$model=$this->prepare();
if(isset($_GET['id']) && isset($model->files[$_GET['id']]))
{
$file=$model->files[$_GET['id']];
if(!in_array($file->type,array('php', 'txt','js','css')))
$diff=false;
elseif($file->operation===CCodeFile::OP_OVERWRITE)
$diff=TextDiff::compare(file_get_contents($file->path), $file->content);
else
$diff='';
$this->renderPartial('/common/diff',array(
'file'=>$file,
'diff'=>$diff,
));
}
else
throw new CHttpException(404,'Unable to find the code you requested.');
}
In CCodeGenerator for their Gii module ( http://www.yiiframework.com/doc/api/1.1/CCodeGenerator/ ). The important part is where they actually hook into the PEAR module:
$diff=TextDiff::compare(file_get_contents($file->path), $file->content);
By reading in the contents of two files which produces a diffed output.
Originally I did not want to use PEAR because of the bloat but this module is quite slim for a fully featured text_diff so I have decided to go with this. Not only that but, at the moment, it is the only text_diff module that has truly worked for me so I am keeping with the best, even if the best is quite memory hungry.
Have you tried one of Philippe's two solutions on this thread?
Quoted here:
In PHP. array_diff compares the first against the second array and
returns the difference.
$a1 = str_split('abcdefghijklmnop');
$a2 = str_split('abcdefghi');
echo join('', array_diff($a1, $a2)); // jklmnop
This will work as well:
$s1 = 'abcdefghijklmnop';
$s2 = 'abcdefghi';
echo str_replace(str_split($s2), '', $s1); // jklmnop
This could handle $s2 = 'ghiabcdef'; as well because str_replace() is fed with an
array, not a string.

How can I make my open-source PHP app cross-server?

I have a PHP program using MySQL that I will be making open-source, including a simple installer, and I want to make it as easy to install on any server with PHP4 or 5 and MySQL 4 as possible.
I've included an installer to make it user-friendly, but I need to know what are the things I can do to make it most likely to install on every server.
I'll start: I've made sure to use full PHP tags (not short) like this <?php ?> and to make sure all variables are declared prior to using them, like so $nVar = (isset($_POST['nVar']) ? $_POST['nVar'] : NULL);.
What other best practices should be incorporated in a PHP app for the best cross-server compatability?
Just a few hints, from the top of my head
The class { __constructor } is deprecated.
Dont use GLOBAL
Use split and join
Watch out for file magic byte recognition functions
The get_class get_parent_class alphanumerical changed to accept camelcasing - use strtolower on returned value before comparing

rename lambda function (php)

I build a (so far) pretty nice templating mechanism for a cms. Now I also added a set of developer tools to the UI for a better UX during development. The only problem I'm left with is that I have to use create_function to add my templates, and therefore have lambda_xyz instead of meaningful template or function names.
Question: Is there a way/work around to give meaningful names to lambda functions in php?
This reference might be able to point you in the right direction:
http://php.net/manual/en/functions.anonymous.php
Anonymous functions require PHP 5 >= 5.3.0
$function_name = 'meaningful_name';
// PHP 5 >= 5.3.0
$$function_name = function(){echo "I am connected to a meaningful name";};
// PHP 4 >= 4.0.1, PHP 5
$$function_name = create_function('', 'echo "I am connected to a meaningful name";');
// Then you can call your function like this
$meaningful_name();
If this isn't what you are looking for, can you update your question with what you are trying to accomplish in more detail?

Categories