<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://sugarclub.sugarai.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>PHP 7.4 Warnings to PHP8.x Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors</link><description /><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title>PHP 7.4 Warnings to PHP8.x Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors</link><pubDate>Wed, 10 Sep 2025 18:25:36 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:dca5875d-93ad-45ff-9416-62a2e4f1b912</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors#comments</comments><description>Current Revision posted to Dev Tutorials by Rafael Fernandes on 9/10/2025 6:25:36 PM&lt;br /&gt;
&lt;div class="flex flex-grow flex-col max-w-full"&gt;
&lt;div data-message-author-role="assistant" data-message-id="e2b43fa2-3f21-462c-a90a-1c802c969a4f"&gt;
&lt;div class="markdown prose w-full break-words dark:prose-invert dark"&gt;
&lt;h2 id="mcetoc_1hgqkj3ct0"&gt;PHP Warnings to Runtime Errors&lt;/h2&gt;
&lt;p&gt;In the transition from PHP 7.4 to PHP 8.x, notable changes have occurred with certain runtime errors that were previously treated as warnings by PHP. As of PHP 8.x, these errors have been elevated to runtime errors.&lt;/p&gt;
&lt;p&gt;Automated tools like Rector can do a lot when it comes to lexical scanning but runtime (&lt;span&gt;non-lexical and more closely tied to the logic and&amp;nbsp;data aspects of code execution&lt;/span&gt;) its help is limited.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Defensive coding techniques serve as a robust shield against runtime errors, empowering&amp;nbsp;you&amp;nbsp;to anticipate and prevent such issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our research,&amp;nbsp;&lt;span&gt;we&amp;#39;ve identified several of these techniques designed to assist you in addressing and rectifying potential errors.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Importance of Sugar&amp;nbsp;logs&lt;/h2&gt;
&lt;p&gt;Logs are crucial to help you understand the services and customizations you develop and operate.&amp;nbsp;Not only can logs help you troubleshoot problems, but they can also help you understand your&amp;nbsp;customizations better, and sometimes provide you with unforeseen logic errors that your code might not expect.&amp;nbsp;Even after applying defensive coding, you may end up with errors in your logs that will not propagate to the requestor, that being a UI trigger or a cron job, so it is important to keep an eye on your logs.&lt;/p&gt;
&lt;p&gt;Some Sugar errors will not be noticeable by users but they&amp;#39;ll be logged in the sugarcrm.log. It is your responsibility as Sugar instance&amp;#39;s administrator to check the logs, understand the causes, and possibly provide fixes.&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable PHP logs&lt;/h2&gt;
&lt;p&gt;The starting point to identify such errors is to enable PHP logs.&amp;nbsp;&lt;span&gt;This foundational step will provide the necessary data (warnings/errors) so you can implement effective defensive coding to prevent them from happening.&lt;/span&gt;&lt;/p&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATION&lt;/code&gt; Log in to the PHP error log and test your code.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Locate your &lt;code&gt;php.ini&lt;/code&gt; file. The location can vary based on your operating system and PHP installation. Common paths include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows: &lt;code&gt;C:\Program Files\PHP\php.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;/etc/php/{version}/apache2/php.ini&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;code&gt;php.ini&lt;/code&gt; file in a text editor with administrative privileges.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for the &lt;code&gt;error_reporting&lt;/code&gt; directive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the directive to include &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATED&lt;/code&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;error_reporting = E_ALL &amp;amp; ~E_NOTICE | E_WARNING | E_DEPRECATED
&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Understanding Rector&amp;#39;s Limitations&lt;/h2&gt;
&lt;p&gt;While Rector serves as a valuable tool for scanning code and conducting lexical analysis, it&amp;#39;s important to note its limitations regarding Sugar expressions used in calculated fields, SugarBPM, and similar contexts.&lt;/p&gt;
&lt;p&gt;During runtime, Sugar evaluates expressions using various methods, including PHP evaluation. This introduces the possibility of encountering exceptions&amp;nbsp;similar to those in native PHP code. Therefore, developers must review their expressions to ensure they are &amp;quot;code safe&amp;quot; for Sugar interpreter, for example, by checking if a variable is not empty before applying a function to it.&lt;/p&gt;
&lt;p&gt;Exceptions occurring during expression evaluation are logged in the &lt;code&gt;sugarcrm.log&lt;/code&gt; file. This log serves as a valuable resource for developers, facilitating the analysis and resolution of runtime issues within&amp;nbsp;Sugar.&lt;/p&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Applying defensive code to avoid Runtime Errors&lt;/h2&gt;
&lt;h3 id="mcetoc_1hgqkpl7g0"&gt;PHP Warning: count(): Parameter must be an array or an object that implements Countable in *&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;safeCount&lt;/i&gt;&lt;/b&gt;&lt;b&gt; will take care of it&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;For Sugar, the best practice is to use &lt;code&gt;safeCount()&lt;/code&gt; instead of &lt;code&gt;count()&lt;/code&gt;!&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g1"&gt;PHP Warning: A non-numeric value encountered*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Occurs when invalid strings are coerced using operators expecting numbers (+ - * / ** % &amp;lt;&amp;lt; &amp;gt;&amp;gt; | &amp;amp; ^) or their assignment equivalents.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cast the values to int or float before the arithmetic operation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Check the values for &lt;i&gt;is_numeric&lt;/i&gt;&lt;i&gt;($value)&lt;/i&gt; and skip the calculation if the values are not numeric.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g2"&gt;PHP Warning: sizeof(): Parameter must be an array or an object that implements Countable in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;if you have code like &lt;code&gt;&lt;i&gt;$a = &lt;/i&gt;&lt;i&gt;sizeof&lt;/i&gt;&lt;i&gt;($b) + 1;&lt;/i&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;replace sizeof with &lt;code&gt;safeCount&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: strlen() expects parameter 1 to be string, array given in*&lt;/h3&gt;
&lt;p&gt;Add defensive for example:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($some_value)) {
  $len = strlen($some_value);
} else { 
  // throw error or deal with your data
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkr1n54"&gt;&lt;br /&gt;PHP Warning: array_key_exists(): The first argument should be either a string or an integer in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ((is_string($haystack) || is_numeric($haystack)) &amp;amp;&amp;amp; array_key_exists($haystack, $myArray)) {
    // continue with your logic  
} else { 
    // throw error or deal with your data;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqksl5u5"&gt;PHP Warning: strpos(): Empty needle in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive code, for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (isset($haystack) &amp;amp;&amp;amp; !empty($haystack) &amp;amp;&amp;amp; isset($needle) &amp;amp;&amp;amp; !empty($needle) &amp;amp;&amp;amp; strpos($haystack, $needle, $offset)) {
   // continue with your logic
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqktv9u6"&gt;PHP Warning: array_intersect(): Expected parameter 1 to be an array, null given in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_array($array) &amp;amp;&amp;amp; is_array($arrays)) {
   $intersect = array_intersect($array, $arrays);
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: Creating default object from empty value*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// Option 1: Skip execution branch if the value is not an object
$a = BeanFactory::newBean(&amp;#39;someweirdstuff&amp;#39;);
if (!($a instanceof SugarBean)) {
  return;
}
$a-&amp;gt;b = &amp;#39;c&amp;#39;;

// Option 2: In cases when the variable is used without being initialized - initialize it first
$a = new stdClass();
$a-&amp;gt; b = ‘c’;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: DateTime::diff() expects parameter 1 to be DateTimeInterface, null given*&lt;/h3&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: DateTime::setTimezone() expects parameter 1 to be DateTimeZone, string given&lt;span class="heading-anchor-wrapper"&gt;&lt;span class="cc-1afrefi"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$date = new \DateTime();
if ($otherDate instanceof \DateTimeInterface) {
  $diff = $date-&amp;gt;diff($otherDate);
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Division by zero&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ($rate != 0) {
  $result = $amount / $rate;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Illegal offset type in isset or empty; PHP Warning: Illegal offset type&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;Array keys can only be int or string. Float, boolean and null get converted transparently (though it may be signal that something went wrong), but arrays, objects and resources don&amp;rsquo;t.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding::&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($key) || is_int($key)) {
  $map[$key] = $value;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Illegal string offset&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;Array keys can only be int or string. Float, boolean and null get converted transparently (though it may be signal that something went wrong), but arrays, objects and resources don&amp;rsquo;t.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding::&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$a = ‘some_string’;
if (is_array($a)) {
  var_dump($a[‘key’]);
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Use of undefined constant SOME_NAME - assumed &amp;#39;SOME_NAME&amp;#39;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This may have multiple causes, the most common is string literal, not wrapped in quotes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is to wrap these to quotes:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$status = $row[&amp;#39;status&amp;#39;];
$duration = $n . &amp;#39;hours&amp;#39;;
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: fclose() expects parameter 1 to be resource, bool given&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The solution is defensive coding, but in case of resources it should be applied as close as possible to the place of its initialization&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$file = fopen($name, &amp;#39;r&amp;#39;);
if ($file === false) {
    // handle error, interrupt execution - whatever appropriate
}
// do something
fclose($file);&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: call_user_func() expects parameter 1 to be a valid callback, function &amp;#39;my_func_name&amp;#39; not found or invalid function name&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;The solution is also defensive coding:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_callable(&amp;#39;my_func_name&amp;#39;)) {
    call_user_func(&amp;#39;my_func_name&amp;#39;);
} else {
    // handle error
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: implode(): Invalid arguments passed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Happens when the second argument is not array:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_array($names)) {
    var_dump(implode(&amp;#39;, &amp;#39;, $names));
}

// or

$pieces = is_array($names) ? $names : [];
var_dump(implode(&amp;#39;, &amp;#39;, $pieces));&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: max(): Array must contain at least one element&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (safeCount($items) &amp;gt; 0) {
    $best = max($items);
} else {
    // handle error, assign some defaults, etc.
}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;PHP Warning: Attempt to assign property &amp;#39;team_id&amp;#39; of non-object&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Defensive coding - check if the object is really an instance of the class you assuming. Makes sense to perform this check as close to object initialization as possible (or at the beginning of the function if the object is passed as an argument)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!($a instanceof SomeClass)) {
    // handle error, interrupt execution, etc.
}
$a-&amp;gt;b = 1;&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: array_multisort(): Array sizes are inconsistent*&lt;/h3&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: array_combine(): Both parameters should have an equal number of elements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;These warnings have similar cause and solution. Make sure, that sorted arrays are of the same size&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (safeCount($apples) !== safeCount($oranges)) {
    // handle error
}
array_multisort($apples, $oranges);&lt;/pre&gt;&lt;/p&gt;
&lt;h3&gt;PHP Warning: array_multisort(): Argument #1 is expected to be an array or a sort flag&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Defensive coding. Assuming here that sorting flags and order are hardcoded, otherwise, check them with is_integer&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!is_array($apples) || !is_array($oranges)) {
    // handle error
}
array_multisort($apples, SORT_ASC, SORT_STRING, $oranges, SORT_ASC, SORT_STRING);
&lt;/pre&gt;&lt;/p&gt;
&lt;h3&gt;PHP Warning: sprintf(): Too few arguments&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Carefully check that number of arguments to sprintf corresponds to number of placeholders in format string&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;echo sprintf(&amp;#39;%s is the capital of %s&amp;#39;, &amp;#39;London&amp;#39;); // error - 2 placeholders but 1 argument
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>PHP 7.4 Warnings to PHP8.2 Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors/revision/11</link><pubDate>Tue, 12 Mar 2024 18:35:36 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:dca5875d-93ad-45ff-9416-62a2e4f1b912</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors#comments</comments><description>Revision 11 posted to Dev Tutorials by Rafael Fernandes on 3/12/2024 6:35:36 PM&lt;br /&gt;
&lt;div class="flex flex-grow flex-col max-w-full"&gt;
&lt;div data-message-author-role="assistant" data-message-id="e2b43fa2-3f21-462c-a90a-1c802c969a4f"&gt;
&lt;div class="markdown prose w-full break-words dark:prose-invert dark"&gt;
&lt;h2 id="mcetoc_1hgqkj3ct0"&gt;PHP Warnings to Runtime Errors&lt;/h2&gt;
&lt;p&gt;In the transition from PHP 7.4 to PHP 8.2, notable changes have occurred with certain runtime errors that were previously treated as warnings by PHP. As of PHP 8.x, these errors have been elevated to runtime errors.&lt;/p&gt;
&lt;p&gt;Automated tools like Rector can do a lot when it comes to lexical scanning but runtime (&lt;span&gt;non-lexical and more closely tied to the logic and&amp;nbsp;data aspects of code execution&lt;/span&gt;) its help is limited.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Defensive coding techniques serve as a robust shield against runtime errors, empowering&amp;nbsp;you&amp;nbsp;to anticipate and prevent such issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our research,&amp;nbsp;&lt;span&gt;we&amp;#39;ve identified several of these techniques designed to assist you in addressing and rectifying potential errors.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Importance of Sugar&amp;nbsp;logs&lt;/h2&gt;
&lt;p&gt;Logs are crucial to help you understand the services and customizations you develop and operate.&amp;nbsp;Not only can logs help you troubleshoot problems, but they can also help you understand your&amp;nbsp;customizations better, and sometimes provide you with unforeseen logic errors that your code might not expect.&amp;nbsp;Even after applying defensive coding, you may end up with errors in your logs that will not propagate to the requestor, that being a UI trigger or a cron job, so it is important to keep an eye on your logs.&lt;/p&gt;
&lt;p&gt;Some Sugar errors will not be noticeable by users but they&amp;#39;ll be logged in the sugarcrm.log. It is your responsibility as Sugar instance&amp;#39;s administrator to check the logs, understand the causes, and possibly provide fixes.&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable PHP logs&lt;/h2&gt;
&lt;p&gt;The starting point to identify such errors is to enable PHP logs.&amp;nbsp;&lt;span&gt;This foundational step will provide the necessary data (warnings/errors) so you can implement effective defensive coding to prevent them from happening.&lt;/span&gt;&lt;/p&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATION&lt;/code&gt; Log in to the PHP error log and test your code.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Locate your &lt;code&gt;php.ini&lt;/code&gt; file. The location can vary based on your operating system and PHP installation. Common paths include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows: &lt;code&gt;C:\Program Files\PHP\php.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;/etc/php/{version}/apache2/php.ini&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;code&gt;php.ini&lt;/code&gt; file in a text editor with administrative privileges.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for the &lt;code&gt;error_reporting&lt;/code&gt; directive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the directive to include &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATED&lt;/code&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;error_reporting = E_ALL &amp;amp; ~E_NOTICE | E_WARNING | E_DEPRECATED
&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Understanding Rector&amp;#39;s Limitations&lt;/h2&gt;
&lt;p&gt;While Rector serves as a valuable tool for scanning code and conducting lexical analysis, it&amp;#39;s important to note its limitations regarding Sugar expressions used in calculated fields, SugarBPM, and similar contexts.&lt;/p&gt;
&lt;p&gt;During runtime, Sugar evaluates expressions using various methods, including PHP evaluation. This introduces the possibility of encountering exceptions&amp;nbsp;similar to those in native PHP code. Therefore, developers must review their expressions to ensure they are &amp;quot;code safe&amp;quot; for Sugar interpreter, for example, by checking if a variable is not empty before applying a function to it.&lt;/p&gt;
&lt;p&gt;Exceptions occurring during expression evaluation are logged in the &lt;code&gt;sugarcrm.log&lt;/code&gt; file. This log serves as a valuable resource for developers, facilitating the analysis and resolution of runtime issues within&amp;nbsp;Sugar.&lt;/p&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Applying defensive code to avoid Runtime Errors&lt;/h2&gt;
&lt;h3 id="mcetoc_1hgqkpl7g0"&gt;PHP Warning: count(): Parameter must be an array or an object that implements Countable in *&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;safeCount&lt;/i&gt;&lt;/b&gt;&lt;b&gt; will take care of it&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;For Sugar, the best practice is to use &lt;code&gt;safeCount()&lt;/code&gt; instead of &lt;code&gt;count()&lt;/code&gt;!&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g1"&gt;PHP Warning: A non-numeric value encountered*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Occurs when invalid strings are coerced using operators expecting numbers (+ - * / ** % &amp;lt;&amp;lt; &amp;gt;&amp;gt; | &amp;amp; ^) or their assignment equivalents.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cast the values to int or float before the arithmetic operation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Check the values for &lt;i&gt;is_numeric&lt;/i&gt;&lt;i&gt;($value)&lt;/i&gt; and skip the calculation if the values are not numeric.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g2"&gt;PHP Warning: sizeof(): Parameter must be an array or an object that implements Countable in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;if you have code like &lt;code&gt;&lt;i&gt;$a = &lt;/i&gt;&lt;i&gt;sizeof&lt;/i&gt;&lt;i&gt;($b) + 1;&lt;/i&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;replace sizeof with &lt;code&gt;safeCount&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: strlen() expects parameter 1 to be string, array given in*&lt;/h3&gt;
&lt;p&gt;Add defensive for example:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($some_value)) {
  $len = strlen($some_value);
} else { 
  // throw error or deal with your data
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkr1n54"&gt;&lt;br /&gt;PHP Warning: array_key_exists(): The first argument should be either a string or an integer in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ((is_string($haystack) || is_numeric($haystack)) &amp;amp;&amp;amp; array_key_exists($haystack, $myArray)) {
    // continue with your logic  
} else { 
    // throw error or deal with your data;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqksl5u5"&gt;PHP Warning: strpos(): Empty needle in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive code, for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (isset($haystack) &amp;amp;&amp;amp; !empty($haystack) &amp;amp;&amp;amp; isset($needle) &amp;amp;&amp;amp; !empty($needle) &amp;amp;&amp;amp; strpos($haystack, $needle, $offset)) {
   // continue with your logic
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqktv9u6"&gt;PHP Warning: array_intersect(): Expected parameter 1 to be an array, null given in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_array($array) &amp;amp;&amp;amp; is_array($arrays)) {
   $intersect = array_intersect($array, $arrays);
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: Creating default object from empty value*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// Option 1: Skip execution branch if the value is not an object
$a = BeanFactory::newBean(&amp;#39;someweirdstuff&amp;#39;);
if (!($a instanceof SugarBean)) {
  return;
}
$a-&amp;gt;b = &amp;#39;c&amp;#39;;

// Option 2: In cases when the variable is used without being initialized - initialize it first
$a = new stdClass();
$a-&amp;gt; b = ‘c’;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: DateTime::diff() expects parameter 1 to be DateTimeInterface, null given*&lt;/h3&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: DateTime::setTimezone() expects parameter 1 to be DateTimeZone, string given&lt;span class="heading-anchor-wrapper"&gt;&lt;span class="cc-1afrefi"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$date = new \DateTime();
if ($otherDate instanceof \DateTimeInterface) {
  $diff = $date-&amp;gt;diff($otherDate);
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Division by zero&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ($rate != 0) {
  $result = $amount / $rate;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Illegal offset type in isset or empty; PHP Warning: Illegal offset type&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;Array keys can only be int or string. Float, boolean and null get converted transparently (though it may be signal that something went wrong), but arrays, objects and resources don&amp;rsquo;t.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding::&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($key) || is_int($key)) {
  $map[$key] = $value;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Illegal string offset&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;Array keys can only be int or string. Float, boolean and null get converted transparently (though it may be signal that something went wrong), but arrays, objects and resources don&amp;rsquo;t.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding::&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$a = ‘some_string’;
if (is_array($a)) {
  var_dump($a[‘key’]);
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Use of undefined constant SOME_NAME - assumed &amp;#39;SOME_NAME&amp;#39;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This may have multiple causes, the most common is string literal, not wrapped in quotes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is to wrap these to quotes:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$status = $row[&amp;#39;status&amp;#39;];
$duration = $n . &amp;#39;hours&amp;#39;;
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: fclose() expects parameter 1 to be resource, bool given&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The solution is defensive coding, but in case of resources it should be applied as close as possible to the place of its initialization&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$file = fopen($name, &amp;#39;r&amp;#39;);
if ($file === false) {
    // handle error, interrupt execution - whatever appropriate
}
// do something
fclose($file);&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: call_user_func() expects parameter 1 to be a valid callback, function &amp;#39;my_func_name&amp;#39; not found or invalid function name&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;The solution is also defensive coding:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_callable(&amp;#39;my_func_name&amp;#39;)) {
    call_user_func(&amp;#39;my_func_name&amp;#39;);
} else {
    // handle error
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: implode(): Invalid arguments passed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Happens when the second argument is not array:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_array($names)) {
    var_dump(implode(&amp;#39;, &amp;#39;, $names));
}

// or

$pieces = is_array($names) ? $names : [];
var_dump(implode(&amp;#39;, &amp;#39;, $pieces));&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: max(): Array must contain at least one element&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (safeCount($items) &amp;gt; 0) {
    $best = max($items);
} else {
    // handle error, assign some defaults, etc.
}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;PHP Warning: Attempt to assign property &amp;#39;team_id&amp;#39; of non-object&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Defensive coding - check if the object is really an instance of the class you assuming. Makes sense to perform this check as close to object initialization as possible (or at the beginning of the function if the object is passed as an argument)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!($a instanceof SomeClass)) {
    // handle error, interrupt execution, etc.
}
$a-&amp;gt;b = 1;&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: array_multisort(): Array sizes are inconsistent*&lt;/h3&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: array_combine(): Both parameters should have an equal number of elements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;These warnings have similar cause and solution. Make sure, that sorted arrays are of the same size&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (safeCount($apples) !== safeCount($oranges)) {
    // handle error
}
array_multisort($apples, $oranges);&lt;/pre&gt;&lt;/p&gt;
&lt;h3&gt;PHP Warning: array_multisort(): Argument #1 is expected to be an array or a sort flag&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Defensive coding. Assuming here that sorting flags and order are hardcoded, otherwise, check them with is_integer&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!is_array($apples) || !is_array($oranges)) {
    // handle error
}
array_multisort($apples, SORT_ASC, SORT_STRING, $oranges, SORT_ASC, SORT_STRING);
&lt;/pre&gt;&lt;/p&gt;
&lt;h3&gt;PHP Warning: sprintf(): Too few arguments&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Carefully check that number of arguments to sprintf corresponds to number of placeholders in format string&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;echo sprintf(&amp;#39;%s is the capital of %s&amp;#39;, &amp;#39;London&amp;#39;); // error - 2 placeholders but 1 argument
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>PHP 7.4 Warnings to PHP8.2 Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors/revision/10</link><pubDate>Tue, 12 Mar 2024 18:23:32 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:dca5875d-93ad-45ff-9416-62a2e4f1b912</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors#comments</comments><description>Revision 10 posted to Dev Tutorials by Rafael Fernandes on 3/12/2024 6:23:32 PM&lt;br /&gt;
&lt;div class="flex flex-grow flex-col max-w-full"&gt;
&lt;div data-message-author-role="assistant" data-message-id="e2b43fa2-3f21-462c-a90a-1c802c969a4f"&gt;
&lt;div class="markdown prose w-full break-words dark:prose-invert dark"&gt;
&lt;h2 id="mcetoc_1hgqkj3ct0"&gt;PHP Warnings to Runtime Errors&lt;/h2&gt;
&lt;p&gt;In the transition from PHP 7.4 to PHP 8.2, notable changes have occurred with certain runtime errors that were previously treated as warnings by PHP. As of PHP 8.x, these errors have been elevated to runtime errors.&lt;/p&gt;
&lt;p&gt;Automated tools like Rector can do a lot when it comes to lexical scanning but runtime (&lt;span&gt;non-lexical and more closely tied to the logic and&amp;nbsp;data aspects of code execution&lt;/span&gt;) its help is limited.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Defensive coding techniques serve as a robust shield against runtime errors, empowering&amp;nbsp;you&amp;nbsp;to anticipate and prevent such issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our research,&amp;nbsp;&lt;span&gt;we&amp;#39;ve identified several of these techniques designed to assist you in addressing and rectifying potential errors.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Importance of Sugar&amp;nbsp;logs&lt;/h2&gt;
&lt;p&gt;Logs are crucial to help you understand the services and customizations you develop and operate.&amp;nbsp;Not only can logs help you troubleshoot problems, but they can also help you understand your&amp;nbsp;customizations better, and sometimes provide you with unforeseen logic errors that your code might not expect.&amp;nbsp;Even after applying defensive coding, you may end up with errors in your logs that will not propagate to the requestor, that being a UI trigger or a cron job, so it is important to keep an eye on your logs.&lt;/p&gt;
&lt;p&gt;Some Sugar errors will not be noticeable by users but they&amp;#39;ll be logged in the sugarcrm.log. It is your responsibility as Sugar instance&amp;#39;s administrator to check the logs, understand the causes, and possibly provide fixes.&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable PHP logs&lt;/h2&gt;
&lt;p&gt;The starting point to identify such errors is to enable PHP logs.&amp;nbsp;&lt;span&gt;This foundational step will provide the necessary data (warnings/errors) so you can implement effective defensive coding to prevent them from happening.&lt;/span&gt;&lt;/p&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATION&lt;/code&gt; Log in to the PHP error log and test your code.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Locate your &lt;code&gt;php.ini&lt;/code&gt; file. The location can vary based on your operating system and PHP installation. Common paths include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows: &lt;code&gt;C:\Program Files\PHP\php.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;/etc/php/{version}/apache2/php.ini&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;code&gt;php.ini&lt;/code&gt; file in a text editor with administrative privileges.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for the &lt;code&gt;error_reporting&lt;/code&gt; directive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the directive to include &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATED&lt;/code&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;error_reporting = E_ALL &amp;amp; ~E_NOTICE | E_WARNING | E_DEPRECATED
&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Applying defensive code to avoid&amp;nbsp;Errors&lt;/h2&gt;
&lt;h3 id="mcetoc_1hgqkpl7g0"&gt;PHP Warning: count(): Parameter must be an array or an object that implements Countable in *&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;safeCount&lt;/i&gt;&lt;/b&gt;&lt;b&gt; will take care of it&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g1"&gt;PHP Warning: A non-numeric value encountered*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Occurs when invalid strings are coerced using operators expecting numbers (+ - * / ** % &amp;lt;&amp;lt; &amp;gt;&amp;gt; | &amp;amp; ^) or their assignment equivalents.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cast the values to int or float before the arithmetic operation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Check the values for &lt;i&gt;is_numeric&lt;/i&gt;&lt;i&gt;($value)&lt;/i&gt; and skip the calculation if the values are not numeric.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g2"&gt;PHP Warning: sizeof(): Parameter must be an array or an object that implements Countable in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;if you have code like &lt;code&gt;&lt;i&gt;$a = &lt;/i&gt;&lt;i&gt;sizeof&lt;/i&gt;&lt;i&gt;($b) + 1;&lt;/i&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;replace sizeof with &lt;code&gt;safeCount&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: strlen() expects parameter 1 to be string, array given in*&lt;/h3&gt;
&lt;p&gt;Add defensive for example:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($some_value)) {
  $len = strlen($some_value);
} else { 
  // throw error or deal with your data
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkr1n54"&gt;&lt;br /&gt;PHP Warning: array_key_exists(): The first argument should be either a string or an integer in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ((is_string($haystack) || is_numeric($haystack)) &amp;amp;&amp;amp; array_key_exists($haystack, $myArray)) {
    // continue with your logic  
} else { 
    // throw error or deal with your data;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqksl5u5"&gt;PHP Warning: strpos(): Empty needle in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive code, for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (isset($haystack) &amp;amp;&amp;amp; !empty($haystack) &amp;amp;&amp;amp; isset($needle) &amp;amp;&amp;amp; !empty($needle) &amp;amp;&amp;amp; strpos($haystack, $needle, $offset)) {
   // continue with your logic
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqktv9u6"&gt;PHP Warning: array_intersect(): Expected parameter 1 to be an array, null given in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_array($array) &amp;amp;&amp;amp; is_array($arrays)) {
   $intersect = array_intersect($array, $arrays);
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: Creating default object from empty value*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// Option 1: Skip execution branch if the value is not an object
$a = BeanFactory::newBean(&amp;#39;someweirdstuff&amp;#39;);
if (!($a instanceof SugarBean)) {
  return;
}
$a-&amp;gt;b = &amp;#39;c&amp;#39;;

// Option 2: In cases when the variable is used without being initialized - initialize it first
$a = new stdClass();
$a-&amp;gt; b = ‘c’;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: DateTime::diff() expects parameter 1 to be DateTimeInterface, null given*&lt;/h3&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: DateTime::setTimezone() expects parameter 1 to be DateTimeZone, string given&lt;span class="heading-anchor-wrapper"&gt;&lt;span class="cc-1afrefi"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$date = new \DateTime();
if ($otherDate instanceof \DateTimeInterface) {
  $diff = $date-&amp;gt;diff($otherDate);
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Division by zero&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ($rate != 0) {
  $result = $amount / $rate;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Illegal offset type in isset or empty; PHP Warning: Illegal offset type&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;Array keys can only be int or string. Float, boolean and null get converted transparently (though it may be signal that something went wrong), but arrays, objects and resources don&amp;rsquo;t.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding::&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($key) || is_int($key)) {
  $map[$key] = $value;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Illegal string offset&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;Array keys can only be int or string. Float, boolean and null get converted transparently (though it may be signal that something went wrong), but arrays, objects and resources don&amp;rsquo;t.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding::&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$a = ‘some_string’;
if (is_array($a)) {
  var_dump($a[‘key’]);
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Use of undefined constant SOME_NAME - assumed &amp;#39;SOME_NAME&amp;#39;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This may have multiple causes, the most common is string literal, not wrapped in quotes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is to wrap these to quotes:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$status = $row[&amp;#39;status&amp;#39;];
$duration = $n . &amp;#39;hours&amp;#39;;
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: fclose() expects parameter 1 to be resource, bool given&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The solution is defensive coding, but in case of resources it should be applied as close as possible to the place of its initialization&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$file = fopen($name, &amp;#39;r&amp;#39;);
if ($file === false) {
    // handle error, interrupt execution - whatever appropriate
}
// do something
fclose($file);&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: call_user_func() expects parameter 1 to be a valid callback, function &amp;#39;my_func_name&amp;#39; not found or invalid function name&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;The solution is also defensive coding:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_callable(&amp;#39;my_func_name&amp;#39;)) {
    call_user_func(&amp;#39;my_func_name&amp;#39;);
} else {
    // handle error
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: implode(): Invalid arguments passed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Happens when the second argument is not array:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_array($names)) {
    var_dump(implode(&amp;#39;, &amp;#39;, $names));
}

// or

$pieces = is_array($names) ? $names : [];
var_dump(implode(&amp;#39;, &amp;#39;, $pieces));&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: max(): Array must contain at least one element&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (safeCount($items) &amp;gt; 0) {
    $best = max($items);
} else {
    // handle error, assign some defaults, etc.
}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;PHP Warning: Attempt to assign property &amp;#39;team_id&amp;#39; of non-object&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Defensive coding - check if the object is really an instance of the class you assuming. Makes sense to perform this check as close to object initialization as possible (or at the beginning of the function if the object is passed as an argument)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!($a instanceof SomeClass)) {
    // handle error, interrupt execution, etc.
}
$a-&amp;gt;b = 1;&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: array_multisort(): Array sizes are inconsistent*&lt;/h3&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: array_combine(): Both parameters should have an equal number of elements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;These warnings have similar cause and solution. Make sure, that sorted arrays are of the same size&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (safeCount($apples) !== safeCount($oranges)) {
    // handle error
}
array_multisort($apples, $oranges);&lt;/pre&gt;&lt;/p&gt;
&lt;h3&gt;PHP Warning: array_multisort(): Argument #1 is expected to be an array or a sort flag&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Defensive coding. Assuming here that sorting flags and order are hardcoded, otherwise, check them with is_integer&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!is_array($apples) || !is_array($oranges)) {
    // handle error
}
array_multisort($apples, SORT_ASC, SORT_STRING, $oranges, SORT_ASC, SORT_STRING);
&lt;/pre&gt;&lt;/p&gt;
&lt;h3&gt;PHP Warning: sprintf(): Too few arguments&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Carefully check that number of arguments to sprintf corresponds to number of placeholders in format string&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;echo sprintf(&amp;#39;%s is the capital of %s&amp;#39;, &amp;#39;London&amp;#39;); // error - 2 placeholders but 1 argument
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>PHP 7.4 Warnings to PHP8.2 Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors/revision/9</link><pubDate>Fri, 15 Dec 2023 15:48:47 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:dca5875d-93ad-45ff-9416-62a2e4f1b912</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors#comments</comments><description>Revision 9 posted to Dev Tutorials by Rafael Fernandes on 12/15/2023 3:48:47 PM&lt;br /&gt;
&lt;div class="flex flex-grow flex-col max-w-full"&gt;
&lt;div data-message-author-role="assistant" data-message-id="e2b43fa2-3f21-462c-a90a-1c802c969a4f"&gt;
&lt;div class="markdown prose w-full break-words dark:prose-invert dark"&gt;
&lt;h2 id="mcetoc_1hgqkj3ct0"&gt;PHP Warnings to Runtime Errors&lt;/h2&gt;
&lt;p&gt;In the transition from PHP 7.4 to PHP 8.2, notable changes have occurred with certain runtime errors that were previously treated as warnings by PHP. As of PHP 8.x, these errors have been elevated to runtime errors.&lt;/p&gt;
&lt;p&gt;Automated tools like Rector can do a lot when it comes to lexical scanning but runtime (&lt;span&gt;non-lexical and more closely tied to the logic and&amp;nbsp;data aspects of code execution&lt;/span&gt;) its help is limited.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Defensive coding techniques serve as a robust shield against runtime errors, empowering&amp;nbsp;you&amp;nbsp;to anticipate and prevent such issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our research,&amp;nbsp;&lt;span&gt;we&amp;#39;ve identified several of these techniques designed to assist you in addressing and rectifying potential errors.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable PHP logs&lt;/h2&gt;
&lt;p&gt;The starting point to identify such errors is to enable PHP logs.&amp;nbsp;&lt;span&gt;This foundational step will provide the necessary data (warnings/errors) so you can implement effective defensive coding to prevent them to happen.&lt;/span&gt;&lt;/p&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATION&lt;/code&gt; Log in to the PHP error log and test your code.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Locate your &lt;code&gt;php.ini&lt;/code&gt; file. The location can vary based on your operating system and PHP installation. Common paths include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows: &lt;code&gt;C:\Program Files\PHP\php.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;/etc/php/{version}/apache2/php.ini&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;code&gt;php.ini&lt;/code&gt; file in a text editor with administrative privileges.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for the &lt;code&gt;error_reporting&lt;/code&gt; directive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the directive to include &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATED&lt;/code&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;error_reporting = E_ALL &amp;amp; ~E_NOTICE | E_WARNING | E_DEPRECATED
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g0"&gt;PHP Warning: count(): Parameter must be an array or an object that implements Countable in *&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;safeCount&lt;/i&gt;&lt;/b&gt;&lt;b&gt; will take care of it&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g1"&gt;PHP Warning: A non-numeric value encountered*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Occurs when invalid strings are coerced using operators expecting numbers (+ - * / ** % &amp;lt;&amp;lt; &amp;gt;&amp;gt; | &amp;amp; ^) or their assignment equivalents.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cast the values to int or float before the arithmetic operation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Check the values for &lt;i&gt;is_numeric&lt;/i&gt;&lt;i&gt;($value)&lt;/i&gt; and skip the calculation if the values are not numeric.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g2"&gt;PHP Warning: sizeof(): Parameter must be an array or an object that implements Countable in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;if you have code like &lt;code&gt;&lt;i&gt;$a = &lt;/i&gt;&lt;i&gt;sizeof&lt;/i&gt;&lt;i&gt;($b) + 1;&lt;/i&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;replace sizeof with &lt;code&gt;safeCount&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: strlen() expects parameter 1 to be string, array given in*&lt;/h3&gt;
&lt;p&gt;Add defensive for example:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($some_value)) {
  $len = strlen($some_value);
} else { 
  // throw error or deal with your data
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkr1n54"&gt;&lt;br /&gt;PHP Warning: array_key_exists(): The first argument should be either a string or an integer in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ((is_string($haystack) || is_numeric($haystack)) &amp;amp;&amp;amp; array_key_exists($haystack, $myArray)) {
    // continue with your logic  
} else { 
    // throw error or deal with your data;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqksl5u5"&gt;PHP Warning: strpos(): Empty needle in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive code, for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (isset($haystack) &amp;amp;&amp;amp; !empty($haystack) &amp;amp;&amp;amp; isset($needle) &amp;amp;&amp;amp; !empty($needle) &amp;amp;&amp;amp; strpos($haystack, $needle, $offset)) {
   // continue with your logic
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqktv9u6"&gt;PHP Warning: array_intersect(): Expected parameter 1 to be an array, null given in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_array($array) &amp;amp;&amp;amp; is_array($arrays)) {
   $intersect = array_intersect($array, $arrays);
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: Creating default object from empty value*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// Option 1: Skip execution branch if the value is not an object
$a = BeanFactory::newBean(&amp;#39;someweirdstuff&amp;#39;);
if (!($a instanceof SugarBean)) {
  return;
}
$a-&amp;gt;b = &amp;#39;c&amp;#39;;

// Option 2: In cases when the variable is used without being initialized - initialize it first
$a = new stdClass();
$a-&amp;gt; b = ‘c’;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: DateTime::diff() expects parameter 1 to be DateTimeInterface, null given*&lt;/h3&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: DateTime::setTimezone() expects parameter 1 to be DateTimeZone, string given&lt;span class="heading-anchor-wrapper"&gt;&lt;span class="cc-1afrefi"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$date = new \DateTime();
if ($otherDate instanceof \DateTimeInterface) {
  $diff = $date-&amp;gt;diff($otherDate);
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Division by zero&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ($rate != 0) {
  $result = $amount / $rate;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Illegal offset type in isset or empty; PHP Warning: Illegal offset type&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;Array keys can only be int or string. Float, boolean and null get converted transparently (though it may be signal that something went wrong), but arrays, objects and resources don&amp;rsquo;t.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding::&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($key) || is_int($key)) {
  $map[$key] = $value;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Illegal string offset&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;Array keys can only be int or string. Float, boolean and null get converted transparently (though it may be signal that something went wrong), but arrays, objects and resources don&amp;rsquo;t.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding::&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$a = ‘some_string’;
if (is_array($a)) {
  var_dump($a[‘key’]);
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Use of undefined constant SOME_NAME - assumed &amp;#39;SOME_NAME&amp;#39;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This may have multiple causes, the most common is string literal, not wrapped in quotes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is to wrap these to quotes:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$status = $row[&amp;#39;status&amp;#39;];
$duration = $n . &amp;#39;hours&amp;#39;;
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: fclose() expects parameter 1 to be resource, bool given&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The solution is defensive coding, but in case of resources it should be applied as close as possible to the place of its initialization&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$file = fopen($name, &amp;#39;r&amp;#39;);
if ($file === false) {
    // handle error, interrupt execution - whatever appropriate
}
// do something
fclose($file);&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: call_user_func() expects parameter 1 to be a valid callback, function &amp;#39;my_func_name&amp;#39; not found or invalid function name&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;The solution is also defensive coding:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_callable(&amp;#39;my_func_name&amp;#39;)) {
    call_user_func(&amp;#39;my_func_name&amp;#39;);
} else {
    // handle error
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: implode(): Invalid arguments passed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Happens when the second argument is not array:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_array($names)) {
    var_dump(implode(&amp;#39;, &amp;#39;, $names));
}

// or

$pieces = is_array($names) ? $names : [];
var_dump(implode(&amp;#39;, &amp;#39;, $pieces));&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: max(): Array must contain at least one element&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (safeCount($items) &amp;gt; 0) {
    $best = max($items);
} else {
    // handle error, assign some defaults, etc.
}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;PHP Warning: Attempt to assign property &amp;#39;team_id&amp;#39; of non-object&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Defensive coding - check if the object is really an instance of the class you assuming. Makes sense to perform this check as close to object initialization as possible (or at the beginning of the function if the object is passed as an argument)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!($a instanceof SomeClass)) {
    // handle error, interrupt execution, etc.
}
$a-&amp;gt;b = 1;&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: array_multisort(): Array sizes are inconsistent*&lt;/h3&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: array_combine(): Both parameters should have an equal number of elements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;These warnings have similar cause and solution. Make sure, that sorted arrays are of the same size&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (safeCount($apples) !== safeCount($oranges)) {
    // handle error
}
array_multisort($apples, $oranges);&lt;/pre&gt;&lt;/p&gt;
&lt;h3&gt;PHP Warning: array_multisort(): Argument #1 is expected to be an array or a sort flag&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Defensive coding. Assuming here that sorting flags and order are hardcoded, otherwise, check them with is_integer&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!is_array($apples) || !is_array($oranges)) {
    // handle error
}
array_multisort($apples, SORT_ASC, SORT_STRING, $oranges, SORT_ASC, SORT_STRING);
&lt;/pre&gt;&lt;/p&gt;
&lt;h3&gt;PHP Warning: sprintf(): Too few arguments&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Carefully check that number of arguments to sprintf corresponds to number of placeholders in format string&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;echo sprintf(&amp;#39;%s is the capital of %s&amp;#39;, &amp;#39;London&amp;#39;); // error - 2 placeholders but 1 argument
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>PHP 7.4 Warnings to PHP8.2 Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors/revision/8</link><pubDate>Fri, 15 Dec 2023 15:41:00 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:dca5875d-93ad-45ff-9416-62a2e4f1b912</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors#comments</comments><description>Revision 8 posted to Dev Tutorials by Rafael Fernandes on 12/15/2023 3:41:00 PM&lt;br /&gt;
&lt;div class="flex flex-grow flex-col max-w-full"&gt;
&lt;div data-message-author-role="assistant" data-message-id="e2b43fa2-3f21-462c-a90a-1c802c969a4f"&gt;
&lt;div class="markdown prose w-full break-words dark:prose-invert dark"&gt;
&lt;h2 id="mcetoc_1hgqkj3ct0"&gt;PHP Warnings to Runtime Errors&lt;/h2&gt;
&lt;p&gt;In the transition from PHP 7.4 to PHP 8.2, notable changes have occurred with certain runtime errors that were previously treated as warnings by PHP. As of PHP 8.x, these errors have been elevated to runtime errors.&lt;/p&gt;
&lt;p&gt;Automated tools like Rector can do a lot when it comes to lexical scanning but runtime (&lt;span&gt;non-lexical and more closely tied to the logic and&amp;nbsp;data aspects of code execution&lt;/span&gt;) its help is limited.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Defensive coding techniques serve as a robust shield against runtime errors, empowering&amp;nbsp;you&amp;nbsp;to anticipate and prevent such issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our research,&amp;nbsp;&lt;span&gt;we&amp;#39;ve identified several of these techniques designed to assist you in addressing and rectifying potential errors.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable PHP logs&lt;/h2&gt;
&lt;p&gt;The starting point to identify such errors is to enable PHP logs.&amp;nbsp;&lt;span&gt;This foundational step will provide the necessary data (warnings/errors) so you can implement effective defensive coding to prevent them to happen.&lt;/span&gt;&lt;/p&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATION&lt;/code&gt; Log in to the PHP error log and test your code.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Locate your &lt;code&gt;php.ini&lt;/code&gt; file. The location can vary based on your operating system and PHP installation. Common paths include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows: &lt;code&gt;C:\Program Files\PHP\php.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;/etc/php/{version}/apache2/php.ini&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;code&gt;php.ini&lt;/code&gt; file in a text editor with administrative privileges.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for the &lt;code&gt;error_reporting&lt;/code&gt; directive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the directive to include &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATED&lt;/code&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;error_reporting = E_ALL &amp;amp; ~E_NOTICE | E_WARNING | E_DEPRECATED
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g0"&gt;PHP Warning: count(): Parameter must be an array or an object that implements Countable in *&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;safeCount&lt;/i&gt;&lt;/b&gt;&lt;b&gt; will take care of it&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g1"&gt;PHP Warning: A non-numeric value encountered*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Occurs when invalid strings are coerced using operators expecting numbers (+ - * / ** % &amp;lt;&amp;lt; &amp;gt;&amp;gt; | &amp;amp; ^) or their assignment equivalents.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cast the values to int or float before the arithmetic operation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Check the values for &lt;i&gt;is_numeric&lt;/i&gt;&lt;i&gt;($value)&lt;/i&gt; and skip the calculation if the values are not numeric.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g2"&gt;PHP Warning: sizeof(): Parameter must be an array or an object that implements Countable in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;if you have code like &lt;code&gt;&lt;i&gt;$a = &lt;/i&gt;&lt;i&gt;sizeof&lt;/i&gt;&lt;i&gt;($b) + 1;&lt;/i&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;replace sizeof with &lt;code&gt;safeCount&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: strlen() expects parameter 1 to be string, array given in*&lt;/h3&gt;
&lt;p&gt;Add defensive for example:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($some_value)) {
  $len = strlen($some_value);
} else { 
  // throw error or deal with your data
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkr1n54"&gt;&lt;br /&gt;PHP Warning: array_key_exists(): The first argument should be either a string or an integer in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ((is_string($haystack) || is_numeric($haystack)) &amp;amp;&amp;amp; array_key_exists($haystack, $myArray)) {
    // continue with your logic  
} else { 
    // throw error or deal with your data;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqksl5u5"&gt;PHP Warning: strpos(): Empty needle in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive code, for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (isset($haystack) &amp;amp;&amp;amp; !empty($haystack) &amp;amp;&amp;amp; isset($needle) &amp;amp;&amp;amp; !empty($needle) &amp;amp;&amp;amp; strpos($haystack, $needle, $offset)) {
   // continue with your logic
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqktv9u6"&gt;PHP Warning: array_intersect(): Expected parameter 1 to be an array, null given in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_array($array) &amp;amp;&amp;amp; is_array($arrays)) {
   $intersect = array_intersect($array, $arrays);
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: Creating default object from empty value*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// Option 1: Skip execution branch if the value is not an object
$a = BeanFactory::newBean(&amp;#39;someweirdstuff&amp;#39;);
if (!($a instanceof SugarBean)) {
  return;
}
$a-&amp;gt;b = &amp;#39;c&amp;#39;;

// Option 2: In cases when the variable is used without being initialized - initialize it first
$a = new stdClass();
$a-&amp;gt; b = ‘c’;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: DateTime::diff() expects parameter 1 to be DateTimeInterface, null given*&lt;/h3&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: DateTime::setTimezone() expects parameter 1 to be DateTimeZone, string given&lt;span class="heading-anchor-wrapper"&gt;&lt;span class="cc-1afrefi"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$date = new \DateTime();
if ($otherDate instanceof \DateTimeInterface) {
  $diff = $date-&amp;gt;diff($otherDate);
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Division by zero&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ($rate != 0) {
  $result = $amount / $rate;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Illegal offset type in isset or empty; PHP Warning: Illegal offset type&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;Array keys can only be int or string. Float, boolean and null get converted transparently (though it may be signal that something went wrong), but arrays, objects and resources don&amp;rsquo;t.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding::&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($key) || is_int($key)) {
  $map[$key] = $value;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Illegal string offset&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p data-renderer-start-pos="1317"&gt;Array keys can only be int or string. Float, boolean and null get converted transparently (though it may be signal that something went wrong), but arrays, objects and resources don&amp;rsquo;t.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The solution is also defensive coding::&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$a = ‘some_string’;
if (is_array($a)) {
  var_dump($a[‘key’]);
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="PHP-Warning:-DateTime::setTimezone()-expects-parameter-1-to-be-DateTimeZone,-string-given" data-renderer-start-pos="902"&gt;PHP Warning: Use of undefined constant SOME_NAME - assumed &amp;#39;SOME_NAME&amp;#39;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This may have multiple causes, the most common is string literal, not wrapped in quotes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Solution is to wrap these to quotes:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$status = $row[&amp;#39;status&amp;#39;];
$duration = $n . &amp;#39;hours&amp;#39;;
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>PHP 7.4 Warnings to PHP8.2 Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors/revision/7</link><pubDate>Fri, 15 Dec 2023 15:35:23 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:dca5875d-93ad-45ff-9416-62a2e4f1b912</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors#comments</comments><description>Revision 7 posted to Dev Tutorials by Rafael Fernandes on 12/15/2023 3:35:23 PM&lt;br /&gt;
&lt;div class="flex flex-grow flex-col max-w-full"&gt;
&lt;div data-message-author-role="assistant" data-message-id="e2b43fa2-3f21-462c-a90a-1c802c969a4f"&gt;
&lt;div class="markdown prose w-full break-words dark:prose-invert dark"&gt;
&lt;h2 id="mcetoc_1hgqkj3ct0"&gt;PHP Warnings to Runtime Errors&lt;/h2&gt;
&lt;p&gt;In the transition from PHP 7.4 to PHP 8.2, notable changes have occurred with certain runtime errors that were previously treated as warnings by PHP. As of PHP 8.x, these errors have been elevated to runtime errors.&lt;/p&gt;
&lt;p&gt;Automated tools like Rector can do a lot when it comes to lexical scanning but runtime (&lt;span&gt;non-lexical and more closely tied to the logic and&amp;nbsp;data aspects of code execution&lt;/span&gt;) its help is limited.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Defensive coding techniques serve as a robust shield against runtime errors, empowering&amp;nbsp;you&amp;nbsp;to anticipate and prevent such issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our research,&amp;nbsp;&lt;span&gt;we&amp;#39;ve identified several of these techniques designed to assist you in addressing and rectifying potential errors.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable PHP logs&lt;/h2&gt;
&lt;p&gt;The starting point to identify such errors is to enable PHP logs.&amp;nbsp;&lt;span&gt;This foundational step will provide the necessary data (warnings/errors) so you can implement effective defensive coding to prevent them to happen.&lt;/span&gt;&lt;/p&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATION&lt;/code&gt; Log in to the PHP error log and test your code.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Locate your &lt;code&gt;php.ini&lt;/code&gt; file. The location can vary based on your operating system and PHP installation. Common paths include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows: &lt;code&gt;C:\Program Files\PHP\php.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;/etc/php/{version}/apache2/php.ini&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;code&gt;php.ini&lt;/code&gt; file in a text editor with administrative privileges.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for the &lt;code&gt;error_reporting&lt;/code&gt; directive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the directive to include &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATED&lt;/code&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;error_reporting = E_ALL &amp;amp; ~E_NOTICE | E_WARNING | E_DEPRECATED
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g0"&gt;PHP Warning: count(): Parameter must be an array or an object that implements Countable in *&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;safeCount&lt;/i&gt;&lt;/b&gt;&lt;b&gt; will take care of it&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g1"&gt;PHP Warning: A non-numeric value encountered*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cast the values to int or float before the arithmetic operation.&lt;/li&gt;
&lt;li&gt;Check the values for &lt;i&gt;is_numeric&lt;/i&gt;&lt;i&gt;($value)&lt;/i&gt; and skip the calculation if the values are not numeric.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g2"&gt;PHP Warning: sizeof(): Parameter must be an array or an object that implements Countable in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;if you have code like &lt;code&gt;&lt;i&gt;$a = &lt;/i&gt;&lt;i&gt;sizeof&lt;/i&gt;&lt;i&gt;($b) + 1;&lt;/i&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;replace sizeof with &lt;code&gt;safeCount&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: strlen() expects parameter 1 to be string, array given in*&lt;/h3&gt;
&lt;p&gt;Add defensive for example:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($some_value)) {
  $len = strlen($some_value);
} else { 
  // throw error or deal with your data
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkr1n54"&gt;&lt;br /&gt;PHP Warning: array_key_exists(): The first argument should be either a string or an integer in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ((is_string($haystack) || is_numeric($haystack)) &amp;amp;&amp;amp; array_key_exists($haystack, $myArray)) {
    // continue with your logic  
} else { 
    // throw error or deal with your data;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqksl5u5"&gt;PHP Warning: strpos(): Empty needle in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive code, for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (isset($haystack) &amp;amp;&amp;amp; !empty($haystack) &amp;amp;&amp;amp; isset($needle) &amp;amp;&amp;amp; !empty($needle) &amp;amp;&amp;amp; strpos($haystack, $needle, $offset)) {
   // continue with your logic
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqktv9u6"&gt;PHP Warning: array_intersect(): Expected parameter 1 to be an array, null given in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_array($array) &amp;amp;&amp;amp; is_array($arrays)) {
   $intersect = array_intersect($array, $arrays);
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: Creating default object from empty value*&lt;/h3&gt;
&lt;p&gt;Add defensive for example:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// Option 1: Skip execution branch if the value is not an object
$a = BeanFactory::newBean(&amp;#39;someweirdstuff&amp;#39;);
if (!($a instanceof SugarBean)) {
  return;
}
$a-&amp;gt;b = &amp;#39;c&amp;#39;;

// Option 2: In cases when the variable is used without being initialized - initialize it first
$a = new stdClass();
$a-&amp;gt; b = ‘c’;&lt;/pre&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>PHP 7.4 Warnings to PHP8.2 Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors/revision/6</link><pubDate>Mon, 04 Dec 2023 14:51:16 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:dca5875d-93ad-45ff-9416-62a2e4f1b912</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors#comments</comments><description>Revision 6 posted to Dev Tutorials by Rafael Fernandes on 12/4/2023 2:51:16 PM&lt;br /&gt;
&lt;div class="flex flex-grow flex-col max-w-full"&gt;
&lt;div data-message-author-role="assistant" data-message-id="e2b43fa2-3f21-462c-a90a-1c802c969a4f"&gt;
&lt;div class="markdown prose w-full break-words dark:prose-invert dark"&gt;
&lt;h2 id="mcetoc_1hgqkj3ct0"&gt;PHP Warnings to Runtime Errors&lt;/h2&gt;
&lt;p&gt;In the transition from PHP 7.4 to PHP 8.2, notable changes have occurred with certain runtime errors that were previously treated as warnings by PHP. As of PHP 8.x, these errors have been elevated to runtime errors.&lt;/p&gt;
&lt;p&gt;Automated tools like Rector can do a lot when it comes to lexical scanning but runtime (&lt;span&gt;non-lexical and more closely tied to the logic and&amp;nbsp;data aspects of code execution&lt;/span&gt;) its help is limited.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Defensive coding techniques serve as a robust shield against runtime errors, empowering&amp;nbsp;you&amp;nbsp;to anticipate and prevent such issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our research,&amp;nbsp;&lt;span&gt;we&amp;#39;ve identified several of these techniques designed to assist you in addressing and rectifying potential errors.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable PHP logs&lt;/h2&gt;
&lt;p&gt;The starting point to identify such errors is to enable PHP logs.&amp;nbsp;&lt;span&gt;This foundational step will provide the necessary data (warnings/errors) so you can implement effective defensive coding to prevent them to happen.&lt;/span&gt;&lt;/p&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATION&lt;/code&gt; Log in to the PHP error log and test your code.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Locate your &lt;code&gt;php.ini&lt;/code&gt; file. The location can vary based on your operating system and PHP installation. Common paths include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows: &lt;code&gt;C:\Program Files\PHP\php.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;/etc/php/{version}/apache2/php.ini&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;code&gt;php.ini&lt;/code&gt; file in a text editor with administrative privileges.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for the &lt;code&gt;error_reporting&lt;/code&gt; directive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the directive to include &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATED&lt;/code&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;error_reporting = E_ALL &amp;amp; ~E_NOTICE | E_WARNING | E_DEPRECATED
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g0"&gt;PHP Warning: count(): Parameter must be an array or an object that implements Countable in *&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;safeCount&lt;/i&gt;&lt;/b&gt;&lt;b&gt; will take care of it&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g1"&gt;PHP Warning: A non-numeric value encountered*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cast the values to int or float before the arithmetic operation.&lt;/li&gt;
&lt;li&gt;Check the values for &lt;i&gt;is_numeric&lt;/i&gt;&lt;i&gt;($value)&lt;/i&gt; and skip the calculation if the values are not numeric.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g2"&gt;PHP Warning: sizeof(): Parameter must be an array or an object that implements Countable in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;if you have code like &lt;code&gt;&lt;i&gt;$a = &lt;/i&gt;&lt;i&gt;sizeof&lt;/i&gt;&lt;i&gt;($b) + 1;&lt;/i&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;replace sizeof with &lt;code&gt;safeCount&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: strlen() expects parameter 1 to be string, array given in*&lt;/h3&gt;
&lt;p&gt;Add defensive for example:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($some_value)) {
  $len = strlen($some_value);
} else { 
  // throw error or deal with your data
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkr1n54"&gt;&lt;br /&gt;PHP Warning: array_key_exists(): The first argument should be either a string or an integer in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ((is_string($haystack) || is_numeric($haystack)) &amp;amp;&amp;amp; array_key_exists($haystack, $myArray)) {
    // continue with your logic  
} else { 
    // throw error or deal with your data;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqksl5u5"&gt;PHP Warning: strpos(): Empty needle in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive code, for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (isset($haystack) &amp;amp;&amp;amp; !empty($haystack) &amp;amp;&amp;amp; isset($needle) &amp;amp;&amp;amp; !empty($needle) &amp;amp;&amp;amp; strpos($haystack, $needle, $offset)) {
   // continue with your logic
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqktv9u6"&gt;PHP Warning: array_intersect(): Expected parameter 1 to be an array, null given in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_array($array) &amp;amp;&amp;amp; is_array($arrays)) {
   $intersect = array_intersect($array, $arrays);
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>PHP 7.4 Warnings to PHP8.2 Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors/revision/5</link><pubDate>Mon, 04 Dec 2023 14:50:40 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:dca5875d-93ad-45ff-9416-62a2e4f1b912</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors#comments</comments><description>Revision 5 posted to Dev Tutorials by Rafael Fernandes on 12/4/2023 2:50:40 PM&lt;br /&gt;
&lt;div class="flex flex-grow flex-col max-w-full"&gt;
&lt;div data-message-author-role="assistant" data-message-id="e2b43fa2-3f21-462c-a90a-1c802c969a4f"&gt;
&lt;div class="markdown prose w-full break-words dark:prose-invert dark"&gt;
&lt;h2 id="mcetoc_1hgqkj3ct0"&gt;PHP Warnings to Runtime Errors&lt;/h2&gt;
&lt;p&gt;In the transition from PHP 7.4 to PHP 8.2, notable changes have occurred with certain runtime errors that were previously treated as warnings by PHP. As of PHP 8.x, these errors have been elevated to runtime errors.&lt;/p&gt;
&lt;p&gt;Automated tools like Rector can do a lot when it comes to lexical scanning but runtime (&lt;span&gt;non-lexical and more closely tied to the logic and&amp;nbsp;data aspects of code execution&lt;/span&gt;) its help is limited.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Defensive coding techniques serve as a robust shield against runtime errors, empowering&amp;nbsp;you&amp;nbsp;to anticipate and prevent such issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our research,&amp;nbsp;&lt;span&gt;we&amp;#39;ve identified several of these techniques designed to assist you in addressing and rectifying potential errors.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable PHP logs&lt;/h2&gt;
&lt;p&gt;The starting point to identify such errors is to enable PHP logs.&amp;nbsp;&lt;span&gt;This foundational step will provide the necessary data (warnings/errors) so you can implement effective defensive coding to prevent them to happen.&lt;/span&gt;&lt;/p&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATION&lt;/code&gt; Log in to the PHP error log and test your code.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Locate your &lt;code&gt;php.ini&lt;/code&gt; file. The location can vary based on your operating system and PHP installation. Common paths include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows: &lt;code&gt;C:\Program Files\PHP\php.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;/etc/php/{version}/apache2/php.ini&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;code&gt;php.ini&lt;/code&gt; file in a text editor with administrative privileges.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for the &lt;code&gt;error_reporting&lt;/code&gt; directive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the directive to include &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATED&lt;/code&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;error_reporting = E_ALL &amp;amp; ~E_NOTICE | E_WARNING | E_DEPRECATED
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkpl7g0"&gt;PHP Warning: count(): Parameter must be an array or an object that implements Countable in *&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;safeCount&lt;/i&gt;&lt;/b&gt;&lt;b&gt; will take care of it&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g1"&gt;PHP Warning: A non-numeric value encountered*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cast the values to int or float before the arithmetic operation.&lt;/li&gt;
&lt;li&gt;Check the values for &lt;i&gt;is_numeric&lt;/i&gt;&lt;i&gt;($value)&lt;/i&gt; and skip the calculation if the values are not numeric.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g2"&gt;PHP Warning: sizeof(): Parameter must be an array or an object that implements Countable in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;if you have code like &lt;i&gt;$a = &lt;/i&gt;&lt;i&gt;sizeof&lt;/i&gt;&lt;i&gt;($b) + 1;&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;replace sizeof with safeCount=&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1hgqkpl7g3"&gt;PHP Warning: strlen() expects parameter 1 to be string, array given in*&lt;/h3&gt;
&lt;p&gt;Add defensive for example:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_string($some_value)) {
  $len = strlen($some_value);
} else { 
  // throw error or deal with your data
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqkr1n54"&gt;&lt;br /&gt;PHP Warning: array_key_exists(): The first argument should be either a string or an integer in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if ((is_string($haystack) || is_numeric($haystack)) &amp;amp;&amp;amp; array_key_exists($haystack, $myArray)) {
    // continue with your logic  
} else { 
    // throw error or deal with your data;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqksl5u5"&gt;PHP Warning: strpos(): Empty needle in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive code, for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (isset($haystack) &amp;amp;&amp;amp; !empty($haystack) &amp;amp;&amp;amp; isset($needle) &amp;amp;&amp;amp; !empty($needle) &amp;amp;&amp;amp; strpos($haystack, $needle, $offset)) {
   // continue with your logic
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1hgqktv9u6"&gt;PHP Warning: array_intersect(): Expected parameter 1 to be an array, null given in*&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add defensive for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (is_array($array) &amp;amp;&amp;amp; is_array($arrays)) {
   $intersect = array_intersect($array, $arrays);
} else { 
   // throw error or deal with your data;
}&lt;/pre&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>PHP 7.4 Warnings to PHP8.2 Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors/revision/4</link><pubDate>Mon, 04 Dec 2023 14:45:02 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:dca5875d-93ad-45ff-9416-62a2e4f1b912</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors#comments</comments><description>Revision 4 posted to Dev Tutorials by Rafael Fernandes on 12/4/2023 2:45:02 PM&lt;br /&gt;
&lt;div class="flex flex-grow flex-col max-w-full"&gt;
&lt;div data-message-author-role="assistant" data-message-id="e2b43fa2-3f21-462c-a90a-1c802c969a4f"&gt;
&lt;div class="markdown prose w-full break-words dark:prose-invert dark"&gt;
&lt;h2 id="mcetoc_1hgqkj3ct0"&gt;PHP Warnings to Runtime Errors&lt;/h2&gt;
&lt;p&gt;In the transition from PHP 7.4 to PHP 8.2, notable changes have occurred with certain runtime errors that were previously treated as warnings by PHP. As of PHP 8.x, these errors have been elevated to runtime errors.&lt;/p&gt;
&lt;p&gt;Automated tools like Rector can do a lot when it comes to lexical scanning but runtime (&lt;span&gt;non-lexical and more closely tied to the logic and&amp;nbsp;data aspects of code execution&lt;/span&gt;) its help is limited.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Defensive coding techniques serve as a robust shield against runtime errors, empowering&amp;nbsp;you&amp;nbsp;to anticipate and prevent such issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our research,&amp;nbsp;&lt;span&gt;we&amp;#39;ve identified several of these techniques designed to assist you in addressing and rectifying potential errors.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable PHP logs&lt;/h2&gt;
&lt;p&gt;The starting point to identify such errors is to enable PHP logs.&amp;nbsp;&lt;span&gt;This foundational step will provide the necessary data (warnings/errors) so you can implement effective defensive coding to prevent them to happen.&lt;/span&gt;&lt;/p&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATION&lt;/code&gt; Log in to the PHP error log and test your code.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Locate your &lt;code&gt;php.ini&lt;/code&gt; file. The location can vary based on your operating system and PHP installation. Common paths include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows: &lt;code&gt;C:\Program Files\PHP\php.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;/etc/php/{version}/apache2/php.ini&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;code&gt;php.ini&lt;/code&gt; file in a text editor with administrative privileges.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for the &lt;code&gt;error_reporting&lt;/code&gt; directive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the directive to include &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATED&lt;/code&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;error_reporting = E_ALL &amp;amp; ~E_NOTICE | E_WARNING | E_DEPRECATED
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>PHP 7.4 Warnings to PHP8.2 Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors/revision/3</link><pubDate>Mon, 04 Dec 2023 14:44:37 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:dca5875d-93ad-45ff-9416-62a2e4f1b912</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors#comments</comments><description>Revision 3 posted to Dev Tutorials by Rafael Fernandes on 12/4/2023 2:44:37 PM&lt;br /&gt;
&lt;div class="flex flex-grow flex-col max-w-full"&gt;
&lt;div data-message-author-role="assistant" data-message-id="e2b43fa2-3f21-462c-a90a-1c802c969a4f"&gt;
&lt;div class="markdown prose w-full break-words dark:prose-invert dark"&gt;
&lt;h2 id="mcetoc_1hgqkj3ct0"&gt;PHP Warnings to Runtime Errors&lt;/h2&gt;
&lt;p&gt;In the transition from PHP 7.4 to PHP 8.2, notable changes have occurred with certain runtime errors that were previously treated as warnings by PHP. As of PHP 8.x, these errors have been elevated to runtime errors.&lt;/p&gt;
&lt;p&gt;Automated tools like Rector can do a lot when it comes to lexical scanning but runtime (&lt;span&gt;non-lexical and more closely tied to the logic and&amp;nbsp;data aspects of code execution&lt;/span&gt;) its help is limited.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Defensive coding techniques serve as a robust shield against runtime errors, empowering&amp;nbsp;you&amp;nbsp;to anticipate and prevent such issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our research,&amp;nbsp;&lt;span&gt;we&amp;#39;ve identified several of these techniques designed to assist you in addressing and rectifying potential errors.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1hgqkj3ct1" class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable PHP logs&lt;/h2&gt;
&lt;p&gt;The starting point to identify such errors is to enable PHP logs.&amp;nbsp;&lt;span&gt;This foundational step will provide the necessary data (warnings/errors) so you can implement effective defensive coding to prevent them to happen.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;Enable &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATION&lt;/code&gt; Log in to the PHP error log and test your code.&lt;/div&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Locate your &lt;code&gt;php.ini&lt;/code&gt; file. The location can vary based on your operating system and PHP installation. Common paths include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows: &lt;code&gt;C:\Program Files\PHP\php.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;/etc/php/{version}/apache2/php.ini&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;code&gt;php.ini&lt;/code&gt; file in a text editor with administrative privileges.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for the &lt;code&gt;error_reporting&lt;/code&gt; directive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the directive to include &lt;code&gt;E_WARNING&lt;/code&gt; and &lt;code&gt;E_DEPRECATED&lt;/code&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;error_reporting = E_ALL &amp;amp; ~E_NOTICE | E_WARNING | E_DEPRECATED
&lt;/pre&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>PHP 7.4 Warnings to PHP8.2 Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors/revision/2</link><pubDate>Mon, 04 Dec 2023 14:36:09 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:dca5875d-93ad-45ff-9416-62a2e4f1b912</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors#comments</comments><description>Revision 2 posted to Dev Tutorials by Rafael Fernandes on 12/4/2023 2:36:09 PM&lt;br /&gt;
&lt;div class="flex flex-grow flex-col max-w-full"&gt;
&lt;div data-message-author-role="assistant" data-message-id="e2b43fa2-3f21-462c-a90a-1c802c969a4f"&gt;
&lt;div class="markdown prose w-full break-words dark:prose-invert dark"&gt;
&lt;p&gt;In the transition from PHP 7.4 to PHP 8.2, notable changes have occurred with certain runtime errors that were previously treated as warnings by PHP. As of PHP 8.x, these errors have been elevated to runtime errors.&lt;/p&gt;
&lt;p&gt;Automated tools like Rector can do a lot when it comes to lexical scanning but runtime (&lt;span&gt;non-lexical and more closely tied to the logic and&amp;nbsp;data aspects of code execution&lt;/span&gt;) its help is limited.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Defensive coding techniques serve as a robust shield against runtime errors, empowering&amp;nbsp;you&amp;nbsp;to anticipate and prevent such issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our research,&amp;nbsp;&lt;span&gt;we&amp;#39;ve identified several of these techniques designed to assist you in addressing and rectifying potential errors.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>PHP 7.4 Warnings to PHP8.2 Errors</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors/revision/1</link><pubDate>Mon, 04 Dec 2023 14:31:36 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:dca5875d-93ad-45ff-9416-62a2e4f1b912</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/896/php-7-4-warnings-to-php8-x-errors#comments</comments><description>Revision 1 posted to Dev Tutorials by Rafael Fernandes on 12/4/2023 2:31:36 PM&lt;br /&gt;
&lt;div class="flex flex-grow flex-col max-w-full"&gt;
&lt;div data-message-author-role="assistant" data-message-id="e2b43fa2-3f21-462c-a90a-1c802c969a4f"&gt;
&lt;div class="markdown prose w-full break-words dark:prose-invert dark"&gt;
&lt;p&gt;In the transition from PHP 7.4 to PHP 8.2, notable changes have occurred with certain runtime errors that were previously treated as warnings by PHP. As of PHP 8.x, these errors have been elevated to runtime errors.&lt;/p&gt;
&lt;p&gt;Automated tools like Rector can do a lot when it comes to lexical scanning but runtime (&lt;span&gt;non-lexical and more closely tied to the logic and&amp;nbsp;data aspects of code execution&lt;/span&gt;) its help is limited.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Defensive coding techniques serve as a robust shield against runtime errors, empowering&amp;nbsp;you&amp;nbsp;to anticipate and prevent such issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our research,&amp;nbsp;&lt;span&gt;we&amp;#39;ve identified several of these techniques designed to assist you in addressing and rectifying potential errors.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="mt-1 flex justify-start gap-3 empty:hidden"&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item></channel></rss>