PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
Polynomial Best Fit not yet implemented
Error message
Polynomial Best Fit not yet implemented
What it means
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.
Source
Thrown at src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php:193
$this->slope = $coefficients; //* @phpstan-ignore assign.propertyType (this whole class is a mess)
$this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, 0, 0, 0);
foreach ($this->xValues as $xKey => $xValue) {
$this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue);
}
}
/**
* Define the regression and calculate the goodness of fit for a set of X and Y data values.
*
* @param int $order Order of Polynomial for this regression
* @param float[] $yValues The set of Y-values for this regression
* @param float[] $xValues The set of X-values for this regression
*/
public function __construct(int $order, array $yValues, array $xValues = [])
{
if (!$this->implemented) {
throw new SpreadsheetException('Polynomial Best Fit not yet implemented');
}
parent::__construct($yValues, $xValues);
if (!$this->error) {
if ($order < $this->valueCount) {
$this->bestFitType .= '_' . $order;
$this->order = $order;
$this->polynomialRegression($order, $yValues, $xValues);
if (($this->getGoodnessOfFit() < 0.0) || ($this->getGoodnessOfFit() > 1.0)) {
$this->error = true;
}
} else {
$this->error = true;
}
}
}
}View on GitHub (pinned to 65b080eef4)
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.
Example fix
// before
$fit = \PhpOffice\PhpSpreadsheet\Shared\Trend\Trend::trend(
\PhpOffice\PhpSpreadsheet\Shared\Trend\Trend::TREND_POLYNOMIAL, $yValues, $xValues
); // Polynomial Best Fit not yet implemented
// after
use Markrogoysk\MathPHP\Statistics\Regression;
$reg = Regression::leastSquares($xValues, $yValues); // polynomial fit outside PhpSpreadsheet
$r2 = $reg->r2(); $coeffs = $reg->getParameters();
// or fall back: Trend::trend(Trend::TREND_LINEAR, $yValues, $xValues) Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED_TRENDS = [
\PhpOffice\PhpSpreadsheet\Shared\Trend\Trend::TREND_LINEAR,
\PhpOffice\PhpSpreadsheet\Shared\Trend\Trend::TREND_LOGARITHMIC,
\PhpOffice\PhpSpreadsheet\Shared\Trend\Trend::TREND_EXPONENTIAL,
\PhpOffice\PhpSpreadsheet\Shared\Trend\Trend::TREND_POWER,
];
// TREND_POLYNOMIAL is intentionally excluded: PolynomialBestFit is not implemented. Type guard
function supportedTrendType(string $type): ?string
{
return in_array($type, ['linear', 'logarithmic', 'exponential', 'power'], true) ? $type : null;
} Try / catch
try {
$fit = Trend::trend($type, $yValues, $xValues);
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
if (str_contains($e->getMessage(), 'not yet implemented')) {
$fit = Trend::trend(Trend::TREND_LINEAR, $yValues, $xValues); // graceful degradation
} else { throw $e; }
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Trend(): Number of elements in coordinate arrays do not matc
- Unknown trend type {$trendType}
- Unsupported binary comparison operator
- Cloning the calculation engine is not allowed!
- Unsupported numeric binary operation
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/1250074c74e2b00e.
Report an issue: GitHub.