Passed
Push — php8 ( bd75dc...d8afb4 )
by Fabio
08:15
created

TPriorityMap::_getZappableSleepProps()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 10
c 0
b 0
f 0
nc 16
nop 1
dl 0
loc 15
rs 9.6111
1
<?php
2
/**
3
 * TPriorityMap, TPriorityMapIterator classes
4
 *
5
 * @author Brad Anderson <[email protected]>
6
 * @link https://github.com/pradosoft/prado
7
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
8
 */
9
10
namespace Prado\Collections;
11
12
use Prado\Exceptions\TInvalidOperationException;
13
use Prado\Exceptions\TInvalidDataTypeException;
14
use Prado\TPropertyValue;
15
16
/**
17
 * TPriorityMap class
18
 *
19
 * TPriorityMap implements a collection that takes key-value pairs with
20
 * a priority to allow key-value pairs to be ordered.  This ordering is
21
 * important when flattening the map. When flattening the map, if some
22
 * key-value pairs are required to be before or after others, use this
23
 * class to keep order to your map.
24
 *
25
 * You can access, add or remove an item with a key by using
26
 * {@link itemAt}, {@link add}, and {@link remove}.  These functions
27
 * can optionally take a priority parameter to allow access to specific
28
 * priorities.  TPriorityMap is functionally backward compatible
29
 * with {@link TMap}.
30
 *
31
 * To get the number of the items in the map, use {@link getCount}.
32
 * TPriorityMap can also be used like a regular array as follows,
33
 * <code>
34
 * $map[$key]=$value; // add a key-value pair
35
 * unset($map[$key]); // remove the value with the specified key
36
 * if(isset($map[$key])) // if the map contains the key
37
 * foreach($map as $key=>$value) // traverse the items in the map
38
 * $n=count($map);  // returns the number of items in the map
39
 * </code>
40
 * Using standard array access method like these will always use
41
 * the default priority.
42
 *
43
 * An item that doesn't specify a priority will receive the default
44
 * priority.  The default priority is set during the instantiation
45
 * of a new TPriorityMap. If no custom default priority is specified,
46
 * the standard default priority of 10 is used.
47
 *
48
 * Priorities with significant digits below precision will be rounded.
49
 *
50
 * A priority may also be a numeric with decimals.  This is set
51
 * during the instantiation of a new TPriorityMap.
52
 * The default is 8 decimal places for a priority.  If a negative number
53
 * is used, rounding occurs into the integer space rather than in
54
 * the decimal space.  See {@link round}.
55
 *
56
 * @author Brad Anderson <[email protected]>
57
 * @since 3.2a
58
 * @method void dyAddItem(mixed $key, mixed $value)
59
 * @method void dyRemoveItem(mixed $key, mixed $value)
60
 * @method mixed dyNoItem(mixed $returnValue, mixed $key)
61
 */
62
class TPriorityMap extends TMap
63
{
64
	/**
65
	 * @var bool indicates if the _d is currently ordered.
66
	 */
67
	protected bool $_o = false;
68
	/**
69
	 * @var null|array cached flattened internal data storage
70
	 */
71
	protected ?array $_fd = null;
72
	/**
73
	 * @var int number of items contain within the map
74
	 */
75
	protected int $_c = 0;
76
	/**
77
	 * @var numeric the default priority of items without specified priorities
0 ignored issues
show
Bug introduced by
The type Prado\Collections\numeric was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
78
	 */
79
	private $_dp = 10;
80
	/**
81
	 * @var int the precision of the numeric priorities within this priority list.
82
	 */
83
	private int $_p = 8;
84
85
	/**
86
	 * Constructor.
87
	 * Initializes the array with an array or an iterable object.
88
	 * @param null|array|TPriorityMap|\Traversable $data the intial data. Default is null, meaning no initialization.
89
	 * @param bool $readOnly whether the list is read-only
90
	 * @param numeric $defaultPriority the default priority of items without specified priorities.
91
	 * @param int $precision the precision of the numeric priorities
92
	 * @throws TInvalidDataTypeException If data is not null and neither an array nor an iterator.
93
	 */
94
	public function __construct($data = null, $readOnly = false, $defaultPriority = 10, $precision = 8)
95
	{
96
		$this->setPrecision($precision);
97
		$this->setDefaultPriority($defaultPriority);
0 ignored issues
show
Bug introduced by
It seems like $defaultPriority can also be of type integer; however, parameter $value of Prado\Collections\TPrior...p::setDefaultPriority() does only seem to accept Prado\Collections\numeric, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

97
		$this->setDefaultPriority(/** @scrutinizer ignore-type */ $defaultPriority);
Loading history...
98
		parent::__construct($data, $readOnly);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type Prado\Collections\TPriorityMap; however, parameter $data of Prado\Collections\TMap::__construct() does only seem to accept Iterator|array|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

98
		parent::__construct(/** @scrutinizer ignore-type */ $data, $readOnly);
Loading history...
99
	}
100
101
	/**
102
	 * @return numeric gets the default priority of inserted items without a specified priority
103
	 */
104
	public function getDefaultPriority()
105
	{
106
		return $this->_dp;
107
	}
108
109
	/**
110
	 * This must be called internally or when instantiated.
111
	 * @param numeric $value sets the default priority of inserted items without a specified priority
112
	 */
113
	protected function setDefaultPriority($value)
114
	{
115
		$this->_dp = (string) round(TPropertyValue::ensureFloat($value), $this->_p);
0 ignored issues
show
Documentation Bug introduced by
It seems like (string)round(Prado\TPro...oat($value), $this->_p) of type string is incompatible with the declared type Prado\Collections\numeric of property $_dp.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
116
	}
117
118
	/**
119
	 * @return int The precision of numeric priorities, defaults to 8
120
	 */
121
	public function getPrecision(): int
122
	{
123
		return $this->_p;
124
	}
125
126
	/**
127
	 * This must be called internally or when instantiated.
128
	 * @param int $value The precision of numeric priorities.
129
	 */
130
	protected function setPrecision($value): void
131
	{
132
		$this->_p = TPropertyValue::ensureInteger($value);
133
	}
134
135
	/**
136
	 * Takes an input Priority and ensures its value.
137
	 * Sets the default $priority when none is set,
138
	 * then rounds to the proper precision and makes
139
	 * into a string.
140
	 * @param null|numeric $priority the priority to ensure
141
	 * @return string the priority in string format
142
	 */
143
	protected function ensurePriority($priority): string
144
	{
145
		if ($priority === null || !is_numeric($priority)) {
0 ignored issues
show
introduced by
The condition is_numeric($priority) is always false.
Loading history...
146
			$priority = $this->getDefaultPriority();
147
		}
148
		return (string) round((float) $priority, $this->_p);
149
	}
150
151
152
	/**
153
	 * Orders the priority list internally.
154
	 */
155
	protected function sortPriorities()
156
	{
157
		if (!$this->_o) {
158
			ksort($this->_d, SORT_NUMERIC);
159
			$this->_o = true;
160
		}
161
	}
162
163
	/**
164
	 * This flattens the priority map into a flat array [0,...,n-1]
165
	 * @return array array of items in the list in priority and index order
166
	 */
167
	protected function flattenPriorities(): array
168
	{
169
		if (is_array($this->_fd)) {
170
			return $this->_fd;
171
		}
172
173
		$this->sortPriorities();
174
		$this->_fd = [];
175
		foreach ($this->_d as $priority => $itemsatpriority) {
176
			$this->_fd = array_merge($this->_fd, $itemsatpriority);
0 ignored issues
show
Bug introduced by
$this->_fd of type null is incompatible with the type array expected by parameter $arrays of array_merge(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

176
			$this->_fd = array_merge(/** @scrutinizer ignore-type */ $this->_fd, $itemsatpriority);
Loading history...
177
		}
178
		return $this->_fd;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_fd returns the type null which is incompatible with the type-hinted return array.
Loading history...
179
	}
180
181
	/**
182
	 * @return int the number of items in the map
183
	 */
184
	public function getCount(): int
185
	{
186
		return $this->_c;
187
	}
188
189
	/**
190
	 * This returns a list of the priorities within this map, ordered lowest to highest.
191
	 * @return array the array of priority numerics in decreasing priority order
192
	 */
193
	public function getPriorities(): array
194
	{
195
		$this->sortPriorities();
196
		return array_keys($this->_d);
197
	}
198
199
	/**
200
	 * Gets the number of items at a priority within the map.
201
	 * @param null|numeric $priority optional priority at which to count items.  if no parameter,
202
	 * it will be set to the default {@link getDefaultPriority}
203
	 * @return false|int the number of items in the map at the specified priority
204
	 */
205
	public function getPriorityCount($priority = null)
206
	{
207
		$priority = $this->ensurePriority($priority);
208
		if (!isset($this->_d[$priority]) || !is_array($this->_d[$priority])) {
209
			return false;
210
		}
211
		return count($this->_d[$priority]);
212
	}
213
214
	/**
215
	 * Returns an iterator for traversing the items in the map.
216
	 * This method is required by the interface \IteratorAggregate.
217
	 * @return \Iterator an iterator for traversing the items in the map.
218
	 */
219
	public function getIterator(): \Iterator
220
	{
221
		return new \ArrayIterator($this->flattenPriorities());
222
	}
223
224
	/**
225
	 * Returns the keys within the map ordered through the priority of each key-value pair
226
	 * @return array the key list
227
	 */
228
	public function getKeys(): array
229
	{
230
		return array_keys($this->flattenPriorities());
231
	}
232
233
	/**
234
	 * Returns the item with the specified key.  If a priority is specified, only items
235
	 * within that specific priority will be selected
236
	 * @param mixed $key the key
237
	 * @param mixed $priority the priority.  null is the default priority, false is any priority,
238
	 * and numeric is a specific priority.  default: false, any priority.
239
	 * @return mixed the element at the offset, null if no element is found at the offset
240
	 */
241
	public function itemAt($key, $priority = false)
242
	{
243
		if ($priority === false) {
244
			$map = $this->flattenPriorities();
245
			return array_key_exists($key, $map) ? $map[$key] : $this->dyNoItem(null, $key);
246
		} else {
247
			$priority = $this->ensurePriority($priority);
248
			return (isset($this->_d[$priority]) && array_key_exists($key, $this->_d[$priority])) ? $this->_d[$priority][$key] : $this->dyNoItem(null, $key);
249
		}
250
	}
251
252
	/**
253
	 * This changes an item's priority.  Specify the item and the new priority.
254
	 * This method is exactly the same as {@link offsetGet}.
255
	 * @param mixed $key the key
256
	 * @param null|numeric $priority the priority.  default: null, filled in with the default priority numeric.
257
	 * @return numeric old priority of the item
258
	 */
259
	public function setPriorityAt($key, $priority = null)
260
	{
261
		$priority = $this->ensurePriority($priority);
262
		$oldpriority = $this->priorityAt($key);
263
		if ($oldpriority !== false && $oldpriority != $priority) {
264
			$value = $this->remove($key, $oldpriority);
265
			$this->add($key, $value, $priority);
0 ignored issues
show
Bug introduced by
$priority of type string is incompatible with the type Prado\Collections\numeric|null expected by parameter $priority of Prado\Collections\TPriorityMap::add(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

265
			$this->add($key, $value, /** @scrutinizer ignore-type */ $priority);
Loading history...
266
		}
267
		return $oldpriority;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $oldpriority could also return false which is incompatible with the documented return type Prado\Collections\numeric. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
268
	}
269
270
	/**
271
	 * Gets all the items at a specific priority.
272
	 * @param null|numeric $priority priority of the items to get.  Defaults to null, filled in with the default priority, if left blank.
273
	 * @return ?array all items at priority in index order, null if there are no items at that priority
274
	 */
275
	public function itemsAtPriority($priority = null): ?array
276
	{
277
		$priority = $this->ensurePriority($priority);
278
		return $this->_d[$priority] ?? null;
279
	}
280
281
	/**
282
	 * Returns the priority of a particular item within the map.  This searches the map for the item.
283
	 * @param mixed $item item to look for within the map
284
	 * @return false|numeric priority of the item in the map
285
	 */
286
	public function priorityOf($item)
287
	{
288
		$this->sortPriorities();
289
		foreach ($this->_d as $priority => $items) {
290
			if (($index = array_search($item, $items, true)) !== false) {
0 ignored issues
show
Unused Code introduced by
The assignment to $index is dead and can be removed.
Loading history...
291
				return $priority;
292
			}
293
		}
294
		return false;
295
	}
296
297
	/**
298
	 * Retutrns the priority of an item at a particular flattened index.
299
	 * @param int $key index of the item within the map
300
	 * @return false|numeric priority of the item in the map
301
	 */
302
	public function priorityAt($key)
303
	{
304
		$this->sortPriorities();
305
		foreach ($this->_d as $priority => $items) {
306
			if (array_key_exists($key, $items)) {
307
				return $priority;
308
			}
309
		}
310
		return false;
311
	}
312
313
	/**
314
	 * Adds an item into the map.  A third parameter may be used to set the priority
315
	 * of the item within the map.  Priority is primarily used during when flattening
316
	 * the map into an array where order may be and important factor of the key-value
317
	 * pairs within the array.
318
	 * Note, if the specified key already exists, the old value will be overwritten.
319
	 * No duplicate keys are allowed regardless of priority.
320
	 * @param mixed $key
321
	 * @param mixed $value
322
	 * @param null|numeric $priority default: null, filled in with default priority
323
	 * @throws TInvalidOperationException if the map is read-only
324
	 * @return numeric priority at which the pair was added
325
	 */
326
	public function add($key, $value, $priority = null)
327
	{
328
		$itemPriority = null;
329
		if (($isPriorityItem = ($value instanceof IPriorityItem)) && ($priority === null || !is_numeric($priority))) {
330
			$itemPriority = $priority = $value->getPriority();
331
		}
332
		$priority = $this->ensurePriority($priority);
333
		if (($value instanceof IPriorityCapture) && (!$isPriorityItem || $itemPriority !== $priority)) {
334
			$value->setPriority($priority);
0 ignored issues
show
Bug introduced by
$priority of type string is incompatible with the type Prado\Collections\numeric expected by parameter $value of Prado\Collections\IPriorityCapture::setPriority(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

334
			$value->setPriority(/** @scrutinizer ignore-type */ $priority);
Loading history...
335
		}
336
337
		if (!$this->getReadOnly()) {
338
			foreach ($this->_d as $innerpriority => $items) {
339
				if (array_key_exists($key, $items)) {
340
					unset($this->_d[$innerpriority][$key]);
341
					$this->_c--;
342
					if (count($this->_d[$innerpriority]) === 0) {
343
						unset($this->_d[$innerpriority]);
344
					}
345
					break;
346
				}
347
			}
348
			if (!isset($this->_d[$priority])) {
349
				$this->_d[$priority] = [$key => $value];
350
				$this->_o = false;
351
			} else {
352
				$this->_d[$priority][$key] = $value;
353
			}
354
			$this->_c++;
355
			$this->_fd = null;
356
			$this->dyAddItem($key, $value);
357
		} else {
358
			throw new TInvalidOperationException('map_readonly', get_class($this));
359
		}
360
		return $priority;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $priority returns the type string which is incompatible with the documented return type Prado\Collections\numeric.
Loading history...
361
	}
362
363
	/**
364
	 * Removes an item from the map by its key. If no priority, or false, is specified
365
	 * then priority is irrelevant. If null is used as a parameter for priority, then
366
	 * the priority will be the default priority.  If a priority is specified, or
367
	 * the default priority is specified, only key-value pairs in that priority
368
	 * will be affected.
369
	 * @param mixed $key the key of the item to be removed
370
	 * @param null|false|numeric $priority priority.  False is any priority, null is the
371
	 * default priority, and numeric is a specific priority
372
	 * @throws TInvalidOperationException if the map is read-only
373
	 * @return mixed the removed value, null if no such key exists.
374
	 */
375
	public function remove($key, $priority = false)
376
	{
377
		if (!$this->getReadOnly()) {
378
			if ($priority === false) {
379
				$this->sortPriorities();
380
				foreach ($this->_d as $priority => $items) {
381
					if (array_key_exists($key, $items)) {
382
						$value = $this->_d[$priority][$key];
383
						unset($this->_d[$priority][$key]);
384
						$this->_c--;
385
						if (count($this->_d[$priority]) === 0) {
386
							unset($this->_d[$priority]);
387
							$this->_o = false;
388
						}
389
						$this->_fd = null;
390
						$this->dyRemoveItem($key, $value);
391
						return $value;
392
					}
393
				}
394
				return null;
395
			} else {
396
				$priority = $this->ensurePriority($priority);
397
				if (isset($this->_d[$priority]) && (isset($this->_d[$priority][$key]) || array_key_exists($key, $this->_d[$priority]))) {
398
					$value = $this->_d[$priority][$key];
399
					unset($this->_d[$priority][$key]);
400
					$this->_c--;
401
					if (count($this->_d[$priority]) === 0) {
402
						unset($this->_d[$priority]);
403
						$this->_o = false;
404
					}
405
					$this->_fd = null;
406
					$this->dyRemoveItem($key, $value);
407
					return $value;
408
				} else {
409
					return null;
410
				}
411
			}
412
		} else {
413
			throw new TInvalidOperationException('map_readonly', get_class($this));
414
		}
415
	}
416
417
	/**
418
	 * Removes all items in the map.  {@link remove} is called on all items.
419
	 */
420
	public function clear(): void
421
	{
422
		foreach ($this->_d as $priority => $items) {
423
			foreach (array_keys($items) as $key) {
424
				$this->remove($key);
425
			}
426
		}
427
	}
428
429
	/**
430
	 * @param mixed $key the key
431
	 * @return bool whether the map contains an item with the specified key
432
	 */
433
	public function contains($key): bool
434
	{
435
		$map = $this->flattenPriorities();
436
		return isset($map[$key]) || array_key_exists($key, $map);
437
	}
438
439
	/**
440
	 * When the map is flattened into an array, the priorities are taken into
441
	 * account and elements of the map are ordered in the array according to
442
	 * their priority.
443
	 * @return array the list of items in array
444
	 */
445
	public function toArray(): array
446
	{
447
		return $this->flattenPriorities();
448
	}
449
450
	/**
451
	 * Combines the map elements which have a priority below the parameter value
452
	 * @param numeric $priority the cut-off priority.  All items of priority less than this are returned.
453
	 * @param bool $inclusive whether or not the input cut-off priority is inclusive.  Default: false, not inclusive.
454
	 * @return array the array of priorities keys with values of arrays of items that are below a specified priority.
455
	 *  The priorities are sorted so important priorities, lower numerics, are first.
456
	 */
457
	public function toArrayBelowPriority($priority, $inclusive = false): array
458
	{
459
		$this->sortPriorities();
460
		$items = [];
461
		foreach ($this->_d as $itemspriority => $itemsatpriority) {
462
			if ((!$inclusive && $itemspriority >= $priority) || $itemspriority > $priority) {
463
				break;
464
			}
465
			$items = array_merge($items, $itemsatpriority);
466
		}
467
		return $items;
468
	}
469
470
	/**
471
	 * Combines the map elements which have a priority above the parameter value
472
	 * @param numeric $priority the cut-off priority.  All items of priority greater than this are returned.
473
	 * @param bool $inclusive whether or not the input cut-off priority is inclusive.  Default: true, inclusive.
474
	 * @return array the array of priorities keys with values of arrays of items that are above a specified priority.
475
	 *  The priorities are sorted so important priorities, lower numerics, are first.
476
	 */
477
	public function toArrayAbovePriority($priority, $inclusive = true): array
478
	{
479
		$this->sortPriorities();
480
		$items = [];
481
		foreach ($this->_d as $itemspriority => $itemsatpriority) {
482
			if ((!$inclusive && $itemspriority <= $priority) || $itemspriority < $priority) {
483
				continue;
484
			}
485
			$items = array_merge($items, $itemsatpriority);
486
		}
487
		return $items;
488
	}
489
490
	/**
491
	 * Copies iterable data into the map.
492
	 * Note, existing data in the map will be cleared first.
493
	 * @param array|TPriorityMap|\Traversable $data the data to be copied from, must be an array, object implementing
494
	 * @throws TInvalidDataTypeException If data is neither an array nor an iterator.
495
	 */
496
	public function copyFrom($data): void
497
	{
498
		if ($data instanceof TPriorityMap) {
499
			if ($this->getCount() > 0) {
500
				$this->clear();
501
			}
502
			foreach ($data->getPriorities() as $priority) {
503
				foreach ($data->itemsAtPriority($priority) as $key => $value) {
504
					$this->add($key, $value, $priority);
505
				}
506
			}
507
		} elseif (is_array($data) || $data instanceof \Traversable) {
0 ignored issues
show
introduced by
$data is always a sub-type of Traversable.
Loading history...
508
			if ($this->getCount() > 0) {
509
				$this->clear();
510
			}
511
			foreach ($data as $key => $value) {
512
				$this->add($key, $value);
513
			}
514
		} elseif ($data !== null) {
515
			throw new TInvalidDataTypeException('map_data_not_iterable');
516
		}
517
	}
518
519
	/**
520
	 * Merges iterable data into the map.
521
	 * Existing data in the map will be kept and overwritten if the keys are the same.
522
	 * @param array|TPriorityMap|\Traversable $data the data to be merged with, must be an array,
523
	 * object implementing Traversable, or a TPriorityMap
524
	 * @throws TInvalidDataTypeException If data is neither an array nor an iterator.
525
	 */
526
	public function mergeWith($data): void
527
	{
528
		if ($data instanceof TPriorityMap) {
529
			foreach ($data->getPriorities() as $priority) {
530
				foreach ($data->itemsAtPriority($priority) as $key => $value) {
531
					$this->add($key, $value, $priority);
532
				}
533
			}
534
		} elseif (is_array($data) || $data instanceof \Traversable) {
0 ignored issues
show
introduced by
$data is always a sub-type of Traversable.
Loading history...
535
			foreach ($data as $key => $value) {
536
				$this->add($key, $value);
537
			}
538
		} elseif ($data !== null) {
539
			throw new TInvalidDataTypeException('map_data_not_iterable');
540
		}
541
	}
542
543
	/**
544
	 * Returns an array with the names of all variables of this object that should NOT be serialized
545
	 * because their value is the default one or useless to be cached for the next page loads.
546
	 * Reimplement in derived classes to add new variables, but remember to  also to call the parent
547
	 * implementation first.
548
	 * @param array $exprops by reference
549
	 * @since 4.2.3
550
	 */
551
	protected function _getZappableSleepProps(&$exprops)
552
	{
553
		parent::_getZappableSleepProps($exprops);
554
		if ($this->_o === false) {
555
			$exprops[] = "\0*\0_o";
556
		}
557
		$exprops[] = "\0*\0_fd";
558
		if ($this->_c === 0) {
559
			$exprops[] = "\0*\0_c";
560
		}
561
		if ($this->_dp == 10) {
0 ignored issues
show
introduced by
The condition $this->_dp == 10 is always false.
Loading history...
562
			$exprops[] = "\0" . __CLASS__ . "\0_dp";
563
		}
564
		if ($this->_p === 8) {
565
			$exprops[] = "\0" . __CLASS__ . "\0_p";
566
		}
567
	}
568
}
569