<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Zen Cart Documentation – PHP</title>
    <link>https://docs.zen-cart.com/dev/php/</link>
    <description>Recent content in PHP on Zen Cart Documentation</description>
    <generator>Hugo -- gohugo.io</generator>
    
	  <atom:link href="https://docs.zen-cart.com/dev/php/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Dev: Configuration Data Validation - About</title>
      <link>https://docs.zen-cart.com/dev/php/data_validation/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://docs.zen-cart.com/dev/php/data_validation/</guid>
      <description>
        
        
        &lt;p&gt;Fields in the configuration table have self-contained validation instructions in the &lt;code&gt;val_function&lt;/code&gt; field.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;val_function&lt;/code&gt; field is described in JSON format, with an error message in case validation fails, the id of the validation to be performed, and a set of options for validation.  This syntax is based on the calling conventions for &lt;a href=&#34;https://www.php.net/manual/en/function.filter-var.php&#34;&gt;filter_var&lt;/a&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;{
  &amp;#34;error&amp;#34;:&amp;#34;TEXT_MAX_PREVIEW&amp;#34;,
  &amp;#34;id&amp;#34;:&amp;#34;FILTER_VALIDATE_INT&amp;#34;,
  &amp;#34;options&amp;#34;:{&amp;#34;options&amp;#34;:{&amp;#34;min_range&amp;#34;:0}}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The list of &lt;code&gt;id&lt;/code&gt; values and possible options for each are shown in the PHP documentation on &lt;a href=&#34;https://www.php.net/manual/en/filter.filters.validate.php&#34;&gt;filters&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;adding-validation-to-a-custom-config&#34;&gt;Adding validation to a custom config&lt;/h3&gt;
&lt;p&gt;Suppose you want to do a check in your cart of an order&amp;rsquo;s value, and only offer PayPal as an option for orders under a certain value.  If you hardcode this threshold, you&amp;rsquo;ll have to change and re-deploy code any time you want to change it.  Storing it in the configuration table is a better idea.  So you add it:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;INSERT INTO configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, last_modified, date_added, use_function, set_function) VALUES (&amp;#39;Max PayPal&amp;#39;,&amp;#39;MAX_PAYPAL&amp;#39;,&amp;#39;4000&amp;#39;,&amp;#39;Enter max total which can use PayPal.  Must be &amp;amp;lt; $10K, per PayPal rules.&amp;#39;,1,100,NULL,now(),NULL,NULL)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But then you decide you want to add validation, so that this value is ranged between 4000 and 9999.&lt;/p&gt;
&lt;p&gt;To do this, you&amp;rsquo;d use the SQL statement&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;UPDATE configuration SET val_function = 
&amp;#39;{&amp;#34;error&amp;#34;:&amp;#34;TEXT_MAX_PAYPAL&amp;#34;,&amp;#34;id&amp;#34;:&amp;#34;FILTER_VALIDATE_INT&amp;#34;,&amp;#34;options&amp;#34;:{&amp;#34;options&amp;#34;:{&amp;#34;min_range&amp;#34;:4000, &amp;#34;max_range&amp;#34;:9999}}}&amp;#39;
WHERE configuration_key = &amp;#39;MAX_PAYPAL&amp;#39;; 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Where &lt;code&gt;TEXT_MAX_PAYPAL&lt;/code&gt; is defined in a globally accessible admin language file like &lt;code&gt;admin/includes/languages/english/extra_definitions/my_errors.php&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;?php
define(&amp;#39;TEXT_MAX_PAYPAL&amp;#39;,&amp;#39;Max PayPal must be in the range 4000-9999&amp;#39;); 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now when an administrator attempts to set it outside this range, an error will be shown at the top of the admin screen like this:&lt;/p&gt;
&lt;img src=&#34;https://docs.zen-cart.com/images/validation_error.png&#34; alt=&#34;Zen Cart admin data validation error&#34; width=&#34;50%&#34; /&gt;
&lt;br&gt;&lt;br&gt;
&lt;h3 id=&#34;validating-module-data&#34;&gt;Validating Module Data&lt;/h3&gt;
&lt;p&gt;As of Zen Cart 1.5.7, you can also perform validation on fields in your shipping, payment and order total modules.&lt;/p&gt;
&lt;p&gt;Use the same &lt;code&gt;val_function&lt;/code&gt; format.  The error defines need to be global (not just local to your module).  For convenience, the following strings are provided for common validations (integer &amp;gt;= 0 and floating point value &amp;gt;= 0):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;define(&amp;#39;TEXT_POSITIVE_INT&amp;#39;,&amp;#39;%s must be an integer greater than or equal to 0&amp;#39;);
define(&amp;#39;TEXT_POSITIVE_FLOAT&amp;#39;,&amp;#39;%s must be a decimal greater than or equal to 0&amp;#39;); 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that they take a parameter, which is passed in by the core; it&amp;rsquo;s the name of the setting being validated.  This is important for modules because unlike configuration values, multiple settings are done at once.&lt;/p&gt;
&lt;p&gt;If you prefer, define an error string of your own and place it in a file in &lt;code&gt;admin/includes/languages/english/extra_definitions&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;See the &lt;code&gt;flat&lt;/code&gt; shipping module for an example.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;val_function&lt;/code&gt; field was added in Zen Cart 1.5.6, but not widely used until Zen Cart 1.5.7.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Dev: PHP Idioms</title>
      <link>https://docs.zen-cart.com/dev/php/php_idioms/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://docs.zen-cart.com/dev/php/php_idioms/</guid>
      <description>
        
        
        &lt;p&gt;This document is intended to capture PHP changes that some developers may find unclear because they differ from what was done in the past.  Some but not all are driven by PHP8 changes.&lt;/p&gt;
&lt;h2 id=&#34;identical-comparison-operator&#34;&gt;Identical comparison operator&lt;/h2&gt;
&lt;p&gt;The comparison operator &lt;code&gt;===&lt;/code&gt; means &amp;ldquo;equal to and of the same type.&amp;rdquo;  It has become more important in PHP8+, which does stricter comparisons.&lt;/p&gt;
&lt;p&gt;See the PHP documentation on &lt;a href=&#34;https://www.php.net/manual/en/language.operators.comparison.php&#34;&gt;Comparison Operators&lt;/a&gt; for more details.&lt;/p&gt;
&lt;h2 id=&#34;null-coalescing-operator&#34;&gt;Null coalescing operator&lt;/h2&gt;
&lt;p&gt;This null coalescing operator &lt;code&gt;??&lt;/code&gt; checks that the first operand exists and is not null, i.e. &lt;code&gt;isset&lt;/code&gt;.  If so, it returns the first  operand; otherwise, it returns the second operand.&lt;/p&gt;
&lt;p&gt;So&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$enddate = zen_db_input($_REQUEST[&amp;#39;end_date&amp;#39;] ?? date(&amp;#39;Y-m-d&amp;#39;));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;is the same as:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;if (isset($_REQUEST[&amp;#39;end_date&amp;#39;])) { 
   $enddate = zen_db_input($_REQUEST[&amp;#39;end_date&amp;#39;]); 
} else {
   $enddate = zen_db_input(date(&amp;#39;Y-m-d&amp;#39;));
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See the PHP documentation on &lt;a href=&#34;https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op&#34;&gt;Null coalescing operator&lt;/a&gt; for more details.&lt;/p&gt;
&lt;h2 id=&#34;missing-php-close-tag--at-the-end-of-a-file&#34;&gt;Missing PHP close tag &lt;code&gt;?&amp;gt;&lt;/code&gt; at the end of a file&lt;/h2&gt;
&lt;p&gt;The close tag &lt;code&gt;?&amp;gt;&lt;/code&gt; is not recommended at the end of a file, and should be left off.&lt;/p&gt;
&lt;h3 id=&#34;coding-help&#34;&gt;Coding Help:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.zen-cart.com/user/upgrading/php_warnings/&#34;&gt;PHP Errors, Warnings and Deprecated messages after upgrading&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.zen-cart.com/dev/php/php_idioms/&#34;&gt;PHP Idioms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.zen-cart.com/user/upgrading/release_specific_upgrade_considerations/&#34;&gt;Release Specific Upgrade Considerations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.zen-cart.com/dev/plugins/upgrading_to_158/&#34;&gt;Upgrading plugins to work with 1.5.8/PHP 8.0+&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;hellip; and when all else fails:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.zen-cart.com/dev/plugins/php_updating/&#34;&gt;PHP migration guides&lt;/a&gt; in the php.net documentation&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Dev: PHP Updates</title>
      <link>https://docs.zen-cart.com/dev/php/php_updates/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://docs.zen-cart.com/dev/php/php_updates/</guid>
      <description>
        
        
        &lt;p&gt;Please see the following FAQs from the plugins section:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.zen-cart.com/dev/php/php_version_deprecations/&#34;&gt;PHP feature changes between versions, particular to Zen Cart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.zen-cart.com/dev/plugins/upgrading_to_158/&#34;&gt;Upgrading plugins to work with 1.5.8/PHP 8.0+&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.zen-cart.com/dev/plugins/php_updating/&#34;&gt;Updating plugins for higher levels of PHP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Dev: PHP Version Changes and Deprecations</title>
      <link>https://docs.zen-cart.com/dev/php/php_version_deprecations/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://docs.zen-cart.com/dev/php/php_version_deprecations/</guid>
      <description>
        
        
        &lt;p&gt;PLEASE NOTE THE OFFICIAL PHP VERSION SUPPORT TIMELINE: &lt;a href=&#34;https://php.net/supported-versions.php&#34;&gt;https://php.net/supported-versions.php&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;NOTE: This page assumes some pretty solid PHP knowledge, because all the changes listed will require adapting your code to find a new way to do whatever it was doing before.&lt;/p&gt;
&lt;p&gt;NOTE: This is not the complete official list of PHP language changes. This list caters mostly to the topics that might affect people writing plugins for Zen Cart.
For much more detailed lists of changes, see the &lt;a href=&#34;http://www.php.net/manual/en/appendices.php&#34;&gt;official PHP documentation on migrating between PHP versions&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;zen-cart-code-compatibility-notes&#34;&gt;Zen Cart code compatibility notes&lt;/h2&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;https://docs.zen-cart.com/user/first_steps/server_requirements/#php-version&#34;&gt;Zen Cart PHP version compatibility matrix&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;the-following-php-changes-required-core-zc-code-changes-for-compatibility-_when-upgrading-from-prior-versions_&#34;&gt;The following PHP changes required core ZC code changes for compatibility &lt;em&gt;when upgrading from prior versions&lt;/em&gt;:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;PHP 7.0 requires classes to use &lt;code&gt;__construct&lt;/code&gt; as the function name instead of just using the name of the class as a constructor.&lt;/li&gt;
&lt;li&gt;PHP 7.2 deprecated the &lt;code&gt;each()&lt;/code&gt; function, which was used prolifically before then.&lt;/li&gt;
&lt;li&gt;PHP 7.4 requires implode/explode to provide the separator as first arg.&lt;/li&gt;
&lt;li&gt;PHP 8.0 requires that any optional function params come after non-optional.&lt;/li&gt;
&lt;li&gt;PHP 8.2 requires class properties (&lt;code&gt;$this-&amp;gt;var&#39;s&lt;/code&gt;) to be declared before referring to them in class code.&lt;/li&gt;
&lt;li&gt;PHP 8.4 requires that nullable parameters be declared as such in function signatures.&lt;/li&gt;
&lt;li&gt;PHP 8.4 Deprecated &lt;code&gt;E_USER_ERROR&lt;/code&gt; ie: &lt;code&gt;trigger_error(..., E_USER_ERROR)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See related upgrade docs for &lt;a href=&#34;https://docs.zen-cart.com/user/upgrading/php_warnings/&#34;&gt;mitigation guidance&lt;/a&gt; on these topics.&lt;/p&gt;
&lt;h4 id=&#34;the-following-php-changes-are-important-to-note-when-_backporting-code-to-older-zc-versions_&#34;&gt;The following PHP changes are important to note when &lt;em&gt;backporting code to older ZC versions&lt;/em&gt;:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;To add support for most &lt;strong&gt;PHP functions added to the PHP language since PHP 7.0&lt;/strong&gt;, use the &lt;a href=&#34;https://github.com/zencart/zencart/blob/master/includes/functions/php_polyfills.php&#34;&gt;php_polyfill.php&lt;/a&gt; (in v1.5.7c or newer, replace it in /includes/functions. In v1.5.7b or older, put it into your &lt;code&gt;extra_configures&lt;/code&gt; folders in &lt;em&gt;both&lt;/em&gt; &lt;em&gt;admin and non-admin&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, the polyfill only deals with missing functions. The following language constructs, if you&amp;rsquo;re using them, will require changing your syntax to older-style PHP approaches, in order to work on older PHP versions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PHP 7.0 added null coalesce (&lt;code&gt;??&lt;/code&gt;) operator&lt;/li&gt;
&lt;li&gt;PHP 7.0 added function/class &lt;code&gt;return types&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;PHP 7.0 added the spaceship &lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt; operator&lt;/li&gt;
&lt;li&gt;PHP 7.0 added &lt;code&gt;yield from&lt;/code&gt; syntax&lt;/li&gt;
&lt;li&gt;PHP 7.0 added &lt;code&gt;Throwable&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;PHP 7.0 added &lt;code&gt;declare strict_types&lt;/code&gt; syntax&lt;/li&gt;
&lt;li&gt;PHP 7.1 added &lt;code&gt;nullable types&lt;/code&gt;, ie: &lt;code&gt;?string&lt;/code&gt;, &lt;code&gt;?int&lt;/code&gt;, &lt;code&gt;?array&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;PHP 7.4 added null coalesce assignment &lt;code&gt;??=&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;PHP 7.4 added arrow functions &lt;code&gt;fn($n) =&amp;gt; $n &amp;gt; 0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;PHP 8.0 added &lt;code&gt;match&lt;/code&gt; syntax&lt;/li&gt;
&lt;li&gt;PHP 8.0 added &lt;code&gt;#[...]&lt;/code&gt; Attributes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More details on all of these can be found in the rest of this document, and on the PHP.net website.&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id=&#34;php-language-history-abbreviated-summary&#34;&gt;PHP Language History (abbreviated summary)&lt;/h1&gt;
&lt;h2 id=&#34;php-7&#34;&gt;PHP 7&lt;/h2&gt;
&lt;h3 id=&#34;php-70&#34;&gt;PHP 7.0&lt;/h3&gt;
&lt;p&gt;In PHP 7.0 the following functionality/features changed:&lt;/p&gt;
&lt;p&gt;a) class &lt;code&gt;constructors&lt;/code&gt; must be named &lt;code&gt;__construct&lt;/code&gt; and not just be the same function name as the class anymore.&lt;/p&gt;
&lt;p&gt;b) indirection - use of &lt;code&gt;$$foo[&#39;bar&#39;][&#39;baz&#39;]&lt;/code&gt; needs to be rewritten as &lt;code&gt;${$foo[&#39;bar&#39;][&#39;baz&#39;]}&lt;/code&gt; else it will be seen as &lt;code&gt;($$foo)[&#39;bar&#39;][&#39;baz&#39;]&lt;/code&gt;. Also, &lt;code&gt;$foo-&amp;gt;$bar[&#39;baz&#39;]&lt;/code&gt; has to be rewritten as &lt;code&gt;$foo-&amp;gt;{$bar[&#39;baz&#39;]}&lt;/code&gt; if that&amp;rsquo;s what was intended.&lt;/p&gt;
&lt;p&gt;c) &lt;code&gt;switch()&lt;/code&gt; statements cannot have multiple &lt;code&gt;default:&lt;/code&gt; blocks.&lt;/p&gt;
&lt;p&gt;Added: Null coalesce operator (&lt;code&gt;??&lt;/code&gt;) was added: &lt;code&gt;$username = $_GET[&#39;user&#39;] ?? &#39;guest&#39;;&lt;/code&gt; is equivalent to &lt;code&gt;$username = isset($_GET[&#39;user&#39;]) ? $_GET[&#39;user&#39;] : &#39;guest&#39;;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: spaceship &lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt; comparison operator&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;define()&lt;/code&gt; can now define arrays.&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;preg_replace_callback_array()&lt;/code&gt;, &lt;code&gt;random_bytes()&lt;/code&gt;, &lt;code&gt;random_int()&lt;/code&gt;, &lt;code&gt;error_clear_last()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: &lt;a href=&#34;https://www.php.net/manual/en/migration70.new-features.php&#34;&gt;Scalar type declarations and return type declarations&lt;/a&gt;: string, int, float, bool, array, callable, class names and interfaces.&lt;/p&gt;
&lt;p&gt;Removed: The POSIX &amp;ldquo;ereg&amp;rdquo; family of functions was fully removed: &lt;code&gt;ereg(), eregi(), ereg_replace(), eregi_replace(), split(), spliti()&lt;/code&gt;. See &lt;a href=&#34;https://docs.zen-cart.com/user/upgrading/php_warnings/#ereg_replace-deprecated&#34;&gt;mitigation&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;php-71&#34;&gt;PHP 7.1&lt;/h3&gt;
&lt;p&gt;Zen Cart: ZC sites using PHP 7.0 can safely jump to PHP 7.1 without issue.&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;null&lt;/code&gt;able types (ie: &lt;code&gt;?&lt;/code&gt; prefix)&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;void&lt;/code&gt; return type&lt;/p&gt;
&lt;p&gt;Added: &lt;a href=&#34;https://stitcher.io/blog/array-destructuring-with-list-in-php&#34;&gt;array destructuring&lt;/a&gt; with &lt;code&gt;[]&lt;/code&gt;, including in &lt;code&gt;foreach&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: class constants can now declare visibility (protected, private, public)&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;is_iterable()&lt;/code&gt; and &lt;code&gt;iterable&lt;/code&gt; pseudo-type&lt;/p&gt;
&lt;p&gt;Deprecated: &lt;code&gt;mcrypt&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;php-72&#34;&gt;PHP 7.2&lt;/h3&gt;
&lt;p&gt;Deprecated: calls to &lt;code&gt;each()&lt;/code&gt; are deprecated; &lt;a href=&#34;https://docs.zen-cart.com/user/upgrading/php_warnings/#each-deprecated&#34;&gt;use &lt;code&gt;foreach()&lt;/code&gt; instead&lt;/a&gt;.
For upgrading code related to Zen Cart, see some code examples here: &lt;a href=&#34;https://github.com/zencart/zencart/pull/1377&#34;&gt;Refactor each() to foreach() for compatibility with PHP 7.2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Deprecated: &lt;code&gt;create_function()&lt;/code&gt; is deprecated. Use anonymous functions (&amp;ldquo;Closures&amp;rdquo;) instead.&lt;/p&gt;
&lt;p&gt;Deprecated: The &lt;code&gt;__autoload()&lt;/code&gt; mechanism is deprecated in favor of &lt;code&gt;spl_autoload_register()&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;Deprecated: calls to missing/undefined constants now trigger &lt;code&gt;E_WARNING: Warning: Use of undefined constant FOO – assumed &#39;FOO&#39;.&lt;/code&gt; (Now a fatal error since PHP 8.0)&lt;/p&gt;
&lt;p&gt;Added: Argon2 added to password functions&lt;/p&gt;
&lt;h3 id=&#34;php-73&#34;&gt;PHP 7.3&lt;/h3&gt;
&lt;p&gt;For PHP 7.3 the only change found necessary in Zen Cart (over PHP 7.2 compatibility) was:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;using the &amp;ldquo;continue&amp;rdquo; statement inside a &amp;ldquo;switch&amp;rdquo; loop &amp;ndash; should be changed to &amp;ldquo;break&amp;rdquo;&lt;/li&gt;
&lt;li&gt;many &amp;ldquo;strict&amp;rdquo; conditions now trigger notices&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other notes about 7.3:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;calls to &lt;code&gt;compact()&lt;/code&gt; with undefined variables will cause errors&lt;/li&gt;
&lt;li&gt;In case of troubleshooting rare problems that could be caused by the very few SPL autoloads in ZC, that any SPL Autoloads that fail will cause all subsequents to fail too, instead of just a warning in previous PHP versions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Added: &lt;code&gt;array_key_first()&lt;/code&gt;, &lt;code&gt;array_key_last()&lt;/code&gt;, &lt;code&gt;is_countable()&lt;/code&gt;, &lt;code&gt;hrtime()&lt;/code&gt;, &lt;code&gt;gc_status()&lt;/code&gt;, &lt;code&gt;fpm_get_status()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;DateTime::createFromImmutable()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Deprecated: case-insensitive constants&lt;/p&gt;
&lt;h3 id=&#34;php-74&#34;&gt;PHP 7.4&lt;/h3&gt;
&lt;p&gt;Zen Cart note: nested ternary operator calls should be checked for clarity, and extra parentheses added as necessary&lt;/p&gt;
&lt;p&gt;Added:  Null coalescing assignment operator: &lt;code&gt;??=&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: Arrow functions, ie: &lt;code&gt;fn($n) =&amp;gt; $n &amp;gt; 0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: &lt;a href=&#34;https://php.watch/versions/7.4/typed-properties&#34;&gt;class properties now support type declarations&lt;/a&gt; (ie: &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;array&lt;/code&gt; etc)&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;password_algos()&lt;/code&gt;, &lt;code&gt;mb_str_split()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: array unpacking in array literals (&lt;code&gt;...$arr&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;Added: numeric literal separators (&lt;code&gt;1_000_000&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;Deprecated: curly-brace array/string offsets. Use &lt;code&gt;$var[$idx]&lt;/code&gt; instead of &lt;code&gt;$var{$idx}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Deprecated: &lt;code&gt;allow_url_include&lt;/code&gt; INI option&lt;/p&gt;
&lt;p&gt;Deprecated: &lt;code&gt;implode()&lt;/code&gt; MUST specify the separator as the first param (previously the param order could be reversed)&lt;/p&gt;
&lt;p&gt;Deprecated: The &lt;code&gt;is_real()&lt;/code&gt; function is deprecated, use &lt;code&gt;is_float()&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;Deprecated: Using &lt;code&gt;array_key_exists()&lt;/code&gt; on objects. Instead either &lt;code&gt;isset()&lt;/code&gt; or &lt;code&gt;property_exists()&lt;/code&gt; should be used.&lt;/p&gt;
&lt;p&gt;Deprecated: The &lt;code&gt;get_magic_quotes_gpc()&lt;/code&gt; and &lt;code&gt;get_magic_quotes_runtime()&lt;/code&gt; functions are deprecated. They always return &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Deprecated: &lt;code&gt;money_format()&lt;/code&gt; replaced by the intl &lt;code&gt;NumberFormatter&lt;/code&gt; functionality.&lt;/p&gt;
&lt;h3 id=&#34;tool-for-php-57-inspection&#34;&gt;TOOL FOR PHP 5,7 INSPECTION:&lt;/h3&gt;
&lt;p&gt;Here is a gist containing some &lt;a href=&#34;https://gist.github.com/drbyte/c188f448137fc149c609&#34;&gt;regex patterns which can be used to identify incompatible old PHP code for PHP 5 and PHP 7&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;php-8&#34;&gt;PHP 8&lt;/h2&gt;
&lt;h3 id=&#34;php-80&#34;&gt;PHP 8.0&lt;/h3&gt;
&lt;p&gt;Added: &lt;code&gt;str_contains()&lt;/code&gt;, &lt;code&gt;str_starts_with()&lt;/code&gt;, &lt;code&gt;str_ends_with()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;get_debug_type()&lt;/code&gt;, &lt;code&gt;preg_last_error_msg()&lt;/code&gt;, &lt;code&gt;fdiv()&lt;/code&gt;, &lt;code&gt;DateTimeInterface::createFromInterface()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: constructor property promotion (ie: automatically set $this-&amp;gt;var when $var is passed to a typed constructor var)&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;match(){};&lt;/code&gt; expression&lt;/p&gt;
&lt;p&gt;Added: nullsafe operator (&lt;code&gt;?-&amp;gt;&lt;/code&gt;). ie: &lt;code&gt;$foo?-&amp;gt;value&lt;/code&gt; safely returns &lt;code&gt;null&lt;/code&gt; if there&amp;rsquo;s no accessible &lt;code&gt;value&lt;/code&gt; property.&lt;/p&gt;
&lt;p&gt;Added: Attributes (&lt;code&gt;#[...]&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;Added: union types (&lt;code&gt;(int|string)&lt;/code&gt; which is &amp;ldquo;or&amp;rdquo; matching, eg: &lt;code&gt;int|string&lt;/code&gt; means could be an int or a string)&lt;/p&gt;
&lt;p&gt;Deprecated: cannot have function/class parameters with a default value before a required parameter: ie: cannot do: &lt;code&gt;function foo($required1 = &#39;&#39;, $required2)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Deprecated: calls to undefined constants now throw &lt;code&gt;Fatal error: Uncaught Error: Undefined constant &amp;quot;FOO&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Removed: &lt;code&gt;Function curl_close() has no effect anymore since PHP 8.0, is deprecated since 8.5&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;php-81&#34;&gt;PHP 8.1&lt;/h3&gt;
&lt;p&gt;Deprecated: can no longer pass &lt;code&gt;null&lt;/code&gt; to a non-nullable scalar type declaration (ie: &lt;code&gt;string $var = null&lt;/code&gt; must be either &lt;code&gt;?string = null&lt;/code&gt; or &lt;code&gt;string = &#39;&#39;&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;Added: &lt;a href=&#34;https://www.php.net/manual/en/language.enumerations.php&#34;&gt;&lt;code&gt;enum&lt;/code&gt;&lt;/a&gt; support&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;array_is_list()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;readonly&lt;/code&gt; properties&lt;/p&gt;
&lt;p&gt;Added: first-class callable syntax (&lt;code&gt;foo(...)&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;Added: intersection types (&lt;code&gt;A&amp;amp;B&lt;/code&gt; where A and B are interfaces, both of which must be implemented)&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;never&lt;/code&gt; return type&lt;/p&gt;
&lt;h3 id=&#34;php-82&#34;&gt;PHP 8.2&lt;/h3&gt;
&lt;p&gt;Added: &lt;a href=&#34;https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly&#34;&gt;&lt;code&gt;readonly&lt;/code&gt;&lt;/a&gt; classes&lt;/p&gt;
&lt;p&gt;Added: constants in traits&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;#{\SensitiveParameter]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Deprecated: dynamic class properties no longer allowed. ie: cannot refer to &lt;code&gt;$this-&amp;gt;foo&lt;/code&gt; if it wasn&amp;rsquo;t previously declared in the class.&lt;/p&gt;
&lt;p&gt;Deprecated: The &lt;code&gt;${var}&lt;/code&gt; and &lt;code&gt;${expr}&lt;/code&gt; style of string interpolation is deprecated. Use &lt;code&gt;$var&lt;/code&gt;/&lt;code&gt;{$var}&lt;/code&gt; and &lt;code&gt;{${expr}}&lt;/code&gt;, respectively.&lt;/p&gt;
&lt;p&gt;Deprecated: &lt;code&gt;utf8_encode()&lt;/code&gt; and &lt;code&gt;utf8_decode()&lt;/code&gt; functions are deprecated. (Moved to mbstring extension in PHP 8.4)&lt;/p&gt;
&lt;p&gt;Deprecated: &lt;code&gt;glob()&lt;/code&gt; now returns an empty &lt;code&gt;array&lt;/code&gt; if all paths are restricted by &lt;code&gt;open_basedir&lt;/code&gt;. Previously it returned &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;php-83&#34;&gt;PHP 8.3&lt;/h3&gt;
&lt;p&gt;Added: &lt;code&gt;json_validate()&lt;/code&gt; (to validate JSON without decoding first)&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;mb_str_pad()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: &lt;a href=&#34;https://php.watch/versions/8.3/typed-constants&#34;&gt;Typed class constants&lt;/a&gt; &lt;code&gt;const string TEXT_MESSAGE = &#39;message&#39;;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Change: &lt;code&gt;number_format()&lt;/code&gt; now handles negative decimals.&lt;/p&gt;
&lt;h3 id=&#34;php-84&#34;&gt;PHP 8.4&lt;/h3&gt;
&lt;p&gt;Added: New &lt;code&gt;mb_trim&lt;/code&gt;, &lt;code&gt;mb_ltrim&lt;/code&gt;, and &lt;code&gt;mb_rtrim&lt;/code&gt; functions&lt;/p&gt;
&lt;p&gt;Change: &lt;code&gt;utf8_encode()&lt;/code&gt; and &lt;code&gt;utf8_decode()&lt;/code&gt; functions are now only present if &lt;code&gt;mbstring&lt;/code&gt; extension is installed.&lt;/p&gt;
&lt;p&gt;Syntax: May now chain &lt;code&gt;new&lt;/code&gt; expressions, ie: &lt;code&gt;(new A)-&amp;gt;b()-&amp;gt;c()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Deprecated: Implicitly nullable parameters. Must specify &lt;code&gt;?&lt;/code&gt; or &lt;code&gt;null&lt;/code&gt; if default is &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Deprecated: E_USER_ERROR, ie: &lt;code&gt;trigger_error(..., E_USER_ERROR)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Deprecated: classes named &lt;code&gt;_&lt;/code&gt; no longer allowed.&lt;/p&gt;
&lt;p&gt;Deprecated: &lt;code&gt;E_STRICT&lt;/code&gt; constant deprecated&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;request_parse_body()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;fpow()&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;php-85&#34;&gt;PHP 8.5&lt;/h3&gt;
&lt;p&gt;Added functions: &lt;code&gt;array_first()&lt;/code&gt;, &lt;code&gt;array_last()&lt;/code&gt;, &lt;code&gt;get_error_handler()&lt;/code&gt;, &lt;code&gt;get_exception_handler()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Added: &lt;a href=&#34;https://php.watch/versions/8.5/pipe-operator&#34;&gt;Pipe operator&lt;/a&gt; (&lt;code&gt;|&amp;gt;&lt;/code&gt;) for enabling functional pipelines.&lt;/p&gt;
&lt;p&gt;Added: &lt;code&gt;final&lt;/code&gt; property promotion&lt;/p&gt;
&lt;p&gt;Added: constant expressions may now contain closures and first-class callables.&lt;/p&gt;
&lt;p&gt;Deprecated: &lt;code&gt;curl_close()&lt;/code&gt; - &lt;code&gt;PHP Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Deprecated: &lt;a href=&#34;https://php.watch/versions/8.5/boolean-double-integer-binary-casts-deprecated&#34;&gt;Non-canonical scalar type casts (boolean|double|integer|binary)&lt;/a&gt;&lt;/p&gt;

      </description>
    </item>
    
  </channel>
</rss>
