Skip to content

PHP 8.4 classList works not correctly if copy HTMLElement by clone keyword. #18744

Closed

Description

@asika32764

Description

The following code:

<?php
$doc = \Dom\HTMLDocument::createEmpty();
$ele1 = $doc->createElement('div');
$ele1->classList->add('foo');
$ele2 = clone $ele1;
$ele2->classList->add('bar');

echo "Element1 class: " . $ele1->getAttribute('class');
echo "\n";
echo "Element2 class: " . $ele2->getAttribute('class');

Resulted in this output:

Element1 class: foo bar
Element2 class: foo

But I expected this output instead:

Element1 class: foo
Element2 class: foo bar

3v4l.org: https://3v4l.org/eaosZ#v8.4.7

If try to clone classList will raise an error:

Fatal error: Uncaught Error: Trying to clone an uncloneable object of class Dom\TokenList

But $ele2 = $ele->cloneNode(true) works.

PHP Version

PHP 8.4.7 (cli) (built: May  6 2025 14:14:22) (NTS Visual C++ 2022 x64)
Copyright (c) The PHP Group
Zend Engine v4.4.7, Copyright (c) Zend Technologie

Operating System

Windows 11 and 3v4l.org

Activity

  1. changed the title [-]PHP 8.4 classList works not correctly if HTMLElement cloned.[/-] [+]PHP 8.4 classList works not correctly if copy HTMLElement by `clone` keyword.[/+] on Jun 3, 2025
  2. added a commit that references this issue on Jun 3, 2025
    1fba294
  3. ndossche commented on Jun 3, 2025

    @ndossche
    Member

    Good find.

    Some clarification as to why cloneNode behaves correctly but clone does not:
    clone creates a copy of the entire object, while cloneNode only copies the tree structure and then creates a new object instance. This is significant if you have custom properties on an Element instance, or you extend the Element class yourself.

    The reason why TokenList is uncloneable is because the DOM spec requires it to always be the same object for a single Element. Therefore, the class can't be cloneable as it would violate this constraint.

  4. added 2 commits that reference this issue on Jun 4, 2025
    307ff3b
    111072a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions