*/ private array $headers; /** * @param array $headers */ public function __construct(array $headers = []) { $this->headers = $this->normalizeHeaders($headers); } /** * @return array */ public function all(): array { $headers = []; foreach ($this->headers as $entry) { $headers[$entry['name']] = $entry['value']; } return $headers; } public function withoutHeaders(): self { if ($this->headers === []) { return $this; } return new self(); } /** * @param array $headers */ public function withHeaders(array $headers): self { if ($headers === []) { return $this; } $merged = array_replace($this->headers, $this->normalizeHeaders($headers)); if ($merged === $this->headers) { return $this; } return self::fromNormalized($merged); } public function withTraceParent(TraceParent $traceParent): self { $normalized = $this->headers; $normalized['traceparent'] = [ 'name' => 'traceparent', 'value' => $traceParent->header(), ]; unset($normalized['tracestate']); if ($normalized === $this->headers) { return $this; } return self::fromNormalized($normalized); } public function withTraceContext(TraceContext $traceContext): self { $normalized = array_replace($this->headers, $this->normalizeHeaders($traceContext->headers())); if ($traceContext->traceState() === null) { unset($normalized['tracestate']); } if ($normalized === $this->headers) { return $this; } return self::fromNormalized($normalized); } /** * @param array $headers * * @return array */ public function merge(array $headers): array { return $this->withHeaders($headers)->all(); } /** * @param array $headers */ private static function fromNormalized(array $headers): self { $self = new self(); $self->headers = $headers; return $self; } /** * @param array $headers * * @return array */ private function normalizeHeaders(array $headers): array { $normalized = []; foreach ($headers as $name => $value) { $name = trim((string) $name); if ($name === '') { continue; } $normalized[strtolower($name)] = [ 'name' => $name, 'value' => $value, ]; } return $normalized; } }