{"record":{"id":"8749a4b461ac395a","repo":"PHPOffice/PhpSpreadsheet","slug":"cloning-a-singleton-is-not-allowed","errorCode":null,"errorMessage":"Cloning a Singleton is not allowed!","messagePattern":"Cloning a Singleton is not allowed!","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/ReferenceHelper.php","lineNumber":1409,"sourceCode":"            // Style\n            $coordinate = Coordinate::stringFromColumnIndex($i) . ($beforeRow - 1);\n            if ($worksheet->cellExists($coordinate)) {\n                $xfIndex = $worksheet->getCell($coordinate)->getXfIndex();\n                for ($j = $beforeRow; $j <= $beforeRow - 1 + $numberOfRows; ++$j) {\n                    if (!empty($xfIndex) || $worksheet->cellExists([$i, $j])) {\n                        $worksheet->getCell(Coordinate::stringFromColumnIndex($i) . $j)->setXfIndex($xfIndex);\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * __clone implementation. Cloning should not be allowed in a Singleton!\n     */\n    final public function __clone()\n    {\n        throw new Exception('Cloning a Singleton is not allowed!');\n    }\n}\n","sourceCodeStart":1391,"sourceCodeEnd":1412,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/ReferenceHelper.php#L1391-L1412","documentation":"ReferenceHelper is a singleton obtained via ReferenceHelper::getInstance(); its __clone is declared final and unconditionally throws, enforcing the singleton contract at the language level. The library does this so no second helper instance can drift out of sync with the one wired into the spreadsheet's insert/delete machinery.","triggerScenarios":"Any direct clone of the singleton: $helper = ReferenceHelper::getInstance(); $copy = clone $helper; generic deep-clone utilities that blindly clone every object in a graph; prototype-style code applied to services it did not create.","commonSituations":"Copy/pasted 'deep clone' helpers that iterate object properties and clone everything; attempts to snapshot spreadsheet state by cloning internals; frameworks that clone services during container compilation.","solutions":["Drop the clone and call ReferenceHelper::getInstance() wherever the helper is needed; it always returns the same shared instance","If you need an independent copy of document state, copy the Spreadsheet (copy() / duplicate sheets), not the helper","In generic deep-clone walkers, skip singletons or objects whose __clone throws"],"exampleFix":"// before\n$helper = ReferenceHelper::getInstance();\n$copy = clone $helper; // throws: Cloning a Singleton is not allowed!\n\n// after\n$helper = ReferenceHelper::getInstance(); // reuse the shared instance","handlingStrategy":"validation","validationCode":"// Refuse to clone known singletons before a generic deep-clone walk\nfunction safeClone(mixed $obj): mixed\n{\n    if ($obj instanceof \\PhpOffice\\PhpSpreadsheet\\ReferenceHelper) {\n        return \\PhpOffice\\PhpSpreadsheet\\ReferenceHelper::getInstance();\n    }\n\n    return clone $obj;\n}","typeGuard":"function isCloneableService(object $obj): bool\n{\n    return !($obj instanceof \\PhpOffice\\PhpSpreadsheet\\ReferenceHelper);\n}","tryCatchPattern":null,"preventionTips":["Fetch singletons via getInstance() at each use site; never store a clone","In deep-clone helpers, skip objects exposing __clone or documented singletons","Snapshot document state via Spreadsheet copy, not helper cloning"],"tags":["singleton","clone","language-level"],"backgroundTag":"singleton-clone-blocked","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}