PHP error on testing server - php

I have a bit of PHP code that works fine on my production server but not on my test server. Here is the code:
function callProcedure0(&$connection, $procname, $dofunction)
{
mysqli_multi_query($connection, "CALL " . $procname . "();");
$first_result = 1;
do
{
$query_result = mysqli_store_result($connection);
if ($first_result)
{
$dofunction($query_result);
$first_result = 0;
}
if ($query_result)
{
mysqli_free_result($query_result);
}
$query_result = NULL;
} while(mysqli_next_result($connection));
}
...
function doGenres($in_result)
{
global $genre_array, $game_array, $genre_order_array;
$genre_count = 1;
// foreach is necessary when retrieving values since gaps may appear in the primary key
while ($genre_row = mysqli_fetch_row($in_result)) // line 81 is here!
{
$genre_array[] = $genre_row[0];
$genre_order_array[$genre_row[1] - 1] = $genre_count;
$game_array[] = [[],[]];
$genre_count += 1;
}
}
...
callProcedure0($con, "get_genres_front", doGenres); // line 138 is here!
The "get_genres_front" bit refers to a stored procedure on my database. Here are the errors:
Notice: Use of undefined constant doGenres - assumed 'doGenres' in /opt/lampp/htdocs/keyboard/keyboard.php on line 138
Again, there are no problems on the production server which is using Apache 2.2.23, MySQL 5.1.73-cll, PHP 5.4.26. The test server where things are broken is running Apache 2.4.10, MySQL 5.6.21, PHP 5.5.19.
Did something change in recent software versions? Thanks.
[edit]
This is not a duplicate question. I'm worried about the first error. I already know what to do about the second error which I have deleted.

The code you have posted is wrong, you must pass function name as string and then use call_user_func to invoke this function.
In your callProcedure0 function change
$dofunction($query_result);
to
call_user_func($dofunction, $query_result);
And then call it with the function name as string like this
callProcedure0($con, "get_genres_front", "doGenres");
The above code could work also with invoking the function with
$dofunction($query_result);
on some php versions, but the line where you pass the function name it should be string, otherwise PHP assumes it is a constant.

Related

PHP Deprecated: Automatic conversion of false to array is deprecated adodb-mssqlnative.inc.php on line 154

We are upgrading PHP to version 8.1. Using MS Sql Server DB. It all seems to work correctly but I see repeated messages in the log file:
[03-Feb-2022 11:51:18 America/New_York] PHP Deprecated: Automatic conversion of false to array is deprecated in C:...\includes\adodb\drivers\adodb-mssqlnative.inc.php on line 154
I've updated adodb to version version 5.22 but that did not stop the messges from logging. The ini file has
extension=php_sqlsrv_81_nts_x64.dll
extension=php_pdo_sqlsrv_81_nts_x64.dll
Does anyone know how to fix this problem?
This is a known issue of backwards incompatibility, affecting the ADOdb library version 5.22.1 and older. PHP 8.1 warns you on autovivification of false-y values and some future version of PHP will throw an error when you do it.
PHP natively allows for autovivification (auto-creation of arrays from falsey values). This feature is very useful and used in a lot of PHP projects, especially if the variable is undefined. However, there is a little oddity that allows creating an array from a false and null value.
And they give this example
// From false
$arr = false;
$arr[] = 2;
I went and found the file in question and this is the function it's in
function ServerInfo() {
global $ADODB_FETCH_MODE;
static $arr = false;
if (is_array($arr))
return $arr;
if ($this->fetchMode === false) {
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
} elseif ($this->fetchMode >=0 && $this->fetchMode <=2) {
$savem = $this->fetchMode;
} else
$savem = $this->SetFetchMode(ADODB_FETCH_NUM);
$arrServerInfo = sqlsrv_server_info($this->_connectionID);
$ADODB_FETCH_MODE = $savem;
$arr['description'] = $arrServerInfo['SQLServerName'].' connected to '.$arrServerInfo['CurrentDatabase'];
$arr['version'] = $arrServerInfo['SQLServerVersion'];//ADOConnection::_findvers($arr['description']);
return $arr;
}
The problem is that it starts with
static $arr = false;
and then tries to autovivificate a non-array (line 154 in your error)
$arr['description'] = $arrServerInfo['SQLServerName'].' connected to '.$arrServerInfo['CurrentDatabase'];
You should be able to fix it (in theory) by making sure it's an array (something they should have done anyways). Add this above that line to make it one before it tries to append
if(!is_array($arr)) $arr = [];

Using Dynamic Variable Names to Call Static Variable in PHP

I am trying to implement a logging library which would fetch the current debug level from the environment the application runs in:
23 $level = $_SERVER['DEBUG_LEVEL'];
24 $handler = new StreamHandler('/var/log/php/php.log', Logger::${$level});
When I do this, the code fails with the error:
A valid variable name starts with a letter or underscore,followed by any number of letters, numbers, or underscores at line 24.
How would I use a specific Logger:: level in this way?
UPDATE:
I have tried having $level = "INFO" and changing ${$level} to $$level. None of these changes helped.
However, replacing the line 24 with $handler = new StreamHandler('/var/log/php/php.log', Logger::INFO); and the code compiles and runs as expected.
The variable itself is declared here
PHP Version => 5.6.99-hhvm
So the answer was to use a function for a constant lookup:
$handler = new StreamHandler('/var/log/php/php.log', constant("Monolog\Logger::" . $level));
<?php
class Logger {
const MY = 1;
}
$lookingfor = 'MY';
// approach 1
$value1 = (new ReflectionClass('Logger'))->getConstants()[$lookingfor];
// approach 2
$value2 = constant("Logger::" . $lookingfor);
echo "$value1|$value2";
?>
Result: "1|1"

PHP Array breaking

This works on my test environment, but on my live server there is a later version of PHP which is throwing up an error and breaking my program
The code is
$oldFile = fopen("D:/ftpfolderreport/report/" . $last_file, "r");
while(!feof($oldFile))
{
$buffler = fgets($oldFile);
$bufflerArray = explode(",", $buffler);
$key = $bufflerArray[0];
$oldFileArray[$key] = $bufflerArray[1];
}
fclose($oldFile);
This line:
$oldFileArray[$key] = $bufflerArray[1];
Is throwing out this error
Notice: Undefined offset: 1 in D:\apps\wamp\www\Compliance2\compareFtpReports.php on line 57
I think this is to do with how I'm adding the $key variable inside the argument. I've tried it as ["$key"] and ['$key'] but it doesn't like it.
I have tried defining the key variable earlier in the program but still doesn't like it. I've been searching around online but can't find anything of help. Anyone any ideas?
Thanks,
Stephen.
add checks for empty
if (!empty($bufflerArray[1])) {
$key = $bufflerArray[0];
$oldFileArray[$key] = $bufflerArray[1];
}

PHP check existance of negative index not working?

I have some code that runs fine until it hits this:
if(array_key_exists($snIdx, $fields));
$surnameField = trim($fields[$snIdx]);
or other version I tried:
if(isset($fields[$snIdx));
$surnameField = trim($fields[$snIdx]);
The $snIdx = -1.
It gives me Undefined offset error at second line ($surname = trim...).
I think I don't need to paste rest of code as the exception says there is sth wrong with those functions. My PHP version is 5.4.16.
Remove the semicolon from the end of the if line. Otherwise it's equivalent to:
if( something) {
// no-op
}
$surnameField = trim($fields[$snIdx]); // undefined offset error.

Creating default object from empty value in php 5.4

i have some code like this:
function getAuthorizedPFComponents($pfState)
{
$authorizedPFComponents = new \stdClass();
$compTypeMap=array('platform'=>'pfAuthorizations','mainSite'=>'mainSiteAuthorizations','microSites'=>'microSiteAuthorizations','apps'=>'appAuthorizations');
foreach($compTypeMap as $compType=>$tagName)
{
$authorizationsNode=$this->pfAuthXMLDOM->getElementsByTagName($tagName)->item(0);
foreach($authorizationsNode->getElementsByTagName('authorizations') as $pfComponentAuthElem)
{
foreach($pfComponentAuthElem->getElementsByTagName('allow') as $allow)
{
switch($allow->getAttribute('orgCode'))
{
case 'K_ALL':
{
$authorizedPFComponents->$compType->{$pfComponentAuthElem->getAttribute('pfComponentCode')}->storeCode=$allow->getAttribute('storeCode');
}
}
It shows a warning:
Warning: Creating default object from empty value
The warning is traced back to the code under case K_ALL:
This was too long for a mere comment, so I'll remove it when it has outlived its usefulness.
First thing you should do is make the code simpler; there's a lot of stuff going on in that one statement:
$compCode = $pfComponentAuthElem->getAttribute('pfComponentCode');
$storeCode = $allow->getAttribute('storeCode');
And add debug code:
var_dump($authorizedPFComponents->$compType);
var_dump($authorizedPFComponents->$compType->$compCode);
$authorizedPFComponents->$compType->$compCode->storeCode = $storeCode;
Consider this code:
$x->y = 'test';
If $x is not defined, it will issue a warning:
Warning: Creating default object from empty value in xxx
The same goes for your chain of references:
$authorizedPFComponents->$compType->$compCode->storeCode
If any of those paths is empty, the next ->yyy will cause that warning.

Categories