Skip to content

Rule model fails to construct under think-orm v4 + PHP 8.x (WeakMap not initialized) #53

Description

@qs9000

Environment

  • PHP: 8.4 (reproduces on 8.1+ as well)
  • topthink/framework: ^8.1.4
  • topthink/think-orm: v4.0.51 (v4.x line)
  • casbin/think-authz: v2.0.4 (also affects 2.0.0)
  • casbin/casbin: v4.3.1

Description

The Rule model cannot be constructed when used with think-orm v4. It throws a fatal error before any Enforcer operation runs.

Steps to reproduce

  1. Install thinkphp 8.1 + think-orm 4.x + casbin/think-authz 2.x.
  2. Boot the framework and let the Enforcer/Rule model load (e.g. new \Casbin\Think\model\Rule() or any Enforcer init that touches the rules model).
  3. Observe the fatal error.

Actual behavior

Fatal error, one of:

  • Cannot auto-initialize an array inside property think\Model::$weakMap of type ?WeakMap
  • or array_search(): Argument #2 ($array) must be of type array, null given (TypeError)

Root cause

src/model/Rule.php assigns dynamic properties BEFORE calling the parent constructor:

public function __construct($data = [])
{
    $this->connection = $this->config('database.connection') ?: '';
    $this->table = $this->config('database.rules_table');
    $this->name = $this->config('database.rules_name');
    parent::__construct($data);
}

In think-orm v4, connection/table/name are no longer declared properties, so these assignments trigger the magic __set → set() → getMappingName(). At this point:

  1. Model::$weakMap (typed ?WeakMap) has not been initialized yet (that happens inside Model::__construct, which runs afterward), so writing self::$weakMap[$this] crashes.
  2. getOption('mapping') returns null for this model, so array_search($name, $mapping) in Attribute::getMappingName() throws a TypeError.

Suggested fix

Call parent::__construct($data) before assigning the connection/table/name, so the WeakMap model state is initialized first:

public function __construct($data = [])
{
    parent::__construct($data);
    $this->connection = $this->config('database.connection') ?: '';
    $this->table = $this->config('database.rules_table');
    $this->name = $this->config('database.rules_name');
}

(Note: the array_search($name, $mapping) null-safety issue should also be patched on the think-orm side — see separate issue for topthink/think-orm.)

Workaround (local, not upstream)

Apply both changes manually as described above.

By the way casbin/casbin last version is v4.3.1,please update composer.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions