{"record":{"id":"1250074c74e2b00e","repo":"PHPOffice/PhpSpreadsheet","slug":"polynomial-best-fit-not-yet-implemented","errorCode":null,"errorMessage":"Polynomial Best Fit not yet implemented","messagePattern":"Polynomial Best Fit not yet implemented","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php","lineNumber":193,"sourceCode":"        $this->slope = $coefficients; //* @phpstan-ignore assign.propertyType (this whole class is a mess)\n\n        $this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, 0, 0, 0);\n        foreach ($this->xValues as $xKey => $xValue) {\n            $this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue);\n        }\n    }\n\n    /**\n     * Define the regression and calculate the goodness of fit for a set of X and Y data values.\n     *\n     * @param int $order Order of Polynomial for this regression\n     * @param float[] $yValues The set of Y-values for this regression\n     * @param float[] $xValues The set of X-values for this regression\n     */\n    public function __construct(int $order, array $yValues, array $xValues = [])\n    {\n        if (!$this->implemented) {\n            throw new SpreadsheetException('Polynomial Best Fit not yet implemented');\n        }\n\n        parent::__construct($yValues, $xValues);\n\n        if (!$this->error) {\n            if ($order < $this->valueCount) {\n                $this->bestFitType .= '_' . $order;\n                $this->order = $order;\n                $this->polynomialRegression($order, $yValues, $xValues);\n                if (($this->getGoodnessOfFit() < 0.0) || ($this->getGoodnessOfFit() > 1.0)) {\n                    $this->error = true;\n                }\n            } else {\n                $this->error = true;\n            }\n        }\n    }\n}","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php#L175-L211","documentation":"Thrown unconditionally by PolynomialBestFit::__construct(): the class carries `protected bool $implemented = false;` (PolynomialBestFit.php:27) and nothing ever sets it true, so any attempt to construct a polynomial trend throws before regression starts. It is a deliberate 'this math is not trusted/finished' switch, not a runtime condition you can influence.","triggerScenarios":"Calling Trend::trend(Trend::TREND_POLYNOMIAL, $yValues, $xValues) (or instantiating new PolynomialBestFit($order, $yValues, $xValues) directly). Regardless of data quality, order, or array sizes, the !$this->implemented check fires on the first line of the constructor.","commonSituations":"Porting Excel trendline features (polynomial order 2-6 fits) to server-side generation; unit-tested code that assumed the TREND_POLYNOMIAL constant implied a working implementation; exploring Shared\\Trend classes and assuming feature parity across trend types.","solutions":["Use a supported fit: TREND_LINEAR, TREND_LOGARITHMIC, TREND_EXPONENTIAL or TREND_POWER all construct working BestFit classes.","Compute the polynomial least-squares fit externally — e.g. the markrogoysk/math-php library (Regression::leastSquares) or a small normal-equations solver — and feed coefficients/results into your sheet manually.","Wrap the call in try/catch and degrade to a linear fit for the same data if polynomial fitting is optional polish rather than a requirement.","Track upstream PhpSpreadsheet issues/PRs; if you fix the math locally, set $implemented accordingly via a subclass and contribute back."],"exampleFix":"// before\n$fit = \\PhpOffice\\PhpSpreadsheet\\Shared\\Trend\\Trend::trend(\n    \\PhpOffice\\PhpSpreadsheet\\Shared\\Trend\\Trend::TREND_POLYNOMIAL, $yValues, $xValues\n); // Polynomial Best Fit not yet implemented\n\n// after\nuse Markrogoysk\\MathPHP\\Statistics\\Regression;\n$reg = Regression::leastSquares($xValues, $yValues); // polynomial fit outside PhpSpreadsheet\n$r2 = $reg->r2(); $coeffs = $reg->getParameters();\n// or fall back: Trend::trend(Trend::TREND_LINEAR, $yValues, $xValues)","handlingStrategy":"validation","validationCode":"const SUPPORTED_TRENDS = [\n    \\PhpOffice\\PhpSpreadsheet\\Shared\\Trend\\Trend::TREND_LINEAR,\n    \\PhpOffice\\PhpSpreadsheet\\Shared\\Trend\\Trend::TREND_LOGARITHMIC,\n    \\PhpOffice\\PhpSpreadsheet\\Shared\\Trend\\Trend::TREND_EXPONENTIAL,\n    \\PhpOffice\\PhpSpreadsheet\\Shared\\Trend\\Trend::TREND_POWER,\n];\n// TREND_POLYNOMIAL is intentionally excluded: PolynomialBestFit is not implemented.","typeGuard":"function supportedTrendType(string $type): ?string\n{\n    return in_array($type, ['linear', 'logarithmic', 'exponential', 'power'], true) ? $type : null;\n}","tryCatchPattern":"try {\n    $fit = Trend::trend($type, $yValues, $xValues);\n} catch (\\PhpOffice\\PhpSpreadsheet\\Exception $e) {\n    if (str_contains($e->getMessage(), 'not yet implemented')) {\n        $fit = Trend::trend(Trend::TREND_LINEAR, $yValues, $xValues); // graceful degradation\n    } else { throw $e; }\n}","preventionTips":["Do not build features on TREND_POLYNOMIAL — the constructor throws by design ($implemented = false).","Compute polynomial regressions with markrogoysk/math-php (or your own normal-equations solver) and write results into cells yourself.","Pin the library version and track upstream work before assuming polynomial support appears in a minor release."],"tags":["trend-analysis","not-implemented","statistics","phpspreadsheet"],"backgroundTag":"unsupported-feature","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}