
PHPMaker 2025 is major upgrade from previous version, it includes a long list of new features. If you upgrade from v2021 or newer, there are no big changes. However, if you upgrade from version prior to v2019, please be reminded that recent versions introduced some new features which are not fully compatible with old versions, make sure you read the following first:
Migrating to v2019
Migrating to v2020
Migrating to v2021
Migrating to v2022
Migrating to v2023
Migrating to v2024
When opening an old project in v2025, PHPMaker will try to convert the changes for you. However, the conversion cannot be 100% and you'll need to do some updates yourself. Please read the follows carefully, review your code, update and test it before deploying the new scripts to your production server.
PHP >= 8.1.0
Requires PHP 8.1.0 or higher. Since active support for PHP 8.1 will end on 2024/12/26 (see [Supported Versions](https://www.php.net/supported-versions.php) on PHP official site), using PHP 8.2 or 8.3 is highly recommended.
Type declarations and Nullable Type
[Type declarations](https://www.php.net/manual/en/language.types.declarations.php) can be added to function arguments, return values, class properties, and as of PHP 8.3.0, class constants. They ensure that the value is of the specified type at call time, otherwise a [TypeError](https://www.php.net/manual/en/class.typeerror.php) is thrown. Type declarations for parameters and return values can now be marked as nullable by prefixing the type name with a question mark, e.g. ``?string``. This signifies that as well as the specified type, ``null`` can be passed as an argument, or returned as a value, respectively. PHPMaker 2025 uses type declarations and nullable types extensively and the signature of **ALL** server events have been changed. For example, If you have added your own functions, it is strongly recommended that you update your code to use type declarations and nullable types too. Note also that PHP 8.4 will deprecate implicitly nullable types, so it is recommended to explicitly declare the type as nullable. For example, Due to these changes, you may see [TypeError](https://www.php.net/manual/en/class.typeerror.php) after you migrate your old projects to v2025, please take a little time to update and fix your code.PHP 8.1 Enumerations
With PHP >= 8.1, native PHP enums are fully used. In v2024, PHPMaker used a third-party package for PHP 8.0, the ``value`` property was required to get the enum value to compare, if you upgrade from PHP 8.0 to 8.1, you should remove the property now. The following enum is also added, if your server events use the ``ACTION_*`` constants (e.g. ``ACTION_POSTBACK``), you should update them to ``ActionType::*`` (e.g. ``ActionType::POSTBACK).Doctrine DBAL 4 and ORM 3
Doctrine packages are upgraded to DBAL 4 and ORM 3. There are some breaking changes. If you use DBAL/ORM in your server events directly, you may need to update your code and database, please read: - [Doctrine ORM 3 and DBAL 4 Released](https://www.doctrine-project.org/2024/02/03/doctrine-orm-3-and-dbal-4-released.html) - [Upgrade to Doctrine DBAL 4.1](https://github.com/doctrine/dbal/blob/4.1.x/UPGRADE.md) (Support for MariaDB 10.4, MySQL 5.7 and Postgres 10 + 11 deprecated) - [Upgrade to Doctrine ORM 3.0](https://github.com/doctrine/orm/blob/3.0.x/UPGRADE.md)Working with Sessions
v2025 uses [Symfony sessions](https://symfony.com/doc/current/session.html) which are designed to replace the usage of the ``$_SESSION`` super global and native PHP functions related to manipulating the session like ``session_start()``, ``session_regenerate_id()``, ``session_id()``, ``session_name()``, and ``session_destroy()``. Sessions are only started if you read or write from it. Avoid using ``$_SESSION`` and the ``session_*()`` directly in your code, it is recommended that you update your server events and use Symfony session methods (see [SessionInterface](https://github.com/symfony/symfony/blob/6.4/src/Symfony/Component/HttpFoundation/Session/SessionInterface.php)) only, e.g. **Note** The old session helper is removed, if your server events use methods other than ``get()`` and ``set()``, you may need to update your code.Password Migration
In order to protect passwords, it is recommended to store them using the latest hash algorithms. This means that if a better hash algorithm is supported on your system, the user's password should be rehashed using the newer algorithm and stored. The old passwords (including plain passwords, case-sensitive/insensitive passwords, md5 hashed passwords, phpass passwords) are all deprecated and should be rehashed by [password_hash()](https://www.php.net/manual/en/function.password-hash.php). PHPMaker 2025 provides a new option [Migrate password algorithm](tools.html?id=migrate-password-algorithm) for migrating legacy passwords to the latest hash algorithms. It is strongly recommended that you enable this setting and migrate passwords. When enabled, upon successful login, the security system will rehash the password using the new hash automatically. This change is transparent to users. However, hashed passwords are at least 60 characters long, so you need to make sure the size of the password field is large enough to store them, ``varchar(255)`` should be a good setting.Login Link
In older versions, the [Allow login by URL](tools.html?id=allow-login-by-url) option allow users to login via a URL like ``login?username=xxx&password=yyy``. However, passing password in URL is unsafe, the option is now replaced by passwordless [Login Link](authentication.html?id=login-link). If you allowed login by URL, you need to update your code.Content Security Policy (CSP)
PHPMaker 2025 supports [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy), which is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross-Site Scripting (XSS) and data injection attacks. There are many [directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#directives) in CSP that is already set up as ``Config("CSP")`` which is an array like: See [Content Security Policy Builder](https://github.com/paragonie/csp-builder) for details. You can customize the ``Config("CSP")`` to change the directives as you need. Content Security Policy uses [nonce](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) attribute to determine whether or not a given fetch will be allowed to proceed for a given element. If you added your own `` The ``Nonce()`` global function outputs the ``nonce`` attribute with the current cryptographic nonce (number used once).User Level Hierarchy
User levels now can be hierarchical, each user level can have multiple sub user levels. A user level will automatically have all the permissions of sub user levels. If you want to use this feature, update your [User Level Security](securitysetup.html?id=user-level-security) settings, and your database if you use Dynamic User Levels.Changes of Some Event Names and Argument Names
Some out-date names are updated to more descriptive and meaningful names. When you open old projects, PHPMaker will try to update the signature and the argument names for you, you may need to do some final fixes yourself though. In general, - ``$rs`` is renamed as ``$row`` (or ``$result`` if the argument of ``Doctrine\DBAL\Result`` type) - ``$rsold`` renamed as ``$oldRow`` (or ``$oldRows`` if the argument is array of rows) - ``$rsnew`` renamed as ``$newRow`` (or ``$newRows`` if the argument is array of rows) - ``$args["rs|rsold|rsnew"]`` is renamed as ``$args["row|old|new"]`` depending on the data - ``Recordset_*`` server events are renamed as ``Records_*`` If your server events use these names, make sure you double check and update accordingly.The "UpdateTable" Property
Database views involving multiple tables are usually not updatable, sometimes you needed to set the "UpdateTable" Property of the page object in multiple server events and select the actual table to update. Now the [Update table](tablesetup.html?id=update-table) can be set under [Table Setup](tablesetup.html), it is recommended that you remove your code in server event. **Note** Doctrine entity does not support "UpdateTable".Single Index Page
In previous versions, there were two index pages, one at the root folder of the project and the other at the "api" subfolder. Now the two index pages are merged as one, there is no "api" subfolder anymore. If you generate your new scripts to the old project folder, make sure you delete the old "api" folder.Configuration Files
Some configuration settings (for debugging and maintenance) are moved from the _config.php_ to _config.development.php_ and _config.production.php_ so you can have different settings for different environments. If you cannot find a setting at where it was, check out the _config.Language Files
As usual there are new or changed phrases in new major version, make sure you update your non-English language files, otherwise some phrases will be missing. The new or changed phrases are marked with ```` in the default language file. If you upgrade from versions earlier than v2024, make sure you read [Language Files](migrate2024.html?id=language-files-1) in **Migrating to v2024** first.Deprecated and Removed
- MariaDB 10.4, MySQL 5.7 and Postgres 10 + 11 are deprecated, support will be removed from next major version. Please upgrade to MariaDB 10.5, MySQL 8.0, and Postgres 12, or later. - The [Charset](htmlsetup.html?id=charset) setting is removed, the value of charset now must be "utf-8" as it is the only valid encoding for HTML5 documents. - [Authenticating against an LDAP server](authentication.html?id=authenticating-against-an-ldap-server) has been updated to use a new LDAP client that supports LDAP search, therefore the **Ldap_Validated** server event has been removed, you can use the new setting [LDAP query string](authentication.html?id=ldap-query-string) instead. - The **MySQL charset (for SET NAMES)** advanced setting is removed and the setting will always be set to "utf8bm4". If you are still using older versions of MySQL/MariaDB and "utf8bm4" is not supported, you can set ``Config("MYSQL_CHARSET", "utf8bm3")`` in Global Code, - CKEditor extension is removed as CKEditor 4 reached its End of Life (EOL) on 2023/06/30 and CKEditor 5 is licensed under GPLv2+. It is recommended that you use TinyMCE v6.8.4 which is still MIT licensed. The TinyMCE extensions uses v6.8.4 by default. If you use TinyMCE v7, note that TinyMCE 7 is also licensed under GPLv2+, make sure your usage complies with the license. If you self-host TinyMCE under a commercial license, a valid license key must be provided. - The FileManager extension (for registered users) now supports TinyMCE only.