change PHP compatibility from 7.4 to 8.0 - php

I have a php script and need to make this code line compatible to php8.0:
if ((is_array($key) && is_array($value)) || (strlen($key) > 0 && strlen($value) > 0)) {
I am not a programmer/coder. What I found out is, that the second part
(strlen($key) > 0 && strlen($value) > 0) makes the error.
Because I get this error message in the application:
Response: {"result":null,"error":{"code":0,"message":"strlen (): Argument #1 ($string) must be of type string, jtl\Connector\Model\Identity given","data":"Exception 'TypeError' (Code: 0) with message 'strlen(): Argument #1 ($string) must be of type string, jtl\Connector\Model\Identity given' in C:\xampp\htdocs\mod2060\jtlconnector\vendor\ jtl\connector\src\Core\Database\Mysql.php:567 "},"jtlrpc":"2.0","id":"unknown"}
Exception bei category.push: strlen(): Argument #1 ($string) must be of type string, jtl\Connector\Model\Identity given
I just changed PHP Version from 7.45 to 8.00 and get the error.
If I go back to PHP 7.45 it works fine again.

This error is being thrown because either $key or $value is an object and not a string - the error message says it is an object of type 'jtl\Connector\Model\Identity'. So you would either need to modify that library and create a __toString magic method function in it for that class, which defines how to convert that object to a string, or you might want to do an is_object check instead of (or before) using strlen.
1 https://www.php.net/manual/en/language.oop5.magic.php#object.tostring

Related

PHP8 - Fatal User Error: Unsupported operand types: array & int

I am trying to fix some PHP8 errors in forum software, need assistance with this.
Error thrown is Fatal User Error: Unsupported operand types: array & int on these lines.
$forumperms & $this->registry->bf_ugp_forumpermissions['cangetattachment'],
$forumperms & $this->registry->bf_ugp_forumpermissions['canseethumbnails']
For reference the whole code section below.
/*
* Processes any attachments to this post.
*/
function process_attachments()
{
global $show;
$forumperms = fetch_permissions($this->thread['forumid']);
require_once(DIR . '/packages/vbattach/attach.php');
$attach = new vB_Attach_Display_Content($this->registry, 'vBForum_Post');
if ($this->post['allattachments'])
{
foreach($this->post['allattachments'] AS $attachmentid => $info)
{
if (!$this->post['attachments'][$attachmentid])
{
unset($this->post['allattachments'][$attachmentid]);
}
}
$attach->process_attachments(
$this->post,
$this->post['allattachments'],
(THIS_SCRIPT == 'external'),
can_moderate($this->forum['forumid'], 'canmoderateattachments'),
$forumperms & $this->registry->bf_ugp_forumpermissions['cangetattachment'], //ERROR
$forumperms & $this->registry->bf_ugp_forumpermissions['canseethumbnails'] //ERROR
);
}
else
{
$show['attachments'] = $show['moderatedattachment'] = $show['thumbnailattachment'] = $show['otherattachment'] = false;
$show['imageattachment'] = $show['imageattachmentlink'] = false;
}
}
Have not tried anything yet trying to work out how those lines must be changed for PHP8 compatability.
Unsupported operand type errors occurred when some kind of mathematical calculation was involved in some part of the code and one of the operands could not be automatically converted to the other type. In your case, the calculation seems to have one operand as int and the other one being an array and an array could not be automatically converted to int, hence the issue.
In your code, the 2 lines that you have marked as the error-causing lines are not the actual point of error. Starting from PHP 8 strict typings have been introduced almost everywhere in PHP core functions so legacy code will break. You can read more here
I think you need to check for vB_Attach_Display_Content::process_attachments method for any mathematical calculations. In the given code block you are passing different parameters to that function and maybe those parameters are not strictly typed. Hence the function is accepting anything.

parse_str syntax errors after upgrading from PHP 7.4 to 8.0 [duplicate]

This question already has answers here:
Fatal error: Uncaught ArgumentCountError: parse_str() expects exactly 2 arguments, 1 given. How do i update for latest php version?
(2 answers)
Closed 1 year ago.
After updating to PHP8, my site has started crashing with the error
PHP message: PHP Fatal error: Uncaught ArgumentCountError: parse_str() expects exactly 2 arguments, 1 given
I believe it some change in the php 8 syntax, but I am not sure. I used to use php 7.4
The problematic line is:
$url_vars = parse_str($parse_url['query'] ?? 0);
The section of the problematic script is below:
if ( $referrer !== FALSE && $referrer !== '' && stripos($referrer, '://') )
{
$parse_url = parse_url($referrer);
$domain = $parse_url['host'];
$query = $parse_url['query'] ?? 0;
$dotdomain = '.'.$domain;
if ( strlen($parse_url['query'] ?? 0) >= 1 )
{
$url_vars = parse_str($parse_url['query'] ?? 0);
if (FALSE === empty($url_vars['q']))
{
$utm_keyword = $url_vars['q'] ?? 0;
}
}
Can someone more familiar with php 8 see any obvious error on the code above?
As of PHP 8.0 the second parameter, result, is no longer optional and is required.
result should be the variable you want to place your output into.
You can view the changelog on the official parse_str documentation.
parse_str($parse_url['query'] ?? 0, $url_vars);

Uncaught ArgumentCountError: Too few arguments to function phpfmg_hsc(), 1

I am very sorry to be asking for help and it's been a while since I last did that.
In general I find my own solutions however I recently switched my website PHP version 7.0 and it seems that the mail send form is no longer working as a result.
The error I receive is:
Fatal error: Uncaught ArgumentCountError: Too few arguments to function phpfmg_hsc(), 1 passed in contact2/indexnl.php on line 61 and exactly 2 expected in form.lib.php:1244
Stack trace:
#0 indexnl.php(61): phpfmg_hsc('field_1')
#1 form.lib.php(193): phpfmg_form('')
#2 indexnl.php(9): phpfmg_display_form()
#3 {main}
thrown in /public_html/contact2/form.lib.php on line 1244
In these lines i have:
#0
<textarea name="field_1" id="field_1" rows=4 cols=25 class='text_area'><?php phpfmg_hsc("field_1"); ?></textarea>
#1
phpfmg_header( $title, $keywords, $description );
if( !$isHideForm ){
phpfmg_form($sErr);
}else{
phpfmg_thankyou();
};
phpfmg_footer();
return;
}
#2
phpfmg_display_form();
#3
function phpfmg_hsc($field, $default){
echo isset($_POST[ $field ])
? HtmlSpecialChars( $_POST[ $field ] )
: $default;
}
I'm sorry for asking what I'm sure for a lot of you higher level programmers is stupid, but can someone please help me out? I really have tried to understand it, but I don't.
I look forward to your help.
-Isaac
I would hazzard a guess that this has always been an error, but when you changed versions of PHP the new php.ini has got error reporting turned on.
#3 tells you how to fix this!
The second parameter is what it should use as a default if the input field has not previously been set.
So change all calls to phpfmg_hsc() to have a default, the simplest solution would be to do
phpfmg_hsc('field_1', '')
to signify to leave the field empty
You might consider changing the function itself like this, but as that code is not yours, that might not be the best idea as if you ever update that addin your problem will come back.
function phpfmg_hsc($field, $default=''){
echo isset($_POST[ $field ])
? HtmlSpecialChars( $_POST[ $field ] )
: $default;
}

Throwing errors from its "correct" source

I hope the title isn't too confusing, I'll try to explain better below.
Suppose I have a function in a separate file, functions.php:
function divide($num1, $num2) {
if ($num1 == 0 || $num2 == 0) {
trigger_error("Cannot divide by 0", E_USER_ERROR);
} else {
return ($num1 / $num2);
}
}
And another file that calls it:
include "functions.php";
echo divide(10, 0);
My error is
Fatal error: Cannot divide by 0 in
C:\Users\Derek\Desktop\projects\functions.php on line 5
My question is, how do I make that error instead point to the location of the error in the main code, so I instead get:
Fatal error: Cannot divide by 0 in
C:\Users\Derek\Desktop\projects\main.php on line 3
The particular reason I want this is because I have a function called load_class that simply finds a PHP file and instantiates the object inside, but if given an incorrect file name, it reports an error from inside load_class, which is technically true, but it's not particularly helpful if I don't remember where I called load_class in the first place. I would like the error to point to the file that called load_class incorrectly.
Also, I would like to write a function error() (something like below) that when given a message as a parameter would throw more "meaningful" error messages, but when done that way, the error always says it comes from error(), not from where the error actually came from!
For example, in an error.php:
/**
* error()
*
* Throws an error of a certain type
*
* #param string $type The type of error. "Fatal", "warning," or "notice"
* #param string $message A description of the error
* #return void
*/
function error($type, $message) {
switch (strtolower($type)) {
case 'fatal':
trigger_error($message, E_USER_ERROR);
break;
case 'notice':
trigger_error($message, E_USER_NOTICE);
default:
trigger_error($message, E_USER_WARNING);
break;
}
}
And in an index.php
error("fatal", "A sample warning!");
My error given is:
Fatal error: A sample warning! in
C:\Users\Derek\Desktop\projects\synthesis\sys\Error.php on line 45
But the error didn't occur in error.php, it happened in index.php! How can I make it show where it really came from?
The debug_backtrace function allows you to obtain the stacktrace as an array. You can pick the original location from there.
Next to that you need to slip into the error message to make this look-alike. Example:
function divide($num1, $num2) {
if ($num1 == 0 || $num2 == 0) {
trigger_error_original("Cannot divide by 0", E_USER_ERROR);
} else {
return ($num1 / $num2);
}
}
function trigger_error_original($message, $type) {
$trace = debug_backtrace(FALSE);
list($location) = array_slice($trace, 1, 1) + array('file' => 'unknown', 'line' => 'unknown');
$message .= sprintf(" in %s on line %d\nTriggered", $location['file'], $location['line']);
trigger_error($message, $type);
}
divide(1, 0);
The error message than shows something like:
> php test-pad.php
Fatal error: Cannot divide by 0 in test-pad.php on line 18
Triggered in test-pad.php on line 15
The downside of this is, that you need to change your code to have this "feature". If you need this for debugging your own code, it's much better that you enable backtraces in your logs. The Xdebug extension does this for you, or you can write your own error handler that takes care of that.
See as well the related question Caller function in PHP 5?. I used array_slice so that you could create an additional parameter to define the number of steps you want to go "up" in the backtrace.
Use debug_backtrace(), and debug_print_backtrace() for a full call stack. These are especially effective when using Xdebug, which will override the function to colorize the output.
I have this same problem...
#1: while 10/0 = ERROR, 0/10 = 0 is perfectly legal, you shouldn't have an exception for that.
#2: when you include a file, it effectively becomes part of this new file, so perhaps you might have to toy a little bit with things like __FILE__ and see if you can make it point it to the file before it gets included in the other file..
You can use xdebug - it will show you the stacktrace or you can register your own error handndler and display the stacktrace. Just check the example in php.net for set_error_handler().
Maybe exceptions are better to use in your case. You get the full stacktrace and can locate where the function was called without relying on some tricky code :)

How do you read from a multidimensional variant array returned from a COM object in PHP?

I'm working with a COM object that returns a multidimensional VARIANT array (vt_array), and I'm trying to read values from the array.
When I use print_r($mdArray) it displays variant Object.
(variant_get_type($mdArray) returns 8204.)
I tried using foreach ($mdArray as $oneArray) but I get the message:
Warning: Loader::getfields() [loader.getfields]: Can only handle
single dimension variant arrays (this
array has 2) in
C:\Inetpub\wwwroot\root\script\fileloader.php
on line 135 Fatal error: Uncaught
exception 'Exception' with message
'Object of type variant did not create
an Iterator' in
C:\Inetpub\wwwroot\root\script\fileloader.php:135
Stack trace: #0
C:\Inetpub\wwwroot\root\script\fileloader.php(135):
Loader::getfields() #1
C:\Inetpub\wwwroot\root\testloader.php(21):
Loader->getfields() #2 {main} thrown
in
C:\Inetpub\wwwroot\root\script\fileloader.php
on line 135
(The foreach loop is on line 135)
The only information I can get about the array is by using count($mdArray) which returns 8.
If anyone here has any experience reading from multidimensional VARIANT arrays please tell me how this can be done.
Try this to extract array values through "VBScript". Yes, you read that right...
<?php
$com = new COM("MSScriptControl.ScriptControl");
$com->Language = 'VBScript';
$com->AllowUI = false;
$com->AddCode('
Function getArrayVal(arr, indexX, indexY)
getArrayVal = arr(indexX, indexY)
End Function
');
$y1 = 0;
$y2 = 1;
for ($x=0; $x < count($mdArray); $x++) {
echo $com->Run('getArrayVal', $mdArray, $x, $y1) . ": ";
echo $com->Run('getArrayVal', $mdArray, $x, $y2) . "\n";
}
?>
Tested good on a VBScript-created array, which otherwise gave me the exact same issues and errors as you when trying to coerce it to behave like a PHP array. The above method spawned by the unholy union of PHP and VBscript should extract values piece by piece just fine.
To explain $y1 = 0; $y2 = 1;, keep in mind the parameters of the VBScript function are byref, so you can't pass anything in except a variable.
Edit: Added $com->AllowUI = false to shut off any on-screen popups. Otherwise it would freeze the request if a MsgBox() somehow got called from VBScript and no one was at the server terminal to click 'ok'.

Categories