Completed
Push — master ( e50785...8e9c44 )
by José
13s
created

Table::resetData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * Phinx
4
 *
5
 * (The MIT license)
6
 * Copyright (c) 2015 Rob Morgan
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated * documentation files (the "Software"), to
10
 * deal in the Software without restriction, including without limitation the
11
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12
 * sell copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24
 * IN THE SOFTWARE.
25
 *
26
 * @package    Phinx
27
 * @subpackage Phinx\Db
28
 */
29
namespace Phinx\Db;
30
31
use Phinx\Db\Action\AddColumn;
32
use Phinx\Db\Action\AddForeignKey;
33
use Phinx\Db\Action\AddIndex;
34
use Phinx\Db\Action\ChangeColumn;
35
use Phinx\Db\Action\CreateTable;
36
use Phinx\Db\Action\DropColumn;
37
use Phinx\Db\Action\DropForeignKey;
38
use Phinx\Db\Action\DropIndex;
39
use Phinx\Db\Action\DropTable;
40
use Phinx\Db\Action\RemoveColumn;
41
use Phinx\Db\Action\RenameColumn;
42
use Phinx\Db\Action\RenameTable;
43
use Phinx\Db\Adapter\AdapterInterface;
44
use Phinx\Db\Plan\Intent;
45
use Phinx\Db\Plan\Plan;
46
use Phinx\Db\Table\Column;
47
use Phinx\Db\Table\Table as TableValue;
48
49
/**
50
 *
51
 * This object is based loosely on: http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html.
52
 */
53
class Table
54
{
55
    /**
56
     * @var \Phinx\Db\Table\Table
57
     */
58
    protected $table;
59
60
    /**
61
     * @var \Phinx\Db\Adapter\AdapterInterface
62
     */
63
    protected $adapter;
64
65
    /**
66
     * @var \Phinx\Db\Plan\Intent
67
     */
68
    protected $actions;
69
70
    /**
71
     * @var array
72
     */
73
    protected $data = [];
74
75
    /**
76
     * Class Constuctor.
77
     *
78
     * @param string $name Table Name
79
     * @param array $options Options
80
     * @param \Phinx\Db\Adapter\AdapterInterface $adapter Database Adapter
81
     */
82
    public function __construct($name, $options = [], AdapterInterface $adapter = null)
83
    {
84 239
        $this->table = new TableValue($name, $options);
85
        $this->actions = new Intent();
86 239
87 239
        if ($adapter !== null) {
88
            $this->setAdapter($adapter);
89 239
        }
90 231
    }
91 231
92 239
    /**
93
     * Gets the table name.
94
     *
95
     * @return string|null
96
     */
97
    public function getName()
98
    {
99
        return $this->table->getName();
100 239
    }
101
102 239
    /**
103 239
     * Gets the table options.
104
     *
105
     * @return array
106
     */
107
    public function getOptions()
108
    {
109
        return $this->table->getOptions();
110
    }
111 215
112
    /**
113 215
     * Gets the table name and options as an object
114
     *
115
     * @return \Phinx\Db\Table\Table
116
     */
117
    public function getTable()
118
    {
119
        return $this->table;
120
    }
121
122 239
    /**
123
     * Sets the database adapter.
124 239
     *
125 239
     * @param \Phinx\Db\Adapter\AdapterInterface $adapter Database Adapter
126
     * @return \Phinx\Db\Table
127
     */
128
    public function setAdapter(AdapterInterface $adapter)
129
    {
130
        $this->adapter = $adapter;
131
132
        return $this;
133 189
    }
134
135 189
    /**
136
     * Gets the database adapter.
137
     *
138
     * @return \Phinx\Db\Adapter\AdapterInterface|null
139
     */
140
    public function getAdapter()
141
    {
142
        if (!$this->adapter) {
143
            throw new \RuntimeException('There is no database adapter set yet, cannot proceed');
144 231
        }
145
146 231
        return $this->adapter;
147 231
    }
148
149
    /**
150
     * Does the table exist?
151
     *
152
     * @return bool
153
     */
154
    public function exists()
155 225
    {
156
        return $this->getAdapter()->hasTable($this->getName());
157 225
    }
158
159
    /**
160
     * Drops the database table.
161
     *
162
     * @return \Phinx\Db\Table
163
     */
164
    public function drop()
165 195
    {
166
        $this->actions->addAction(new DropTable($this->table));
167 195
168
        return $this;
169
    }
170
171
    /**
172
     * Renames the database table.
173
     *
174
     * @param string $newTableName New Table Name
175 1
     * @return \Phinx\Db\Table
176
     */
177 1
    public function rename($newTableName)
178 1
    {
179
        $this->actions->addAction(new RenameTable($this->table, $newTableName));
180
181
        return $this;
182
    }
183
184
    /**
185
     * Gets an array of the table columns.
186 3
     *
187
     * @return \Phinx\Db\Table\Column[]
188 3
     */
189 3
    public function getColumns()
190 3
    {
191
        return $this->getAdapter()->getColumns($this->getName());
192
    }
193
194
    /**
195
     * Sets an array of data to be inserted.
196
     *
197
     * @param array $data Data
198
     * @return \Phinx\Db\Table
199
     */
200
    public function setData($data)
201
    {
202
        $this->data = $data;
203
204
        return $this;
205
    }
206
207
    /**
208
     * Gets the data waiting to be inserted.
209
     *
210
     * @return array
211 10
     */
212
    public function getData()
213 10
    {
214
        return $this->data;
215
    }
216
217
    /**
218
     * Resets all of the pending data to be inserted
219
     *
220
     * @return void
221
     */
222 196
    public function resetData()
223
    {
224 196
        $this->setData([]);
225 196
    }
226
227
    /**
228
     * Resets all of the pending table changes.
229
     *
230
     * @return void
231
     */
232
    public function reset()
233 204
    {
234
        $this->actions = new Intent();
235 204
        $this->resetData();
236
    }
237
238
    /**
239
     * Add a table column.
240
     *
241
     * Type can be: string, text, integer, float, decimal, datetime, timestamp,
242
     * time, date, binary, boolean.
243
     *
244 196
     * Valid options can be: limit, default, null, precision or scale.
245
     *
246 196
     * @param string|\Phinx\Db\Table\Column $columnName Column Name
247 196
     * @param string|\Phinx\Util\Literal $type Column Type
248
     * @param array $options Column Options
249
     * @throws \RuntimeException
250
     * @throws \InvalidArgumentException
251
     * @return \Phinx\Db\Table
252
     */
253
    public function addColumn($columnName, $type = null, $options = [])
254
    {
255 191 View Code Duplication
        if ($columnName instanceof Column) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
256
            $action = new AddColumn($this->table, $columnName);
257 191
        } else {
258
            $action = AddColumn::build($this->table, $columnName, $type, $options);
259
        }
260
261
        // Delegate to Adapters to check column type
262
        if (!$this->getAdapter()->isValidColumnType($action->getColumn())) {
263
            throw new \InvalidArgumentException(sprintf(
264
                'An invalid column type "%s" was specified for column "%s".',
265
                $type,
266 196
                $action->getColumn()->getName()
267
            ));
268 196
        }
269 196
270
        $this->actions->addAction($action);
271
272
        return $this;
273
    }
274
275
    /**
276
     * Remove a table column.
277 192
     *
278
     * @param string $columnName Column Name
279 192
     * @return \Phinx\Db\Table
280
     */
281
    public function removeColumn($columnName)
282
    {
283
        $action = RemoveColumn::build($this->table, $columnName);
284
        $this->actions->addAction($action);
285
286
        return $this;
287
    }
288 196
289
    /**
290 196
     * Rename a table column.
291 196
     *
292
     * @param string $oldName Old Column Name
293
     * @param string $newName New Column Name
294
     * @return \Phinx\Db\Table
295
     */
296
    public function renameColumn($oldName, $newName)
297
    {
298
        $action = RenameColumn::build($this->table, $oldName, $newName);
299 197
        $this->actions->addAction($action);
300
301 197
        return $this;
302
    }
303
304
    /**
305
     * Change a table column type.
306
     *
307
     * @param string        $columnName    Column Name
308
     * @param string|\Phinx\Db\Table\Column|\Phinx\Util\Literal $newColumnType New Column Type
309 196
     * @param array         $options       Options
310
     * @return \Phinx\Db\Table
311 196
     */
312 196
    public function changeColumn($columnName, $newColumnType, array $options = [])
313 196
    {
314 196 View Code Duplication
        if ($newColumnType instanceof Column) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
315 196
            $action = new ChangeColumn($this->table, $columnName, $newColumnType);
316
        } else {
317
            $action = ChangeColumn::build($this->table, $columnName, $newColumnType, $options);
318
        }
319
        $this->actions->addAction($action);
320
321
        return $this;
322
    }
323
324
    /**
325
     * Checks to see if a column exists.
326
     *
327
     * @param string $columnName Column Name
328
     * @return bool
329
     */
330
    public function hasColumn($columnName)
331
    {
332 210
        return $this->getAdapter()->hasColumn($this->getName(), $columnName);
333
    }
334
335 210
    /**
336 1
     * Add an index to a database table.
337
     *
338
     * In $options you can specific unique = true/false or name (index name).
339
     *
340 209
     * @param string|array|\Phinx\Db\Table\Index $columns Table Column(s)
341 207
     * @param array $options Index Options
342 207
     * @return \Phinx\Db\Table
343 207
     */
344 207
    public function addIndex($columns, array $options = [])
345 207
    {
346 2
        $action = AddIndex::build($this->table, $columns, $options);
347
        $this->actions->addAction($action);
348
349
        return $this;
350 209
    }
351 1
352 1
    /**
353 1
     * Removes the given index from a table.
354 1
     *
355 1
     * @param array $columns Columns
356
     * @return \Phinx\Db\Table
357
     */
358 208
    public function removeIndex(array $columns)
359 208
    {
360
        $action = DropIndex::build($this->table, $columns);
361
        $this->actions->addAction($action);
362
363
        return $this;
364
    }
365
366
    /**
367
     * Removes the given index identified by its name from a table.
368 1
     *
369
     * @param string $name Index name
370 1
     * @return \Phinx\Db\Table
371 1
     */
372
    public function removeIndexByName($name)
373
    {
374
        $action = DropIndex::buildFromName($this->table, $name);
375
        $this->actions->addAction($action);
376
377
        return $this;
378
    }
379
380
    /**
381 4
     * Checks to see if an index exists.
382
     *
383 4
     * @param string|array $columns Columns
384 4
     * @return bool
385
     */
386
    public function hasIndex($columns)
387
    {
388
        return $this->getAdapter()->hasIndex($this->getName(), $columns);
389
    }
390
391
    /**
392
     * Checks to see if an index specified by name exists.
393
     *
394
     * @param string $indexName
395 17
     * @return bool
396
     */
397
    public function hasIndexByName($indexName)
398 17
    {
399 4
        return $this->getAdapter()->hasIndexByName($this->getName(), $indexName);
400 4
    }
401 4
402 4
    /**
403 13
     * Add a foreign key to a database table.
404
     *
405
     * In $options you can specify on_delete|on_delete = cascade|no_action ..,
406
     * on_update, constraint = constraint name.
407 17
     *
408 15
     * @param string|array $columns Columns
409 15
     * @param string|\Phinx\Db\Table $referencedTable   Referenced Table
410
     * @param string|array $referencedColumns Referenced Columns
411 17
     * @param array $options Options
412 17
     * @return \Phinx\Db\Table
413
     */
414 View Code Duplication
    public function addForeignKey($columns, $referencedTable, $referencedColumns = ['id'], $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
415
    {
416
        $action = AddForeignKey::build($this->table, $columns, $referencedTable, $referencedColumns, $options);
0 ignored issues
show
Bug introduced by
It seems like $columns defined by parameter $columns on line 414 can also be of type array; however, Phinx\Db\Action\AddForeignKey::build() does only seem to accept string|array<integer,string>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
Bug introduced by
It seems like $referencedTable defined by parameter $referencedTable on line 414 can also be of type object<Phinx\Db\Table>; however, Phinx\Db\Action\AddForeignKey::build() does only seem to accept object<Phinx\Db\Table\Table>|string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
417
        $this->actions->addAction($action);
418
419
        return $this;
420
    }
421 89
422
    /**
423 89
     * Add a foreign key to a database table with a given name.
424
     *
425
     * In $options you can specify on_delete|on_delete = cascade|no_action ..,
426
     * on_update, constraint = constraint name.
427
     *
428
     * @param string $name The constaint name
429
     * @param string|array $columns Columns
430
     * @param string|\Phinx\Db\Table $referencedTable   Referenced Table
431
     * @param string|array $referencedColumns Referenced Columns
432
     * @param array $options Options
433
     * @return \Phinx\Db\Table
434
     */
435 29 View Code Duplication
    public function addForeignKeyWithName($name, $columns, $referencedTable, $referencedColumns = ['id'], $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
436
    {
437
        $action = AddForeignKey::build(
438 29
            $this->table,
439 28
            $columns,
0 ignored issues
show
Bug introduced by
It seems like $columns defined by parameter $columns on line 435 can also be of type array; however, Phinx\Db\Action\AddForeignKey::build() does only seem to accept string|array<integer,string>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
440 28
            $referencedTable,
0 ignored issues
show
Bug introduced by
It seems like $referencedTable defined by parameter $referencedTable on line 435 can also be of type object<Phinx\Db\Table>; however, Phinx\Db\Action\AddForeignKey::build() does only seem to accept object<Phinx\Db\Table\Table>|string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
441 22
            $referencedColumns,
442 22
            $options,
443 28
            $name
444 28
        );
445 28
        $this->actions->addAction($action);
446 1
447
        return $this;
448
    }
449 29
450 29
    /**
451
     * Removes the given foreign key from the table.
452
     *
453
     * @param string|array $columns    Column(s)
454
     * @param null|string  $constraint Constraint names
455
     * @return \Phinx\Db\Table
456
     */
457
    public function dropForeignKey($columns, $constraint = null)
458
    {
459 1
        $action = DropForeignKey::build($this->table, $columns, $constraint);
0 ignored issues
show
Bug introduced by
It seems like $columns defined by parameter $columns on line 457 can also be of type array; however, Phinx\Db\Action\DropForeignKey::build() does only seem to accept string|array<integer,string>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
460
        $this->actions->addAction($action);
461 1
462 1
        return $this;
463
    }
464
465
    /**
466
     * Checks to see if a foreign key exists.
467
     *
468
     * @param  string|array $columns    Column(s)
469
     * @param  null|string  $constraint Constraint names
470
     * @return bool
471 1
     */
472
    public function hasForeignKey($columns, $constraint = null)
473 1
    {
474 1
        return $this->getAdapter()->hasForeignKey($this->getName(), $columns, $constraint);
0 ignored issues
show
Documentation introduced by
$columns is of type string|array, but the function expects a array<integer,string>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
475
    }
476
477
    /**
478
     * Add timestamp columns created_at and updated_at to the table.
479
     *
480
     * @param string|null $createdAt    Alternate name for the created_at column
481
     * @param string|null $updatedAt    Alternate name for the updated_at column
482
     * @param bool        $withTimezone Whether to set the timezone option on the added columns
483
     *
484 12
     * @return \Phinx\Db\Table
485
     */
486 12
    public function addTimestamps($createdAt = 'created_at', $updatedAt = 'updated_at', $withTimezone = false)
487
    {
488
        $createdAt = is_null($createdAt) ? 'created_at' : $createdAt;
489
        $updatedAt = is_null($updatedAt) ? 'updated_at' : $updatedAt;
490
491
        $this->addColumn($createdAt, 'timestamp', [
492
                   'default' => 'CURRENT_TIMESTAMP',
493
                   'update' => '',
494
                   'timezone' => $withTimezone,
495
             ])
496
             ->addColumn($updatedAt, 'timestamp', [
497
                 'null' => true,
498
                 'default' => null,
499
                 'timezone' => $withTimezone,
500
             ]);
501 8
502
        return $this;
503 8
    }
504 4
505 4
    /**
506 8
     * Alias that always sets $withTimezone to true
507 8
     * @see addTimestamps
508
     *
509
     * @param string|null $createdAt Alternate name for the created_at column
510 8
     * @param string|null $updatedAt Alternate name for the updated_at column
511
     *
512 8
     * @return \Phinx\Db\Table
513 8
     */
514 8
    public function addTimestampsWithTimezone($createdAt = null, $updatedAt = null)
515 8
    {
516
        $this->addTimestamps($createdAt, $updatedAt, true);
517 8
518
        return $this;
519
    }
520
521
    /**
522
     * Insert data into the table.
523
     *
524
     * @param array $data array of data in the form:
525
     *              array(
526
     *                  array("col1" => "value1", "col2" => "anotherValue1"),
527 1
     *                  array("col2" => "value2", "col2" => "anotherValue2"),
528
     *              )
529 1
     *              or array("col1" => "value1", "col2" => "anotherValue1")
530 1
     *
531 1
     * @return \Phinx\Db\Table
532 1
     */
533
    public function insert($data)
534
    {
535 1
        // handle array of array situations
536
        if (isset($data[0]) && is_array($data[0])) {
537
            foreach ($data as $row) {
538 1
                $this->data[] = $row;
539
            }
540
541
            return $this;
542
        }
543
        $this->data[] = $data;
544
545
        return $this;
546
    }
547
548 1
    /**
549
     * Creates a table from the object instance.
550 1
     *
551
     * @return void
552
     */
553
    public function create()
554
    {
555
        $this->executeActions(false);
556
        $this->saveData();
557
        $this->reset(); // reset pending changes
558
    }
559
560
    /**
561 15
     * Updates a table from the object instance.
562
     *
563 15
     * @throws \RuntimeException
564 15
     * @return void
565 15
     */
566 15
    public function update()
567
    {
568 15
        $this->executeActions(true);
569 15
        $this->saveData();
570 15
        $this->reset(); // reset pending changes
571
    }
572 15
573
    /**
574 15
     * Commit the pending data waiting for insertion.
575
     *
576
     * @return void
577
     */
578
    public function saveData()
579
    {
580
        $rows = $this->getData();
581
        if (empty($rows)) {
582
            return;
583
        }
584
585
        $bulk = true;
586
        $row = current($rows);
587
        $c = array_keys($row);
588
        foreach ($this->getData() as $row) {
589 17
            $k = array_keys($row);
590
            if ($k != $c) {
591
                $bulk = false;
592 17
                break;
593 11
            }
594 11
        }
595 11
596 11
        if ($bulk) {
597
            $this->getAdapter()->bulkinsert($this->table, $this->getData());
598 8
        } else {
599 8
            foreach ($this->getData() as $row) {
600
                $this->getAdapter()->insert($this->table, $row);
601
            }
602
        }
603
604
        $this->resetData();
605
    }
606
607 196
    /**
608
     * Immediately truncates the table. This operation cannot be undone
609 196
     *
610 196
     * @return void
611 196
     */
612 196
    public function truncate()
613
    {
614
        $this->getAdapter()->truncateTable($this->getName());
615
    }
616
617
    /**
618
     * Commits the table changes.
619
     *
620 46
     * If the table doesn't exist it is created otherwise it is updated.
621
     *
622 46
     * @return void
623
     */
624
    public function save()
625
    {
626
        if ($this->exists()) {
627 46
            $this->update(); // update the table
628 38
        } else {
629 46
            $this->create(); // create the table
630
        }
631 46
    }
632 6
633 46
    /**
634
     * Executes all the pending actions for this table
635 46
     *
636 3
     * @param bool $exists Whether or not the table existed prior to executing this method
637 46
     * @return void
638
     */
639 46
    protected function executeActions($exists)
640 46
    {
641 46
        // Renaming a table is tricky, specially when running a reversible migration
642
        // down. We will just assume the table already exists if the user commands a
643
        // table rename.
644
        $renamed = collection($this->actions->getActions())
645
            ->filter(function ($action) {
646
                return $action instanceof RenameTable;
647
            })
648 196
            ->first();
649
650 196
        if ($renamed) {
651 196
            $exists = true;
652 192
        }
653
654
        // If the table does not exist, the last command in the chain needs to be
655 12
        // a CreateTable action.
656 12
        if (!$exists) {
657 12
            $this->actions->addAction(new CreateTable($this->table));
658 12
        }
659 12
660 12
        $plan = new Plan($this->actions);
661 1
        $plan->execute($this->getAdapter());
0 ignored issues
show
Bug introduced by
It seems like $this->getAdapter() can be null; however, execute() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
662 1
    }
663
}
664