This is a documentation for Board Game Arena: play board games online !

PHP 8 upgrade: Difference between revisions

From Board Game Arena
Jump to navigation Jump to search
mNo edit summary
(Complete! 🎉)
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{Studio_Framework_Navigation}}
{{Studio_Framework_Navigation}}
[[Category:Studio]]


Starting December 2023, BGA is upgrading game servers from PHP 7.4 to PHP 8.2. See https://boardgamearena.com/forum/viewtopic.php?t=33940 for more information.
Starting in 2023-12, BGA began upgrading game servers from PHP 7.4 to PHP 8.2. See https://boardgamearena.com/forum/viewtopic.php?t=33940 for more information.


== Current Status ==
As of 2024-08-09, the BGA upgrade to PHP 8.2 is '''complete'''. Your game can now use PHP 8-specific features. 🎉
BGA studio and production are both currently running in a <b>mixed environment</b>, with some servers on PHP 7 and others on PHP 8. Until this upgrade is fully completed, your game code must be compatible with both versions of PHP. You <b>cannot</b> use any PHP 8-specific features yet.


The following servers are currently running PHP 8.2:
== Fix your game's code ==
* <b>PHP 8 gameservers in Studio:</b> 2
* <b>PHP 8 gameservers in Production:</b> 5, 7, 8, 12


== How to control your game's PHP version ==
Here are a few common scenarios that may make your game incompatible with PHP 8 and how to fix them:


In studio, you can switch between PHP 7.4 and PHP 8.2 using the [https://studio.boardgamearena.com/studio Managed Game] page. You can also change the gameserver portion of the URL between "/1" and "/2" (although this doesn't test your game setup code). For example, https://studio.boardgamearena.com/1/nowboarding?table=575275 is PHP 7 and https://studio.boardgamearena.com/2/nowboarding?table=575275 is PHP 8.
=== <code>implode</code> argument order ===
 
📖 See https://www.php.net/manual/en/function.implode.php
 
The signature of this function is <code>implode(string $separator, array $array): string</code>. PHP 7 accepted the arguments in either order, but PHP 8 requires the string argument first and the array argument second.
 
=== Static calls to non-static methods ===


In production, you can add the <b>PHP8</b> tag using the [https://boardgamearena.com/controlpanelgames Game Metadata Manager] page. This allows (but does not guarantee) new real-time tables for your game to be created on one of the PHP 8 servers. All turn-based tables continue to run on the PHP 7 servers.
📖 See https://php.watch/versions/8.0/non-static-static-call-fatal-error and https://www.php.net/manual/en/language.oop5.basic.php


== How to fix your game's code ==
PHP 8 no longer allows non-static class methods to be called statically. This may affect your game if you've created a class which <code>extends APP_GameClass</code> and you call various BGA framework functions statically using <code>self::</code>.


Here are a few common scenarios that may make your game incompatible with PHP 8:
If possible, the simplest change is to replace <code>self::</code> with <code>$this-></code> (which refers to the current instance of your game class). This works if your function is non-static.


=== <code>implode</code> argument order ===
Non-compliant example:
The signature of this function is <code>implode(string $separator, array $array): string</code>.


PHP 7 accepted the arguments in either order, but PHP 8 requires the string argument first and the array argument second.
    class NMap extends APP_GameClass {
        public function getPossibleMoves($playerId) {
            $planeHasNervous = intval(self::getUniqueValueFromDB("SELECT COUNT(1) FROM `pax` WHERE `player_id` = $playerId AND `status` = 'SEAT' AND `vip` = 'NERVOUS'")) > 0;


See https://www.php.net/implode
Fix:


=== Static calls to non-static methods ===
    class NMap extends APP_GameClass {
        public function getPossibleMoves($playerId) {
            $planeHasNervous = intval($this->getUniqueValueFromDB("SELECT COUNT(1) FROM `pax` WHERE `player_id` = $playerId AND `status` = 'SEAT' AND `vip` = 'NERVOUS'")) > 0;


PHP 8 no longer allows non-static class methods to be called statically. This may affect your game if you've created a class which <code>extends APP_GameClass</code> and you call various BGA framework functions statically using <code>self::</code>.
Otherwise, if your own function is static and <code>$this-></code> doesn't exist, you can create a static variable like <code>$instance</code> in your game class, populate the variable in your game's constructor, and call the BGA framework functions through this variable.


Non-compliant example:
Non-compliant example:
Line 38: Line 45:
         }
         }


See https://php.watch/versions/8.0/non-static-static-call-fatal-error
Fix:
 
    class hardback extends Table {
        public static $instance = null;
        function __construct() {
            parent::__construct();
            self::$instance = $this;
 
    class PlayerMgr extends APP_GameClass {
        public static function getMaxScore() {
            return hardback::$instance->getUniqueValueFromDB("SELECT MAX(player_score) FROM player WHERE player_eliminated = 0 AND player_zombie = 0");
        }

Latest revision as of 13:56, 10 August 2024


Game File Reference



Useful Components

Official

  • Deck: a PHP component to manage cards (deck, hands, picking cards, moving cards, shuffle deck, ...).
  • Draggable: a JS component to manage drag'n'drop actions.
  • Counter: a JS component to manage a counter that can increase/decrease (ex: player's score).
  • ExpandableSection: a JS component to manage a rectangular block of HTML than can be displayed/hidden.
  • Scrollmap: a JS component to manage a scrollable game area (useful when the game area can be infinite. Examples: Saboteur or Takenoko games).
  • Stock: a JS component to manage and display a set of game elements displayed at a position.
  • Zone: a JS component to manage a zone of the board where several game elements can come and leave, but should be well displayed together (See for example: token's places at Can't Stop).

Undocumented component (if somebody knows please help with docs)

  • Wrapper: a JS component to wrap a <div> element around its child, even if these elements are absolute positioned.

Unofficial



Game Development Process



Guides for Common Topics



Miscellaneous Resources

Starting in 2023-12, BGA began upgrading game servers from PHP 7.4 to PHP 8.2. See https://boardgamearena.com/forum/viewtopic.php?t=33940 for more information.

As of 2024-08-09, the BGA upgrade to PHP 8.2 is complete. Your game can now use PHP 8-specific features. 🎉

Fix your game's code

Here are a few common scenarios that may make your game incompatible with PHP 8 and how to fix them:

implode argument order

📖 See https://www.php.net/manual/en/function.implode.php

The signature of this function is implode(string $separator, array $array): string. PHP 7 accepted the arguments in either order, but PHP 8 requires the string argument first and the array argument second.

Static calls to non-static methods

📖 See https://php.watch/versions/8.0/non-static-static-call-fatal-error and https://www.php.net/manual/en/language.oop5.basic.php

PHP 8 no longer allows non-static class methods to be called statically. This may affect your game if you've created a class which extends APP_GameClass and you call various BGA framework functions statically using self::.

If possible, the simplest change is to replace self:: with $this-> (which refers to the current instance of your game class). This works if your function is non-static.

Non-compliant example:

   class NMap extends APP_GameClass {
       public function getPossibleMoves($playerId) {
           $planeHasNervous = intval(self::getUniqueValueFromDB("SELECT COUNT(1) FROM `pax` WHERE `player_id` = $playerId AND `status` = 'SEAT' AND `vip` = 'NERVOUS'")) > 0;

Fix:

   class NMap extends APP_GameClass {
       public function getPossibleMoves($playerId) {
           $planeHasNervous = intval($this->getUniqueValueFromDB("SELECT COUNT(1) FROM `pax` WHERE `player_id` = $playerId AND `status` = 'SEAT' AND `vip` = 'NERVOUS'")) > 0;

Otherwise, if your own function is static and $this-> doesn't exist, you can create a static variable like $instance in your game class, populate the variable in your game's constructor, and call the BGA framework functions through this variable.

Non-compliant example:

   class PlayerMgr extends APP_GameClass {
       public static function getMaxScore() {
           return self::getUniqueValueFromDB("SELECT MAX(player_score) FROM player WHERE player_eliminated = 0 AND player_zombie = 0");
       }

Fix:

   class hardback extends Table {
       public static $instance = null;
       function __construct() {
           parent::__construct();
           self::$instance = $this;
   class PlayerMgr extends APP_GameClass {
       public static function getMaxScore() {
           return hardback::$instance->getUniqueValueFromDB("SELECT MAX(player_score) FROM player WHERE player_eliminated = 0 AND player_zombie = 0");
       }