@@ -41,7 +41,7 @@ class Cookie
4141 * @see https://www.php.net/manual/en/datetime.formats.php
4242 * @see https://www.php.net/manual/en/function.setcookie.php
4343 *
44- * @throws CookieException if $sameSite value is wrong
44+ * @throws CookieException if $sameSite value is wrong.
4545 */
4646 public function __construct (
4747 private string $ domain = '' ,
@@ -52,12 +52,7 @@ public function __construct(
5252 private null |string $ sameSite = null ,
5353 private bool $ secure = false ,
5454 ) {
55- $ this ->failIfSameSiteValueIsWrong ();
56-
57- set_error_handler (
58- fn (int $ severity , string $ message , string $ file ) =>
59- $ file === __FILE__ && throw new CookieException ($ message )
60- );
55+ $ this ->throwExceptionIfSameSiteValueIsWrong ();
6156 }
6257
6358 /**
@@ -97,11 +92,13 @@ public function get(string $name, mixed $default = null): mixed
9792 *
9893 * @see https://www.php.net/manual/en/datetime.formats.php
9994 *
100- * @throws CookieException if headers already sent
101- * @throws CookieException if failure in date/time string analysis
95+ * @throws CookieException if headers already sent.
96+ * @throws CookieException if failure in date/time string analysis.
10297 */
10398 public function set (string $ name , mixed $ value , null |int |string |DateTime $ expires = null ): void
10499 {
100+ $ this ->throwExceptionIfHeadersWereSent ();
101+
105102 $ params = [$ name , $ value , $ this ->getOptions ($ expires === null ? $ this ->expires : $ expires )];
106103
107104 $ this ->raw ? setrawcookie (...$ params ) : setcookie (...$ params );
@@ -119,10 +116,12 @@ public function set(string $name, mixed $value, null|int|string|DateTime $expire
119116 *
120117 * @see https://www.php.net/manual/en/datetime.formats.php
121118 *
122- * @throws CookieException if headers already sent
119+ * @throws CookieException if headers already sent.
123120 */
124121 public function replace (array $ data , null |int |string |DateTime $ expires = null ): void
125122 {
123+ $ this ->throwExceptionIfHeadersWereSent ();
124+
126125 foreach ($ data as $ name => $ value ) {
127126 $ this ->set ($ name , $ value , $ expires );
128127 }
@@ -133,10 +132,12 @@ public function replace(array $data, null|int|string|DateTime $expires = null):
133132 *
134133 * Optionally defines a default value when the cookie does not exist.
135134 *
136- * @throws CookieException if headers already sent
135+ * @throws CookieException if headers already sent.
137136 */
138137 public function pull (string $ name , mixed $ default = null ): mixed
139138 {
139+ $ this ->throwExceptionIfHeadersWereSent ();
140+
140141 $ value = $ _COOKIE [$ name ] ?? $ default ;
141142
142143 $ this ->remove ($ name );
@@ -147,11 +148,13 @@ public function pull(string $name, mixed $default = null): mixed
147148 /**
148149 * Deletes a cookie by name.
149150 *
150- * @throws CookieException if headers already sent
151- * @throws CookieException if failure in date/time string analysis
151+ * @throws CookieException if headers already sent.
152+ * @throws CookieException if failure in date/time string analysis.
152153 */
153154 public function remove (string $ name ): void
154155 {
156+ $ this ->throwExceptionIfHeadersWereSent ();
157+
155158 $ params = [$ name , '' , $ this ->getOptions (1 , false )];
156159
157160 $ this ->raw ? setrawcookie (...$ params ) : setcookie (...$ params );
@@ -160,10 +163,12 @@ public function remove(string $name): void
160163 /**
161164 * Deletes all cookies.
162165 *
163- * @throws CookieException if headers already sent
166+ * @throws CookieException if headers already sent.
164167 */
165168 public function clear (): void
166169 {
170+ $ this ->throwExceptionIfHeadersWereSent ();
171+
167172 foreach ($ _COOKIE ?? [] as $ name ) {
168173 $ this ->remove ($ name );
169174 }
@@ -172,7 +177,7 @@ public function clear(): void
172177 /**
173178 * Gets cookie options.
174179 *
175- * @throws CookieException if failure in date/time string analysis
180+ * @throws CookieException if failure in date/time string analysis.
176181 */
177182 private function getOptions (null |int |string |DateTime $ expires , bool $ formatTime = true ): array
178183 {
@@ -198,7 +203,7 @@ private function getOptions(null|int|string|DateTime $expires, bool $formatTime
198203 /**
199204 * Format the expiration time.
200205 *
201- * @throws CookieException if failure in date/time string analysis
206+ * @throws CookieException if failure in date/time string analysis.
202207 */
203208 private function formatExpirationTime (int |string |DateTime $ expires ): int
204209 {
@@ -215,12 +220,26 @@ private function formatExpirationTime(int|string|DateTime $expires): int
215220 }
216221 }
217222
223+ /**
224+ * Throw exception if headers have already been sent.
225+ *
226+ * @throws CookieException if headers already sent.
227+ */
228+ private function throwExceptionIfHeadersWereSent (): void
229+ {
230+ headers_sent ($ file , $ line ) && throw new CookieException (sprintf (
231+ 'The headers have already been sent in "%s" at line %d. ' ,
232+ $ file ,
233+ $ line
234+ ));
235+ }
236+
218237 /**
219238 * Throw exception if $sameSite value is wrong.
220239 *
221- * @throws CookieException if $sameSite value is wrong
240+ * @throws CookieException if $sameSite value is wrong.
222241 */
223- private function failIfSameSiteValueIsWrong (): void
242+ private function throwExceptionIfSameSiteValueIsWrong (): void
224243 {
225244 $ values = ['none ' , 'lax ' , 'strict ' ];
226245
0 commit comments