• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

codeigniter4 / CodeIgniter4 / 26891695236

03 Jun 2026 02:32PM UTC coverage: 88.549% (+0.002%) from 88.547%
26891695236

Pull #10274

github

web-flow
Merge 55bce5981 into 12888fbec
Pull Request #10274: feat: Add Request ID to IncomingRequest

24296 of 27438 relevant lines covered (88.55%)

224.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.65
/system/HTTP/IncomingRequest.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of CodeIgniter 4 framework.
7
 *
8
 * (c) CodeIgniter Foundation <admin@codeigniter.com>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace CodeIgniter\HTTP;
15

16
use CodeIgniter\Exceptions\InvalidArgumentException;
17
use CodeIgniter\HTTP\Exceptions\HTTPException;
18
use CodeIgniter\HTTP\Files\FileCollection;
19
use CodeIgniter\HTTP\Files\UploadedFile;
20
use Config\App;
21
use Config\Services;
22
use Locale;
23
use stdClass;
24

25
/**
26
 * Class IncomingRequest
27
 *
28
 * Represents an incoming, server-side HTTP request.
29
 *
30
 * Per the HTTP specification, this interface includes properties for
31
 * each of the following:
32
 *
33
 * - Protocol version
34
 * - HTTP method
35
 * - URI
36
 * - Headers
37
 * - Message body
38
 *
39
 * Additionally, it encapsulates all data as it has arrived to the
40
 * application from the CGI and/or PHP environment, including:
41
 *
42
 * - The values represented in $_SERVER.
43
 * - Any cookies provided (generally via $_COOKIE)
44
 * - Query string arguments (generally via $_GET, or as parsed via parse_str())
45
 * - Upload files, if any (as represented by $_FILES)
46
 * - Deserialized body binds (generally from $_POST)
47
 *
48
 * @see \CodeIgniter\HTTP\IncomingRequestTest
49
 */
50
class IncomingRequest extends Request
51
{
52
    /**
53
     * The Request ID associated with this request useful for
54
     * debugging, traceability, and logging.
55
     *
56
     * Incoming request's X-Request-Id header will get priority
57
     * over automatically generated request ids.
58
     */
59
    protected string $requestId;
60

61
    /**
62
     * The URI for this request.
63
     *
64
     * Note: This WILL NOT match the actual URL in the browser since for
65
     * everything this cares about (and the router, etc) is the portion
66
     * AFTER the baseURL. So, if hosted in a sub-folder this will
67
     * appear different than actual URI path. If you need that use getPath().
68
     *
69
     * @var URI
70
     */
71
    protected $uri;
72

73
    /**
74
     * The detected URI path (relative to the baseURL).
75
     *
76
     * Note: current_url() uses this to build its URI,
77
     * so this becomes the source for the "current URL"
78
     * when working with the share request instance.
79
     *
80
     * @var string|null
81
     */
82
    protected $path;
83

84
    /**
85
     * File collection
86
     *
87
     * @var FileCollection|null
88
     */
89
    protected $files;
90

91
    /**
92
     * Negotiator
93
     *
94
     * @var Negotiate|null
95
     */
96
    protected $negotiator;
97

98
    /**
99
     * The default Locale this request
100
     * should operate under.
101
     *
102
     * @var string
103
     */
104
    protected $defaultLocale;
105

106
    /**
107
     * The current locale of the application.
108
     * Default value is set in app/Config/App.php
109
     *
110
     * @var string
111
     */
112
    protected $locale;
113

114
    /**
115
     * Stores the valid locale codes.
116
     *
117
     * @var array
118
     */
119
    protected $validLocales = [];
120

121
    /**
122
     * Holds the old data from a redirect.
123
     *
124
     * @var array
125
     */
126
    protected $oldInput = [];
127

128
    /**
129
     * The user agent this request is from.
130
     *
131
     * @var UserAgent
132
     */
133
    protected $userAgent;
134

135
    /**
136
     * Typed input data selector.
137
     */
138
    protected ?RequestInput $input = null;
139

140
    /**
141
     * Constructor
142
     *
143
     * @param App         $config
144
     * @param string|null $body
145
     */
146
    public function __construct($config, ?URI $uri = null, $body = 'php://input', ?UserAgent $userAgent = null)
147
    {
148
        if (! $uri instanceof URI || ! $userAgent instanceof UserAgent) {
3,455✔
149
            throw new InvalidArgumentException('You must supply the parameters: uri, userAgent.');
×
150
        }
151

152
        $this->populateHeaders();
3,455✔
153

154
        if (
155
            $body === 'php://input'
3,455✔
156
            // php://input is not available with enctype="multipart/form-data".
157
            // See https://www.php.net/manual/en/wrappers.php.php#wrappers.php.input
158
            && ! str_contains($this->getHeaderLine('Content-Type'), 'multipart/form-data')
3,455✔
159
            && (int) $this->getHeaderLine('Content-Length') <= $this->getPostMaxSize()
3,455✔
160
        ) {
161
            // Get our body from php://input
162
            $body = file_get_contents('php://input');
3,082✔
163
        }
164

165
        // If file_get_contents() returns false or empty string, set null.
166
        if ($body === false || $body === '') {
3,455✔
167
            $body = null;
3,085✔
168
        }
169

170
        $this->requestId    = $this->hasHeader('X-Request-ID') ? $this->getHeaderLine('X-Request-ID') : $this->generateRequestId();
3,455✔
171
        $this->uri          = $uri;
3,455✔
172
        $this->body         = $body;
3,455✔
173
        $this->userAgent    = $userAgent;
3,455✔
174
        $this->validLocales = $config->supportedLocales;
3,455✔
175

176
        parent::__construct($config);
3,455✔
177

178
        if ($uri instanceof SiteURI) {
3,455✔
179
            $this->setPath($uri->getRoutePath());
3,455✔
180
        } else {
181
            $this->setPath($uri->getPath());
×
182
        }
183

184
        $this->detectLocale($config);
3,455✔
185
    }
186

187
    public function __clone()
188
    {
189
        $this->input = null;
126✔
190
    }
191

192
    private function generateRequestId(): string
193
    {
194
        return bin2hex(random_bytes(16));
3,455✔
195
    }
196

197
    private function getPostMaxSize(): int
198
    {
199
        $postMaxSize = ini_get('post_max_size');
3,082✔
200

201
        return match (strtoupper(substr($postMaxSize, -1))) {
3,082✔
202
            'G'     => (int) str_replace('G', '', $postMaxSize) * 1024 ** 3,
×
203
            'M'     => (int) str_replace('M', '', $postMaxSize) * 1024 ** 2,
3,082✔
204
            'K'     => (int) str_replace('K', '', $postMaxSize) * 1024,
×
205
            default => (int) $postMaxSize,
3,082✔
206
        };
3,082✔
207
    }
208

209
    public function getRequestId(): string
210
    {
211
        return $this->requestId;
2✔
212
    }
213

214
    /**
215
     * Handles setting up the locale, perhaps auto-detecting through
216
     * content negotiation.
217
     *
218
     * @param App $config
219
     *
220
     * @return void
221
     */
222
    public function detectLocale($config)
223
    {
224
        $this->locale = $this->defaultLocale = $config->defaultLocale;
3,455✔
225

226
        if (! $config->negotiateLocale) {
3,455✔
227
            return;
3,455✔
228
        }
229

230
        $this->setLocale($this->negotiate('language', $config->supportedLocales));
2✔
231
    }
232

233
    /**
234
     * Provides a convenient way to work with the Negotiate class
235
     * for content negotiation.
236
     */
237
    public function negotiate(string $type, array $supported, bool $strictMatch = false): string
238
    {
239
        if ($this->negotiator === null) {
17✔
240
            $this->negotiator = Services::negotiator($this, true);
17✔
241
        }
242

243
        return match (strtolower($type)) {
17✔
244
            'media'    => $this->negotiator->media($supported, $strictMatch),
11✔
245
            'charset'  => $this->negotiator->charset($supported),
1✔
246
            'encoding' => $this->negotiator->encoding($supported),
1✔
247
            'language' => $this->negotiator->language($supported),
3✔
248
            default    => throw HTTPException::forInvalidNegotiationType($type),
17✔
249
        };
17✔
250
    }
251

252
    /**
253
     * Checks this request type.
254
     */
255
    public function is(string $type): bool
256
    {
257
        $valueUpper = strtoupper($type);
59✔
258

259
        $httpMethods = Method::all();
59✔
260

261
        if (in_array($valueUpper, $httpMethods, true)) {
59✔
262
            return $this->getMethod() === $valueUpper;
44✔
263
        }
264

265
        if ($valueUpper === 'JSON') {
15✔
266
            return str_contains($this->getHeaderLine('Content-Type'), 'application/json');
13✔
267
        }
268

269
        if ($valueUpper === 'AJAX') {
2✔
270
            return $this->isAJAX();
1✔
271
        }
272

273
        throw new InvalidArgumentException('Unknown type: ' . $type);
1✔
274
    }
275

276
    /**
277
     * Determines if this request was made from the command line (CLI).
278
     */
279
    public function isCLI(): bool
280
    {
281
        return false;
6✔
282
    }
283

284
    /**
285
     * Test to see if a request contains the HTTP_X_REQUESTED_WITH header.
286
     */
287
    public function isAJAX(): bool
288
    {
289
        return $this->hasHeader('X-Requested-With')
94✔
290
            && strtolower($this->header('X-Requested-With')->getValue()) === 'xmlhttprequest';
94✔
291
    }
292

293
    /**
294
     * Attempts to detect if the current connection is secure through
295
     * a few different methods.
296
     */
297
    public function isSecure(): bool
298
    {
299
        $https = service('superglobals')->server('HTTPS');
11✔
300

301
        if ($https !== null && strtolower($https) !== 'off') {
11✔
302
            return true;
1✔
303
        }
304

305
        if ($this->hasHeader('X-Forwarded-Proto') && $this->header('X-Forwarded-Proto')->getValue() === 'https') {
10✔
306
            return true;
1✔
307
        }
308

309
        return $this->hasHeader('Front-End-Https') && ! empty($this->header('Front-End-Https')->getValue()) && strtolower($this->header('Front-End-Https')->getValue()) !== 'off';
9✔
310
    }
311

312
    /**
313
     * Sets the URI path relative to baseURL.
314
     *
315
     * Note: Since current_url() accesses the shared request
316
     * instance, this can be used to change the "current URL"
317
     * for testing.
318
     *
319
     * @param string $path URI path relative to baseURL
320
     *
321
     * @return $this
322
     */
323
    private function setPath(string $path)
324
    {
325
        $this->path = $path;
3,455✔
326

327
        return $this;
3,455✔
328
    }
329

330
    /**
331
     * Returns the URI path relative to baseURL,
332
     * running detection as necessary.
333
     */
334
    public function getPath(): string
335
    {
336
        return $this->path;
116✔
337
    }
338

339
    /**
340
     * Sets the locale string for this request.
341
     *
342
     * @return IncomingRequest
343
     */
344
    public function setLocale(string $locale)
345
    {
346
        // If it's not a valid locale, set it
347
        // to the default locale for the site.
348
        if (! in_array($locale, $this->validLocales, true)) {
5✔
349
            $locale = $this->defaultLocale;
1✔
350
        }
351

352
        $this->locale = $locale;
5✔
353
        Locale::setDefault($locale);
5✔
354

355
        return $this;
5✔
356
    }
357

358
    /**
359
     * Set the valid locales.
360
     *
361
     * @return $this
362
     */
363
    public function setValidLocales(array $locales)
364
    {
365
        $this->validLocales = $locales;
1✔
366

367
        return $this;
1✔
368
    }
369

370
    /**
371
     * Gets the current locale, with a fallback to the default
372
     * locale if none is set.
373
     */
374
    public function getLocale(): string
375
    {
376
        return $this->locale;
578✔
377
    }
378

379
    /**
380
     * Returns the default locale as set in app/Config/App.php
381
     */
382
    public function getDefaultLocale(): string
383
    {
384
        return $this->defaultLocale;
3✔
385
    }
386

387
    /**
388
     * Fetch an item from JSON input stream with fallback to $_REQUEST object. This is the simplest way
389
     * to grab data from the request object and can be used in lieu of the
390
     * other get* methods in most cases.
391
     *
392
     * @param array|string|null $index
393
     * @param int|null          $filter Filter constant
394
     * @param array|int|null    $flags
395
     *
396
     * @return array|bool|float|int|stdClass|string|null
397
     */
398
    public function getVar($index = null, $filter = null, $flags = null)
399
    {
400
        if (
401
            str_contains($this->getHeaderLine('Content-Type'), 'application/json')
18✔
402
            && $this->body !== null
18✔
403
        ) {
404
            return $this->getJsonVar($index, false, $filter, $flags);
1✔
405
        }
406

407
        return $this->fetchGlobal('request', $index, $filter, $flags);
17✔
408
    }
409

410
    /**
411
     * A convenience method that grabs the raw input stream and decodes
412
     * the JSON into an array.
413
     *
414
     * If $assoc == true, then all objects in the response will be converted
415
     * to associative arrays.
416
     *
417
     * @param bool $assoc   Whether to return objects as associative arrays
418
     * @param int  $depth   How many levels deep to decode
419
     * @param int  $options Bitmask of options
420
     *
421
     * @see http://php.net/manual/en/function.json-decode.php
422
     *
423
     * @return array|bool|float|int|stdClass|null
424
     *
425
     * @throws HTTPException When the body is invalid as JSON.
426
     */
427
    public function getJSON(bool $assoc = false, int $depth = 512, int $options = 0)
428
    {
429
        if ($this->body === null) {
29✔
430
            return null;
4✔
431
        }
432

433
        $result = json_decode($this->body, $assoc, $depth, $options);
25✔
434

435
        if (json_last_error() !== JSON_ERROR_NONE) {
24✔
436
            throw HTTPException::forInvalidJSON(json_last_error_msg());
4✔
437
        }
438

439
        return $result;
20✔
440
    }
441

442
    /**
443
     * Get a specific variable from a JSON input stream
444
     *
445
     * @param array|string|null $index  The variable that you want which can use dot syntax for getting specific values.
446
     * @param bool              $assoc  If true, return the result as an associative array.
447
     * @param int|null          $filter Filter Constant
448
     * @param array|int|null    $flags  Option
449
     *
450
     * @return array|bool|float|int|stdClass|string|null
451
     */
452
    public function getJsonVar($index = null, bool $assoc = false, ?int $filter = null, $flags = null)
453
    {
454
        helper('array');
6✔
455

456
        $data = $this->getJSON(true);
6✔
457
        if (! is_array($data)) {
6✔
458
            return null;
1✔
459
        }
460

461
        if (is_string($index)) {
5✔
462
            $data = dot_array_search($index, $data);
5✔
463
        } elseif (is_array($index)) {
2✔
464
            $result = [];
2✔
465

466
            foreach ($index as $key) {
2✔
467
                $result[$key] = dot_array_search($key, $data);
2✔
468
            }
469

470
            [$data, $result] = [$result, null];
2✔
471
        }
472

473
        if ($data === null) {
5✔
474
            return null;
2✔
475
        }
476

477
        $filter ??= FILTER_UNSAFE_RAW;
5✔
478
        $flags = is_array($flags) ? $flags : (is_numeric($flags) ? (int) $flags : 0);
5✔
479

480
        if ($filter !== FILTER_UNSAFE_RAW
5✔
481
            || (
482
                (is_numeric($flags) && $flags !== 0)
5✔
483
                || is_array($flags) && $flags !== []
5✔
484
            )
485
        ) {
486
            if (is_array($data)) {
2✔
487
                // Iterate over array and append filter and flags
488
                array_walk_recursive($data, static function (&$val) use ($filter, $flags): void {
1✔
489
                    $valType = gettype($val);
1✔
490
                    $val     = filter_var($val, $filter, $flags);
1✔
491

492
                    if (in_array($valType, ['int', 'integer', 'float', 'double', 'bool', 'boolean'], true) && $val !== false) {
1✔
493
                        settype($val, $valType);
1✔
494
                    }
495
                });
1✔
496
            } else {
497
                $dataType = gettype($data);
1✔
498
                $data     = filter_var($data, $filter, $flags);
1✔
499

500
                if (in_array($dataType, ['int', 'integer', 'float', 'double', 'bool', 'boolean'], true) && $data !== false) {
1✔
501
                    settype($data, $dataType);
×
502
                }
503
            }
504
        }
505

506
        if (! $assoc) {
5✔
507
            if (is_array($index)) {
4✔
508
                foreach ($data as &$val) {
2✔
509
                    $val = is_array($val) ? json_decode(json_encode($val)) : $val;
2✔
510
                }
511

512
                return $data;
2✔
513
            }
514

515
            return json_decode(json_encode($data));
3✔
516
        }
517

518
        return $data;
2✔
519
    }
520

521
    /**
522
     * A convenience method that grabs the raw input stream(send method in PUT, PATCH, DELETE) and decodes
523
     * the String into an array.
524
     *
525
     * @return array
526
     */
527
    public function getRawInput()
528
    {
529
        parse_str($this->body ?? '', $output);
14✔
530

531
        return $output;
14✔
532
    }
533

534
    /**
535
     * Gets a specific variable from raw input stream (send method in PUT, PATCH, DELETE).
536
     *
537
     * @param array|string|null $index  The variable that you want which can use dot syntax for getting specific values.
538
     * @param int|null          $filter Filter Constant
539
     * @param array|int|null    $flags  Option
540
     *
541
     * @return array|bool|float|int|object|string|null
542
     */
543
    public function getRawInputVar($index = null, ?int $filter = null, $flags = null)
544
    {
545
        helper('array');
10✔
546

547
        parse_str($this->body ?? '', $output);
10✔
548

549
        if (is_string($index)) {
10✔
550
            $output = dot_array_search($index, $output);
6✔
551
        } elseif (is_array($index)) {
4✔
552
            $data = [];
2✔
553

554
            foreach ($index as $key) {
2✔
555
                $data[$key] = dot_array_search($key, $output);
2✔
556
            }
557

558
            [$output, $data] = [$data, null];
2✔
559
        }
560

561
        $filter ??= FILTER_UNSAFE_RAW;
10✔
562
        $flags = is_array($flags) ? $flags : (is_numeric($flags) ? (int) $flags : 0);
10✔
563

564
        if (is_array($output)
10✔
565
            && (
566
                $filter !== FILTER_UNSAFE_RAW
10✔
567
                || (
10✔
568
                    (is_numeric($flags) && $flags !== 0)
10✔
569
                    || is_array($flags) && $flags !== []
10✔
570
                )
10✔
571
            )
572
        ) {
573
            // Iterate over array and append filter and flags
574
            array_walk_recursive($output, static function (&$val) use ($filter, $flags): void {
×
575
                $val = filter_var($val, $filter, $flags);
×
576
            });
×
577

578
            return $output;
×
579
        }
580

581
        if (is_string($output)) {
10✔
582
            return filter_var($output, $filter, $flags);
5✔
583
        }
584

585
        return $output;
5✔
586
    }
587

588
    /**
589
     * Fetch an item from GET data.
590
     *
591
     * @param array|string|null $index  Index for item to fetch from $_GET.
592
     * @param int|null          $filter A filter name to apply.
593
     * @param array|int|null    $flags
594
     *
595
     * @return array|bool|float|int|object|string|null
596
     */
597
    public function getGet($index = null, $filter = null, $flags = null)
598
    {
599
        return $this->fetchGlobal('get', $index, $filter, $flags);
70✔
600
    }
601

602
    /**
603
     * Returns a typed input data selector.
604
     */
605
    public function input(): RequestInput
606
    {
607
        return $this->input ??= new RequestInput($this, service('inputdatafactory'));
10✔
608
    }
609

610
    /**
611
     * Fetch an item from POST.
612
     *
613
     * @param array|string|null $index  Index for item to fetch from $_POST.
614
     * @param int|null          $filter A filter name to apply
615
     * @param array|int|null    $flags
616
     *
617
     * @return array|bool|float|int|object|string|null
618
     */
619
    public function getPost($index = null, $filter = null, $flags = null)
620
    {
621
        return $this->fetchGlobal('post', $index, $filter, $flags);
137✔
622
    }
623

624
    /**
625
     * Fetch an item from POST data with fallback to GET.
626
     *
627
     * @param array|string|null $index  Index for item to fetch from $_POST or $_GET
628
     * @param int|null          $filter A filter name to apply
629
     * @param array|int|null    $flags
630
     *
631
     * @return array|bool|float|int|object|string|null
632
     */
633
    public function getPostGet($index = null, $filter = null, $flags = null)
634
    {
635
        if ($index === null) {
5✔
636
            return array_merge($this->getGet($index, $filter, $flags), $this->getPost($index, $filter, $flags));
3✔
637
        }
638

639
        // Use $_POST directly here, since filter_has_var only
640
        // checks the initial POST data, not anything that might
641
        // have been added since.
642
        return service('superglobals')->post($index) !== null
2✔
643
            ? $this->getPost($index, $filter, $flags)
1✔
644
            : (service('superglobals')->get($index) !== null ? $this->getGet($index, $filter, $flags) : $this->getPost($index, $filter, $flags));
2✔
645
    }
646

647
    /**
648
     * Fetch an item from GET data with fallback to POST.
649
     *
650
     * @param array|string|null $index  Index for item to be fetched from $_GET or $_POST
651
     * @param int|null          $filter A filter name to apply
652
     * @param array|int|null    $flags
653
     *
654
     * @return array|bool|float|int|object|string|null
655
     */
656
    public function getGetPost($index = null, $filter = null, $flags = null)
657
    {
658
        if ($index === null) {
5✔
659
            return array_merge($this->getPost($index, $filter, $flags), $this->getGet($index, $filter, $flags));
3✔
660
        }
661

662
        // Use $_GET directly here, since filter_has_var only
663
        // checks the initial GET data, not anything that might
664
        // have been added since.
665
        return service('superglobals')->get($index) !== null
2✔
666
            ? $this->getGet($index, $filter, $flags)
1✔
667
            : (service('superglobals')->post($index) !== null ? $this->getPost($index, $filter, $flags) : $this->getGet($index, $filter, $flags));
2✔
668
    }
669

670
    /**
671
     * Fetch an item from the COOKIE array.
672
     *
673
     * @param array|string|null $index  Index for item to be fetched from $_COOKIE
674
     * @param int|null          $filter A filter name to be applied
675
     * @param array|int|null    $flags
676
     *
677
     * @return array|bool|float|int|object|string|null
678
     */
679
    public function getCookie($index = null, $filter = null, $flags = null)
680
    {
681
        return $this->fetchGlobal('cookie', $index, $filter, $flags);
154✔
682
    }
683

684
    /**
685
     * Fetch the user agent string
686
     *
687
     * @return UserAgent
688
     */
689
    public function getUserAgent()
690
    {
691
        return $this->userAgent;
6✔
692
    }
693

694
    /**
695
     * Attempts to get old Input data that has been flashed to the session
696
     * with redirect_with_input(). It first checks for the data in the old
697
     * POST data, then the old GET data and finally check for dot arrays
698
     *
699
     * @return array|string|null
700
     */
701
    public function getOldInput(string $key)
702
    {
703
        // If the session hasn't been started, we're done.
704
        if (! isset($_SESSION)) {
20✔
705
            return null;
×
706
        }
707

708
        // Get previously saved in session
709
        $old = session('_ci_old_input');
20✔
710

711
        // If no data was previously saved, we're done.
712
        if ($old === null) {
20✔
713
            return null;
6✔
714
        }
715

716
        // Check for the value in the POST array first.
717
        if (isset($old['post'][$key])) {
16✔
718
            return $old['post'][$key];
13✔
719
        }
720

721
        // Next check in the GET array.
722
        if (isset($old['get'][$key])) {
8✔
723
            return $old['get'][$key];
3✔
724
        }
725

726
        helper('array');
6✔
727

728
        // Check for an array value in POST.
729
        if (isset($old['post'])) {
6✔
730
            $value = dot_array_search($key, $old['post']);
6✔
731
            if ($value !== null) {
6✔
732
                return $value;
1✔
733
            }
734
        }
735

736
        // Check for an array value in GET.
737
        if (isset($old['get'])) {
6✔
738
            $value = dot_array_search($key, $old['get']);
3✔
739
            if ($value !== null) {
3✔
740
                return $value;
1✔
741
            }
742
        }
743

744
        // requested session key not found
745
        return null;
5✔
746
    }
747

748
    /**
749
     * Returns an array of all files that have been uploaded with this
750
     * request. Each file is represented by an UploadedFile instance.
751
     */
752
    public function getFiles(): array
753
    {
754
        if ($this->files === null) {
1✔
755
            $this->files = new FileCollection();
1✔
756
        }
757

758
        return $this->files->all(); // return all files
1✔
759
    }
760

761
    /**
762
     * Verify if a file exist, by the name of the input field used to upload it, in the collection
763
     * of uploaded files and if is have been uploaded with multiple option.
764
     *
765
     * @return array|null
766
     */
767
    public function getFileMultiple(string $fileID)
768
    {
769
        if ($this->files === null) {
61✔
770
            $this->files = new FileCollection();
61✔
771
        }
772

773
        return $this->files->getFileMultiple($fileID);
61✔
774
    }
775

776
    /**
777
     * Retrieves a single file by the name of the input field used
778
     * to upload it.
779
     *
780
     * @return UploadedFile|null
781
     */
782
    public function getFile(string $fileID)
783
    {
784
        if ($this->files === null) {
57✔
785
            $this->files = new FileCollection();
1✔
786
        }
787

788
        return $this->files->getFile($fileID);
57✔
789
    }
790
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc