Strange behaviour from PHP. var_dump(390.0) outputs 38: - php

Test file:
<?php
$var = 0.28682926829268;
$roundedVar = round($var, 2);
var_dump($roundedVar);
var_dump(is_float($roundedVar));
echo "Rounded var: $roundedVar";
?>
Output:
float(0.28:)
bool(true)
Rounded var: 0.28:
Note the strange colon character that appears after 0.28 both in the var_dump and in the echo output.
After discovering that, I figured PHP must be corrupted somehow. So I uninstalled and reinstalled PHP. I reinstalled the same version of PHP, as detailed below. I re-ran the test code and got the same result
I then reinstalled both PHP and Apache 2.2. After doing that the test case above worked as expected, but then another error turned up, that I reduced to the following test case.
Test file:
<?php
$var = 390;
echo "var: " ; var_dump($var );
echo "is_float(): " ; var_dump(is_float($var) );
echo "is_string(): "; var_dump(is_string($var));
echo "echo: $var<br/>\n";
$var = 390.0;
echo "var: " ; var_dump($var );
echo "is_float(): " ; var_dump(is_float($var) );
echo "is_string(): "; var_dump(is_string($var));
echo "echo: $var<br/>\n";
?>
Output:
var: int(390) is_float(): bool(false) is_string(): bool(false) echo: 390
var: float(38:) is_float(): bool(true) is_string(): bool(false) echo: 38:
Can anyone explain this strange behavior?
Updates:
I found by running hardware diagnostics that the the CPU on the server was overheating. When that problem was fixed so that the hardware diagnostic passed, the error stopped appearing in the logs (see the accepted answer below).
For anyone else investigating a similar problem, I found discussion of another weird PHP bug involving floating-point numbers and colon suffixes at the following URL. Not sure whether related.
https://bugs.php.net/bug.php?id=51396
PHP version info:

The CPU was faulty.
I downloaded an Intel CPU diagnostic tool from here:
https://downloadcenter.intel.com/download/19792/Intel-Processor-Diagnostic-Tool
Relevant output:
Current Junction Temperature is 99C
Current Degrees Below Max 1C
Maximum Junction Temp Allowed 100C
Test Result - FAIL
Please check your Processor Thermal Solution

Related

Has PHP 7.4 broken fgets(STDIN)?

I have just upgraded from PHP 7.3.12 to PHP 7.4.0 (released today) on Windows.
This worked until just now:
<?php
$input = fgets(STDIN);
var_dump($input);
It now outputs:
bool(false)
It doesn't ask/allow for input at all anymore. It immediately returns a bool false.
I can't find any mention of any recent changes to fgets in either the changelog or the manual page.
What is wrong? What am I supposed to do? Is this a bug? Is it known? Has it been encountered by anyone else?
Also, if this is wrong somehow (in spite of working for so long, and in spite of me finding this code recommended online), what is the "real" way to accept user input/wait for Enter?
I have now downgraded back to 7.3.12 for the moment to fix this issue.
EDIT: Somebody has finally submitted a bug report for this. I sure hope it won't be ignored, as is so often the case in many FOSS projects: https://bugs.php.net/bug.php?id=78883
Confirming that I'm experiencing the same behavior with 7.4. I created a kludgy workaround for now:
ob_start(); // buffer so we don't see the output generated at DOS prompt
$cmd_line='SET/P phpinput= & SET phpinput'; // Step 1: prompt user to enter a value for variable phpinput & Step 2: display the value for phpinput
$result=system($cmd_line); // Execute
$result=str_replace('phpinput=', '', $result); // Clean up the returned result
ob_end_clean(); // resume normal output
echo "\nReturned result from user typing is: $result\n";

Why PHP COM objects are not returning correct results?

I'm trying to access Windows SAPI5 or Text to speech (TTS) using PHP. The standard approach is to create a COM object for "SAPI.SpVoice", then get the installed voices.
Sample PHP code:
<?php
$obj = new COM('SAPI.SpVoice');
$voices = $obj->GetVoices;
$count = $voices->Count;
print $count; #prints "1"
Unfortunately the output returned from PHP's COM object is incorrect because I have 5 voices installed on my system, but PHP only returns 1.
So, just to check if this a PHP specific issue, I wrote the same code in Perl 5.8 (strawberry).
Sample Perl code:
#!/usr/bin/perl
use Win32::OLE;
my $obj = Win32::OLE->new('SAPI.SpVoice');
my $voices = $obj->GetVoices;
my $count = $voices->Count;
print $count; #print "5" which is correct.
So the perl code correctly returns that I have 5 TTS voices on my system, but PHP returns only 1?
Is this a bug or am I doing something wrong? What could be the possible cause of this?
P.S. I've tried this on two different computers and results are the same.
I figured this after some trial error. It looks like if I use the 32-bit version of PHP then I get the correct results (5 voices). But since I had installed the 64-bit version by default I only get 1 voice.
I think the TTS voices are mostly 32 bit (like those installed on my system) and so when running with a 64-bit php.exe it only returns 64-bit voices. With 32 php.exe it returns all voices.
Posting this as answer in case someone faces a similar issue in future.

Echoing large string in PHP results in no output at all

I am helping to build a Joomla site (using Joomla 1.5.26). One of the pages are really really big. As a result, PHP just stops working without any error and all previously printed strings are ignored. There is no output at all. We have display_errors set to TRUE and error_reporting set to E_ALL.
I found the exact line where PHP breaks. It's in libraries/joomla/application/component/view.php:196
function display($tpl = null)
{
$result = $this->loadTemplate($tpl);
if (JError::isError($result)) {
return $result;
}
echo $result;
}
Some information:
Replacing echo $result; with echo strlen($result); works. The length of the string is 257759.
echo substr($result, 0, 103396); is printing partial content.
echo substr($result, 0, 103397); results in no output at all.
echo substr($result, 0, 103396) . "A"; results in no output at all. So splitting string into chunks is not a solution.
I have checked server performance during the execution of the script. CPU usage is 100% but there's plenty of memory left. PHP memory limit is 1024M. output_buffering is 4096 but I tried setting it to unreasonably high number - dies at exact same position. Server runs Apache 2.2.14-5ubuntu8.10 and PHP 5.3.2-1ubuntu4.18. PHP runs as fast_cgi module.
I have never experienced something like that and Google search results in nothing also. Have any of you experienced something like that and know the solution?
Thanks for reading!
Maybe try exploding the string and looping through each line.
You could also try this, found on php.net - echo:
<?php
function echobig($string, $bufferSize = 8192)
{
// suggest doing a test for Integer & positive bufferSize
for ($chars = strlen($string)-1, $start = 0;$start <= $chars; $start += $bufferSize) {
echo substr($string, $start, $bufferSize);
}
}
?>
Basically, it seems echo can't handle such large data in one call. Breaking it up somehow should get you where you need to go.
what about try using print_r rather than echo
function display($tpl = null)
{
$result = $this->loadTemplate($tpl);
if (JError::isError($result)) {
return $result;
}
print_r($result);
}
I have tested this on the CLI and it works fine with PHP 5.4.11 and 5.3.15:
$str = '';
for ($i=0;$i<257759;$i++) {
$str .= 'a';
}
echo $str;
It seems a reasonable assumption that PHP itself works fine, but that the output buffer is too large for Apache/fast_cgi. I would investigate the Apache config further. Do you have any special Apache settings?
May be that?
Try something like this
php_flag output_buffering On
Or try to turn on gzip in Joomla!
Or use nginx as reverse proxy or standalone server :^ )
It seems I solved the problem by myself. It was somewhat unexpected thing - faulty HTML formatting. We use a template for order page and inside there is a loop which shows all ordered products. When there were a few products, everything worked great but when I tried to do the same with 40 products, the page did break.
However I still don't understand why the server response would be empty with status code 200.
Thanks for answers, everybody!

exp() returns NaN stuff

Ok, I'm stuck. I have this PHP code:
echo exp(12), '<br/>';
echo exp(4.2);
just like on the PHP.net page. And what I have on the screen:
NAN
298.86740096706
but then there comes the weirdest thing ever. I thought that maybe there's some PHP.ini problem with numbers like 2.67e8 and so (I mean with the 'e' inside) or something. But then, when I changed the above code into:
echo (2.67e8), '<br/>';
echo exp(4.2);
suddenly I saw this whatever:
267000000
NAN
It's kind of WTF especially because of the last NAN, when first it was a quite normal, calm float 298.86740096706 but then just with no reason it went to hell replaced by NAN. Do you have any ideas? Please?
If true, this must be a bug in your PHP version. Please report it.
By the way, I'm unable to reproduce it on PHP 5.3.2. Running:
php -r 'do { $c = exp(4.2); echo "point "; } while (is_nan($c)); echo "$c\n";'
produces the expected output:
point 66.686331040925

Which PHP version is required for str_split?

I relogin to my server in dreamhost and test some scripts.And I found I couldn't use str_split. Message of Undefined function was given.I checked the version in the server and its PHP Version is 5.2.12.And I just wonder which version is required?Thanks.
Testcode:
<?php
$arr = str_split("lsdjflsdjflsdjflsdjfl");
print_r($arr);
?>
Message:
Fatal error: Call to undefined function: str_split() in /test.php on line 3
Edit #Justin Johnson
I checked the server's system directory,and I found there are two versions of PHP in Dreamhost.In user's webroot,file will be parsed by PHP5 and that's why I got php 5.2.12 by putting a phpinfo.php in the webroot.And if php files are ran in command line directly using php test.php,another php version which is 4.x worked.That's the reason I got an error.When I use
/usr/local/php5/bin/php test.php
Everything is fine.
Rather than use str_split, it's usually much easier to iterate through the characters of the string directly:
$s="abc";
$i=0;
while(isset($s[$i])) {
echo $s[$i++]." ";
}
see?
First off: The PHP documentation will always say what version is required for every function on that function's documentation page directly under the function name.
It is possible that an .htaccess file is somewhere in your path and is causing a previous version (<5) of PHP to be used. To double (or triple) check to make sure that you are running in the proper PHP version, place this code above the line where you call str_split
echo "version:", phpversion(),
"<br/>\nstr_split exists? ",
function_exists("str_split") ? "true" : "false";
However, as shown by Col. Shrapnel, it is not necessary to convert a string to an array of individual characters in order to iterate over the characters of that string. Strings can also be iterated over using traditional iteration methods, thus making the call to str_split unnecessary and wasteful (unless you need to segment the string into fixed length chunks, e.g.: str_split($s, 3))
foreach ( str_split($s) as $c ) {
// do something with character $c
}
can be replaced by
$s = "lsdjflsdjflsdjflsdjfl";
for ( $i=0; isset($s[$i]); ++$i ) {
// do something with character $s[$i]." ";
}
which is equally, if not more clear.
According to dreamhost wiki, you need to switch to php5 manually from control panel, if you created your domain before 2008 sept.
http://wiki.dreamhost.com/Installing_PHP5#Using_DreamHost.27s_PHP_5
PHP 5 was added to all plans by
DreamHost as of June 2005. As of
September 2008, support for PHP4 was
discontinued, so you can no longer
switch back to PHP 4 from PHP 5 from
the panel.
If you haven't switched to PHP 5 yet,
you can do this in the Control Panel.
But, again, you will not be able to
switch back to PHP 4 after switching
to PHP 5.
Here's how to switch from PHP 4 to PHP
5:
Log into the DreamHost Control Panel.
Click Domains, then Manage Domains.
Click the wrench icon next to the domain you want to activate PHP 5
on (under the Web Hosting column).
Select PHP 5.x.x from the dropdown menu.
Click Change fully hosted settings now! at the bottom of the
section.
Repeat steps 3-5 for each additional domain you want to
activate.
you could also check your php version with
<?php
phpinfo();
?>
The version required is PHP 5 or later. So theoretically your program should work.
If you can't get str_split to work, just use a string as an array:
$stuff = "abcdefghijkl";
echo $stuff[3];
will produce
d
This method is fastest, anyway. I don't know if it suits your needs, but if it does, I hope it helps!
Could be anything in your code. How do we know its not a 10 line script or 2000 line script?
You can use preg_split() to split an array into single characters, but it will return an extra empty string at the begining and the end.
$a = preg_split("//","abcdefg");
echo json_encode($a);
prints:
["","a","b","c","d","e","f","g",""]

Categories