How can I compare MySQL Versions in PHP? - php

Okay, so I'm getting my MySQL Version like so:
preg_replace('#[^0-9\.]#', '', mysql_get_server_info());
Which gives me a number like: 5.1.36
That's all good. What I need to do, is compare that version with another version. I was about to attempt to write my function to compare them, when I thought of version_compare(). However, upon testing I became unsure, but perhaps I'm just not sure how MySQL Version Numbers work.
This is what I tested:
version_compare('5.1.36', '5.1.4', '<');
or
5.1.36 < 5.1.4
I assumed that this would return true, that 5.1.36 is less than 5.1.4. My reason for that is, I figure 5.1.4 is actually 5.1.40 not 5.1.04. Perhaps I'm wrong there.
So am I thinking wrong, or is the function returning the incorrect result?

The function is correct. The numbering system is M.m.r where each "number" is a decimal number.
M is the major version number
m is the minor version number
r is the revision number
So 5.1.36 would be revision 36 of the 5.1 minor version... Therefore, 5.1.4 would be revision 4 (and hence 36 > 4)...

http://php.net/version_compare :)

http://www.php.net/manual/en/mysqli.get-server-version.php
mysqli's get_server_version() method will return the version as an integer.
main_version * 10000 + minor_version
* 100 + sub_version (i.e. version 4.1.0 is 40100).

I assumed that this would return true,
that 5.1.36 is less than 5.1.4. My
reason for that is, I figure 5.1.4 is
actually 5.1.40 not 5.1.04. Perhaps
I'm wrong there.
Yes, 5.1.36 is greater than 5.1.4.

Related

Why string with hex format number convert to correct integer value? PHP

I've found out unclear php behavior
echo '0x12' + 2; // 20
As I understand from http://php.net/manual/en/language.types.string.php string '0x12' should cast to 0 like '0b11' do
echo '0b11' + 1; // 1
Please explain why is it so.
UPDATE
First example give me 2 in 7.x and 20 in 5.x versions.
Thanks AntoineB and Mark Baker for the comments. From this point I can conclude it was more like an issue in php 5.x rather then feature and fixed in php 7.x (Backward incompatible changes for PHP7).

PHP round and PHP_ROUND_HALF_UP related issue

I have a number string with the following number :
$str=14.5;
I want to half up this value so that I get
15
I have tried this code
echo round($str,0,PHP_ROUND_HALF_UP);
But It doesn't work and I am getting errors :
Use of undefined constants "PHP_ROUND_HALF_UP" , "Wrong parameter count for round"
In PHP 5.3.0 the mode parameter was introduced. The errors suggest you are using an older version and are replicated here in older versions.
However, in older versions PHP_ROUND_HALF_UP is the default, so you shouldn't have an issue. Just use round($str, 0).
If you need to use different modes and must use version <5.3.0 there are other questions on the matter:
round() mode ROUND_HALF_DOWN with PHP 5.2.17

Memcached bug in PHP - binary protocol

I came across a bug using Memcached in PHP. Here's my piece of code:
<?php
$mc = new \Memcached();
$mc->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
$mc->addServer("127.0.0.1", 11211);
$mc->touch("key", time() + 600);
$touchResult = $mc->getResultCode();
$mc->set("key", 1, time() + 600);
$setResult = $mc->getResultCode();
echo "<pre>";
echo "Touch result: $touchResult\n";
echo "Set result: $setResult\n";
echo "</pre>";
When you run this for the first time, this is the output:
Touch result: 16
Set result: 0
And for the second time forth:
Touch result: 0
Set result: 5
Correct me if I'm wrong but this is a bug right? Does anyone know a workaround for this?
Here are the versions I use:
Ubuntu 12.04 64bit
PHP 5.3.14
memcached 2.1.0 (PECL module)
libmemcached 1.0.8
Memcached sever 1.4.13
PS. If you wonder what the result codes mean, here they are:
0 RES_SUCCESS
5 RES_WRITE_FAILURE
16 RES_NOTFOUND
[UPDATE]
I played a little more with the code and found something even more interesting. This bug happens regardless of the key that touch and set are working on. As long as the touch operation returns 0 (which means it was successful) the set operation will fail.
[UPDATE]
I managed to produce some other errors as well. e.g. acquiring some key from server and then adding some other will also lead to nasty problems (RES_END code). I believe all these problems are somehow related to binary protocol. It seems to me as if binary protocol's implementation is hardly near stable. Operations which can work without binary protocol will do just fine but once the protocol is set to binary, they will result in blocking problems.
All right.
In first time, you touch not existed key - result is RES_NOTFOUND. When you do set - you write value success - RES_SUCCESS.
In next time you touch existed key (you set it in first linch) and get result of operation RES_SUCCESS, next you try set value for existed key - result false. All right.
If you want change existing value you must use Memcached::replace() method instead of "set"

PHP rand(10000000000000,9999999999999) returning "-114888782"

So, I have a PHP script:
<?
rand(1000000000000,9999999999999);
The expected result is a number with 13 digits.
But it's returning some weird numbers, as:
987419207
1032717476
-455563764
Does anyone know what's going on?
PHP: 5.2.17
OS: Tested on Debian Squeeze and Windows 7, both 64 bits
Solution (workaround)
<?
echo rand(10000,99999).rand(10000000,99999999);
Use getrandmax() to see the max value that you can get from rand(), its clearly a overflow problem.
you could use 2 of this int and make a longer one, calling rand for a 6 digit and again for a 7 digits, just an idea.
i think 10000000000000 its not a valid integer!
output
getrandmax();
Use a bignum library like BCMath or GMP. GMP is newer and seems to have a better API but that's just my opinion

regain constant pseudo-random in PHP 5.2

I am including the same "random.inc" in foo.php and bar.php. For each, I want reproducible "random" results.
So in foo.php I always want one set of numbers and/or keywords. In bar.php another. Which shouldn't change on reload. That's what I mean by contant pseudo-random. And that's why I seeding on the url. However I still get different results for individual numbers as well as for array pickson every reload. This is the full php file:
<?
header('Content-Type: text/plain');
$seed = crc32( $_SERVER['REQUEST_URI'] );
echo "phpversion: ".phpversion()."\nseed: $seed\n";
srand( $seed ); // (seed verified to be contant as expected)
// neither single values nor array pics turn out deterministic
echo ''.rand(0,100).' '.rand(0,100).' '.rand(0,100)."\n";
$values = array( '0'=>21,'1'=>89,'2'=>96,'3'=>47,'4'=>88 );
print_r( array_rand( $values, 3 ) );
?>
In the days of PHP4.1 it was (verified) possible to achieve constant pseudo-random like this. array_rand API documentation describes as a feature that since 4.2 initialization happens automatically. Perhaps this is overriding any explicit seeding? (if so, perhaps explicit seeding should raise an internal PHP flag, preventing automatic seeding?). Btw: mt_srand() and srand() are equally not working.
I would really like to get my deterministic / constant pseudo-random back...
Update: Solution below (Windows and/or version 5.2 's fault)
Works for me (PHP/5.3.6):
<?php
$data = range(1, 100);
srand(1);
print_r(array_rand($data, 3));
... always prints:
Array
(
[0] => 21
[1] => 89
[2] => 95
)
... in my machine. Apparently, the exact numbers differ depending on the exact environment but they're reproducible.
Guys, you are all correct! (Sorry, I answer it myself now)
my web hoster runs 5.2.17 under Linux 2.6.36, and above problem exists.
under Win x64 5.3.0 everything works as expected.
So it's everyone's guess if that's an OS related bug and/or a PHP bug, fixed in 5.3.0.
Given that random constant seeding worked before, I am guessing they fixed in 5.3 the bug that came with the autoseed feature enhancement in 4.2. Anyway, Thanx again, at least there's clarity now.
The seeding functions are still available, and should still work; it's just since PHP 4.2 they are automatically seeded with the time on page load; but you can still call them to reset the random sequence to a known starting point.
[edit] I have just done a quick test program to make sure I wasn't imagining it!
mt_srand(50000);
print "rand="+mt_rand(0,10000);
Using PHP 5.2, this always results in the same value being printed (1749).
[EDIT]
As noted by #cwd and in the accepted answer to this question, there appears to be a discrepancy in PHP 5.2's behaviour with random number seeding between the Linux and Windows versions. In PHP 5.2 on Linux, the above technique does not appear to work.
Fortunately, the bug seems to have been fixed in PHP 5.3, so the solution to this problem is simply to upgrade. (PHP 5.2 is not supported any longer, so you should upgrade anyway)
Btw, if anyone else wants "constant windows-pre-5.3 pseudo-random" (of low quality, e.g. for stuff like SEO buzzwording) this is a tested workaround:
$r = abs(crc32($URL))%20; // a number between 0 and 19, based on URL
In PHP 5.2.17 and probably on all versions of PHP 5.2, (not sure about windows), we lose the capability of generating random numbers based on a seed as PHP changes the algorithm used for random numbers.
rand and mt_rand are "broken" not only because they will not give one random number, but they will also not give a same sequence of random numbers - even when using a seed!
At first the PHP developers tried to argue that this is the way that it "should" work, but we can guess they caught enough grief about the problem that they have reverted the way that it works with PHP 5.3.
See the php mt_rand page and the bug tracker to learn about this issue.

Categories